Merge remote-tracking branch 'mkp-scsi/4.5/scsi-fixes' into fixes
authorJames Bottomley <James.Bottomley@HansenPartnership.com>
Wed, 27 Jan 2016 01:44:42 +0000 (17:44 -0800)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Wed, 27 Jan 2016 01:44:42 +0000 (17:44 -0800)
2480 files changed:
CREDITS
Documentation/ABI/testing/configfs-rdma_cm [new file with mode: 0644]
Documentation/ABI/testing/configfs-usb-gadget-tcm [new file with mode: 0644]
Documentation/ABI/testing/sysfs-class-infiniband [new file with mode: 0644]
Documentation/DMA-API-HOWTO.txt
Documentation/arm/pxa/mfp.txt
Documentation/cgroup-v2.txt
Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
Documentation/devicetree/bindings/arm/bcm/brcm,bcm4708.txt
Documentation/devicetree/bindings/arm/bcm/brcm,nsp-cpu-method.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/compulab-boards.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/cpus.txt
Documentation/devicetree/bindings/arm/fsl.txt
Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
Documentation/devicetree/bindings/arm/mediatek.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
Documentation/devicetree/bindings/arm/omap/omap.txt
Documentation/devicetree/bindings/arm/rockchip.txt
Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt
Documentation/devicetree/bindings/arm/scu.txt
Documentation/devicetree/bindings/arm/shmobile.txt
Documentation/devicetree/bindings/arm/technologic.txt [new file with mode: 0644]
Documentation/devicetree/bindings/bus/uniphier-system-bus.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/arm-syscon-icst.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/dove-divider-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/renesas,h8300-div-clock.txt
Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/gpio-keys.txt
Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/ralink,rt2880-net.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt
Documentation/devicetree/bindings/pci/qcom,pcie.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pci/rcar-pci.txt
Documentation/devicetree/bindings/phy/phy-ath79-usb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt
Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/tps65217.txt
Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/mtk-uart.txt
Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/dove/pmu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/ti/wkup_m3_ipc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/spi/ti_qspi.txt
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt
Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/watchdog/meson-wdt.txt [new file with mode: 0644]
Documentation/devicetree/bindings/watchdog/meson6-wdt.txt [deleted file]
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
Documentation/devicetree/bindings/watchdog/sp805-wdt.txt [new file with mode: 0644]
Documentation/features/io/dma_map_attrs/arch-support.txt [deleted file]
Documentation/filesystems/vfat.txt
Documentation/infiniband/core_locking.txt
Documentation/kernel-parameters.txt
Documentation/kernel-per-CPU-kthreads.txt
Documentation/sysctl/fs.txt
Documentation/sysctl/kernel.txt
Documentation/ubsan.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/dma-mapping.h
arch/alpha/include/uapi/asm/mman.h
arch/arc/include/asm/dma-mapping.h
arch/arc/mm/dma.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-baltos-ir5221.dts
arch/arm/boot/dts/am335x-bone-common.dtsi
arch/arm/boot/dts/am335x-boneblack.dts
arch/arm/boot/dts/am335x-bonegreen.dts
arch/arm/boot/dts/am335x-chiliboard.dts
arch/arm/boot/dts/am335x-chilisom.dtsi
arch/arm/boot/dts/am335x-cm-t335.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-lxm.dts
arch/arm/boot/dts/am335x-nano.dts
arch/arm/boot/dts/am335x-pepper.dts
arch/arm/boot/dts/am335x-phycore-som.dtsi
arch/arm/boot/dts/am335x-sbc-t335.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-shc.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-sl50.dts
arch/arm/boot/dts/am335x-wega.dtsi
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am3517-craneboard.dts
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-cm-t43.dts [new file with mode: 0644]
arch/arm/boot/dts/am437x-gp-evm.dts
arch/arm/boot/dts/am437x-idk-evm.dts
arch/arm/boot/dts/am437x-sbc-t43.dts [new file with mode: 0644]
arch/arm/boot/dts/am437x-sk-evm.dts
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/am57xx-beagle-x15.dts
arch/arm/boot/dts/am57xx-cl-som-am57x.dts [new file with mode: 0644]
arch/arm/boot/dts/am57xx-sbc-am57x.dts [new file with mode: 0644]
arch/arm/boot/dts/arm-realview-pb11mp.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-370-netgear-rn102.dts
arch/arm/boot/dts/armada-370-netgear-rn104.dts
arch/arm/boot/dts/armada-388-clearfog.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-388-gp.dts
arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-vinco.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm-cygnus.dtsi
arch/arm/boot/dts/bcm-nsp.dtsi
arch/arm/boot/dts/bcm11351.dtsi
arch/arm/boot/dts/bcm21664.dtsi
arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
arch/arm/boot/dts/bcm2835-rpi-b.dts
arch/arm/boot/dts/bcm2835-rpi.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/bcm2836-rpi-2-b.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm2836.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm283x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm4708.dtsi
arch/arm/boot/dts/bcm4709-netgear-r8000.dts
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/boot/dts/bcm63138.dtsi
arch/arm/boot/dts/bcm94708.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm94709.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm953012k.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm958625k.dts
arch/arm/boot/dts/berlin2.dtsi
arch/arm/boot/dts/berlin2cd.dtsi
arch/arm/boot/dts/berlin2q-marvell-dmp.dts
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/compulab-sb-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/da850-enbw-cmc.dts
arch/arm/boot/dts/da850-evm.dts
arch/arm/boot/dts/da850.dtsi
arch/arm/boot/dts/dm8148-evm.dts
arch/arm/boot/dts/dm8148-t410.dts
arch/arm/boot/dts/dm814x-clocks.dtsi
arch/arm/boot/dts/dm814x.dtsi
arch/arm/boot/dts/dm816x.dtsi
arch/arm/boot/dts/dove-cubox.dts
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/dra62x-clocks.dtsi [new file with mode: 0644]
arch/arm/boot/dts/dra62x-j5eco-evm.dts [new file with mode: 0644]
arch/arm/boot/dts/dra62x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/dra72-evm.dts
arch/arm/boot/dts/ea3250.dts
arch/arm/boot/dts/emev2.dtsi
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210-origen.dts
arch/arm/boot/dts/exynos4210-smdkv310.dts
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4412-odroid-common.dtsi
arch/arm/boot/dts/exynos4412-odroidu3.dts
arch/arm/boot/dts/exynos4412-origen.dts
arch/arm/boot/dts/exynos4412-smdk4412.dts
arch/arm/boot/dts/exynos4412-trats2.dts
arch/arm/boot/dts/exynos4x12.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250-snow-common.dtsi
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5410.dtsi
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
arch/arm/boot/dts/exynos5422-odroidxu3.dts
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/imx25-pinfunc.h
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx28-cfa10057.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx51-ts4800.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl.dtsi
arch/arm/boot/dts/imx6q-novena.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
arch/arm/boot/dts/imx6qdl-gw551x.dtsi
arch/arm/boot/dts/imx6qdl-gw552x.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/imx6sx.dtsi
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/imx7d-cl-som-imx7.dts [new file with mode: 0644]
arch/arm/boot/dts/imx7d-sbc-imx7.dts [new file with mode: 0644]
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/kirkwood-nsa325.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts [new file with mode: 0644]
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/logicpd-torpedo-som.dtsi
arch/arm/boot/dts/lpc18xx.dtsi
arch/arm/boot/dts/lpc32xx.dtsi
arch/arm/boot/dts/lpc4337-ciaa.dts
arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
arch/arm/boot/dts/lpc4357.dtsi
arch/arm/boot/dts/ls1021a-qds.dts
arch/arm/boot/dts/ls1021a-twr.dts
arch/arm/boot/dts/ls1021a.dtsi
arch/arm/boot/dts/meson8b-odroidc1.dts
arch/arm/boot/dts/meson8b.dtsi
arch/arm/boot/dts/mt2701-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/mt2701.dtsi [new file with mode: 0644]
arch/arm/boot/dts/mt8135.dtsi
arch/arm/boot/dts/omap3-beagle-xm.dts
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-cm-t3x.dtsi
arch/arm/boot/dts/omap3-devkit8000-common.dtsi
arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
arch/arm/boot/dts/omap3-evm-37xx.dts
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/omap3-igep0020.dts
arch/arm/boot/dts/omap3-igep0030.dts
arch/arm/boot/dts/omap3-ldp.dts
arch/arm/boot/dts/omap3-lilly-a83x.dtsi
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/omap3-n950-n9.dtsi
arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
arch/arm/boot/dts/omap3-overo-palo35-common.dtsi
arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
arch/arm/boot/dts/omap3-pandora-common.dtsi
arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi
arch/arm/boot/dts/omap3-zoom3.dts
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap4-duovero-parlor.dts
arch/arm/boot/dts/omap4-panda-a4.dts
arch/arm/boot/dts/omap4-panda-common.dtsi
arch/arm/boot/dts/omap4-panda-es.dts
arch/arm/boot/dts/omap4-sdp-es23plus.dts
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4-var-om44customboard.dtsi
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap5-board-common.dtsi
arch/arm/boot/dts/omap5-cm-t54.dts
arch/arm/boot/dts/omap5-uevm.dts
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/phy3250.dts
arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts [new file with mode: 0644]
arch/arm/boot/dts/qcom-apq8064.dtsi
arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
arch/arm/boot/dts/qcom-apq8084-ifc6540.dts
arch/arm/boot/dts/qcom-apq8084-mtp.dts
arch/arm/boot/dts/qcom-apq8084.dtsi
arch/arm/boot/dts/qcom-msm8960.dtsi
arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/qcom-pm8841.dtsi
arch/arm/boot/dts/qcom-pm8941.dtsi
arch/arm/boot/dts/qcom-pma8084.dtsi
arch/arm/boot/dts/r7s72100.dtsi
arch/arm/boot/dts/r8a73a4-ape6evm.dts
arch/arm/boot/dts/r8a7740-armadillo800eva.dts
arch/arm/boot/dts/r8a7740.dtsi
arch/arm/boot/dts/r8a7778-bockw.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-henninger.dts [deleted file]
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791-porter.dts
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/r8a7793-gose.dts
arch/arm/boot/dts/r8a7793.dtsi
arch/arm/boot/dts/r8a7794-alt.dts
arch/arm/boot/dts/r8a7794-silk.dts
arch/arm/boot/dts/r8a7794.dtsi
arch/arm/boot/dts/rk3036-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3036-kylin.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3036.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3066a.dtsi
arch/arm/boot/dts/rk3188.dtsi
arch/arm/boot/dts/rk3228-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3228.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3288-evb-act8846.dts
arch/arm/boot/dts/rk3288-evb-rk808.dts
arch/arm/boot/dts/rk3288-evb.dtsi
arch/arm/boot/dts/rk3288-r89.dts
arch/arm/boot/dts/rk3288-rock2-som.dtsi
arch/arm/boot/dts/rk3288-rock2-square.dts
arch/arm/boot/dts/rk3288-thermal.dtsi
arch/arm/boot/dts/rk3288-veyron-brain.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron-mickey.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron-minnie.dts
arch/arm/boot/dts/rk3288-veyron-speedy.dts
arch/arm/boot/dts/rk3288-veyron.dtsi
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/rk3xxx.dtsi
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/sama5d4.dtsi
arch/arm/boot/dts/sh73a0-kzm9g.dts
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria5_socdk.dts
arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi [new file with mode: 0644]
arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts [new file with mode: 0644]
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href-stuib.dtsi
arch/arm/boot/dts/ste-href-tvk1281618.dtsi
arch/arm/boot/dts/ste-hrefv60plus.dtsi
arch/arm/boot/dts/ste-nomadik-s8815.dts
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/ste-u300.dts
arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
arch/arm/boot/dts/sun4i-a10-inet1.dts
arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts
arch/arm/boot/dts/sun4i-a10-mk802.dts
arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
arch/arm/boot/dts/sun7i-a20-bananapi.dts
arch/arm/boot/dts/sun7i-a20-icnova-swac.dts [new file with mode: 0644]
arch/arm/boot/dts/sun7i-a20-mk808c.dts
arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
arch/arm/boot/dts/sun7i-a20-pcduino3.dts
arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
arch/arm/boot/dts/sun9i-a80-optimus.dts
arch/arm/boot/dts/sun9i-a80.dtsi
arch/arm/boot/dts/tango4-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tango4-smp8758.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tango4-vantage-1172.dts [new file with mode: 0644]
arch/arm/boot/dts/tps65217.dtsi [deleted file]
arch/arm/boot/dts/twl4030_omap3.dtsi
arch/arm/boot/dts/twl6030_omap4.dtsi
arch/arm/boot/dts/uniphier-common32.dtsi [new file with mode: 0644]
arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
arch/arm/boot/dts/uniphier-proxstream2.dtsi
arch/arm/boot/dts/versatile-ab.dts
arch/arm/boot/dts/vf-colibri.dtsi
arch/arm/boot/dts/vf610m4-cosmic.dts [new file with mode: 0644]
arch/arm/boot/dts/vfxxx.dtsi
arch/arm/boot/dts/wm8505.dtsi
arch/arm/boot/dts/zynq-7000.dtsi
arch/arm/boot/dts/zynq-zc702.dts
arch/arm/common/mcpm_platsmp.c
arch/arm/common/scoop.c
arch/arm/configs/bcm2835_defconfig
arch/arm/configs/ep93xx_defconfig
arch/arm/configs/exynos_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/lpc18xx_defconfig
arch/arm/configs/lpc32xx_defconfig
arch/arm/configs/multi_v5_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mv78xx0_defconfig
arch/arm/configs/mvebu_v5_defconfig
arch/arm/configs/netwinder_defconfig
arch/arm/configs/orion5x_defconfig
arch/arm/configs/pxa_defconfig [new file with mode: 0644]
arch/arm/configs/qcom_defconfig
arch/arm/configs/realview-smp_defconfig
arch/arm/configs/realview_defconfig
arch/arm/configs/s3c6400_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/socfpga_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/versatile_defconfig
arch/arm/configs/zx_defconfig
arch/arm/include/asm/cputype.h
arch/arm/include/asm/div64.h
arch/arm/include/asm/dma-mapping.h
arch/arm/include/asm/psci.h
arch/arm/include/debug/dc21285.S [new file with mode: 0644]
arch/arm/kernel/devtree.c
arch/arm/kernel/psci_smp.c
arch/arm/kernel/xscale-cp0.c
arch/arm/mach-alpine/Kconfig
arch/arm/mach-alpine/platsmp.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-axxia/Kconfig
arch/arm/mach-axxia/platsmp.c
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/bcm63xx_smp.c
arch/arm/mach-bcm/bcm_5301x.c
arch/arm/mach-bcm/board_bcm2835.c
arch/arm/mach-bcm/kona_smp.c [deleted file]
arch/arm/mach-bcm/platsmp-brcmstb.c
arch/arm/mach-bcm/platsmp.c [new file with mode: 0644]
arch/arm/mach-berlin/Kconfig
arch/arm/mach-berlin/platsmp.c
arch/arm/mach-cns3xxx/Kconfig
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-mityomapl138.c
arch/arm/mach-davinci/board-omapl138-hawk.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-davinci/cp_intc.c
arch/arm/mach-davinci/cp_intc.h [new file with mode: 0644]
arch/arm/mach-davinci/cpuidle.c
arch/arm/mach-davinci/cpuidle.h [new file with mode: 0644]
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/da8xx-dt.c
arch/arm/mach-davinci/ddr2.h [new file with mode: 0644]
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/include/mach/cp_intc.h [deleted file]
arch/arm/mach-davinci/include/mach/cpuidle.h [deleted file]
arch/arm/mach-davinci/include/mach/ddr2.h [deleted file]
arch/arm/mach-davinci/include/mach/psc.h [deleted file]
arch/arm/mach-davinci/include/mach/sram.h [deleted file]
arch/arm/mach-davinci/pm.c
arch/arm/mach-davinci/psc.c
arch/arm/mach-davinci/psc.h [new file with mode: 0644]
arch/arm/mach-davinci/sleep.S
arch/arm/mach-davinci/sram.c
arch/arm/mach-davinci/sram.h [new file with mode: 0644]
arch/arm/mach-dove/cm-a510.c
arch/arm/mach-dove/common.c
arch/arm/mach-dove/dove-db-setup.c
arch/arm/mach-dove/include/mach/dove.h
arch/arm/mach-dove/include/mach/entry-macro.S [deleted file]
arch/arm/mach-dove/include/mach/irqs.h
arch/arm/mach-dove/include/mach/pm.h
arch/arm/mach-dove/irq.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pmu.c
arch/arm/mach-exynos/regs-pmu.h
arch/arm/mach-footbridge/include/mach/debug-macro.S [deleted file]
arch/arm/mach-highbank/Kconfig
arch/arm/mach-hisi/Kconfig
arch/arm/mach-hisi/core.h
arch/arm/mach-hisi/platmcpm.c
arch/arm/mach-hisi/platsmp.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/common.h
arch/arm/mach-imx/iomux-imx31.c
arch/arm/mach-imx/mach-imx6ul.c
arch/arm/mach-imx/mach-imx7d.c
arch/arm/mach-imx/platsmp.c
arch/arm/mach-integrator/Kconfig
arch/arm/mach-iop13xx/include/mach/msi.h [deleted file]
arch/arm/mach-iop13xx/include/mach/pci.h [deleted file]
arch/arm/mach-iop13xx/iq81340mc.c
arch/arm/mach-iop13xx/iq81340sc.c
arch/arm/mach-iop13xx/irq.c
arch/arm/mach-iop13xx/msi.h [new file with mode: 0644]
arch/arm/mach-iop13xx/pci.c
arch/arm/mach-iop13xx/pci.h
arch/arm/mach-keystone/keystone.h
arch/arm/mach-keystone/platsmp.c
arch/arm/mach-ks8695/board-acs5k.c
arch/arm/mach-ks8695/board-dsm320.c
arch/arm/mach-ks8695/board-micrel.c
arch/arm/mach-ks8695/board-og.c
arch/arm/mach-ks8695/board-sg.c
arch/arm/mach-ks8695/cpu.c
arch/arm/mach-ks8695/devices.c
arch/arm/mach-ks8695/devices.h [new file with mode: 0644]
arch/arm/mach-ks8695/include/mach/devices.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-hpna.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-lan.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-mem.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-pci.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-sys.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-wan.h [deleted file]
arch/arm/mach-ks8695/pci.c
arch/arm/mach-ks8695/regs-hpna.h [new file with mode: 0644]
arch/arm/mach-ks8695/regs-lan.h [new file with mode: 0644]
arch/arm/mach-ks8695/regs-mem.h [new file with mode: 0644]
arch/arm/mach-ks8695/regs-pci.h [new file with mode: 0644]
arch/arm/mach-ks8695/regs-sys.h [new file with mode: 0644]
arch/arm/mach-ks8695/regs-wan.h [new file with mode: 0644]
arch/arm/mach-mediatek/Kconfig
arch/arm/mach-mediatek/mediatek.c
arch/arm/mach-mediatek/platsmp.c
arch/arm/mach-meson/Kconfig
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/Makefile
arch/arm/mach-mmp/addr-map.h [new file with mode: 0644]
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/avengers_lite.c
arch/arm/mach-mmp/brownstone.c
arch/arm/mach-mmp/clock-mmp2.c
arch/arm/mach-mmp/clock-pxa168.c
arch/arm/mach-mmp/clock-pxa910.c
arch/arm/mach-mmp/clock.c
arch/arm/mach-mmp/clock.h
arch/arm/mach-mmp/common.c
arch/arm/mach-mmp/common.h
arch/arm/mach-mmp/cputype.h [new file with mode: 0644]
arch/arm/mach-mmp/devices.c
arch/arm/mach-mmp/devices.h [new file with mode: 0644]
arch/arm/mach-mmp/flint.c
arch/arm/mach-mmp/gplugd.c
arch/arm/mach-mmp/include/mach/addr-map.h [deleted file]
arch/arm/mach-mmp/include/mach/cputype.h [deleted file]
arch/arm/mach-mmp/include/mach/devices.h [deleted file]
arch/arm/mach-mmp/include/mach/dma.h [deleted file]
arch/arm/mach-mmp/include/mach/hardware.h [deleted file]
arch/arm/mach-mmp/include/mach/irqs.h [deleted file]
arch/arm/mach-mmp/include/mach/mfp-mmp2.h [deleted file]
arch/arm/mach-mmp/include/mach/mfp-pxa168.h [deleted file]
arch/arm/mach-mmp/include/mach/mfp-pxa910.h [deleted file]
arch/arm/mach-mmp/include/mach/mfp.h [deleted file]
arch/arm/mach-mmp/include/mach/mmp2.h [deleted file]
arch/arm/mach-mmp/include/mach/pm-mmp2.h [deleted file]
arch/arm/mach-mmp/include/mach/pm-pxa910.h [deleted file]
arch/arm/mach-mmp/include/mach/pxa168.h [deleted file]
arch/arm/mach-mmp/include/mach/pxa910.h [deleted file]
arch/arm/mach-mmp/include/mach/regs-apbc.h [deleted file]
arch/arm/mach-mmp/include/mach/regs-apmu.h [deleted file]
arch/arm/mach-mmp/include/mach/regs-icu.h [deleted file]
arch/arm/mach-mmp/include/mach/regs-smc.h [deleted file]
arch/arm/mach-mmp/include/mach/regs-timers.h [deleted file]
arch/arm/mach-mmp/include/mach/regs-usb.h [deleted file]
arch/arm/mach-mmp/include/mach/teton_bga.h [deleted file]
arch/arm/mach-mmp/include/mach/uncompress.h [deleted file]
arch/arm/mach-mmp/irqs.h [new file with mode: 0644]
arch/arm/mach-mmp/jasper.c
arch/arm/mach-mmp/mfp-mmp2.h [new file with mode: 0644]
arch/arm/mach-mmp/mfp-pxa168.h [new file with mode: 0644]
arch/arm/mach-mmp/mfp-pxa910.h [new file with mode: 0644]
arch/arm/mach-mmp/mfp.h [new file with mode: 0644]
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/mmp2.h [new file with mode: 0644]
arch/arm/mach-mmp/pm-mmp2.c
arch/arm/mach-mmp/pm-mmp2.h [new file with mode: 0644]
arch/arm/mach-mmp/pm-pxa910.c
arch/arm/mach-mmp/pm-pxa910.h [new file with mode: 0644]
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa168.h [new file with mode: 0644]
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-mmp/pxa910.h [new file with mode: 0644]
arch/arm/mach-mmp/regs-apbc.h [new file with mode: 0644]
arch/arm/mach-mmp/regs-apmu.h [new file with mode: 0644]
arch/arm/mach-mmp/regs-icu.h [new file with mode: 0644]
arch/arm/mach-mmp/regs-timers.h [new file with mode: 0644]
arch/arm/mach-mmp/regs-usb.h [new file with mode: 0644]
arch/arm/mach-mmp/tavorevb.c
arch/arm/mach-mmp/teton_bga.c
arch/arm/mach-mmp/teton_bga.h [new file with mode: 0644]
arch/arm/mach-mmp/time.c
arch/arm/mach-mmp/ttc_dkb.c
arch/arm/mach-moxart/Kconfig
arch/arm/mach-mv78xx0/Kconfig
arch/arm/mach-mv78xx0/Makefile
arch/arm/mach-mv78xx0/bridge-regs.h [new file with mode: 0644]
arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-mv78xx0/db78x00-bp-setup.c
arch/arm/mach-mv78xx0/include/mach/bridge-regs.h [deleted file]
arch/arm/mach-mv78xx0/include/mach/entry-macro.S [deleted file]
arch/arm/mach-mv78xx0/include/mach/hardware.h [deleted file]
arch/arm/mach-mv78xx0/include/mach/irqs.h [deleted file]
arch/arm/mach-mv78xx0/include/mach/mv78xx0.h [deleted file]
arch/arm/mach-mv78xx0/include/mach/uncompress.h [deleted file]
arch/arm/mach-mv78xx0/irq.c
arch/arm/mach-mv78xx0/irqs.h [new file with mode: 0644]
arch/arm/mach-mv78xx0/mpp.c
arch/arm/mach-mv78xx0/mv78xx0.h [new file with mode: 0644]
arch/arm/mach-mv78xx0/pcie.c
arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-mvebu/armada-370-xp.h
arch/arm/mach-mvebu/include/mach/gpio.h [deleted file]
arch/arm/mach-mvebu/platsmp-a9.c
arch/arm/mach-mvebu/platsmp.c
arch/arm/mach-netx/include/mach/param.h [deleted file]
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-sx1-mmc.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-sx1.h [new file with mode: 0644]
arch/arm/mach-omap1/camera.h [new file with mode: 0644]
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap1/flash.c
arch/arm/mach-omap1/flash.h [new file with mode: 0644]
arch/arm/mach-omap1/include/mach/board-sx1.h [deleted file]
arch/arm/mach-omap1/include/mach/camera.h [deleted file]
arch/arm/mach-omap1/include/mach/flash.h [deleted file]
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/clockdomains81xx_data.c
arch/arm/mach-omap2/cm81xx.h
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap-iommu.c [deleted file]
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/omap2-restart.c
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/mach-omap2/omap_hwmod_81xx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/powerdomains3xxx_data.c
arch/arm/mach-omap2/prm_common.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/Makefile
arch/arm/mach-orion5x/board-d2net.c
arch/arm/mach-orion5x/board-dt.c
arch/arm/mach-orion5x/board-mss2.c
arch/arm/mach-orion5x/board-rd88f5182.c
arch/arm/mach-orion5x/bridge-regs.h [new file with mode: 0644]
arch/arm/mach-orion5x/common.c
arch/arm/mach-orion5x/db88f5281-setup.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/include/mach/bridge-regs.h [deleted file]
arch/arm/mach-orion5x/include/mach/entry-macro.S [deleted file]
arch/arm/mach-orion5x/include/mach/hardware.h [deleted file]
arch/arm/mach-orion5x/include/mach/irqs.h [deleted file]
arch/arm/mach-orion5x/include/mach/orion5x.h [deleted file]
arch/arm/mach-orion5x/include/mach/uncompress.h [deleted file]
arch/arm/mach-orion5x/irq.c
arch/arm/mach-orion5x/irqs.h [new file with mode: 0644]
arch/arm/mach-orion5x/kurobox_pro-setup.c
arch/arm/mach-orion5x/ls-chl-setup.c
arch/arm/mach-orion5x/ls_hgl-setup.c
arch/arm/mach-orion5x/mpp.c
arch/arm/mach-orion5x/mv2120-setup.c
arch/arm/mach-orion5x/net2big-setup.c
arch/arm/mach-orion5x/orion5x.h [new file with mode: 0644]
arch/arm/mach-orion5x/pci.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
arch/arm/mach-orion5x/terastation_pro2-setup.c
arch/arm/mach-orion5x/ts209-setup.c
arch/arm/mach-orion5x/ts409-setup.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-orion5x/tsx09-common.c
arch/arm/mach-orion5x/wnr854t-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-picoxcell/Kconfig
arch/arm/mach-prima2/Kconfig
arch/arm/mach-prima2/common.h
arch/arm/mach-prima2/platsmp.c
arch/arm/mach-pxa/am200epd.c
arch/arm/mach-pxa/am300epd.c
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/capc7117.c
arch/arm/mach-pxa/cm-x255.c
arch/arm/mach-pxa/cm-x270.c
arch/arm/mach-pxa/cm-x2xx.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-evalboard.c
arch/arm/mach-pxa/colibri-pxa270-income.c
arch/arm/mach-pxa/colibri-pxa270.c
arch/arm/mach-pxa/colibri-pxa300.c
arch/arm/mach-pxa/colibri-pxa320.c
arch/arm/mach-pxa/colibri-pxa3xx.c
arch/arm/mach-pxa/colibri.h [new file with mode: 0644]
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/corgi_pm.c
arch/arm/mach-pxa/csb726.c
arch/arm/mach-pxa/csb726.h [new file with mode: 0644]
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/eseries-irq.h [new file with mode: 0644]
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/gumstix.c
arch/arm/mach-pxa/gumstix.h [new file with mode: 0644]
arch/arm/mach-pxa/h5000.c
arch/arm/mach-pxa/h5000.h [new file with mode: 0644]
arch/arm/mach-pxa/himalaya.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/icontrol.c
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/idp.h [new file with mode: 0644]
arch/arm/mach-pxa/include/mach/colibri.h [deleted file]
arch/arm/mach-pxa/include/mach/csb726.h [deleted file]
arch/arm/mach-pxa/include/mach/eseries-irq.h [deleted file]
arch/arm/mach-pxa/include/mach/gumstix.h [deleted file]
arch/arm/mach-pxa/include/mach/h5000.h [deleted file]
arch/arm/mach-pxa/include/mach/idp.h [deleted file]
arch/arm/mach-pxa/include/mach/littleton.h [deleted file]
arch/arm/mach-pxa/include/mach/lpd270.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa25x.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa27x.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa300.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa320.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h [deleted file]
arch/arm/mach-pxa/include/mach/mfp-pxa930.h [deleted file]
arch/arm/mach-pxa/include/mach/mioa701.h [deleted file]
arch/arm/mach-pxa/include/mach/mxm8x10.h [deleted file]
arch/arm/mach-pxa/include/mach/palm27x.h [deleted file]
arch/arm/mach-pxa/include/mach/palmt5.h [deleted file]
arch/arm/mach-pxa/include/mach/palmte2.h [deleted file]
arch/arm/mach-pxa/include/mach/palmtreo.h [deleted file]
arch/arm/mach-pxa/include/mach/palmz72.h [deleted file]
arch/arm/mach-pxa/include/mach/pcm027.h [deleted file]
arch/arm/mach-pxa/include/mach/pcm990_baseboard.h [deleted file]
arch/arm/mach-pxa/include/mach/pm.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa25x.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa27x-udc.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa27x.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa300.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa320.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa3xx.h [deleted file]
arch/arm/mach-pxa/include/mach/pxa930.h [deleted file]
arch/arm/mach-pxa/include/mach/regs-rtc.h [deleted file]
arch/arm/mach-pxa/include/mach/regs-u2d.h [deleted file]
arch/arm/mach-pxa/include/mach/sharpsl_pm.h [deleted file]
arch/arm/mach-pxa/include/mach/tosa_bt.h [deleted file]
arch/arm/mach-pxa/include/mach/udc.h [deleted file]
arch/arm/mach-pxa/include/mach/viper.h [deleted file]
arch/arm/mach-pxa/include/mach/zeus.h [deleted file]
arch/arm/mach-pxa/include/mach/zylonite.h [deleted file]
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/littleton.h [new file with mode: 0644]
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lpd270.h [new file with mode: 0644]
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mfp-pxa25x.h [new file with mode: 0644]
arch/arm/mach-pxa/mfp-pxa27x.h [new file with mode: 0644]
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/mfp-pxa2xx.h [new file with mode: 0644]
arch/arm/mach-pxa/mfp-pxa300.h [new file with mode: 0644]
arch/arm/mach-pxa/mfp-pxa320.h [new file with mode: 0644]
arch/arm/mach-pxa/mfp-pxa3xx.c
arch/arm/mach-pxa/mfp-pxa3xx.h [new file with mode: 0644]
arch/arm/mach-pxa/mfp-pxa930.h [new file with mode: 0644]
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/mioa701.h [new file with mode: 0644]
arch/arm/mach-pxa/mp900.c
arch/arm/mach-pxa/mxm8x10.c
arch/arm/mach-pxa/mxm8x10.h [new file with mode: 0644]
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palm27x.h [new file with mode: 0644]
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmt5.c
arch/arm/mach-pxa/palmt5.h [new file with mode: 0644]
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/palmte2.c
arch/arm/mach-pxa/palmte2.h [new file with mode: 0644]
arch/arm/mach-pxa/palmtreo.c
arch/arm/mach-pxa/palmtreo.h [new file with mode: 0644]
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/palmz72.h [new file with mode: 0644]
arch/arm/mach-pxa/pcm027.c
arch/arm/mach-pxa/pcm027.h [new file with mode: 0644]
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/pcm990_baseboard.h [new file with mode: 0644]
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/pm.h [new file with mode: 0644]
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa25x.h [new file with mode: 0644]
arch/arm/mach-pxa/pxa27x-udc.h [new file with mode: 0644]
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa27x.h [new file with mode: 0644]
arch/arm/mach-pxa/pxa2xx.c
arch/arm/mach-pxa/pxa300.c
arch/arm/mach-pxa/pxa300.h [new file with mode: 0644]
arch/arm/mach-pxa/pxa320.c
arch/arm/mach-pxa/pxa320.h [new file with mode: 0644]
arch/arm/mach-pxa/pxa3xx-ulpi.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa3xx.h [new file with mode: 0644]
arch/arm/mach-pxa/pxa930.c
arch/arm/mach-pxa/pxa930.h [new file with mode: 0644]
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/regs-rtc.h [new file with mode: 0644]
arch/arm/mach-pxa/regs-u2d.h [new file with mode: 0644]
arch/arm/mach-pxa/saar.c
arch/arm/mach-pxa/sharpsl_pm.c
arch/arm/mach-pxa/sharpsl_pm.h [new file with mode: 0644]
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/spitz_pm.c
arch/arm/mach-pxa/stargate2.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/tosa-bt.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/tosa_bt.h [new file with mode: 0644]
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/udc.h [new file with mode: 0644]
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/viper.h [new file with mode: 0644]
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-pxa/xcep.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zeus.c
arch/arm/mach-pxa/zeus.h [new file with mode: 0644]
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-pxa/zylonite.h [new file with mode: 0644]
arch/arm/mach-pxa/zylonite_pxa300.c
arch/arm/mach-pxa/zylonite_pxa320.c
arch/arm/mach-qcom/Kconfig
arch/arm/mach-qcom/platsmp.c
arch/arm/mach-realview/Kconfig
arch/arm/mach-realview/Makefile
arch/arm/mach-realview/board-eb.h [new file with mode: 0644]
arch/arm/mach-realview/board-pb1176.h [new file with mode: 0644]
arch/arm/mach-realview/board-pb11mp.h [new file with mode: 0644]
arch/arm/mach-realview/board-pba8.h [new file with mode: 0644]
arch/arm/mach-realview/board-pbx.h [new file with mode: 0644]
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.h
arch/arm/mach-realview/hardware.h [new file with mode: 0644]
arch/arm/mach-realview/include/mach/barriers.h [deleted file]
arch/arm/mach-realview/include/mach/board-eb.h [deleted file]
arch/arm/mach-realview/include/mach/board-pb1176.h [deleted file]
arch/arm/mach-realview/include/mach/board-pb11mp.h [deleted file]
arch/arm/mach-realview/include/mach/board-pba8.h [deleted file]
arch/arm/mach-realview/include/mach/board-pbx.h [deleted file]
arch/arm/mach-realview/include/mach/hardware.h [deleted file]
arch/arm/mach-realview/include/mach/irqs-eb.h [deleted file]
arch/arm/mach-realview/include/mach/irqs-pb1176.h [deleted file]
arch/arm/mach-realview/include/mach/irqs-pb11mp.h [deleted file]
arch/arm/mach-realview/include/mach/irqs-pba8.h [deleted file]
arch/arm/mach-realview/include/mach/irqs-pbx.h [deleted file]
arch/arm/mach-realview/include/mach/irqs.h [deleted file]
arch/arm/mach-realview/include/mach/memory.h [deleted file]
arch/arm/mach-realview/include/mach/platform.h [deleted file]
arch/arm/mach-realview/include/mach/uncompress.h [deleted file]
arch/arm/mach-realview/irqs-eb.h [new file with mode: 0644]
arch/arm/mach-realview/irqs-pb1176.h [new file with mode: 0644]
arch/arm/mach-realview/irqs-pb11mp.h [new file with mode: 0644]
arch/arm/mach-realview/irqs-pba8.h [new file with mode: 0644]
arch/arm/mach-realview/irqs-pbx.h [new file with mode: 0644]
arch/arm/mach-realview/platform.h [new file with mode: 0644]
arch/arm/mach-realview/platsmp-dt.c [new file with mode: 0644]
arch/arm/mach-realview/platsmp.c
arch/arm/mach-realview/realview-dt.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-rockchip/Kconfig
arch/arm/mach-rockchip/platsmp.c
arch/arm/mach-rockchip/rockchip.c
arch/arm/mach-s3c24xx/include/mach/pm-core.h
arch/arm/mach-s3c24xx/irq-pm.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/common.c
arch/arm/mach-s3c64xx/cpuidle.c
arch/arm/mach-s3c64xx/dev-uart.c
arch/arm/mach-s3c64xx/include/mach/debug-macro.S [deleted file]
arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
arch/arm/mach-s3c64xx/include/mach/irqs.h
arch/arm/mach-s3c64xx/include/mach/pm-core.h
arch/arm/mach-s3c64xx/irq-pm.c
arch/arm/mach-s3c64xx/mach-anw6410.c
arch/arm/mach-s3c64xx/mach-crag6410-module.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-ncp.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smartq5.c
arch/arm/mach-s3c64xx/mach-smartq7.c
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/pl080.c
arch/arm/mach-s3c64xx/pm.c
arch/arm/mach-s3c64xx/s3c6400.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/include/mach/irqs.h [deleted file]
arch/arm/mach-shmobile/irqs.h [deleted file]
arch/arm/mach-shmobile/r8a7779.h
arch/arm/mach-shmobile/r8a7790.h
arch/arm/mach-shmobile/r8a7791.h
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-shmobile/sh73a0.h
arch/arm/mach-shmobile/smp-emev2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-r8a7790.c
arch/arm/mach-shmobile/smp-r8a7791.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-socfpga/Kconfig
arch/arm/mach-socfpga/platsmp.c
arch/arm/mach-spear/Kconfig
arch/arm/mach-spear/generic.h
arch/arm/mach-spear/platsmp.c
arch/arm/mach-sti/Kconfig
arch/arm/mach-sti/platsmp.c
arch/arm/mach-sti/smp.h
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-sunxi/platsmp.c
arch/arm/mach-tango/Kconfig [new file with mode: 0644]
arch/arm/mach-tango/Makefile [new file with mode: 0644]
arch/arm/mach-tango/platsmp.c [new file with mode: 0644]
arch/arm/mach-tango/setup.c [new file with mode: 0644]
arch/arm/mach-tango/smc.S [new file with mode: 0644]
arch/arm/mach-tango/smc.h [new file with mode: 0644]
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/common.h
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/sleep-tegra20.S
arch/arm/mach-tegra/sleep-tegra30.S
arch/arm/mach-u300/Kconfig
arch/arm/mach-uniphier/Kconfig
arch/arm/mach-uniphier/platsmp.c
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/Makefile
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-ux500/setup.h
arch/arm/mach-ux500/timer.c [deleted file]
arch/arm/mach-versatile/Kconfig
arch/arm/mach-versatile/Makefile
arch/arm/mach-versatile/Makefile.boot [deleted file]
arch/arm/mach-versatile/core.c [deleted file]
arch/arm/mach-versatile/core.h [deleted file]
arch/arm/mach-versatile/include/mach/clkdev.h [deleted file]
arch/arm/mach-versatile/include/mach/hardware.h [deleted file]
arch/arm/mach-versatile/include/mach/irqs.h [deleted file]
arch/arm/mach-versatile/include/mach/platform.h [deleted file]
arch/arm/mach-versatile/include/mach/uncompress.h [deleted file]
arch/arm/mach-versatile/pci.c [deleted file]
arch/arm/mach-versatile/versatile_ab.c [deleted file]
arch/arm/mach-versatile/versatile_dt.c
arch/arm/mach-versatile/versatile_pb.c [deleted file]
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-vexpress/core.h
arch/arm/mach-vexpress/platsmp.c
arch/arm/mach-w90x900/cpu.c
arch/arm/mach-w90x900/include/mach/regs-ebi.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-gcr.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-timer.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-usb.h [deleted file]
arch/arm/mach-w90x900/regs-ebi.h [new file with mode: 0644]
arch/arm/mach-w90x900/regs-gcr.h [new file with mode: 0644]
arch/arm/mach-w90x900/regs-timer.h [new file with mode: 0644]
arch/arm/mach-w90x900/regs-usb.h [new file with mode: 0644]
arch/arm/mach-w90x900/time.c
arch/arm/mach-zx/Kconfig
arch/arm/mach-zx/platsmp.c
arch/arm/mach-zynq/Kconfig
arch/arm/mach-zynq/common.h
arch/arm/mach-zynq/platsmp.c
arch/arm/mm/Kconfig
arch/arm/mm/dma-mapping.c
arch/arm/mm/idmap.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-mohawk.S
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-orion/common.c
arch/arm/plat-orion/include/plat/common.h
arch/arm/plat-orion/irq.c
arch/arm/plat-orion/mpp.c
arch/arm/plat-pxa/Makefile
arch/arm/plat-pxa/ssp.c
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/gpio-samsung.c [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/pm.h
arch/arm/plat-samsung/init.c
arch/arm/plat-samsung/pm.c
arch/arm64/Kconfig
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/Makefile
arch/arm64/boot/dts/apm/apm-merlin.dts
arch/arm64/boot/dts/apm/apm-mustang.dts
arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
arch/arm64/boot/dts/apm/apm-storm.dtsi
arch/arm64/boot/dts/arm/juno-r1.dts
arch/arm64/boot/dts/arm/juno.dts
arch/arm64/boot/dts/broadcom/ns2-svk.dts
arch/arm64/boot/dts/broadcom/ns2.dtsi
arch/arm64/boot/dts/exynos/exynos7-espresso.dts
arch/arm64/boot/dts/exynos/exynos7.dtsi
arch/arm64/boot/dts/freescale/Makefile
arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
arch/arm64/boot/dts/hisilicon/hi6220.dtsi
arch/arm64/boot/dts/marvell/berlin4ct.dtsi
arch/arm64/boot/dts/mediatek/mt8173-evb.dts
arch/arm64/boot/dts/mediatek/mt8173.dtsi
arch/arm64/boot/dts/nvidia/Makefile [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra132-norrin.dts [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra132.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2571.dts [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/nvidia/tegra210.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
arch/arm64/boot/dts/qcom/msm8916-mtp.dts
arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi
arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
arch/arm64/boot/dts/qcom/msm8916.dtsi
arch/arm64/boot/dts/qcom/pm8916.dtsi
arch/arm64/boot/dts/renesas/Makefile [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a7795.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/Makefile
arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3368-r88.dts
arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3368.dtsi
arch/arm64/boot/dts/socionext/Makefile [new file with mode: 0644]
arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts [new file with mode: 0644]
arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi [new symlink]
arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi [new symlink]
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
arch/arm64/configs/defconfig
arch/arm64/include/asm/dma-mapping.h
arch/avr32/include/asm/dma-mapping.h
arch/avr32/mm/dma-coherent.c
arch/blackfin/include/asm/dma-mapping.h
arch/blackfin/kernel/dma-mapping.c
arch/c6x/Kconfig
arch/c6x/include/asm/dma-mapping.h
arch/c6x/kernel/dma.c
arch/c6x/mm/dma-coherent.c
arch/cris/arch-v10/kernel/debugport.c
arch/cris/arch-v10/kernel/head.S
arch/cris/arch-v32/drivers/pci/dma.c
arch/cris/arch-v32/kernel/head.S
arch/cris/include/asm/dma-mapping.h
arch/cris/kernel/vmlinux.lds.S
arch/frv/Kconfig
arch/frv/include/asm/dma-mapping.h
arch/frv/include/asm/io.h
arch/frv/mb93090-mb00/pci-dma-nommu.c
arch/frv/mb93090-mb00/pci-dma.c
arch/h8300/Kconfig
arch/h8300/boot/compressed/Makefile
arch/h8300/boot/compressed/misc.c
arch/h8300/boot/compressed/vmlinux.lds
arch/h8300/include/asm/dma-mapping.h
arch/h8300/include/asm/io.h
arch/h8300/include/asm/kgdb.h [new file with mode: 0644]
arch/h8300/include/asm/traps.h
arch/h8300/kernel/Makefile
arch/h8300/kernel/entry.S
arch/h8300/kernel/kgdb.c [new file with mode: 0644]
arch/h8300/kernel/signal.c
arch/h8300/kernel/traps.c
arch/hexagon/Kconfig
arch/hexagon/include/asm/dma-mapping.h
arch/ia64/Kconfig
arch/ia64/include/asm/dma-mapping.h
arch/ia64/include/asm/unistd.h
arch/ia64/include/uapi/asm/unistd.h
arch/ia64/kernel/entry.S
arch/m68k/include/asm/dma-mapping.h
arch/m68k/kernel/dma.c
arch/metag/include/asm/dma-mapping.h
arch/metag/kernel/dma.c
arch/microblaze/Kconfig
arch/microblaze/include/asm/dma-mapping.h
arch/mips/Kbuild.platforms
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/alchemy/common/gpiolib.c
arch/mips/ar7/gpio.c
arch/mips/ath79/common.h
arch/mips/ath79/irq.c
arch/mips/ath79/setup.c
arch/mips/bcm47xx/sprom.c
arch/mips/bcm63xx/nvram.c
arch/mips/bmips/setup.c
arch/mips/boot/compressed/Makefile
arch/mips/boot/compressed/uart-prom.c [new file with mode: 0644]
arch/mips/boot/dts/Makefile
arch/mips/boot/dts/brcm/bcm6328.dtsi
arch/mips/boot/dts/brcm/bcm6368.dtsi
arch/mips/boot/dts/ingenic/ci20.dts
arch/mips/boot/dts/ingenic/jz4780.dtsi
arch/mips/boot/dts/pic32/Makefile [new file with mode: 0644]
arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi [new file with mode: 0644]
arch/mips/boot/dts/pic32/pic32mzda.dtsi [new file with mode: 0644]
arch/mips/boot/dts/pic32/pic32mzda_sk.dts [new file with mode: 0644]
arch/mips/boot/dts/qca/ar9132.dtsi
arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts
arch/mips/configs/pic32mzda_defconfig [new file with mode: 0644]
arch/mips/include/asm/cacheops.h
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/cpu.h
arch/mips/include/asm/dma-mapping.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/fpu_emulator.h
arch/mips/include/asm/io.h
arch/mips/include/asm/irqflags.h
arch/mips/include/asm/kvm_host.h
arch/mips/include/asm/mach-ath79/ath79.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h [deleted file]
arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mach-pic32/irq.h [new file with mode: 0644]
arch/mips/include/asm/mach-pic32/pic32.h [new file with mode: 0644]
arch/mips/include/asm/mach-pic32/spaces.h [new file with mode: 0644]
arch/mips/include/asm/mach-ralink/irq.h [new file with mode: 0644]
arch/mips/include/asm/mach-ralink/mt7621.h [new file with mode: 0644]
arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mips-cm.h
arch/mips/include/asm/mips-r2-to-r6-emul.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/page.h
arch/mips/include/asm/pgtable.h
arch/mips/include/uapi/asm/inst.h
arch/mips/include/uapi/asm/mman.h
arch/mips/kernel/cpu-bugs64.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/elf.c
arch/mips/kernel/gpio_txx9.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/setup.c
arch/mips/kernel/smp-cps.c
arch/mips/kernel/sync-r4k.c
arch/mips/kernel/traps.c
arch/mips/kvm/callback.c
arch/mips/kvm/dyntrans.c
arch/mips/kvm/emulate.c
arch/mips/kvm/interrupt.c
arch/mips/kvm/locore.S
arch/mips/kvm/mips.c
arch/mips/kvm/opcode.h [deleted file]
arch/mips/kvm/tlb.c
arch/mips/kvm/trap_emul.c
arch/mips/lib/mips-atomic.c
arch/mips/loongson64/Platform
arch/mips/loongson64/loongson-3/hpet.c
arch/mips/loongson64/loongson-3/smp.c
arch/mips/math-emu/cp1emu.c
arch/mips/math-emu/dp_simple.c
arch/mips/math-emu/dp_tint.c
arch/mips/math-emu/dp_tlong.c
arch/mips/math-emu/dsemul.c
arch/mips/math-emu/ieee754.c
arch/mips/math-emu/ieee754.h
arch/mips/math-emu/ieee754dp.c
arch/mips/math-emu/ieee754int.h
arch/mips/math-emu/ieee754sp.c
arch/mips/math-emu/sp_fdp.c
arch/mips/math-emu/sp_simple.c
arch/mips/math-emu/sp_tint.c
arch/mips/math-emu/sp_tlong.c
arch/mips/mm/tlbex.c
arch/mips/pci/Makefile
arch/mips/pci/pci-mt7620.c [new file with mode: 0644]
arch/mips/pic32/Kconfig [new file with mode: 0644]
arch/mips/pic32/Makefile [new file with mode: 0644]
arch/mips/pic32/Platform [new file with mode: 0644]
arch/mips/pic32/common/Makefile [new file with mode: 0644]
arch/mips/pic32/common/irq.c [new file with mode: 0644]
arch/mips/pic32/common/reset.c [new file with mode: 0644]
arch/mips/pic32/pic32mzda/Makefile [new file with mode: 0644]
arch/mips/pic32/pic32mzda/config.c [new file with mode: 0644]
arch/mips/pic32/pic32mzda/early_clk.c [new file with mode: 0644]
arch/mips/pic32/pic32mzda/early_console.c [new file with mode: 0644]
arch/mips/pic32/pic32mzda/early_pin.c [new file with mode: 0644]
arch/mips/pic32/pic32mzda/early_pin.h [new file with mode: 0644]
arch/mips/pic32/pic32mzda/init.c [new file with mode: 0644]
arch/mips/pic32/pic32mzda/pic32mzda.h [new file with mode: 0644]
arch/mips/pic32/pic32mzda/time.c [new file with mode: 0644]
arch/mips/ralink/Kconfig
arch/mips/ralink/Makefile
arch/mips/ralink/Platform
arch/mips/ralink/irq-gic.c [new file with mode: 0644]
arch/mips/ralink/mt7620.c
arch/mips/ralink/mt7621.c [new file with mode: 0644]
arch/mips/ralink/rt288x.c
arch/mips/ralink/rt305x.c
arch/mips/ralink/rt3883.c
arch/mips/ralink/timer-gic.c [new file with mode: 0644]
arch/mips/rb532/gpio.c
arch/mips/txx9/generic/setup.c
arch/mn10300/Kconfig
arch/mn10300/include/asm/dma-mapping.h
arch/mn10300/mm/dma-alloc.c
arch/nios2/include/asm/dma-mapping.h
arch/nios2/mm/dma-mapping.c
arch/openrisc/Kconfig
arch/openrisc/include/asm/dma-mapping.h
arch/parisc/Kconfig
arch/parisc/include/asm/dma-mapping.h
arch/parisc/include/uapi/asm/mman.h
arch/parisc/kernel/drivers.c
arch/parisc/kernel/pci-dma.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/fadump.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/fadump.c
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/vdso32/Makefile
arch/powerpc/kernel/vdso64/Makefile
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/xmon/Makefile
arch/s390/Kconfig
arch/s390/hypfs/inode.c
arch/s390/include/asm/dma-mapping.h
arch/sh/Kconfig
arch/sh/include/asm/dma-mapping.h
arch/sparc/Kconfig
arch/sparc/include/asm/dma-mapping.h
arch/tile/Kconfig
arch/tile/include/asm/dma-mapping.h
arch/tile/kernel/pci-dma.c
arch/unicore32/Kconfig
arch/unicore32/include/asm/dma-mapping.h
arch/x86/Kconfig
arch/x86/boot/Makefile
arch/x86/boot/compressed/Makefile
arch/x86/entry/vdso/Makefile
arch/x86/include/asm/device.h
arch/x86/include/asm/dma-mapping.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/pci_x86.h
arch/x86/include/asm/pmem.h
arch/x86/include/asm/uaccess.h
arch/x86/include/asm/uaccess_64.h
arch/x86/kernel/machine_kexec_64.c
arch/x86/pci/Makefile
arch/x86/pci/common.c
arch/x86/pci/pcbios.c
arch/x86/pci/vmd.c [new file with mode: 0644]
arch/x86/realmode/rm/Makefile
arch/xtensa/Kconfig
arch/xtensa/include/asm/dma-mapping.h
arch/xtensa/include/uapi/asm/mman.h
block/Makefile
block/bio-integrity.c
block/blk-core.c
block/blk-iopoll.c [deleted file]
block/blk-mq.c
block/blk-timeout.c
block/blk.h
block/ioctl.c
crypto/af_alg.c
crypto/ahash.c
crypto/algif_hash.c
crypto/algif_skcipher.c
crypto/crc32c_generic.c
crypto/shash.c
crypto/skcipher.c
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_video.c
drivers/acpi/acpica/acapps.h
drivers/acpi/acpica/accommon.h
drivers/acpi/acpica/acdebug.h
drivers/acpi/acpica/acdispat.h
drivers/acpi/acpica/acevents.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/achware.h
drivers/acpi/acpica/acinterp.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acmacros.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/acobject.h
drivers/acpi/acpica/acopcode.h
drivers/acpi/acpica/acparser.h
drivers/acpi/acpica/acpredef.h
drivers/acpi/acpica/acresrc.h
drivers/acpi/acpica/acstruct.h
drivers/acpi/acpica/actables.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/amlcode.h
drivers/acpi/acpica/amlresrc.h
drivers/acpi/acpica/dbcmds.c
drivers/acpi/acpica/dbconvert.c
drivers/acpi/acpica/dbdisply.c
drivers/acpi/acpica/dbexec.c
drivers/acpi/acpica/dbfileio.c
drivers/acpi/acpica/dbhistry.c
drivers/acpi/acpica/dbinput.c
drivers/acpi/acpica/dbmethod.c
drivers/acpi/acpica/dbnames.c
drivers/acpi/acpica/dbobject.c
drivers/acpi/acpica/dbstats.c
drivers/acpi/acpica/dbtest.c
drivers/acpi/acpica/dbutils.c
drivers/acpi/acpica/dbxface.c
drivers/acpi/acpica/dsargs.c
drivers/acpi/acpica/dscontrol.c
drivers/acpi/acpica/dsdebug.c
drivers/acpi/acpica/dsfield.c
drivers/acpi/acpica/dsinit.c
drivers/acpi/acpica/dsmethod.c
drivers/acpi/acpica/dsmthdat.c
drivers/acpi/acpica/dsobject.c
drivers/acpi/acpica/dsopcode.c
drivers/acpi/acpica/dsutils.c
drivers/acpi/acpica/dswexec.c
drivers/acpi/acpica/dswload.c
drivers/acpi/acpica/dswload2.c
drivers/acpi/acpica/dswscope.c
drivers/acpi/acpica/dswstate.c
drivers/acpi/acpica/evevent.c
drivers/acpi/acpica/evglock.c
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/evgpeblk.c
drivers/acpi/acpica/evgpeinit.c
drivers/acpi/acpica/evgpeutil.c
drivers/acpi/acpica/evhandler.c
drivers/acpi/acpica/evmisc.c
drivers/acpi/acpica/evregion.c
drivers/acpi/acpica/evrgnini.c
drivers/acpi/acpica/evsci.c
drivers/acpi/acpica/evxface.c
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/acpica/evxfregn.c
drivers/acpi/acpica/exconfig.c
drivers/acpi/acpica/exconvrt.c
drivers/acpi/acpica/excreate.c
drivers/acpi/acpica/exdebug.c
drivers/acpi/acpica/exdump.c
drivers/acpi/acpica/exfield.c
drivers/acpi/acpica/exfldio.c
drivers/acpi/acpica/exmisc.c
drivers/acpi/acpica/exmutex.c
drivers/acpi/acpica/exnames.c
drivers/acpi/acpica/exoparg1.c
drivers/acpi/acpica/exoparg2.c
drivers/acpi/acpica/exoparg3.c
drivers/acpi/acpica/exoparg6.c
drivers/acpi/acpica/exprep.c
drivers/acpi/acpica/exregion.c
drivers/acpi/acpica/exresnte.c
drivers/acpi/acpica/exresolv.c
drivers/acpi/acpica/exresop.c
drivers/acpi/acpica/exstore.c
drivers/acpi/acpica/exstoren.c
drivers/acpi/acpica/exstorob.c
drivers/acpi/acpica/exsystem.c
drivers/acpi/acpica/extrace.c
drivers/acpi/acpica/exutils.c
drivers/acpi/acpica/hwacpi.c
drivers/acpi/acpica/hwesleep.c
drivers/acpi/acpica/hwgpe.c
drivers/acpi/acpica/hwpci.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/hwsleep.c
drivers/acpi/acpica/hwtimer.c
drivers/acpi/acpica/hwvalid.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/acpica/hwxfsleep.c
drivers/acpi/acpica/nsaccess.c
drivers/acpi/acpica/nsalloc.c
drivers/acpi/acpica/nsarguments.c
drivers/acpi/acpica/nsconvert.c
drivers/acpi/acpica/nsdump.c
drivers/acpi/acpica/nsdumpdv.c
drivers/acpi/acpica/nseval.c
drivers/acpi/acpica/nsinit.c
drivers/acpi/acpica/nsload.c
drivers/acpi/acpica/nsnames.c
drivers/acpi/acpica/nsobject.c
drivers/acpi/acpica/nsparse.c
drivers/acpi/acpica/nspredef.c
drivers/acpi/acpica/nsprepkg.c
drivers/acpi/acpica/nsrepair.c
drivers/acpi/acpica/nsrepair2.c
drivers/acpi/acpica/nssearch.c
drivers/acpi/acpica/nsutils.c
drivers/acpi/acpica/nswalk.c
drivers/acpi/acpica/nsxfeval.c
drivers/acpi/acpica/nsxfname.c
drivers/acpi/acpica/nsxfobj.c
drivers/acpi/acpica/psargs.c
drivers/acpi/acpica/psloop.c
drivers/acpi/acpica/psobject.c
drivers/acpi/acpica/psopcode.c
drivers/acpi/acpica/psopinfo.c
drivers/acpi/acpica/psparse.c
drivers/acpi/acpica/psscope.c
drivers/acpi/acpica/pstree.c
drivers/acpi/acpica/psutils.c
drivers/acpi/acpica/pswalk.c
drivers/acpi/acpica/psxface.c
drivers/acpi/acpica/rsaddr.c
drivers/acpi/acpica/rscalc.c
drivers/acpi/acpica/rscreate.c
drivers/acpi/acpica/rsdump.c
drivers/acpi/acpica/rsdumpinfo.c
drivers/acpi/acpica/rsinfo.c
drivers/acpi/acpica/rsio.c
drivers/acpi/acpica/rsirq.c
drivers/acpi/acpica/rslist.c
drivers/acpi/acpica/rsmemory.c
drivers/acpi/acpica/rsmisc.c
drivers/acpi/acpica/rsserial.c
drivers/acpi/acpica/rsutils.c
drivers/acpi/acpica/rsxface.c
drivers/acpi/acpica/tbdata.c
drivers/acpi/acpica/tbfadt.c
drivers/acpi/acpica/tbfind.c
drivers/acpi/acpica/tbinstal.c
drivers/acpi/acpica/tbprint.c
drivers/acpi/acpica/tbutils.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/acpica/tbxfload.c
drivers/acpi/acpica/tbxfroot.c
drivers/acpi/acpica/utaddress.c
drivers/acpi/acpica/utalloc.c
drivers/acpi/acpica/utbuffer.c
drivers/acpi/acpica/utcache.c
drivers/acpi/acpica/utcopy.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/acpica/utdecode.c
drivers/acpi/acpica/utdelete.c
drivers/acpi/acpica/uterror.c
drivers/acpi/acpica/uteval.c
drivers/acpi/acpica/utexcep.c
drivers/acpi/acpica/utglobal.c
drivers/acpi/acpica/uthex.c
drivers/acpi/acpica/utids.c
drivers/acpi/acpica/utinit.c
drivers/acpi/acpica/utlock.c
drivers/acpi/acpica/utmath.c
drivers/acpi/acpica/utmisc.c
drivers/acpi/acpica/utmutex.c
drivers/acpi/acpica/utnonansi.c
drivers/acpi/acpica/utobject.c
drivers/acpi/acpica/utosi.c
drivers/acpi/acpica/utownerid.c
drivers/acpi/acpica/utpredef.c
drivers/acpi/acpica/utprint.c
drivers/acpi/acpica/utresrc.c
drivers/acpi/acpica/utstate.c
drivers/acpi/acpica/utstring.c
drivers/acpi/acpica/uttrack.c
drivers/acpi/acpica/utuuid.c
drivers/acpi/acpica/utxface.c
drivers/acpi/acpica/utxferror.c
drivers/acpi/acpica/utxfinit.c
drivers/acpi/acpica/utxfmutex.c
drivers/acpi/apei/erst.c
drivers/acpi/device_pm.c
drivers/acpi/fan.c
drivers/amba/Kconfig
drivers/base/cpu.c
drivers/base/dd.c
drivers/base/devtmpfs.c
drivers/base/dma-mapping.c
drivers/base/platform.c
drivers/base/power/clock_ops.c
drivers/base/power/common.c
drivers/base/power/domain.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/block/aoe/aoecmd.c
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/drbd/drbd_debugfs.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_proc.c
drivers/block/drbd/drbd_protocol.h
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_req.c
drivers/block/drbd/drbd_req.h
drivers/block/drbd/drbd_state.c
drivers/block/drbd/drbd_state.h
drivers/block/drbd/drbd_state_change.h [new file with mode: 0644]
drivers/block/drbd/drbd_worker.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/null_blk.c
drivers/block/rbd.c
drivers/block/sx8.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/uniphier-system-bus.c [new file with mode: 0644]
drivers/char/mem.c
drivers/char/mspec.c
drivers/char/ps3flash.c
drivers/clk/mmp/clk-mmp2.c
drivers/clk/mmp/clk-pxa168.c
drivers/clk/mmp/clk-pxa910.c
drivers/clk/pxa/clk-pxa25x.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/tegra/clk-divider.c
drivers/clk/ti/clk-814x.c
drivers/clk/versatile/Kconfig
drivers/clk/versatile/clk-icst.c
drivers/clk/versatile/clk-realview.c
drivers/clocksource/clksrc-dbx500-prcmu.c
drivers/cpuidle/Kconfig
drivers/cpuidle/cpuidle.c
drivers/cpuidle/governors/ladder.c
drivers/cpuidle/governors/menu.c
drivers/crypto/Kconfig
drivers/crypto/atmel-aes.c
drivers/crypto/qat/qat_common/qat_hal.c
drivers/devfreq/devfreq-event.c
drivers/devfreq/devfreq.c
drivers/firmware/broadcom/bcm47xx_nvram.c
drivers/firmware/efi/libstub/Makefile
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-samsung.c [deleted file]
drivers/gpu/drm/Kconfig
drivers/gpu/drm/drm_hashtab.c
drivers/gpu/drm/imx/Kconfig
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
drivers/gpu/drm/rcar-du/Kconfig
drivers/gpu/drm/shmobile/Kconfig
drivers/gpu/drm/sti/Kconfig
drivers/gpu/drm/tilcdc/Kconfig
drivers/gpu/drm/vc4/Kconfig
drivers/gpu/vga/vga_switcheroo.c
drivers/hid/hid-sensor-hub.c
drivers/iio/adc/exynos_adc.c
drivers/iio/industrialio-sw-trigger.c
drivers/infiniband/Kconfig
drivers/infiniband/core/Makefile
drivers/infiniband/core/addr.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/cma_configfs.c [new file with mode: 0644]
drivers/infiniband/core/core_priv.h
drivers/infiniband/core/cq.c [new file with mode: 0644]
drivers/infiniband/core/device.c
drivers/infiniband/core/fmr_pool.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/mad_priv.h
drivers/infiniband/core/multicast.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/ud_header.c
drivers/infiniband/core/umem_odp.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/uverbs_marshall.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb3/iwch_cq.c
drivers/infiniband/hw/cxgb3/iwch_mem.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb3/iwch_provider.h
drivers/infiniband/hw/cxgb3/iwch_qp.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/cq.c
drivers/infiniband/hw/cxgb4/device.c
drivers/infiniband/hw/cxgb4/iw_cxgb4.h
drivers/infiniband/hw/cxgb4/mem.c
drivers/infiniband/hw/cxgb4/provider.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/cxgb4/t4.h
drivers/infiniband/hw/cxgb4/user.h
drivers/infiniband/hw/mlx4/ah.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/mr.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mlx5/ah.c
drivers/infiniband/hw/mlx5/cq.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/odp.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/mlx5/srq.c
drivers/infiniband/hw/mlx5/user.h
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_cm.h
drivers/infiniband/hw/nes/nes_utils.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/hw/nes/nes_verbs.h
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
drivers/infiniband/hw/qib/qib_fs.c
drivers/infiniband/hw/qib/qib_mr.c
drivers/infiniband/hw/qib/qib_qp.c
drivers/infiniband/hw/qib/qib_verbs.c
drivers/infiniband/hw/qib/qib_verbs.h
drivers/infiniband/hw/qib/qib_verbs_mcast.c
drivers/infiniband/hw/usnic/usnic_debugfs.c
drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.h
drivers/infiniband/hw/usnic/usnic_vnic.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/isert/ib_isert.h
drivers/infiniband/ulp/isert/isert_proto.h [deleted file]
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/infiniband/ulp/srpt/ib_srpt.h
drivers/input/joystick/xpad.c
drivers/input/keyboard/gpio_keys.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/irqchip/Kconfig
drivers/irqchip/Makefile
drivers/irqchip/irq-pic32-evic.c [new file with mode: 0644]
drivers/irqchip/irq-renesas-h8s.c
drivers/irqchip/irq-versatile-fpga.c
drivers/lightnvm/Makefile
drivers/lightnvm/core.c
drivers/lightnvm/gennvm.c
drivers/lightnvm/rrpc.c
drivers/lightnvm/rrpc.h
drivers/lightnvm/sysblk.c [new file with mode: 0644]
drivers/md/bcache/btree.c
drivers/md/bcache/super.c
drivers/md/bcache/writeback.c
drivers/md/bcache/writeback.h
drivers/media/platform/Kconfig
drivers/memory/tegra/tegra124.c
drivers/memstick/core/ms_block.c
drivers/misc/Kconfig
drivers/misc/mei/pci-me.c
drivers/misc/mei/pci-txe.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/pwrseq_simple.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_cis.c
drivers/mmc/host/mmci.c
drivers/mmc/host/tmio_mmc_dma.c
drivers/mtd/bcm63xxpart.c
drivers/mtd/ubi/cdev.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/eq.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/qp.c
drivers/net/ethernet/mellanox/mlx5/core/srq.c
drivers/net/ethernet/mellanox/mlx5/core/transobj.c
drivers/net/ethernet/mellanox/mlx5/core/transobj.h [deleted file]
drivers/net/ethernet/mellanox/mlx5/core/vport.c
drivers/ntb/hw/Kconfig
drivers/ntb/hw/Makefile
drivers/ntb/hw/amd/Kconfig [new file with mode: 0644]
drivers/ntb/hw/amd/Makefile [new file with mode: 0644]
drivers/ntb/hw/amd/ntb_hw_amd.c [new file with mode: 0644]
drivers/ntb/hw/amd/ntb_hw_amd.h [new file with mode: 0644]
drivers/ntb/hw/intel/ntb_hw_intel.c
drivers/ntb/hw/intel/ntb_hw_intel.h
drivers/ntb/ntb_transport.c
drivers/ntb/test/Kconfig
drivers/ntb/test/Makefile
drivers/ntb/test/ntb_perf.c [new file with mode: 0644]
drivers/nvme/host/Kconfig
drivers/nvme/host/Makefile
drivers/nvme/host/core.c [new file with mode: 0644]
drivers/nvme/host/lightnvm.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/scsi.c
drivers/oprofile/oprofilefs.c
drivers/parisc/ccio-dma.c
drivers/parisc/sba_iommu.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host/Kconfig
drivers/pci/host/Makefile
drivers/pci/host/pci-dra7xx.c
drivers/pci/host/pci-exynos.c
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-imx6.c
drivers/pci/host/pci-rcar-gen2.c
drivers/pci/host/pci-tegra.c
drivers/pci/host/pci-versatile.c
drivers/pci/host/pcie-designware.c
drivers/pci/host/pcie-hisi.c
drivers/pci/host/pcie-iproc-bcma.c
drivers/pci/host/pcie-iproc-msi.c [new file with mode: 0644]
drivers/pci/host/pcie-iproc-platform.c
drivers/pci/host/pcie-iproc.c
drivers/pci/host/pcie-iproc.h
drivers/pci/host/pcie-qcom.c [new file with mode: 0644]
drivers/pci/host/pcie-rcar.c
drivers/pci/host/pcie-spear13xx.c
drivers/pci/host/pcie-xilinx.c
drivers/pci/hotplug/acpi_pcihp.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/cpci_hotplug.h
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpci_hotplug_pci.c
drivers/pci/hotplug/cpcihp_generic.c
drivers/pci/hotplug/cpcihp_zt5550.c
drivers/pci/hotplug/cpqphp.h
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_ctrl.c
drivers/pci/hotplug/cpqphp_nvram.c
drivers/pci/hotplug/cpqphp_pci.c
drivers/pci/hotplug/cpqphp_sysfs.c
drivers/pci/hotplug/ibmphp.h
drivers/pci/hotplug/ibmphp_core.c
drivers/pci/hotplug/ibmphp_ebda.c
drivers/pci/hotplug/ibmphp_hpc.c
drivers/pci/hotplug/ibmphp_pci.c
drivers/pci/hotplug/ibmphp_res.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pcihp_skeleton.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpaphp.h
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/s390_pci_hpc.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/hotplug/shpchp_sysfs.c
drivers/pci/msi.c
drivers/pci/pci-label.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aer/aer_inject.c
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/aspm.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/rom.c
drivers/pci/setup-bus.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel_telemetry_debugfs.c
drivers/platform/x86/thinkpad_acpi.c
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/core.c
drivers/pwm/pwm-bcm2835.c
drivers/pwm/pwm-fsl-ftm.c
drivers/pwm/pwm-lpc32xx.c
drivers/pwm/pwm-lpss.c
drivers/pwm/pwm-lpss.h
drivers/pwm/pwm-omap-dmtimer.c [new file with mode: 0644]
drivers/pwm/pwm-rcar.c
drivers/rapidio/rio-sysfs.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/core.c
drivers/reset/hisilicon/Kconfig [new file with mode: 0644]
drivers/reset/hisilicon/Makefile [new file with mode: 0644]
drivers/reset/hisilicon/hi6220_reset.c [new file with mode: 0644]
drivers/reset/reset-ath79.c
drivers/reset/reset-berlin.c
drivers/reset/reset-socfpga.c
drivers/reset/reset-sunxi.c
drivers/reset/reset-zynq.c
drivers/reset/sti/reset-stih407.c
drivers/reset/sti/reset-syscfg.c
drivers/scsi/3w-xxxx.c
drivers/scsi/Kconfig
drivers/scsi/NCR5380.c
drivers/scsi/NCR5380.h
drivers/scsi/arm/cumana_1.c
drivers/scsi/arm/oak.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/be2iscsi/Kconfig
drivers/scsi/be2iscsi/be.h
drivers/scsi/be2iscsi/be_iscsi.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
drivers/scsi/dmx3191d.c
drivers/scsi/dtc.c
drivers/scsi/dtc.h
drivers/scsi/g_NCR5380.c
drivers/scsi/g_NCR5380.h
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
drivers/scsi/imm.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/mac_scsi.c
drivers/scsi/megaraid/megaraid_mm.c
drivers/scsi/pas16.c
drivers/scsi/pas16.h
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_dfs.c
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla2xxx/qla_target.h
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/scsi/storvsc_drv.c
drivers/scsi/sun3_scsi.c
drivers/scsi/t128.c
drivers/scsi/t128.h
drivers/sh/clk/core.c
drivers/soc/Kconfig
drivers/soc/Makefile
drivers/soc/bcm/Kconfig [new file with mode: 0644]
drivers/soc/bcm/Makefile [new file with mode: 0644]
drivers/soc/bcm/raspberrypi-power.c [new file with mode: 0644]
drivers/soc/dove/pmu.c
drivers/soc/mediatek/mtk-scpsys.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/Makefile
drivers/soc/qcom/smd-rpm.c
drivers/soc/qcom/smd.c
drivers/soc/qcom/smem_state.c [new file with mode: 0644]
drivers/soc/qcom/smp2p.c [new file with mode: 0644]
drivers/soc/qcom/smsm.c [new file with mode: 0644]
drivers/soc/qcom/spm.c
drivers/soc/qcom/wcnss_ctrl.c [new file with mode: 0644]
drivers/soc/tegra/Kconfig [new file with mode: 0644]
drivers/soc/ti/Kconfig
drivers/soc/ti/Makefile
drivers/soc/ti/wkup_m3_ipc.c [new file with mode: 0644]
drivers/soc/versatile/soc-realview.c
drivers/staging/board/armadillo800eva.c
drivers/staging/board/kzm9d.c
drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/llite/llite_nfs.c
drivers/staging/lustre/lustre/llite/lloop.c
drivers/staging/lustre/lustre/llite/rw.c
drivers/staging/lustre/lustre/llite/rw26.c
drivers/staging/lustre/lustre/llite/vvp_io.c
drivers/staging/lustre/lustre/llite/vvp_page.c
drivers/staging/rdma/amso1100/c2_cq.c
drivers/staging/rdma/amso1100/c2_provider.c
drivers/staging/rdma/ehca/ehca_classes.h
drivers/staging/rdma/ehca/ehca_iverbs.h
drivers/staging/rdma/ehca/ehca_main.c
drivers/staging/rdma/ehca/ehca_mrmw.c
drivers/staging/rdma/ehca/ehca_mrmw.h
drivers/staging/rdma/ehca/ehca_reqs.c
drivers/staging/rdma/hfi1/mr.c
drivers/staging/rdma/hfi1/verbs.c
drivers/staging/rdma/hfi1/verbs.h
drivers/staging/rdma/ipath/ipath_fs.c
drivers/staging/rdma/ipath/ipath_mr.c
drivers/staging/rdma/ipath/ipath_verbs.c
drivers/staging/rdma/ipath/ipath_verbs.h
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/iscsi/iscsi_target_erl1.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/target/iscsi/iscsi_target_tmr.c
drivers/target/iscsi/iscsi_target_tpg.c
drivers/target/iscsi/iscsi_target_tpg.h
drivers/target/loopback/tcm_loop.c
drivers/target/sbp/sbp_target.c
drivers/target/target_core_configfs.c
drivers/target/target_core_device.c
drivers/target/target_core_iblock.c
drivers/target/target_core_pr.c
drivers/target/target_core_sbc.c
drivers/target/target_core_spc.c
drivers/target/target_core_tmr.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
drivers/target/target_core_user.c
drivers/target/tcm_fc/tcm_fc.h
drivers/target/tcm_fc/tfc_conf.c
drivers/target/tcm_fc/tfc_io.c
drivers/target/tcm_fc/tfc_sess.c
drivers/thermal/int340x_thermal/processor_thermal_device.c
drivers/thermal/intel_pch_thermal.c
drivers/thermal/rcar_thermal.c
drivers/thermal/rockchip_thermal.c
drivers/thermal/step_wise.c
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.h
drivers/tty/serial/Kconfig
drivers/usb/core/port.c
drivers/usb/core/usb.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/function/Makefile
drivers/usb/gadget/function/f_printer.c
drivers/usb/gadget/function/f_tcm.c [new file with mode: 0644]
drivers/usb/gadget/function/tcm.h [new file with mode: 0644]
drivers/usb/gadget/function/u_tcm.h [new file with mode: 0644]
drivers/usb/gadget/legacy/Kconfig
drivers/usb/gadget/legacy/inode.c
drivers/usb/gadget/legacy/tcm_usb_gadget.c
drivers/usb/gadget/legacy/tcm_usb_gadget.h [deleted file]
drivers/usb/gadget/udc/atmel_usba_udc.c
drivers/usb/host/Kconfig
drivers/video/fbdev/core/fb_defio.c
fs/9p/vfs_file.c
fs/adfs/adfs.h
fs/affs/file.c
fs/afs/flock.c
fs/afs/write.c
fs/attr.c
fs/binfmt_elf.c
fs/binfmt_misc.c
fs/block_dev.c
fs/btrfs/backref.c
fs/btrfs/ctree.h
fs/btrfs/dev-replace.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h
fs/btrfs/file.c
fs/btrfs/inode-map.c
fs/btrfs/inode-map.h
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/raid56.c
fs/btrfs/relocation.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/volumes.c
fs/btrfs/xattr.c
fs/cachefiles/interface.c
fs/cachefiles/namei.c
fs/ceph/addr.c
fs/ceph/cache.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/export.c
fs/ceph/file.c
fs/ceph/inode.c
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/readdir.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smb2proto.h
fs/cifs/smb2transport.c
fs/cifs/transport.c
fs/coda/coda_linux.h
fs/coda/dir.c
fs/coda/file.c
fs/configfs/dir.c
fs/configfs/file.c
fs/configfs/inode.c
fs/coredump.c
fs/dax.c
fs/dcache.c
fs/debugfs/inode.c
fs/devpts/inode.c
fs/direct-io.c
fs/dlm/user.c
fs/ecryptfs/inode.c
fs/ecryptfs/mmap.c
fs/efivarfs/file.c
fs/efivarfs/super.c
fs/eventpoll.c
fs/exec.c
fs/exofs/file.c
fs/exportfs/expfs.c
fs/ext2/file.c
fs/ext2/ioctl.c
fs/ext4/crypto.c
fs/ext4/crypto_key.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/file.c
fs/ext4/ialloc.c
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/namei.c
fs/ext4/super.c
fs/ext4/truncate.h
fs/f2fs/data.c
fs/f2fs/file.c
fs/fat/cache.c
fs/fat/dir.c
fs/fat/fat.h
fs/fat/fatent.c
fs/fat/file.c
fs/fat/inode.c
fs/filesystems.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/gfs2/file.c
fs/gfs2/inode.c
fs/gfs2/quota.c
fs/hfs/catalog.c
fs/hfs/dir.c
fs/hfs/inode.c
fs/hfsplus/dir.c
fs/hfsplus/inode.c
fs/hfsplus/ioctl.c
fs/hostfs/hostfs_kern.c
fs/hpfs/dir.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/ioctl.c
fs/jffs2/build.c
fs/jffs2/file.c
fs/jffs2/fs.c
fs/jffs2/super.c
fs/jfs/file.c
fs/jfs/ioctl.c
fs/jfs/super.c
fs/kernfs/dir.c
fs/libfs.c
fs/locks.c
fs/logfs/file.c
fs/namei.c
fs/namespace.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/file.c
fs/nfs/filelayout/filelayout.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs42proc.c
fs/nfs/nfs4file.c
fs/nfs/write.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfsfh.h
fs/nfsd/vfs.c
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/ntfs/dir.c
fs/ntfs/file.c
fs/ntfs/quota.c
fs/ntfs/super.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/dir.c
fs/ocfs2/dlmglue.c
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/ioctl.c
fs/ocfs2/journal.c
fs/ocfs2/localalloc.c
fs/ocfs2/move_extents.c
fs/ocfs2/namei.c
fs/ocfs2/quota_global.c
fs/ocfs2/refcounttree.c
fs/ocfs2/resize.c
fs/ocfs2/suballoc.c
fs/ocfs2/xattr.c
fs/open.c
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/readdir.c
fs/overlayfs/super.c
fs/pipe.c
fs/proc/array.c
fs/proc/base.c
fs/proc/kcore.c
fs/proc/namespaces.c
fs/proc/self.c
fs/proc/task_mmu.c
fs/proc/thread_self.c
fs/pstore/inode.c
fs/quota/dquot.c
fs/read_write.c
fs/readdir.c
fs/reiserfs/dir.c
fs/reiserfs/file.c
fs/reiserfs/ioctl.c
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/tracefs/inode.c
fs/ubifs/dir.c
fs/ubifs/file.c
fs/ubifs/xattr.c
fs/udf/file.c
fs/udf/inode.c
fs/udf/super.c
fs/utimes.c
fs/xattr.c
fs/xfs/libxfs/xfs_format.h
fs/xfs/libxfs/xfs_fs.h
fs/xfs/xfs_buf.c
fs/xfs/xfs_file.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_pnfs.c
fs/xfs/xfs_trans_ail.c
include/acpi/acbuffer.h
include/acpi/acconfig.h
include/acpi/acexcep.h
include/acpi/acnames.h
include/acpi/acoutput.h
include/acpi/acpi.h
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/acpi/acrestyp.h
include/acpi/actbl.h
include/acpi/actbl1.h
include/acpi/actbl2.h
include/acpi/actbl3.h
include/acpi/actypes.h
include/acpi/acuuid.h
include/acpi/platform/acenv.h
include/acpi/platform/acenvex.h
include/acpi/platform/acgcc.h
include/acpi/platform/aclinux.h
include/acpi/platform/aclinuxex.h
include/acpi/platform/acmsvcex.h
include/acpi/platform/acwinex.h
include/acpi/video.h
include/asm-generic/div64.h
include/asm-generic/dma-coherent.h [deleted file]
include/asm-generic/dma-mapping-broken.h [deleted file]
include/asm-generic/dma-mapping-common.h [deleted file]
include/crypto/hash.h
include/crypto/if_alg.h
include/crypto/skcipher.h
include/dt-bindings/clock/exynos4.h
include/dt-bindings/clock/r8a7791-clock.h
include/dt-bindings/clock/r8a7794-clock.h
include/dt-bindings/clock/sh73a0-clock.h
include/dt-bindings/pinctrl/am43xx.h
include/dt-bindings/pinctrl/dm814x.h [new file with mode: 0644]
include/dt-bindings/pinctrl/dra.h
include/dt-bindings/pinctrl/omap.h
include/dt-bindings/power/raspberrypi-power.h [new file with mode: 0644]
include/dt-bindings/reset-controller/mt8135-resets.h [deleted file]
include/dt-bindings/reset-controller/mt8173-resets.h [deleted file]
include/dt-bindings/reset/hisi,hi6220-resets.h [new file with mode: 0644]
include/dt-bindings/reset/mt8135-resets.h [new file with mode: 0644]
include/dt-bindings/reset/mt8173-resets.h [new file with mode: 0644]
include/dt-bindings/reset/stih407-resets.h
include/linux/aer.h
include/linux/bcm963xx_nvram.h [new file with mode: 0644]
include/linux/bcm963xx_tag.h [new file with mode: 0644]
include/linux/bio.h
include/linux/blk-iopoll.h [deleted file]
include/linux/blk_types.h
include/linux/blkdev.h
include/linux/ceph/ceph_frag.h
include/linux/ceph/messenger.h
include/linux/clk/mmp.h [new file with mode: 0644]
include/linux/clk/ti.h
include/linux/clksrc-dbx500-prcmu.h [deleted file]
include/linux/configfs.h
include/linux/cpumask.h
include/linux/dax.h
include/linux/devfreq.h
include/linux/device.h
include/linux/dma-attrs.h
include/linux/dma-mapping.h
include/linux/drbd.h
include/linux/drbd_genl.h
include/linux/fs.h
include/linux/huge_mm.h
include/linux/idr.h
include/linux/interrupt.h
include/linux/io.h
include/linux/irq_poll.h [new file with mode: 0644]
include/linux/kexec.h
include/linux/lightnvm.h
include/linux/list_lru.h
include/linux/lru_cache.h
include/linux/lz4.h
include/linux/memcontrol.h
include/linux/mlx4/cmd.h
include/linux/mlx4/device.h
include/linux/mlx4/qp.h
include/linux/mlx5/device.h
include/linux/mlx5/driver.h
include/linux/mlx5/mlx5_ifc.h
include/linux/mlx5/qp.h
include/linux/mlx5/transobj.h [new file with mode: 0644]
include/linux/mlx5/vport.h
include/linux/msi.h
include/linux/nvme.h
include/linux/of_pci.h
include/linux/pagemap.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pipe_fs_i.h
include/linux/platform_data/iommu-omap.h
include/linux/platform_data/pwm_omap_dmtimer.h [new file with mode: 0644]
include/linux/platform_data/sdhci-pic32.h [new file with mode: 0644]
include/linux/platform_data/touchscreen-s3c2410.h
include/linux/pm.h
include/linux/pm_domain.h
include/linux/pmem.h
include/linux/ptrace.h
include/linux/radix-tree.h
include/linux/rbtree.h
include/linux/reset.h
include/linux/sched.h
include/linux/sh_clk.h
include/linux/shm.h
include/linux/shmem_fs.h
include/linux/slab.h
include/linux/slab_def.h
include/linux/slub_def.h
include/linux/soc/dove/pmu.h
include/linux/soc/qcom/smem_state.h [new file with mode: 0644]
include/linux/sunrpc/svc_rdma.h
include/linux/swap.h
include/linux/thermal.h
include/linux/tick.h
include/linux/uaccess.h
include/linux/wkup_m3_ipc.h [new file with mode: 0644]
include/net/tcp_memcontrol.h [deleted file]
include/rdma/ib_addr.h
include/rdma/ib_cache.h
include/rdma/ib_mad.h
include/rdma/ib_pack.h
include/rdma/ib_pma.h
include/rdma/ib_sa.h
include/rdma/ib_verbs.h
include/scsi/iser.h [new file with mode: 0644]
include/soc/bcm2835/raspberrypi-firmware.h
include/sound/timer.h
include/target/target_core_base.h
include/target/target_core_fabric.h
include/trace/events/ext4.h
include/trace/events/huge_memory.h
include/trace/events/irq.h
include/uapi/linux/Kbuild
include/uapi/linux/eventpoll.h
include/uapi/linux/fs.h
include/uapi/linux/fuse.h
include/uapi/linux/lightnvm.h
include/uapi/linux/magic.h
include/xen/interface/io/blkif.h
init/Kconfig
init/do_mounts.h
init/do_mounts_initrd.c
init/main.c
ipc/mqueue.c
ipc/sem.c
ipc/shm.c
ipc/util.c
ipc/util.h
kernel/audit_fsnotify.c
kernel/audit_watch.c
kernel/cpu.c
kernel/events/core.c
kernel/exit.c
kernel/futex.c
kernel/futex_compat.c
kernel/irq/irqdomain.c
kernel/irq/msi.c
kernel/kcmp.c
kernel/kexec.c
kernel/kexec_core.c
kernel/kexec_file.c
kernel/kexec_internal.h
kernel/printk/printk.c
kernel/ptrace.c
kernel/relay.c
kernel/sched/core.c
kernel/sched/idle.c
kernel/sys.c
kernel/sysctl.c
kernel/time/tick-sched.c
lib/Kconfig
lib/Kconfig.debug
lib/Kconfig.ubsan [new file with mode: 0644]
lib/Makefile
lib/div64.c
lib/iomap_copy.c
lib/irq_poll.c [new file with mode: 0644]
lib/libcrc32c.c
lib/lru_cache.c
lib/ratelimit.c
lib/string_helpers.c
lib/strncpy_from_user.c
lib/strnlen_user.c
lib/test-hexdump.c [deleted file]
lib/test_hexdump.c [new file with mode: 0644]
lib/ubsan.c [new file with mode: 0644]
lib/ubsan.h [new file with mode: 0644]
mm/filemap.c
mm/huge_memory.c
mm/kasan/Makefile
mm/list_lru.c
mm/memcontrol.c
mm/memory.c
mm/mincore.c
mm/mlock.c
mm/percpu.c
mm/process_vm_access.c
mm/shmem.c
mm/slab.h
mm/slab_common.c
mm/slub.c
mm/swap_state.c
mm/swapfile.c
mm/truncate.c
mm/util.c
mm/vmscan.c
mm/vmstat.c
mm/workingset.c
mm/zsmalloc.c
net/9p/trans_fd.c
net/9p/trans_virtio.c
net/ceph/auth_x.c
net/ceph/auth_x.h
net/ceph/messenger.c
net/ceph/mon_client.c
net/ipv4/Makefile
net/ipv4/fib_trie.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_memcontrol.c [deleted file]
net/ipv6/tcp_ipv6.c
net/mac80211/debugfs.c
net/rds/ib.c
net/rds/iw.c
net/sunrpc/cache.c
net/sunrpc/rpc_pipe.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/Makefile
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/svc_rdma.c
net/sunrpc/xprtrdma/svc_rdma_backchannel.c [new file with mode: 0644]
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h
scripts/Makefile.lib
scripts/Makefile.ubsan [new file with mode: 0644]
scripts/checkpatch.pl
scripts/get_maintainer.pl
security/commoncap.c
security/inode.c
security/integrity/ima/ima_main.c
security/selinux/selinuxfs.c
security/smack/smack_lsm.c
security/yama/yama_lsm.c
sound/core/control.c
sound/core/hrtimer.c
sound/core/pcm_compat.c
sound/core/seq/seq_compat.c
sound/core/timer.c
sound/hda/hdac_i915.c
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/soc/samsung/smartq_wm8987.c
sound/spi/at73c213.c
tools/lib/traceevent/event-parse.c
tools/perf/util/trace-event-parse.c
tools/power/acpi/common/cmfsize.c
tools/power/acpi/common/getopt.c
tools/power/acpi/os_specific/service_layers/oslibcfs.c
tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
tools/power/acpi/os_specific/service_layers/osunixdir.c
tools/power/acpi/os_specific/service_layers/osunixmap.c
tools/power/acpi/os_specific/service_layers/osunixxf.c
tools/power/acpi/tools/acpidump/acpidump.h
tools/power/acpi/tools/acpidump/apdump.c
tools/power/acpi/tools/acpidump/apfiles.c
tools/power/acpi/tools/acpidump/apmain.c
tools/power/cpupower/utils/cpufreq-info.c

diff --git a/CREDITS b/CREDITS
index 25133c5..a3887b5 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1856,6 +1856,16 @@ S: Korte Heul 95
 S: 1403 ND  BUSSUM
 S: The Netherlands
 
+N: Martin Kepplinger
+E: martink@posteo.de
+E: martin.kepplinger@theobroma-systems.com
+W: http://www.martinkepplinger.com
+D: mma8452 accelerators iio driver
+D: Kernel cleanups
+S: Garnisonstraße 26
+S: 4020 Linz
+S: Austria
+
 N: Karl Keyte
 E: karl@koft.com
 D: Disk usage statistics and modifications to line printer driver
diff --git a/Documentation/ABI/testing/configfs-rdma_cm b/Documentation/ABI/testing/configfs-rdma_cm
new file mode 100644 (file)
index 0000000..5c389aa
--- /dev/null
@@ -0,0 +1,22 @@
+What:          /config/rdma_cm
+Date:          November 29, 2015
+KernelVersion:  4.4.0
+Description:   Interface is used to configure RDMA-cable HCAs in respect to
+               RDMA-CM attributes.
+
+               Attributes are visible only when configfs is mounted. To mount
+               configfs in /config directory use:
+               # mount -t configfs none /config/
+
+               In order to set parameters related to a specific HCA, a directory
+               for this HCA has to be created:
+               mkdir -p /config/rdma_cm/<hca>
+
+
+What:          /config/rdma_cm/<hca>/ports/<port-num>/default_roce_mode
+Date:          November 29, 2015
+KernelVersion:  4.4.0
+Description:   RDMA-CM based connections from HCA <hca> at port <port-num>
+               will be initiated with this RoCE type as default.
+               The possible RoCE types are either "IB/RoCE v1" or "RoCE v2".
+               This parameter has RW access.
diff --git a/Documentation/ABI/testing/configfs-usb-gadget-tcm b/Documentation/ABI/testing/configfs-usb-gadget-tcm
new file mode 100644 (file)
index 0000000..a29ed2d
--- /dev/null
@@ -0,0 +1,6 @@
+What:          /config/usb-gadget/gadget/functions/tcm.name
+Date:          Dec 2015
+KernelVersion: 4.5
+Description:
+               There are no attributes because all the configuration
+               is performed in the "target" subsystem of configfs.
diff --git a/Documentation/ABI/testing/sysfs-class-infiniband b/Documentation/ABI/testing/sysfs-class-infiniband
new file mode 100644 (file)
index 0000000..a86abe6
--- /dev/null
@@ -0,0 +1,16 @@
+What:          /sys/class/infiniband/<hca>/ports/<port-number>/gid_attrs/ndevs/<gid-index>
+Date:          November 29, 2015
+KernelVersion: 4.4.0
+Contact:       linux-rdma@vger.kernel.org
+Description:   The net-device's name associated with the GID resides
+               at index <gid-index>.
+
+What:          /sys/class/infiniband/<hca>/ports/<port-number>/gid_attrs/types/<gid-index>
+Date:          November 29, 2015
+KernelVersion: 4.4.0
+Contact:       linux-rdma@vger.kernel.org
+Description:   The RoCE type of the associated GID resides at index <gid-index>.
+               This could either be "IB/RoCE v1" for IB and RoCE v1 based GODs
+               or "RoCE v2" for RoCE v2 based GIDs.
+
+
index d69b3fc..781024e 100644 (file)
@@ -951,16 +951,6 @@ to "Closing".
    alignment constraints (e.g. the alignment constraints about 64-bit
    objects).
 
-3) Supporting multiple types of IOMMUs
-
-   If your architecture needs to support multiple types of IOMMUs, you
-   can use include/linux/asm-generic/dma-mapping-common.h. It's a
-   library to support the DMA API with multiple types of IOMMUs. Lots
-   of architectures (x86, powerpc, sh, alpha, ia64, microblaze and
-   sparc) use it. Choose one to see how it can be used. If you need to
-   support multiple types of IOMMUs in a single system, the example of
-   x86 or powerpc helps.
-
                           Closing
 
 This document, and the API itself, would not be in its current
index a179e5b..0b7cab9 100644 (file)
@@ -49,7 +49,7 @@ to this new MFP mechanism, here are several key points:
      internal controllers like PWM, SSP and UART, with 128 internal signals
      which can be routed to external through one or more MFPs (e.g. GPIO<0>
      can be routed through either MFP_PIN_GPIO0 as well as MFP_PIN_GPIO0_2,
-     see arch/arm/mach-pxa/mach/include/mfp-pxa300.h)
+     see arch/arm/mach-pxa/mfp-pxa300.h)
 
   2. Alternate function configuration is removed from this GPIO controller,
      the remaining functions are pure GPIO-specific, i.e.
@@ -76,11 +76,11 @@ For board code writers, here are some guidelines:
 
 1. include ONE of the following header files in your <board>.c:
 
-   - #include <mach/mfp-pxa25x.h>
-   - #include <mach/mfp-pxa27x.h>
-   - #include <mach/mfp-pxa300.h>
-   - #include <mach/mfp-pxa320.h>
-   - #include <mach/mfp-pxa930.h>
+   - #include "mfp-pxa25x.h"
+   - #include "mfp-pxa27x.h"
+   - #include "mfp-pxa300.h"
+   - #include "mfp-pxa320.h"
+   - #include "mfp-pxa930.h"
 
    NOTE: only one file in your <board>.c, depending on the processors used,
    because pin configuration definitions may conflict in these file (i.e.
@@ -203,20 +203,20 @@ make them effective there-after.
     1. Unified pin definitions - enum constants for all configurable pins
     2. processor-neutral bit definitions for a possible MFP configuration
 
-  - arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
+  - arch/arm/mach-pxa/mfp-pxa3xx.h
 
   for PXA3xx specific MFPR register bit definitions and PXA3xx common pin
   configurations
 
-  - arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
+  - arch/arm/mach-pxa/mfp-pxa2xx.h
 
   for PXA2xx specific definitions and PXA25x/PXA27x common pin configurations
 
-  - arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
-    arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
-    arch/arm/mach-pxa/include/mach/mfp-pxa300.h
-    arch/arm/mach-pxa/include/mach/mfp-pxa320.h
-    arch/arm/mach-pxa/include/mach/mfp-pxa930.h
+  - arch/arm/mach-pxa/mfp-pxa25x.h
+    arch/arm/mach-pxa/mfp-pxa27x.h
+    arch/arm/mach-pxa/mfp-pxa300.h
+    arch/arm/mach-pxa/mfp-pxa320.h
+    arch/arm/mach-pxa/mfp-pxa930.h
 
   for processor specific definitions
 
index 31d1f7b..65b3eac 100644 (file)
@@ -819,6 +819,78 @@ PAGE_SIZE multiple when read back.
                the cgroup.  This may not exactly match the number of
                processes killed but should generally be close.
 
+  memory.stat
+
+       A read-only flat-keyed file which exists on non-root cgroups.
+
+       This breaks down the cgroup's memory footprint into different
+       types of memory, type-specific details, and other information
+       on the state and past events of the memory management system.
+
+       All memory amounts are in bytes.
+
+       The entries are ordered to be human readable, and new entries
+       can show up in the middle. Don't rely on items remaining in a
+       fixed position; use the keys to look up specific values!
+
+         anon
+
+               Amount of memory used in anonymous mappings such as
+               brk(), sbrk(), and mmap(MAP_ANONYMOUS)
+
+         file
+
+               Amount of memory used to cache filesystem data,
+               including tmpfs and shared memory.
+
+         file_mapped
+
+               Amount of cached filesystem data mapped with mmap()
+
+         file_dirty
+
+               Amount of cached filesystem data that was modified but
+               not yet written back to disk
+
+         file_writeback
+
+               Amount of cached filesystem data that was modified and
+               is currently being written back to disk
+
+         inactive_anon
+         active_anon
+         inactive_file
+         active_file
+         unevictable
+
+               Amount of memory, swap-backed and filesystem-backed,
+               on the internal memory management lists used by the
+               page reclaim algorithm
+
+         pgfault
+
+               Total number of page faults incurred
+
+         pgmajfault
+
+               Number of major page faults incurred
+
+  memory.swap.current
+
+       A read-only single value file which exists on non-root
+       cgroups.
+
+       The total amount of swap currently being used by the cgroup
+       and its descendants.
+
+  memory.swap.max
+
+       A read-write single value file which exists on non-root
+       cgroups.  The default is "max".
+
+       Swap usage hard limit.  If a cgroup's swap usage reaches this
+       limit, anonymous meomry of the cgroup will not be swapped out.
+
 
 5-2-2. General Usage
 
@@ -1291,3 +1363,20 @@ allocation from the slack available in other groups or the rest of the
 system than killing the group.  Otherwise, memory.max is there to
 limit this type of spillover and ultimately contain buggy or even
 malicious applications.
+
+The combined memory+swap accounting and limiting is replaced by real
+control over swap space.
+
+The main argument for a combined memory+swap facility in the original
+cgroup design was that global or parental pressure would always be
+able to swap all anonymous memory of a child group, regardless of the
+child's own (possibly untrusted) configuration.  However, untrusted
+groups can sabotage swapping by other means - such as referencing its
+anonymous memory in a tight loop - and an admin can not assume full
+swappability when overcommitting untrusted jobs.
+
+For trusted jobs, on the other hand, a combined counter is not an
+intuitive userspace interface, and it flies in the face of the idea
+that cgroup controllers should account and limit specific physical
+resources.  Swap space is a resource like all others in the system,
+and that's why unified hierarchy allows distributing it separately.
index c78576b..11d3056 100644 (file)
@@ -26,6 +26,10 @@ Raspberry Pi Model B+
 Required root node properties:
 compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
 
+Raspberry Pi 2 Model B
+Required root node properties:
+compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
+
 Raspberry Pi Compute Module
 Required root node properties:
 compatible = "raspberrypi,compute-module", "brcm,bcm2835";
index 6b0f49f..8608a77 100644 (file)
@@ -5,4 +5,11 @@ Boards with the BCM4708 SoC shall have the following properties:
 
 Required root node property:
 
+bcm4708
 compatible = "brcm,bcm4708";
+
+bcm4709
+compatible = "brcm,bcm4709";
+
+bcm53012
+compatible = "brcm,bcm53012";
diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,nsp-cpu-method.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp-cpu-method.txt
new file mode 100644 (file)
index 0000000..677ef9d
--- /dev/null
@@ -0,0 +1,39 @@
+Broadcom Northstar Plus SoC CPU Enable Method
+---------------------------------------------
+This binding defines the enable method used for starting secondary
+CPU in the following Broadcom SoCs:
+  BCM58522, BCM58525, BCM58535, BCM58622, BCM58623, BCM58625, BCM88312
+
+The enable method is specified by defining the following required
+properties in the corresponding secondary "cpu" device tree node:
+  - enable-method = "brcm,bcm-nsp-smp";
+  - secondary-boot-reg = <...>;
+
+The secondary-boot-reg property is a u32 value that specifies the
+physical address of the register which should hold the common
+entry point for a secondary CPU. This entry is cpu node specific
+and should be added per cpu. E.g., in case of NSP (BCM58625) which
+is a dual core CPU SoC, this entry should be added to cpu1 node.
+
+
+Example:
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       enable-method = "brcm,bcm-nsp-smp";
+                       secondary-boot-reg = <0xffff042c>;
+                       reg = <1>;
+               };
+       };
diff --git a/Documentation/devicetree/bindings/arm/compulab-boards.txt b/Documentation/devicetree/bindings/arm/compulab-boards.txt
new file mode 100644 (file)
index 0000000..42a1028
--- /dev/null
@@ -0,0 +1,25 @@
+CompuLab SB-SOM is a multi-module baseboard capable of carrying:
+ - CM-T43
+ - CM-T54
+ - CM-QS600
+ - CL-SOM-AM57x
+ - CL-SOM-iMX7
+modules with minor modifications to the SB-SOM assembly.
+
+Required root node properties:
+    - compatible = should be "compulab,sb-som"
+
+Compulab CL-SOM-iMX7 is a miniature System-on-Module (SoM) based on
+Freescale i.MX7 ARM Cortex-A7 System-on-Chip.
+
+Required root node properties:
+    - compatible = "compulab,cl-som-imx7", "fsl,imx7d";
+
+Compulab SBC-iMX7 is a single board computer based on the
+Freescale i.MX7 system-on-chip. SBC-iMX7 is implemented with
+the CL-SOM-iMX7 System-on-Module providing most of the functions,
+and SB-SOM-iMX7 carrier board providing additional peripheral
+functions and connectors.
+
+Required root node properties:
+    - compatible = "compulab,sbc-imx7", "compulab,cl-som-imx7", "fsl,imx7d";
index c352c11..ae9be07 100644 (file)
@@ -191,6 +191,8 @@ nodes to be present and contain the properties described below.
                            "allwinner,sun6i-a31"
                            "allwinner,sun8i-a23"
                            "arm,psci"
+                           "arm,realview-smp"
+                           "brcm,bcm-nsp-smp"
                            "brcm,brahma-b15"
                            "marvell,armada-375-smp"
                            "marvell,armada-380-smp"
@@ -201,6 +203,7 @@ nodes to be present and contain the properties described below.
                            "qcom,gcc-msm8660"
                            "qcom,kpss-acc-v1"
                            "qcom,kpss-acc-v2"
+                           "rockchip,rk3036-smp"
                            "rockchip,rk3066-smp"
                            "ste,dbx500-smp"
 
index 34c88b0..752a685 100644 (file)
@@ -131,6 +131,10 @@ Example:
 Freescale ARMv8 based Layerscape SoC family Device Tree Bindings
 ----------------------------------------------------------------
 
+LS1043A ARMv8 based RDB Board
+Required root node properties:
+    - compatible = "fsl,ls1043a-rdb", "fsl,ls1043a";
+
 LS2080A ARMv8 based Simulator model
 Required root node properties:
     - compatible = "fsl,ls2080a-simu", "fsl,ls2080a";
index 5171ad8..ab0c9cd 100644 (file)
@@ -24,6 +24,8 @@ board. Currently known boards are:
 "buffalo,lswxl"
 "buffalo,lsxhl"
 "buffalo,lsxl"
+"cloudengines,pogo02"
+"cloudengines,pogoplugv4"
 "dlink,dns-320"
 "dlink,dns-320-a1"
 "dlink,dns-325"
index 618a919..54f43bc 100644 (file)
@@ -6,6 +6,7 @@ following property:
 Required root node property:
 
 compatible: Must contain one of
+   "mediatek,mt2701"
    "mediatek,mt6580"
    "mediatek,mt6589"
    "mediatek,mt6592"
@@ -17,6 +18,9 @@ compatible: Must contain one of
 
 Supported boards:
 
+- Evaluation board for MT2701:
+    Required root node properties:
+      - compatible = "mediatek,mt2701-evb", "mediatek,mt2701";
 - Evaluation board for MT6580:
     Required root node properties:
       - compatible = "mediatek,mt6580-evbp1", "mediatek,mt6580";
index f6cd3e4..aaf8d14 100644 (file)
@@ -18,7 +18,7 @@ The available clocks are defined in dt-bindings/clock/mt*-clk.h.
 Also it uses the common reset controller binding from
 Documentation/devicetree/bindings/reset/reset.txt.
 The available reset outputs are defined in
-dt-bindings/reset-controller/mt*-resets.h
+dt-bindings/reset/mt*-resets.h
 
 Example:
 
index f25b854..2f6ff86 100644 (file)
@@ -18,7 +18,7 @@ The available clocks are defined in dt-bindings/clock/mt*-clk.h.
 Also it uses the common reset controller binding from
 Documentation/devicetree/bindings/reset/reset.txt.
 The available reset outputs are defined in
-dt-bindings/reset-controller/mt*-resets.h
+dt-bindings/reset/mt*-resets.h
 
 Example:
 
index 9f4e513..a2bd593 100644 (file)
@@ -138,9 +138,21 @@ Boards:
 - AM335X phyBOARD-WEGA: Single Board Computer dev kit
   compatible = "phytec,am335x-wega", "phytec,am335x-phycore-som", "ti,am33xx"
 
+- AM335X CM-T335 : System On Module, built around the Sitara AM3352/4
+  compatible = "compulab,cm-t335", "ti,am33xx"
+
+- AM335X SBC-T335 : single board computer, built around the Sitara AM3352/4
+  compatible = "compulab,sbc-t335", "compulab,cm-t335", "ti,am33xx"
+
 - OMAP5 EVM : Evaluation Module
   compatible = "ti,omap5-evm", "ti,omap5"
 
+- AM437x CM-T43
+  compatible = "compulab,am437x-cm-t43", "ti,am4372", "ti,am43"
+
+- AM437x SBC-T43
+  compatible = "compulab,am437x-sbc-t43", "compulab,am437x-cm-t43", "ti,am4372", "ti,am43"
+
 - AM43x EPOS EVM
   compatible = "ti,am43x-epos-evm", "ti,am4372", "ti,am43"
 
@@ -150,6 +162,12 @@ Boards:
 - AM437x SK EVM: AM437x StarterKit Evaluation Module
   compatible = "ti,am437x-sk-evm", "ti,am4372", "ti,am43"
 
+- AM57XX CL-SOM-AM57x
+  compatible = "compulab,cl-som-am57x", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7"
+
+- AM57XX SBC-AM57x
+  compatible = "compulab,sbc-am57x", "compulab,cl-som-am57x", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7"
+
 - DRA742 EVM:  Software Development Board for DRA742
   compatible = "ti,dra7-evm", "ti,dra742", "ti,dra74", "ti,dra7"
 
index 8e985dd..078c14f 100644 (file)
@@ -1,6 +1,10 @@
 Rockchip platforms device tree bindings
 ---------------------------------------
 
+- Kylin RK3036 board:
+    Required root node properties:
+      - compatible = "rockchip,kylin-rk3036", "rockchip,rk3036";
+
 - MarsBoard RK3066 board:
     Required root node properties:
       - compatible = "haoyu,marsboard-rk3066", "rockchip,rk3066a";
@@ -35,6 +39,11 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "netxeon,r89", "rockchip,rk3288";
 
+- Google Brain (dev-board):
+    Required root node properties:
+      - compatible = "google,veyron-brain-rev0", "google,veyron-brain",
+                    "google,veyron", "rockchip,rk3288";
+
 - Google Jaq (Haier Chromebook 11 and more):
     Required root node properties:
       - compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
@@ -49,6 +58,15 @@ Rockchip platforms device tree bindings
                     "google,veyron-jerry-rev3", "google,veyron-jerry",
                     "google,veyron", "rockchip,rk3288";
 
+- Google Mickey (Asus Chromebit CS10):
+    Required root node properties:
+      - compatible = "google,veyron-mickey-rev8", "google,veyron-mickey-rev7",
+                    "google,veyron-mickey-rev6", "google,veyron-mickey-rev5",
+                    "google,veyron-mickey-rev4", "google,veyron-mickey-rev3",
+                    "google,veyron-mickey-rev2", "google,veyron-mickey-rev1",
+                    "google,veyron-mickey-rev0", "google,veyron-mickey",
+                    "google,veyron", "rockchip,rk3288";
+
 - Google Minnie (Asus Chromebook Flip C100P):
     Required root node properties:
       - compatible = "google,veyron-minnie-rev4", "google,veyron-minnie-rev3",
@@ -69,6 +87,14 @@ Rockchip platforms device tree bindings
                     "google,veyron-speedy-rev3", "google,veyron-speedy-rev2",
                     "google,veyron-speedy", "google,veyron", "rockchip,rk3288";
 
+- Rockchip RK3368 evb:
+    Required root node properties:
+      - compatible = "rockchip,rk3368-evb-act8846", "rockchip,rk3368";
+
 - Rockchip R88 board:
     Required root node properties:
       - compatible = "rockchip,r88", "rockchip,rk3368";
+
+- Rockchip RK3228 Evaluation board:
+    Required root node properties:
+      - compatible = "rockchip,rk3228-evb", "rockchip,rk3228";
index f46ca9a..ccaaec6 100644 (file)
@@ -47,6 +47,9 @@ Required properties:
 
 - samsung,syscon-phandle Contains the PMU system controller node
                        (To access the ADC_PHY register on Exynos5250/5420/5800/3250)
+Optional properties:
+- has-touchscreen:     If present, indicates that a touchscreen is
+                       connected an usable.
 
 Note: child nodes can be added for auto probing from device tree.
 
index c447680..08a5878 100644 (file)
@@ -10,10 +10,13 @@ References:
   Revision r2p0
 - Cortex-A5: see DDI0434B Cortex-A5 MPCore Technical Reference Manual
   Revision r0p1
+- ARM11 MPCore: see DDI0360F ARM 11 MPCore Processor Technical Reference
+  Manial Revision r2p0
 
 - compatible : Should be:
        "arm,cortex-a9-scu"
        "arm,cortex-a5-scu"
+       "arm,arm11mp-scu"
 
 - reg : Specify the base address and the size of the SCU register window.
 
index 40bb900..9cf67e4 100644 (file)
@@ -27,6 +27,8 @@ SoCs:
     compatible = "renesas,r8a7793"
   - R-Car E2 (R8A77940)
     compatible = "renesas,r8a7794"
+  - R-Car H3 (R8A77950)
+    compatible = "renesas,r8a7795"
 
 
 Boards:
@@ -57,5 +59,7 @@ Boards:
     compatible = "renesas,marzen", "renesas,r8a7779"
   - Porter (M2-LCDP)
     compatible = "renesas,porter", "renesas,r8a7791"
+  - Salvator-X (RTP0RC7795SIPB0010S)
+    compatible = "renesas,salvator-x", "renesas,r8a7795";
   - SILK (RTP0RC7794LCB00011S)
     compatible = "renesas,silk", "renesas,r8a7794"
diff --git a/Documentation/devicetree/bindings/arm/technologic.txt b/Documentation/devicetree/bindings/arm/technologic.txt
new file mode 100644 (file)
index 0000000..8422988
--- /dev/null
@@ -0,0 +1,6 @@
+Technologic Systems Platforms Device Tree Bindings
+--------------------------------------------------
+
+TS-4800 board
+Required root node properties:
+       - compatible = "technologic,imx51-ts4800", "fsl,imx51";
diff --git a/Documentation/devicetree/bindings/bus/uniphier-system-bus.txt b/Documentation/devicetree/bindings/bus/uniphier-system-bus.txt
new file mode 100644 (file)
index 0000000..68ef80a
--- /dev/null
@@ -0,0 +1,66 @@
+UniPhier System Bus
+
+The UniPhier System Bus is an external bus that connects on-board devices to
+the UniPhier SoC.  It is a simple (semi-)parallel bus with address, data, and
+some control signals.  It supports up to 8 banks (chip selects).
+
+Before any access to the bus, the bus controller must be configured; the bus
+controller registers provide the control for the translation from the offset
+within each bank to the CPU-viewed address.  The needed setup includes the base
+address, the size of each bank.  Optionally, some timing parameters can be
+optimized for faster bus access.
+
+Required properties:
+- compatible: should be "socionext,uniphier-system-bus".
+- reg: offset and length of the register set for the bus controller device.
+- #address-cells: should be 2.  The first cell is the bank number (chip select).
+  The second cell is the address offset within the bank.
+- #size-cells: should be 1.
+- ranges: should provide a proper address translation from the System Bus to
+  the parent bus.
+
+Note:
+The address region(s) that can be assigned for the System Bus is implementation
+defined.  Some SoCs can use 0x00000000-0x0fffffff and 0x40000000-0x4fffffff,
+while other SoCs can only use 0x40000000-0x4fffffff.  There might be additional
+limitations depending on SoCs and the boot mode.  The address translation is
+arbitrary as long as the banks are assigned in the supported address space with
+the required alignment and they do not overlap one another.
+For example, it is possible to map:
+  bank 0 to 0x42000000-0x43ffffff, bank 5 to 0x46000000-0x46ffffff
+It is also possible to map:
+  bank 0 to 0x48000000-0x49ffffff, bank 5 to 0x44000000-0x44ffffff
+There is no reason to stick to a particular translation mapping, but the
+"ranges" property should provide a "reasonable" default that is known to work.
+The software should initialize the bus controller according to it.
+
+Example:
+
+       system-bus {
+               compatible = "socionext,uniphier-system-bus";
+               reg = <0x58c00000 0x400>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <1 0x00000000 0x42000000 0x02000000
+                         5 0x00000000 0x46000000 0x01000000>;
+
+               ethernet@1,01f00000 {
+                       compatible = "smsc,lan9115";
+                       reg = <1 0x01f00000 0x1000>;
+                       interrupts = <0 48 4>
+                       phy-mode = "mii";
+               };
+
+               uart@5,00200000 {
+                       compatible = "ns16550a";
+                       reg = <5 0x00200000 0x20>;
+                       interrupts = <0 49 4>
+                       clock-frequency = <12288000>;
+               };
+       };
+
+In this example,
+ - the Ethernet device is connected at the offset 0x01f00000 of CS1 and
+   mapped to 0x43f00000 of the parent bus.
+ - the UART device is connected at the offset 0x00200000 of CS5 and
+   mapped to 0x46200000 of the parent bus.
diff --git a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
new file mode 100644 (file)
index 0000000..8b7177c
--- /dev/null
@@ -0,0 +1,40 @@
+ARM System Controller ICST clocks
+
+The ICS525 and ICS307 oscillators are produced by Integrated Devices
+Technology (IDT). ARM integrated these oscillators deeply into their
+reference designs by adding special control registers that manage such
+oscillators to their system controllers.
+
+The ARM system controller contains logic to serialize and initialize
+an ICST clock request after a write to the 32 bit register at an offset
+into the system controller. Furthermore, to even be able to alter one of
+these frequencies, the system controller must first be unlocked by
+writing a special token to another offset in the system controller.
+
+The ICST oscillator must be provided inside a system controller node.
+
+Required properties:
+- lock-offset: the offset address into the system controller where the
+  unlocking register is located
+- vco-offset: the offset address into the system controller where the
+  ICST control register is located (even 32 bit address)
+- compatible: must be one of "arm,syscon-icst525" or "arm,syscon-icst307"
+- #clock-cells: must be <0>
+- clocks: parent clock, since the ICST needs a parent clock to derive its
+  frequency from, this attribute is compulsory.
+
+Example:
+
+syscon: syscon@10000000 {
+       compatible = "syscon";
+       reg = <0x10000000 0x1000>;
+
+       oscclk0: osc0@0c {
+               compatible = "arm,syscon-icst307";
+               #clock-cells = <0>;
+               lock-offset = <0x20>;
+               vco-offset = <0x0c>;
+               clocks = <&xtal24mhz>;
+       };
+       (...)
+};
diff --git a/Documentation/devicetree/bindings/clock/dove-divider-clock.txt b/Documentation/devicetree/bindings/clock/dove-divider-clock.txt
new file mode 100644 (file)
index 0000000..e3eb0f6
--- /dev/null
@@ -0,0 +1,28 @@
+PLL divider based Dove clocks
+
+Marvell Dove has a 2GHz PLL, which feeds into a set of dividers to provide
+high speed clocks for a number of peripherals.  These dividers are part of
+the PMU, and thus this node should be a child of the PMU node.
+
+The following clocks are provided:
+
+ID     Clock
+-------------
+0      AXI bus clock
+1      GPU clock
+2      VMeta clock
+3      LCD clock
+
+Required properties:
+- compatible : shall be "marvell,dove-divider-clock"
+- reg : shall be the register address of the Core PLL and Clock Divider
+   Control 0 register.  This will cover that register, as well as the
+   Core PLL and Clock Divider Control 1 register.  Thus, it will have
+   a size of 8.
+- #clock-cells : from common clock binding; shall be set to 1
+
+divider_clk: core-clock@0064 {
+       compatible = "marvell,dove-divider-clock";
+       reg = <0x0064 0x8>;
+       #clock-cells = <1>;
+};
index 36c2b52..399e0da 100644 (file)
@@ -2,7 +2,7 @@
 
 Required Properties:
 
-  - compatible: Must be "renesas,sh73a0-h8300-div-clock"
+  - compatible: Must be "renesas,h8300-div-clock"
 
   - clocks: Reference to the parent clocks ("extal1" and "extal2")
 
index 1fd8cf9..d474f59 100644 (file)
@@ -2,10 +2,9 @@ Device-Tree bindings for drm hdmi driver
 
 Required properties:
 - compatible: value should be one among the following:
-       1) "samsung,exynos5-hdmi" <DEPRECATED>
-       2) "samsung,exynos4210-hdmi"
-       3) "samsung,exynos4212-hdmi"
-       4) "samsung,exynos5420-hdmi"
+       1) "samsung,exynos4210-hdmi"
+       2) "samsung,exynos4212-hdmi"
+       3) "samsung,exynos5420-hdmi"
 - reg: physical base address of the hdmi and length of memory mapped
        region.
 - interrupts: interrupt number to the cpu.
diff --git a/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt b/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt
new file mode 100644 (file)
index 0000000..70cd8d1
--- /dev/null
@@ -0,0 +1,4 @@
+Startek Electronic Technology Co. KD050C 5.0" WVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "startek,startek-kd050c"
index cf1333d..2164123 100644 (file)
@@ -6,6 +6,7 @@ Required properties:
 Optional properties:
        - autorepeat: Boolean, Enable auto repeat feature of Linux input
          subsystem.
+       - label: String, name of the input device.
 
 Each button (key) is represented as a sub-node of "gpio-keys":
 Subnode properties:
index afef6a8..b8e1674 100644 (file)
@@ -14,6 +14,7 @@ Required properties:
        "mediatek,mt6582-sysirq"
        "mediatek,mt6580-sysirq"
        "mediatek,mt6577-sysirq"
+       "mediatek,mt2701-sysirq"
 - interrupt-controller : Identifies the node as an interrupt controller
 - #interrupt-cells : Use the same format as specified by GIC in
   Documentation/devicetree/bindings/arm/gic.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt b/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt
new file mode 100644 (file)
index 0000000..c3a1b37
--- /dev/null
@@ -0,0 +1,67 @@
+Microchip PIC32 Interrupt Controller
+====================================
+
+The Microchip PIC32 contains an Enhanced Vectored Interrupt Controller (EVIC).
+It handles all internal and external interrupts. This controller exists outside
+of the CPU and is the arbitrator of all interrupts (including interrupts from
+the CPU itself) before they are presented to the CPU.
+
+External interrupts have a software configurable edge polarity. Non external
+interrupts have a type and polarity that is determined by the source of the
+interrupt.
+
+Required properties
+-------------------
+
+- compatible: Should be "microchip,pic32mzda-evic"
+- reg: Specifies physical base address and size of register range.
+- interrupt-controller: Identifies the node as an interrupt controller.
+- #interrupt cells: Specifies the number of cells used to encode an interrupt
+  source connected to this controller. The value shall be 2 and interrupt
+  descriptor shall have the following format:
+
+       <hw_irq irq_type>
+
+  hw_irq - represents the hardware interrupt number as in the data sheet.
+  irq_type - is used to describe the type and polarity of an interrupt. For
+  internal interrupts use IRQ_TYPE_EDGE_RISING for non persistent interrupts and
+  IRQ_TYPE_LEVEL_HIGH for persistent interrupts. For external interrupts use
+  IRQ_TYPE_EDGE_RISING or IRQ_TYPE_EDGE_FALLING to select the desired polarity.
+
+Optional properties
+-------------------
+- microchip,external-irqs: u32 array of external interrupts with software
+  polarity configuration. This array corresponds to the bits in the INTCON
+  SFR.
+
+Example
+-------
+
+evic: interrupt-controller@1f810000 {
+       compatible = "microchip,pic32mzda-evic";
+       interrupt-controller;
+       #interrupt-cells = <2>;
+       reg = <0x1f810000 0x1000>;
+       microchip,external-irqs = <3 8 13 18 23>;
+};
+
+Each device/peripheral must request its interrupt line with the associated type
+and polarity.
+
+Internal interrupt DTS snippet
+------------------------------
+
+device@1f800000 {
+       ...
+       interrupts = <113 IRQ_TYPE_LEVEL_HIGH>;
+       ...
+};
+
+External interrupt DTS snippet
+------------------------------
+
+device@1f800000 {
+       ...
+       interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+       ...
+};
diff --git a/Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt b/Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt
new file mode 100644 (file)
index 0000000..1c8dbc4
--- /dev/null
@@ -0,0 +1,31 @@
+* Microchip PIC32MZDA Platforms
+
+PIC32MZDA Starter Kit
+Required root node properties:
+    - compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda"
+
+CPU nodes:
+----------
+A "cpus" node is required.  Required properties:
+ - #address-cells: Must be 1.
+ - #size-cells: Must be 0.
+A CPU sub-node is also required.  Required properties:
+ - device_type: Must be "cpu".
+ - compatible: Must be "mti,mips14KEc".
+Example:
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mti,mips14KEc";
+               };
+       };
+
+Boot protocol
+--------------
+In accordance with Unified Hosting Interface Reference Manual (MD01069), the
+bootloader must pass the following arguments to the kernel:
+ - $a0: -2.
+ - $a1: KSEG0 address of the flattened device-tree blob.
diff --git a/Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt b/Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt
new file mode 100644 (file)
index 0000000..aa63130
--- /dev/null
@@ -0,0 +1,26 @@
+Mediatek Gigabit Switch
+=======================
+
+The mediatek gigabit switch can be found on Mediatek SoCs (mt7620, mt7621).
+
+Required properties:
+- compatible: Should be "mediatek,mt7620-gsw" or "mediatek,mt7621-gsw"
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the gigabit switches interrupt
+- resets: Should contain the gigabit switches resets
+- reset-names: Should contain the reset names "gsw"
+
+Example:
+
+gsw@10110000 {
+       compatible = "ralink,mt7620-gsw";
+       reg = <0x10110000 8000>;
+
+       resets = <&rstctrl 23>;
+       reset-names = "gsw";
+
+       interrupt-parent = <&intc>;
+       interrupts = <17>;
+};
diff --git a/Documentation/devicetree/bindings/net/ralink,rt2880-net.txt b/Documentation/devicetree/bindings/net/ralink,rt2880-net.txt
new file mode 100644 (file)
index 0000000..88b095d
--- /dev/null
@@ -0,0 +1,61 @@
+Ralink Frame Engine Ethernet controller
+=======================================
+
+The Ralink frame engine ethernet controller can be found on Ralink and
+Mediatek SoCs (RT288x, RT3x5x, RT366x, RT388x, rt5350, mt7620, mt7621, mt76x8).
+
+Depending on the SoC, there is a number of ports connected to the CPU port
+directly and/or via a (gigabit-)switch.
+
+* Ethernet controller node
+
+Required properties:
+- compatible: Should be one of "ralink,rt2880-eth", "ralink,rt3050-eth",
+  "ralink,rt3050-eth", "ralink,rt3883-eth", "ralink,rt5350-eth",
+  "mediatek,mt7620-eth", "mediatek,mt7621-eth"
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the frame engines interrupt
+- resets: Should contain the frame engines resets
+- reset-names: Should contain the reset names "fe". If a switch is present
+  "esw" is also required.
+
+
+* Ethernet port node
+
+Required properties:
+- compatible: Should be "ralink,eth-port"
+- reg: The number of the physical port
+- phy-handle: reference to the node describing the phy
+
+Example:
+
+mdio-bus {
+       ...
+       phy0: ethernet-phy@0 {
+               phy-mode = "mii";
+               reg = <0>;
+       };
+};
+
+ethernet@400000 {
+       compatible = "ralink,rt2880-eth";
+       reg = <0x00400000 10000>;
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       resets = <&rstctrl 18>;
+       reset-names = "fe";
+
+       interrupt-parent = <&cpuintc>;
+       interrupts = <5>;
+
+       port@0 {
+               compatible = "ralink,eth-port";
+               reg = <0>;
+               phy-handle = <&phy0>;
+       };
+
+};
diff --git a/Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt b/Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt
new file mode 100644 (file)
index 0000000..2e79bd3
--- /dev/null
@@ -0,0 +1,32 @@
+Ralink Fast Ethernet Embedded Switch
+====================================
+
+The ralink fast ethernet embedded switch can be found on Ralink and Mediatek
+SoCs (RT3x5x, RT5350, MT76x8).
+
+Required properties:
+- compatible: Should be "ralink,rt3050-esw"
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the embedded switches interrupt
+- resets: Should contain the embedded switches resets
+- reset-names: Should contain the reset names "esw"
+
+Optional properties:
+- ralink,portmap: can be used to choose if the default switch setup is
+  llllw or wllll
+- ralink,led_polarity: override the active high/low settings of the leds
+
+Example:
+
+esw@10110000 {
+       compatible = "ralink,rt3050-esw";
+       reg = <0x10110000 8000>;
+
+       resets = <&rstctrl 23>;
+       reset-names = "esw";
+
+       interrupt-parent = <&intc>;
+       interrupts = <17>;
+};
index 45c2a80..01b88f4 100644 (file)
@@ -1,7 +1,10 @@
 * Broadcom iProc PCIe controller with the platform bus interface
 
 Required properties:
-- compatible: Must be "brcm,iproc-pcie"
+- compatible: Must be "brcm,iproc-pcie" for PAXB, or "brcm,iproc-pcie-paxc"
+  for PAXC.  PAXB-based root complex is used for external endpoint devices.
+  PAXC-based root complex is connected to emulated endpoint devices
+  internal to the ASIC
 - reg: base address and length of the PCIe controller I/O register space
 - #interrupt-cells: set to <1>
 - interrupt-map-mask and interrupt-map, standard PCI properties to define the
@@ -32,6 +35,28 @@ Optional:
 - brcm,pcie-ob-oarr-size: Some iProc SoCs need the OARR size bit to be set to
 increase the outbound window size
 
+MSI support (optional):
+
+For older platforms without MSI integrated in the GIC, iProc PCIe core provides
+an event queue based MSI support.  The iProc MSI uses host memories to store
+MSI posted writes in the event queues
+
+- msi-parent: Link to the device node of the MSI controller.  On newer iProc
+platforms, the MSI controller may be gicv2m or gicv3-its.  On older iProc
+platforms without MSI support in its interrupt controller, one may use the
+event queue based MSI support integrated within the iProc PCIe core.
+
+When the iProc event queue based MSI is used, one needs to define the
+following properties in the MSI device node:
+- compatible: Must be "brcm,iproc-msi"
+- msi-controller: claims itself as an MSI controller
+- interrupt-parent: Link to its parent interrupt device
+- interrupts: List of interrupt IDs from its parent interrupt device
+
+Optional properties:
+- brcm,pcie-msi-inten: Needs to be present for some older iProc platforms that
+require the interrupt enable registers to be set explicitly to enable MSI
+
 Example:
        pcie0: pcie@18012000 {
                compatible = "brcm,iproc-pcie";
@@ -58,6 +83,19 @@ Example:
                brcm,pcie-ob-oarr-size;
                brcm,pcie-ob-axi-offset = <0x00000000>;
                brcm,pcie-ob-window-size = <256>;
+
+               msi-parent = <&msi0>;
+
+               /* iProc event queue based MSI */
+               msi0: msi@18012000 {
+                       compatible = "brcm,iproc-msi";
+                       msi-controller;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_NONE>,
+                                    <GIC_SPI 97 IRQ_TYPE_NONE>,
+                                    <GIC_SPI 98 IRQ_TYPE_NONE>,
+                                    <GIC_SPI 99 IRQ_TYPE_NONE>,
+               };
        };
 
        pcie1: pcie@18013000 {
index 17c6ed9..b721bea 100644 (file)
@@ -1,4 +1,4 @@
-HiSilicon PCIe host bridge DT description
+HiSilicon Hip05 and Hip06 PCIe host bridge DT description
 
 HiSilicon PCIe host controller is based on Designware PCI core.
 It shares common functions with PCIe Designware core driver and inherits
@@ -7,8 +7,8 @@ Documentation/devicetree/bindings/pci/designware-pci.txt.
 
 Additional properties are described here:
 
-Required properties:
-- compatible: Should contain "hisilicon,hip05-pcie".
+Required properties
+- compatible: Should contain "hisilicon,hip05-pcie" or "hisilicon,hip06-pcie".
 - reg: Should contain rc_dbi, config registers location and length.
 - reg-names: Must include the following entries:
   "rc_dbi": controller configuration registers;
@@ -20,7 +20,7 @@ Optional properties:
 - status: Either "ok" or "disabled".
 - dma-coherent: Present if DMA operations are coherent.
 
-Example:
+Hip05 Example (note that Hip06 is the same except compatible):
        pcie@0xb0080000 {
                compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
                reg = <0 0xb0080000 0 0x10000>, <0x220 0x00000000 0 0x2000>;
index 7fab84b..4e8b90e 100644 (file)
@@ -8,7 +8,14 @@ OHCI and EHCI controllers.
 Required properties:
 - compatible: "renesas,pci-r8a7790" for the R8A7790 SoC;
              "renesas,pci-r8a7791" for the R8A7791 SoC;
-             "renesas,pci-r8a7794" for the R8A7794 SoC.
+             "renesas,pci-r8a7794" for the R8A7794 SoC;
+             "renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device
+
+
+             When compatible with the generic version, nodes must list the
+             SoC-specific version corresponding to the platform first
+             followed by the generic version.
+
 - reg: A list of physical regions to access the device: the first is
        the operational registers for the OHCI/EHCI controllers and the
        second is for the bridge configuration and control registers.
@@ -24,10 +31,15 @@ Required properties:
 - interrupt-map-mask: standard property that helps to define the interrupt
   mapping.
 
+Optional properties:
+- dma-ranges: a single range for the inbound memory region. If not supplied,
+  defaults to 1GiB at 0x40000000. Note there are hardware restrictions on the
+  allowed combinations of address and size.
+
 Example SoC configuration:
 
        pci0: pci@ee090000  {
-               compatible = "renesas,pci-r8a7790";
+               compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2";
                clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
                reg = <0x0 0xee090000 0x0 0xc00>,
                      <0x0 0xee080000 0x0 0x1100>;
@@ -38,6 +50,7 @@ Example SoC configuration:
                #address-cells = <3>;
                #size-cells = <2>;
                #interrupt-cells = <1>;
+               dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x40000000>;
                interrupt-map-mask = <0xff00 0 0 0x7>;
                interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
                                 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
new file mode 100644 (file)
index 0000000..4059a6f
--- /dev/null
@@ -0,0 +1,233 @@
+* Qualcomm PCI express root complex
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: Value should contain
+                       - "qcom,pcie-ipq8064" for ipq8064
+                       - "qcom,pcie-apq8064" for apq8064
+                       - "qcom,pcie-apq8084" for apq8084
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: Register ranges as listed in the reg-names property
+
+- reg-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: Must include the following entries
+                       - "parf"   Qualcomm specific registers
+                       - "dbi"    Designware PCIe registers
+                       - "elbi"   External local bus interface registers
+                       - "config" PCIe configuration space
+
+- device_type:
+       Usage: required
+       Value type: <string>
+       Definition: Should be "pci". As specified in designware-pcie.txt
+
+- #address-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: Should be 3. As specified in designware-pcie.txt
+
+- #size-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: Should be 2. As specified in designware-pcie.txt
+
+- ranges:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: As specified in designware-pcie.txt
+
+- interrupts:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: MSI interrupt
+
+- interrupt-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: Should contain "msi"
+
+- #interrupt-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: Should be 1. As specified in designware-pcie.txt
+
+- interrupt-map-mask:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: As specified in designware-pcie.txt
+
+- interrupt-map:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: As specified in designware-pcie.txt
+
+- clocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: List of phandle and clock specifier pairs as listed
+                   in clock-names property
+
+- clock-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: Should contain the following entries
+                       - "iface"       Configuration AHB clock
+
+- clock-names:
+       Usage: required for ipq/apq8064
+       Value type: <stringlist>
+       Definition: Should contain the following entries
+                       - "core"        Clocks the pcie hw block
+                       - "phy"         Clocks the pcie PHY block
+- clock-names:
+       Usage: required for apq8084
+       Value type: <stringlist>
+       Definition: Should contain the following entries
+                       - "aux"         Auxiliary (AUX) clock
+                       - "bus_master"  Master AXI clock
+                       - "bus_slave"   Slave AXI clock
+- resets:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: List of phandle and reset specifier pairs as listed
+                   in reset-names property
+
+- reset-names:
+       Usage: required for ipq/apq8064
+       Value type: <stringlist>
+       Definition: Should contain the following entries
+                       - "axi"  AXI reset
+                       - "ahb"  AHB reset
+                       - "por"  POR reset
+                       - "pci"  PCI reset
+                       - "phy"  PHY reset
+
+- reset-names:
+       Usage: required for apq8084
+       Value type: <stringlist>
+       Definition: Should contain the following entries
+                       - "core" Core reset
+
+- power-domains:
+       Usage: required for apq8084
+       Value type: <prop-encoded-array>
+       Definition: A phandle and power domain specifier pair to the
+                   power domain which is responsible for collapsing
+                   and restoring power to the peripheral
+
+- vdda-supply:
+       Usage: required
+       Value type: <phandle>
+       Definition: A phandle to the core analog power supply
+
+- vdda_phy-supply:
+       Usage: required for ipq/apq8064
+       Value type: <phandle>
+       Definition: A phandle to the analog power supply for PHY
+
+- vdda_refclk-supply:
+       Usage: required for ipq/apq8064
+       Value type: <phandle>
+       Definition: A phandle to the analog power supply for IC which generates
+                   reference clock
+
+- phys:
+       Usage: required for apq8084
+       Value type: <phandle>
+       Definition: List of phandle(s) as listed in phy-names property
+
+- phy-names:
+       Usage: required for apq8084
+       Value type: <stringlist>
+       Definition: Should contain "pciephy"
+
+- <name>-gpios:
+       Usage: optional
+       Value type: <prop-encoded-array>
+       Definition: List of phandle and gpio specifier pairs. Should contain
+                       - "perst-gpios" PCIe endpoint reset signal line
+                       - "wake-gpios"  PCIe endpoint wake signal line
+
+* Example for ipq/apq8064
+       pcie@1b500000 {
+               compatible = "qcom,pcie-apq8064", "qcom,pcie-ipq8064", "snps,dw-pcie";
+               reg = <0x1b500000 0x1000
+                      0x1b502000 0x80
+                      0x1b600000 0x100
+                      0x0ff00000 0x100000>;
+               reg-names = "dbi", "elbi", "parf", "config";
+               device_type = "pci";
+               linux,pci-domain = <0>;
+               bus-range = <0x00 0xff>;
+               num-lanes = <1>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000   /* I/O */
+                         0x82000000 0 0 0x08000000 0 0x07e00000>; /* memory */
+               interrupts = <GIC_SPI 238 IRQ_TYPE_NONE>;
+               interrupt-names = "msi";
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0x7>;
+               interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                               <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                               <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                               <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+               clocks = <&gcc PCIE_A_CLK>,
+                        <&gcc PCIE_H_CLK>,
+                        <&gcc PCIE_PHY_CLK>;
+               clock-names = "core", "iface", "phy";
+               resets = <&gcc PCIE_ACLK_RESET>,
+                        <&gcc PCIE_HCLK_RESET>,
+                        <&gcc PCIE_POR_RESET>,
+                        <&gcc PCIE_PCI_RESET>,
+                        <&gcc PCIE_PHY_RESET>;
+               reset-names = "axi", "ahb", "por", "pci", "phy";
+               pinctrl-0 = <&pcie_pins_default>;
+               pinctrl-names = "default";
+       };
+
+* Example for apq8084
+       pcie0@fc520000 {
+               compatible = "qcom,pcie-apq8084", "snps,dw-pcie";
+               reg = <0xfc520000 0x2000>,
+                     <0xff000000 0x1000>,
+                     <0xff001000 0x1000>,
+                     <0xff002000 0x2000>;
+               reg-names = "parf", "dbi", "elbi", "config";
+               device_type = "pci";
+               linux,pci-domain = <0>;
+               bus-range = <0x00 0xff>;
+               num-lanes = <1>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               ranges = <0x81000000 0 0          0xff200000 0 0x00100000   /* I/O */
+                         0x82000000 0 0x00300000 0xff300000 0 0x00d00000>; /* memory */
+               interrupts = <GIC_SPI 243 IRQ_TYPE_NONE>;
+               interrupt-names = "msi";
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0x7>;
+               interrupt-map = <0 0 0 1 &intc 0 244 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                               <0 0 0 2 &intc 0 245 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                               <0 0 0 3 &intc 0 247 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                               <0 0 0 4 &intc 0 248 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+               clocks = <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+                        <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+                        <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+                        <&gcc GCC_PCIE_0_AUX_CLK>;
+               clock-names = "iface", "master_bus", "slave_bus", "aux";
+               resets = <&gcc GCC_PCIE_0_BCR>;
+               reset-names = "core";
+               power-domains = <&gcc PCIE0_GDSC>;
+               vdda-supply = <&pma8084_l3>;
+               phys = <&pciephy0>;
+               phy-names = "pciephy";
+               perst-gpio = <&tlmm 70 GPIO_ACTIVE_LOW>;
+               pinctrl-0 = <&pcie0_pins_default>;
+               pinctrl-names = "default";
+       };
index 29d3b98..558fe52 100644 (file)
@@ -1,8 +1,16 @@
 * Renesas RCar PCIe interface
 
 Required properties:
-- compatible: should contain one of the following
-       "renesas,pcie-r8a7779", "renesas,pcie-r8a7790", "renesas,pcie-r8a7791"
+compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC;
+           "renesas,pcie-r8a7790" for the R8A7790 SoC;
+           "renesas,pcie-r8a7791" for the R8A7791 SoC;
+           "renesas,pcie-r8a7795" for the R8A7795 SoC;
+           "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device.
+
+           When compatible with the generic version, nodes must list the
+           SoC-specific version corresponding to the platform first
+           followed by the generic version.
+
 - reg: base address and length of the pcie controller registers.
 - #address-cells: set to <3>
 - #size-cells: set to <2>
@@ -25,7 +33,7 @@ Example:
 SoC specific DT Entry:
 
        pcie: pcie@fe000000 {
-               compatible = "renesas,pcie-r8a7791";
+               compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2";
                reg = <0 0xfe000000 0 0x80000>;
                #address-cells = <3>;
                #size-cells = <2>;
diff --git a/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt b/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt
new file mode 100644 (file)
index 0000000..cafe219
--- /dev/null
@@ -0,0 +1,18 @@
+* Atheros AR71XX/9XXX USB PHY
+
+Required properties:
+- compatible: "qca,ar7100-usb-phy"
+- #phys-cells: should be 0
+- reset-names: "usb-phy"[, "usb-suspend-override"]
+- resets: references to the reset controllers
+
+Example:
+
+       usb-phy {
+               compatible = "qca,ar7100-usb-phy";
+
+               reset-names = "usb-phy", "usb-suspend-override";
+               resets = <&rst 4>, <&rst 3>;
+
+               #phy-cells = <0>;
+       };
index cfe1db3..74b5bc5 100644 (file)
@@ -6,7 +6,12 @@ Required properties:
 
 Examples:
 
-pwm@0x4005C000 {
+pwm@4005c000 {
        compatible = "nxp,lpc3220-pwm";
-       reg = <0x4005C000 0x8>;
+       reg = <0x4005c000 0x4>;
+};
+
+pwm@4005c004 {
+       compatible = "nxp,lpc3220-pwm";
+       reg = <0x4005c004 0x4>;
 };
diff --git a/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt b/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt
new file mode 100644 (file)
index 0000000..5befb53
--- /dev/null
@@ -0,0 +1,18 @@
+* OMAP PWM for dual-mode timers
+
+Required properties:
+- compatible: Shall contain "ti,omap-dmtimer-pwm".
+- ti,timers: phandle to PWM capable OMAP timer. See arm/omap/timer.txt for info
+  about these timers.
+- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+
+Optional properties:
+- ti,prescaler: Should be a value between 0 and 7, see the timers datasheet
+
+Example:
+       pwm9: dmtimer-pwm@9 {
+               compatible = "ti,omap-dmtimer-pwm";
+               ti,timers = <&timer9>;
+               #pwm-cells = <3>;
+       };
index 4f05d20..d181096 100644 (file)
@@ -26,7 +26,11 @@ Example:
                ti,pmic-shutdown-controller;
 
                regulators {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
                        dcdc1_reg: dcdc1 {
+                               reg = <0>;
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <1800000>;
                                regulator-boot-on;
@@ -34,6 +38,7 @@ Example:
                        };
 
                        dcdc2_reg: dcdc2 {
+                               reg = <1>;
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
@@ -41,6 +46,7 @@ Example:
                        };
 
                        dcdc3_reg: dcc3 {
+                               reg = <2>;
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <1500000>;
                                regulator-boot-on;
@@ -48,6 +54,7 @@ Example:
                        };
 
                        ldo1_reg: ldo1 {
+                               reg = <3>;
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
@@ -55,6 +62,7 @@ Example:
                        };
 
                        ldo2_reg: ldo2 {
+                               reg = <4>;
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
@@ -62,6 +70,7 @@ Example:
                        };
 
                        ldo3_reg: ldo3 {
+                               reg = <5>;
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
@@ -69,6 +78,7 @@ Example:
                        };
 
                        ldo4_reg: ldo4 {
+                               reg = <6>;
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt
new file mode 100644 (file)
index 0000000..e0b185a
--- /dev/null
@@ -0,0 +1,34 @@
+Hisilicon System Reset Controller
+======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+The reset controller registers are part of the system-ctl block on
+hi6220 SoC.
+
+Required properties:
+- compatible: may be "hisilicon,hi6220-sysctrl"
+- reg: should be register base and length as documented in the
+  datasheet
+- #reset-cells: 1, see below
+
+Example:
+sys_ctrl: sys_ctrl@f7030000 {
+       compatible = "hisilicon,hi6220-sysctrl", "syscon";
+       reg = <0x0 0xf7030000 0x0 0x2000>;
+       #clock-cells = <1>;
+       #reset-cells = <1>;
+};
+
+Specifying reset lines connected to IP modules
+==============================================
+example:
+
+        uart1: serial@..... {
+                ...
+                resets = <&sys_ctrl PERIPH_RSTEN3_UART1>;
+                ...
+        };
+
+The index could be found in <dt-bindings/reset/hisi,hi6220-resets.h>.
index 2d47add..a833a01 100644 (file)
@@ -2,15 +2,15 @@
 
 Required properties:
 - compatible should contain:
-  * "mediatek,mt8135-uart" for MT8135 compatible UARTS
+  * "mediatek,mt2701-uart" for MT2701 compatible UARTS
+  * "mediatek,mt6580-uart" for MT6580 compatible UARTS
+  * "mediatek,mt6582-uart" for MT6582 compatible UARTS
+  * "mediatek,mt6589-uart" for MT6589 compatible UARTS
+  * "mediatek,mt6795-uart" for MT6795 compatible UARTS
   * "mediatek,mt8127-uart" for MT8127 compatible UARTS
+  * "mediatek,mt8135-uart" for MT8135 compatible UARTS
   * "mediatek,mt8173-uart" for MT8173 compatible UARTS
-  * "mediatek,mt6795-uart" for MT6795 compatible UARTS
-  * "mediatek,mt6589-uart" for MT6589 compatible UARTS
-  * "mediatek,mt6582-uart" for MT6582 compatible UARTS
-  * "mediatek,mt6580-uart" for MT6580 compatible UARTS
-  * "mediatek,mt6577-uart" for all compatible UARTS (MT8173, MT6795,
-        MT6589, MT6582, MT6580, MT6577)
+  * "mediatek,mt6577-uart" for MT6577 and all of the above
 
 - reg: The base address of the UART register bank.
 
diff --git a/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt b/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt
new file mode 100644 (file)
index 0000000..30942cf
--- /dev/null
@@ -0,0 +1,47 @@
+Raspberry Pi power domain driver
+
+Required properties:
+
+- compatible:          Should be "raspberrypi,bcm2835-power".
+- firmware:            Reference to the RPi firmware device node.
+- #power-domain-cells: Should be <1>, we providing multiple power domains.
+
+The valid defines for power domain are:
+
+ RPI_POWER_DOMAIN_I2C0
+ RPI_POWER_DOMAIN_I2C1
+ RPI_POWER_DOMAIN_I2C2
+ RPI_POWER_DOMAIN_VIDEO_SCALER
+ RPI_POWER_DOMAIN_VPU1
+ RPI_POWER_DOMAIN_HDMI
+ RPI_POWER_DOMAIN_USB
+ RPI_POWER_DOMAIN_VEC
+ RPI_POWER_DOMAIN_JPEG
+ RPI_POWER_DOMAIN_H264
+ RPI_POWER_DOMAIN_V3D
+ RPI_POWER_DOMAIN_ISP
+ RPI_POWER_DOMAIN_UNICAM0
+ RPI_POWER_DOMAIN_UNICAM1
+ RPI_POWER_DOMAIN_CCP2RX
+ RPI_POWER_DOMAIN_CSI2
+ RPI_POWER_DOMAIN_CPI
+ RPI_POWER_DOMAIN_DSI0
+ RPI_POWER_DOMAIN_DSI1
+ RPI_POWER_DOMAIN_TRANSPOSER
+ RPI_POWER_DOMAIN_CCP2TX
+ RPI_POWER_DOMAIN_CDP
+ RPI_POWER_DOMAIN_ARM
+
+Example:
+
+power: power {
+       compatible = "raspberrypi,bcm2835-power";
+       firmware = <&firmware>;
+       #power-domain-cells = <1>;
+};
+
+Example for using power domain:
+
+&usb {
+       power-domains = <&power RPI_POWER_DOMAIN_USB>;
+};
diff --git a/Documentation/devicetree/bindings/soc/dove/pmu.txt b/Documentation/devicetree/bindings/soc/dove/pmu.txt
new file mode 100644 (file)
index 0000000..edd40b7
--- /dev/null
@@ -0,0 +1,56 @@
+Device Tree bindings for Marvell PMU
+
+Required properties:
+ - compatible: value should be "marvell,dove-pmu".
+    May also include "simple-bus" if there are child devices, in which
+    case the ranges node is required.
+ - reg: two base addresses and sizes of the PM controller and PMU.
+ - interrupts: single interrupt number for the PMU interrupt
+ - interrupt-controller: must be specified as the PMU itself is an
+    interrupt controller.
+ - #interrupt-cells: must be 1.
+ - #reset-cells: must be 1.
+ - domains: sub-node containing domain descriptions
+
+Optional properties:
+ - ranges: defines the address mapping for child devices, as per the
+   standard property of this name.  Required when compatible includes
+   "simple-bus".
+
+Power domain descriptions are listed as child nodes of the "domains"
+sub-node.  Each domain has the following properties:
+
+Required properties:
+ - #power-domain-cells: must be 0.
+
+Optional properties:
+ - marvell,pmu_pwr_mask: specifies the mask value for PMU power register
+ - marvell,pmu_iso_mask: specifies the mask value for PMU isolation register
+ - resets: points to the reset manager (PMU node) and reset index.
+
+Example:
+
+       pmu: power-management@d0000 {
+               compatible = "marvell,dove-pmu";
+               reg = <0xd0000 0x8000>, <0xd8000 0x8000>;
+               interrupts = <33>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               #reset-cells = <1>;
+
+               domains {
+                       vpu_domain: vpu-domain {
+                               #power-domain-cells = <0>;
+                               marvell,pmu_pwr_mask = <0x00000008>;
+                               marvell,pmu_iso_mask = <0x00000001>;
+                               resets = <&pmu 16>;
+                       };
+
+                       gpu_domain: gpu-domain {
+                               #power-domain-cells = <0>;
+                               marvell,pmu_pwr_mask = <0x00000004>;
+                               marvell,pmu_iso_mask = <0x00000002>;
+                               resets = <&pmu 18>;
+                       };
+               };
+       };
index a6c8afc..e8f15e3 100644 (file)
@@ -21,6 +21,18 @@ Required properties:
                      These are the clocks which hardware needs to be enabled
                      before enabling certain power domains.
 
+Optional properties:
+- vdec-supply: Power supply for the vdec power domain
+- venc-supply: Power supply for the venc power domain
+- isp-supply: Power supply for the isp power domain
+- mm-supply: Power supply for the mm power domain
+- venc_lt-supply: Power supply for the venc_lt power domain
+- audio-supply: Power supply for the audio power domain
+- usb-supply: Power supply for the usb power domain
+- mfg_async-supply: Power supply for the mfg_async power domain
+- mfg_2d-supply: Power supply for the mfg_2d power domain
+- mfg-supply: Power supply for the mfg power domain
+
 Example:
 
        scpsys: scpsys@10006000 {
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt
new file mode 100644 (file)
index 0000000..5cc82b8
--- /dev/null
@@ -0,0 +1,104 @@
+Qualcomm Shared Memory Point 2 Point binding
+
+The Shared Memory Point to Point (SMP2P) protocol facilitates communication of
+a single 32-bit value between two processors.  Each value has a single writer
+(the local side) and a single reader (the remote side).  Values are uniquely
+identified in the system by the directed edge (local processor ID to remote
+processor ID) and a string identifier.
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be one of:
+                   "qcom,smp2p"
+
+- interrupts:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: one entry specifying the smp2p notification interrupt
+
+- qcom,ipc:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: three entries specifying the outgoing ipc bit used for
+                   signaling the remote end of the smp2p edge:
+                   - phandle to a syscon node representing the apcs registers
+                   - u32 representing offset to the register within the syscon
+                   - u32 representing the ipc bit within the register
+
+- qcom,smem:
+       Usage: required
+       Value type: <u32 array>
+       Definition: two identifiers of the inbound and outbound smem items used
+                   for this edge
+
+- qcom,local-pid:
+       Usage: required
+       Value type: <u32>
+       Definition: specifies the identfier of the local endpoint of this edge
+
+- qcom,remote-pid:
+       Usage: required
+       Value type: <u32>
+       Definition: specifies the identfier of the remote endpoint of this edge
+
+= SUBNODES
+Each SMP2P pair contain a set of inbound and outbound entries, these are
+described in subnodes of the smp2p device node. The node names are not
+important.
+
+- qcom,entry-name:
+       Usage: required
+       Value type: <string>
+       Definition: specifies the name of this entry, for inbound entries this
+                   will be used to match against the remotely allocated entry
+                   and for outbound entries this name is used for allocating
+                   entries
+
+- interrupt-controller:
+       Usage: required for incoming entries
+       Value type: <empty>
+       Definition: marks the entry as inbound; the node should be specified
+                   as a two cell interrupt-controller as defined in
+                   "../interrupt-controller/interrupts.txt"
+                   If not specified this node will denote the outgoing entry
+
+- #interrupt-cells:
+       Usage: required for incoming entries
+       Value type: <u32>
+       Definition: must be 2 - denoting the bit in the entry and IRQ flags
+
+- #qcom,state-cells:
+       Usage: required for outgoing entries
+       Value type: <u32>
+       Definition: must be 1 - denoting the bit in the entry
+
+= EXAMPLE
+The following example shows the SMP2P setup with the wireless processor,
+defined from the 8974 apps processor's point-of-view. It encompasses one
+inbound and one outbound entry:
+
+wcnss-smp2p {
+       compatible = "qcom,smp2p";
+       qcom,smem = <431>, <451>;
+
+       interrupts = <0 143 1>;
+
+       qcom,ipc = <&apcs 8 18>;
+
+       qcom,local-pid = <0>;
+       qcom,remote-pid = <4>;
+
+       wcnss_smp2p_out: master-kernel {
+               qcom,entry-name = "master-kernel";
+
+               #qcom,state-cells = <1>;
+       };
+
+       wcnss_smp2p_in: slave-kernel {
+               qcom,entry-name = "slave-kernel";
+
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt
new file mode 100644 (file)
index 0000000..a6634c7
--- /dev/null
@@ -0,0 +1,104 @@
+Qualcomm Shared Memory State Machine
+
+The Shared Memory State Machine facilitates broadcasting of single bit state
+information between the processors in a Qualcomm SoC. Each processor is
+assigned 32 bits of state that can be modified. A processor can through a
+matrix of bitmaps signal subscription of notifications upon changes to a
+certain bit owned by a certain remote processor.
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be one of:
+                   "qcom,smsm"
+
+- qcom,ipc-N:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: three entries specifying the outgoing ipc bit used for
+                   signaling the N:th remote processor
+                   - phandle to a syscon node representing the apcs registers
+                   - u32 representing offset to the register within the syscon
+                   - u32 representing the ipc bit within the register
+
+- qcom,local-host:
+       Usage: optional
+       Value type: <u32>
+       Definition: identifier of the local processor in the list of hosts, or
+                   in other words specifier of the column in the subscription
+                   matrix representing the local processor
+                   defaults to host 0
+
+- #address-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 1
+
+- #size-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 0
+
+= SUBNODES
+Each processor's state bits are described by a subnode of the smsm device node.
+Nodes can either be flagged as an interrupt-controller to denote a remote
+processor's state bits or the local processors bits.  The node names are not
+important.
+
+- reg:
+       Usage: required
+       Value type: <u32>
+       Definition: specifies the offset, in words, of the first bit for this
+                   entry
+
+- #qcom,state-cells:
+       Usage: required for local entry
+       Value type: <u32>
+       Definition: must be 1 - denotes bit number
+
+- interrupt-controller:
+       Usage: required for remote entries
+       Value type: <empty>
+       Definition: marks the entry as a interrupt-controller and the state bits
+                   to belong to a remote processor
+
+- #interrupt-cells:
+       Usage: required for remote entries
+       Value type: <u32>
+       Definition: must be 2 - denotes bit number and IRQ flags
+
+- interrupts:
+       Usage: required for remote entries
+       Value type: <prop-encoded-array>
+       Definition: one entry specifying remote IRQ used by the remote processor
+                   to signal changes of its state bits
+
+
+= EXAMPLE
+The following example shows the SMEM setup for controlling properties of the
+wireless processor, defined from the 8974 apps processor's point-of-view. It
+encompasses one outbound entry and the outgoing interrupt for the wireless
+processor.
+
+smsm {
+       compatible = "qcom,smsm";
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       qcom,ipc-3 = <&apcs 8 19>;
+
+       apps_smsm: apps@0 {
+               reg = <0>;
+
+               #qcom,state-cells = <1>;
+       };
+
+       wcnss_smsm: wcnss@7 {
+               reg = <7>;
+               interrupts = <0 144 1>;
+
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/soc/ti/wkup_m3_ipc.txt b/Documentation/devicetree/bindings/soc/ti/wkup_m3_ipc.txt
new file mode 100644 (file)
index 0000000..4015504
--- /dev/null
@@ -0,0 +1,57 @@
+Wakeup M3 IPC Driver
+=====================
+
+The TI AM33xx and AM43xx family of devices use a small Cortex M3 co-processor
+(commonly referred to as Wakeup M3 or CM3) to help with various low power tasks
+that cannot be controlled from the MPU, like suspend/resume and certain deep
+C-states for CPU Idle. Once the wkup_m3_ipc driver uses the wkup_m3_rproc driver
+to boot the wkup_m3, it handles communication with the CM3 using IPC registers
+present in the SoC's control module and a mailbox. The wkup_m3_ipc exposes an
+API to allow the SoC PM code to execute specific PM tasks.
+
+Wkup M3 Device Node:
+====================
+A wkup_m3_ipc device node is used to represent the IPC registers within an
+SoC.
+
+Required properties:
+--------------------
+- compatible:          Should be,
+                               "ti,am3352-wkup-m3-ipc" for AM33xx SoCs
+                               "ti,am4372-wkup-m3-ipc" for AM43xx SoCs
+- reg:                 Contains the IPC register address space to communicate
+                       with the Wakeup M3 processor
+- interrupts:          Contains the interrupt information for the wkup_m3
+                       interrupt that signals the MPU.
+- ti,rproc:            phandle to the wkup_m3 rproc node so the IPC driver
+                       can boot it.
+- mboxes:              phandles used by IPC framework to get correct mbox
+                       channel for communication. Must point to appropriate
+                       mbox_wkupm3 child node.
+
+Example:
+--------
+/* AM33xx */
+       l4_wkup: l4_wkup@44c00000 {
+               ...
+
+               scm: scm@210000 {
+                       compatible = "ti,am3-scm", "simple-bus";
+                       reg = <0x210000 0x2000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x210000 0x2000>;
+
+                       ...
+
+                       wkup_m3_ipc: wkup_m3_ipc@1324 {
+                               compatible = "ti,am3352-wkup-m3-ipc";
+                               reg = <0x1324 0x24>;
+                               interrupts = <78>;
+                               ti,rproc = <&wkup_m3>;
+                               mboxes = <&mailbox &mbox_wkupm3>;
+                       };
+
+                       ...
+               };
+       };
index 601a360..cc8304a 100644 (file)
@@ -15,14 +15,32 @@ Recommended properties:
 - spi-max-frequency: Definition as per
                      Documentation/devicetree/bindings/spi/spi-bus.txt
 
+Optional properties:
+- syscon-chipselects: Handle to system control region contains QSPI
+                     chipselect register and offset of that register.
+
 Example:
 
+For am4372:
 qspi: qspi@4b300000 {
-       compatible = "ti,dra7xxx-qspi";
-       reg = <0x47900000 0x100>, <0x30000000 0x3ffffff>;
+       compatible = "ti,am4372-qspi";
+       reg = <0x47900000 0x100>, <0x30000000 0x4000000>;
        reg-names = "qspi_base", "qspi_mmap";
        #address-cells = <1>;
        #size-cells = <0>;
        spi-max-frequency = <25000000>;
        ti,hwmods = "qspi";
 };
+
+For dra7xx:
+qspi: qspi@4b300000 {
+       compatible = "ti,dra7xxx-qspi";
+       reg = <0x4b300000 0x100>,
+             <0x5c000000 0x4000000>,
+       reg-names = "qspi_base", "qspi_mmap";
+       syscon-chipselects = <&scm_conf 0x558>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       spi-max-frequency = <48000000>;
+       ti,hwmods = "qspi";
+};
index 0dfa60d..08efe6b 100644 (file)
@@ -2,8 +2,10 @@
 
 Required properties:
 - compatible : should be "rockchip,<name>-tsadc"
+   "rockchip,rk3228-tsadc": found on RK3228 SoCs
    "rockchip,rk3288-tsadc": found on RK3288 SoCs
    "rockchip,rk3368-tsadc": found on RK3368 SoCs
+   "rockchip,rk3399-tsadc": found on RK3399 SoCs
 - reg : physical base address of the controller and length of memory mapped
        region.
 - interrupts : The interrupt number to the cpu. The interrupt specifier format
index 64083bc..8ff54eb 100644 (file)
@@ -3,6 +3,7 @@ Mediatek MT6577, MT6572 and MT6589 Timers
 
 Required properties:
 - compatible should contain:
+       * "mediatek,mt2701-timer" for MT2701 compatible timers
        * "mediatek,mt6580-timer" for MT6580 compatible timers
        * "mediatek,mt6589-timer" for MT6589 compatible timers
        * "mediatek,mt8127-timer" for MT8127 compatible timers
index 084439d..72e2c5a 100644 (file)
@@ -124,6 +124,7 @@ jedec       JEDEC Solid State Technology Association
 karo   Ka-Ro electronics GmbH
 keymile        Keymile GmbH
 kinetic Kinetic Technologies
+kosagi Sutajio Ko-Usagi PTE Ltd.
 kyo    Kyocera Corporation
 lacie  LaCie
 lantiq Lantiq Semiconductor
@@ -222,11 +223,13 @@ sony      Sony Corporation
 spansion       Spansion Inc.
 sprd   Spreadtrum Communications Inc.
 st     STMicroelectronics
+startek        Startek
 ste    ST-Ericsson
 stericsson     ST-Ericsson
 synology       Synology, Inc.
 tbs    TBS Technologies
 tcl    Toby Churchill Ltd.
+technologic    Technologic Systems
 thine  THine Electronics, Inc.
 ti     Texas Instruments
 tlm    Trusted Logic Mobility
diff --git a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt
new file mode 100644 (file)
index 0000000..ae70185
--- /dev/null
@@ -0,0 +1,13 @@
+Meson SoCs Watchdog timer
+
+Required properties:
+
+- compatible : should be "amlogic,meson6-wdt" or "amlogic,meson8b-wdt"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+wdt: watchdog@c1109900 {
+       compatible = "amlogic,meson6-wdt";
+       reg = <0xc1109900 0x8>;
+};
diff --git a/Documentation/devicetree/bindings/watchdog/meson6-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson6-wdt.txt
deleted file mode 100644 (file)
index 9200fc2..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-Meson SoCs Watchdog timer
-
-Required properties:
-
-- compatible : should be "amlogic,meson6-wdt"
-- reg : Specifies base physical address and size of the registers.
-
-Example:
-
-wdt: watchdog@c1109900 {
-       compatible = "amlogic,meson6-wdt";
-       reg = <0xc1109900 0x8>;
-};
index af9eb5b..6a00939 100644 (file)
@@ -2,7 +2,11 @@ Mediatek SoCs Watchdog timer
 
 Required properties:
 
-- compatible : should be "mediatek,mt6589-wdt"
+- compatible should contain:
+       * "mediatek,mt2701-wdt" for MT2701 compatible watchdog timers
+       * "mediatek,mt6589-wdt" for all compatible watchdog timers (MT2701,
+               MT6589)
+
 - reg : Specifies base physical address and size of the registers.
 
 Example:
diff --git a/Documentation/devicetree/bindings/watchdog/sp805-wdt.txt b/Documentation/devicetree/bindings/watchdog/sp805-wdt.txt
new file mode 100644 (file)
index 0000000..edc4f0e
--- /dev/null
@@ -0,0 +1,31 @@
+* ARM SP805 Watchdog Timer (WDT) Controller
+
+SP805 WDT is a ARM Primecell Peripheral and has a standard-id register that
+can be used to identify the peripheral type, vendor, and revision.
+This value can be used for driver matching.
+
+As SP805 WDT is a primecell IP, it follows the base bindings specified in
+'arm/primecell.txt'
+
+Required properties:
+- compatible : Should be "arm,sp805-wdt", "arm,primecell"
+- reg : Base address and size of the watchdog timer registers.
+- clocks : From common clock binding.
+           First clock is PCLK and the second is WDOGCLK.
+           WDOGCLK can be equal to or be a sub-multiple of the PCLK frequency.
+- clock-names : From common clock binding.
+                Shall be "apb_pclk" for first clock and "wdog_clk" for the
+                second one.
+
+Optional properties:
+- interrupts : Should specify WDT interrupt number.
+
+Examples:
+
+               cluster1_core0_watchdog: wdt@c000000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc000000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
diff --git a/Documentation/features/io/dma_map_attrs/arch-support.txt b/Documentation/features/io/dma_map_attrs/arch-support.txt
deleted file mode 100644 (file)
index 51d0f1c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Feature name:          dma_map_attrs
-#         Kconfig:       HAVE_DMA_ATTRS
-#         description:   arch provides dma_*map*_attrs() APIs
-#
-    -----------------------
-    |         arch |status|
-    -----------------------
-    |       alpha: |  ok  |
-    |         arc: | TODO |
-    |         arm: |  ok  |
-    |       arm64: |  ok  |
-    |       avr32: | TODO |
-    |    blackfin: | TODO |
-    |         c6x: | TODO |
-    |        cris: | TODO |
-    |         frv: | TODO |
-    |       h8300: |  ok  |
-    |     hexagon: |  ok  |
-    |        ia64: |  ok  |
-    |        m32r: | TODO |
-    |        m68k: | TODO |
-    |       metag: | TODO |
-    |  microblaze: |  ok  |
-    |        mips: |  ok  |
-    |     mn10300: | TODO |
-    |       nios2: | TODO |
-    |    openrisc: |  ok  |
-    |      parisc: | TODO |
-    |     powerpc: |  ok  |
-    |        s390: |  ok  |
-    |       score: | TODO |
-    |          sh: |  ok  |
-    |       sparc: |  ok  |
-    |        tile: |  ok  |
-    |          um: | TODO |
-    |   unicore32: |  ok  |
-    |         x86: |  ok  |
-    |      xtensa: | TODO |
-    -----------------------
index ce1126a..223c321 100644 (file)
@@ -180,6 +180,16 @@ dos1xfloppy  -- If set, use a fallback default BIOS Parameter Block
 
 <bool>: 0,1,yes,no,true,false
 
+LIMITATION
+---------------------------------------------------------------------
+* The fallocated region of file is discarded at umount/evict time
+  when using fallocate with FALLOC_FL_KEEP_SIZE.
+  So, User should assume that fallocated region can be discarded at
+  last close if there is memory pressure resulting in eviction of
+  the inode from the memory. As a result, for any dependency on
+  the fallocated region, user should make sure to recheck fallocate
+  after reopening the file.
+
 TODO
 ----------------------------------------------------------------------
 * Need to get rid of the raw scanning stuff.  Instead, always use
index e167854..4b1f36b 100644 (file)
@@ -15,7 +15,6 @@ Sleeping and interrupt context
     modify_ah
     query_ah
     destroy_ah
-    bind_mw
     post_send
     post_recv
     poll_cq
@@ -31,7 +30,6 @@ Sleeping and interrupt context
     ib_modify_ah
     ib_query_ah
     ib_destroy_ah
-    ib_bind_mw
     ib_post_send
     ib_post_recv
     ib_req_notify_cq
index 3ea869d..87d40a7 100644 (file)
@@ -611,6 +611,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        cgroup.memory=  [KNL] Pass options to the cgroup memory controller.
                        Format: <string>
                        nosocket -- Disable socket memory accounting.
+                       nokmem -- Disable kernel memory accounting.
 
        checkreqprot    [SELINUX] Set initial checkreqprot flag value.
                        Format: { "0" | "1" }
@@ -1453,6 +1454,41 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        In such case C2/C3 won't be used again.
                        idle=nomwait: Disable mwait for CPU C-states
 
+       ieee754=        [MIPS] Select IEEE Std 754 conformance mode
+                       Format: { strict | legacy | 2008 | relaxed }
+                       Default: strict
+
+                       Choose which programs will be accepted for execution
+                       based on the IEEE 754 NaN encoding(s) supported by
+                       the FPU and the NaN encoding requested with the value
+                       of an ELF file header flag individually set by each
+                       binary.  Hardware implementations are permitted to
+                       support either or both of the legacy and the 2008 NaN
+                       encoding mode.
+
+                       Available settings are as follows:
+                       strict  accept binaries that request a NaN encoding
+                               supported by the FPU
+                       legacy  only accept legacy-NaN binaries, if supported
+                               by the FPU
+                       2008    only accept 2008-NaN binaries, if supported
+                               by the FPU
+                       relaxed accept any binaries regardless of whether
+                               supported by the FPU
+
+                       The FPU emulator is always able to support both NaN
+                       encodings, so if no FPU hardware is present or it has
+                       been disabled with 'nofpu', then the settings of
+                       'legacy' and '2008' strap the emulator accordingly,
+                       'relaxed' straps the emulator for both legacy-NaN and
+                       2008-NaN, whereas 'strict' enables legacy-NaN only on
+                       legacy processors and both NaN encodings on MIPS32 or
+                       MIPS64 CPUs.
+
+                       The setting for ABS.fmt/NEG.fmt instruction execution
+                       mode generally follows that for the NaN encoding,
+                       except where unsupported by hardware.
+
        ignore_loglevel [KNL]
                        Ignore loglevel setting - this will print /all/
                        kernel messages to the console. Useful for debugging.
index f4cbfe0..edec3a3 100644 (file)
@@ -90,7 +90,7 @@ BLOCK_SOFTIRQ:  Do all of the following:
        from being initiated from tasks that might run on the CPU to
        be de-jittered.  (It is OK to force this CPU offline and then
        bring it back online before you start your application.)
-BLOCK_IOPOLL_SOFTIRQ:  Do all of the following:
+IRQ_POLL_SOFTIRQ:  Do all of the following:
 1.     Force block-device interrupts onto some other CPU.
 2.     Initiate any block I/O and block-I/O polling on other CPUs.
 3.     Once your application has started, prevent CPU-hotplug operations
index 88152f2..302b5ed 100644 (file)
@@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
 - nr_open
 - overflowuid
 - overflowgid
+- pipe-user-pages-hard
+- pipe-user-pages-soft
 - protected_hardlinks
 - protected_symlinks
 - suid_dumpable
@@ -159,6 +161,27 @@ The default is 65534.
 
 ==============================================================
 
+pipe-user-pages-hard:
+
+Maximum total number of pages a non-privileged user may allocate for pipes.
+Once this limit is reached, no new pipes may be allocated until usage goes
+below the limit again. When set to 0, no limit is applied, which is the default
+setting.
+
+==============================================================
+
+pipe-user-pages-soft:
+
+Maximum total number of pages a non-privileged user may allocate for pipes
+before the pipe size gets limited to a single page. Once this limit is reached,
+new pipes will be limited to a single page in size for this user in order to
+limit total memory usage, and trying to increase them using fcntl() will be
+denied until usage goes below the limit again. The default value allows to
+allocate up to 1024 pipes at their default size. When set to 0, no limit is
+applied.
+
+==============================================================
+
 protected_hardlinks:
 
 A long-standing class of security issues is the hardlink-based
index 73c6b1e..a93b414 100644 (file)
@@ -825,14 +825,13 @@ via the /proc/sys interface:
        Each write syscall must fully contain the sysctl value to be
        written, and multiple writes on the same sysctl file descriptor
        will rewrite the sysctl value, regardless of file position.
-   0 - (default) Same behavior as above, but warn about processes that
-       perform writes to a sysctl file descriptor when the file position
-       is not 0.
-   1 - Respect file position when writing sysctl strings. Multiple writes
-       will append to the sysctl value buffer. Anything past the max length
-       of the sysctl value buffer will be ignored. Writes to numeric sysctl
-       entries must always be at file position 0 and the value must be
-       fully contained in the buffer sent in the write syscall.
+   0 - Same behavior as above, but warn about processes that perform writes
+       to a sysctl file descriptor when the file position is not 0.
+   1 - (default) Respect file position when writing sysctl strings. Multiple
+       writes will append to the sysctl value buffer. Anything past the max
+       length of the sysctl value buffer will be ignored. Writes to numeric
+       sysctl entries must always be at file position 0 and the value must
+       be fully contained in the buffer sent in the write syscall.
 
 ==============================================================
 
diff --git a/Documentation/ubsan.txt b/Documentation/ubsan.txt
new file mode 100644 (file)
index 0000000..f58215e
--- /dev/null
@@ -0,0 +1,84 @@
+Undefined Behavior Sanitizer - UBSAN
+
+Overview
+--------
+
+UBSAN is a runtime undefined behaviour checker.
+
+UBSAN uses compile-time instrumentation to catch undefined behavior (UB).
+Compiler inserts code that perform certain kinds of checks before operations
+that may cause UB. If check fails (i.e. UB detected) __ubsan_handle_*
+function called to print error message.
+
+GCC has that feature since 4.9.x [1] (see -fsanitize=undefined option and
+its suboptions). GCC 5.x has more checkers implemented [2].
+
+Report example
+---------------
+
+        ================================================================================
+        UBSAN: Undefined behaviour in ../include/linux/bitops.h:110:33
+        shift exponent 32 is to large for 32-bit type 'unsigned int'
+        CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.0-rc1+ #26
+         0000000000000000 ffffffff82403cc8 ffffffff815e6cd6 0000000000000001
+         ffffffff82403cf8 ffffffff82403ce0 ffffffff8163a5ed 0000000000000020
+         ffffffff82403d78 ffffffff8163ac2b ffffffff815f0001 0000000000000002
+        Call Trace:
+         [<ffffffff815e6cd6>] dump_stack+0x45/0x5f
+         [<ffffffff8163a5ed>] ubsan_epilogue+0xd/0x40
+         [<ffffffff8163ac2b>] __ubsan_handle_shift_out_of_bounds+0xeb/0x130
+         [<ffffffff815f0001>] ? radix_tree_gang_lookup_slot+0x51/0x150
+         [<ffffffff8173c586>] _mix_pool_bytes+0x1e6/0x480
+         [<ffffffff83105653>] ? dmi_walk_early+0x48/0x5c
+         [<ffffffff8173c881>] add_device_randomness+0x61/0x130
+         [<ffffffff83105b35>] ? dmi_save_one_device+0xaa/0xaa
+         [<ffffffff83105653>] dmi_walk_early+0x48/0x5c
+         [<ffffffff831066ae>] dmi_scan_machine+0x278/0x4b4
+         [<ffffffff8111d58a>] ? vprintk_default+0x1a/0x20
+         [<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
+         [<ffffffff830b2240>] setup_arch+0x405/0xc2c
+         [<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
+         [<ffffffff830ae053>] start_kernel+0x83/0x49a
+         [<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
+         [<ffffffff830ad386>] x86_64_start_reservations+0x2a/0x2c
+         [<ffffffff830ad4f3>] x86_64_start_kernel+0x16b/0x17a
+        ================================================================================
+
+Usage
+-----
+
+To enable UBSAN configure kernel with:
+
+       CONFIG_UBSAN=y
+
+and to check the entire kernel:
+
+        CONFIG_UBSAN_SANITIZE_ALL=y
+
+To enable instrumentation for specific files or directories, add a line
+similar to the following to the respective kernel Makefile:
+
+        For a single file (e.g. main.o):
+                UBSAN_SANITIZE_main.o := y
+
+        For all files in one directory:
+                UBSAN_SANITIZE := y
+
+To exclude files from being instrumented even if
+CONFIG_UBSAN_SANITIZE_ALL=y, use:
+
+                UBSAN_SANITIZE_main.o := n
+        and:
+                UBSAN_SANITIZE := n
+
+Detection of unaligned accesses controlled through the separate option -
+CONFIG_UBSAN_ALIGNMENT. It's off by default on architectures that support
+unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
+still enable it in config, just note that it will produce a lot of UBSAN
+reports.
+
+References
+----------
+
+[1] - https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
+[2] - https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
index 66662b8..30aca4a 100644 (file)
@@ -781,6 +781,7 @@ F:  sound/aoa/
 APM DRIVER
 M:     Jiri Kosina <jikos@kernel.org>
 S:     Odd fixes
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm.git
 F:     arch/x86/kernel/apm_32.c
 F:     include/linux/apm_bios.h
 F:     include/uapi/linux/apm_bios.h
@@ -946,6 +947,7 @@ M:  Alexandre Belloni <alexandre.belloni@free-electrons.com>
 M:     Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.linux4sam.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
 S:     Supported
 F:     arch/arm/mach-at91/
 F:     include/soc/at91/
@@ -1415,12 +1417,13 @@ W:      http://www.arm.linux.org.uk/
 S:     Maintained
 
 ARM/QUALCOMM SUPPORT
-M:     Kumar Gala <galak@codeaurora.org>
-M:     Andy Gross <agross@codeaurora.org>
-M:     David Brown <davidb@codeaurora.org>
+M:     Andy Gross <andy.gross@linaro.org>
+M:     David Brown <david.brown@linaro.org>
 L:     linux-arm-msm@vger.kernel.org
 L:     linux-soc@vger.kernel.org
 S:     Maintained
+F:     arch/arm/boot/dts/qcom-*.dts
+F:     arch/arm/boot/dts/qcom-*.dtsi
 F:     arch/arm/mach-qcom/
 F:     drivers/soc/qcom/
 F:     drivers/tty/serial/msm_serial.h
@@ -1428,13 +1431,22 @@ F:      drivers/tty/serial/msm_serial.c
 F:     drivers/*/pm8???-*
 F:     drivers/mfd/ssbi.c
 F:     drivers/firmware/qcom_scm.c
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git
 
 ARM/RADISYS ENP2611 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
+ARM/RENESAS ARM64 ARCHITECTURE
+M:     Simon Horman <horms@verge.net.au>
+M:     Magnus Damm <magnus.damm@gmail.com>
+L:     linux-sh@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/linux-sh/list/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
+S:     Supported
+F:     arch/arm64/boot/dts/renesas/
+
 ARM/RISCPC ARCHITECTURE
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1454,6 +1466,7 @@ ARM/Rockchip SoC support
 M:     Heiko Stuebner <heiko@sntech.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-rockchip@lists.infradead.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git
 S:     Maintained
 F:     arch/arm/boot/dts/rk3*
 F:     arch/arm/mach-rockchip/
@@ -1532,7 +1545,6 @@ ARM/SHMOBILE ARM ARCHITECTURE
 M:     Simon Horman <horms@verge.net.au>
 M:     Magnus Damm <magnus.damm@gmail.com>
 L:     linux-renesas-soc@vger.kernel.org
-W:     http://oss.renesas.com
 Q:     http://patchwork.kernel.org/project/linux-renesas-soc/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
 S:     Supported
@@ -1603,6 +1615,13 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git
 N:     stm32
 F:     drivers/clocksource/armv7m_systick.c
 
+ARM/TANGO ARCHITECTURE
+M:     Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
+L:     linux-arm-kernel@lists.infradead.org
+S:     Maintained
+F:     arch/arm/mach-tango/
+F:     arch/arm/boot/dts/tango*
+
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1657,6 +1676,8 @@ F:        arch/arm/boot/dts/uniphier*
 F:     arch/arm/include/asm/hardware/cache-uniphier.h
 F:     arch/arm/mach-uniphier/
 F:     arch/arm/mm/cache-uniphier.c
+F:     arch/arm64/boot/dts/socionext/
+F:     drivers/bus/uniphier-system-bus.c
 F:     drivers/i2c/busses/i2c-uniphier*
 F:     drivers/pinctrl/uniphier/
 F:     drivers/tty/serial/8250/8250_uniphier.c
@@ -1778,6 +1799,7 @@ ARM64 PORT (AARCH64 ARCHITECTURE)
 M:     Catalin Marinas <catalin.marinas@arm.com>
 M:     Will Deacon <will.deacon@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
 S:     Maintained
 F:     arch/arm64/
 F:     Documentation/arm64/
@@ -1863,7 +1885,7 @@ ATHEROS ATH6KL WIRELESS DRIVER
 M:     Kalle Valo <kvalo@qca.qualcomm.com>
 L:     linux-wireless@vger.kernel.org
 W:     http://wireless.kernel.org/en/users/Drivers/ath6kl
-T:     git git://github.com/kvalo/ath.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
 S:     Supported
 F:     drivers/net/wireless/ath/ath6kl/
 
@@ -2115,6 +2137,7 @@ F:        drivers/net/wireless/broadcom/b43legacy/
 BACKLIGHT CLASS/SUBSYSTEM
 M:     Jingoo Han <jingoohan1@gmail.com>
 M:     Lee Jones <lee.jones@linaro.org>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git
 S:     Maintained
 F:     drivers/video/backlight/
 F:     include/linux/backlight.h
@@ -2377,6 +2400,7 @@ M:        Brian Norris <computersforpeace@gmail.com>
 M:     Gregory Fong <gregory.0xf0@gmail.com>
 M:     Florian Fainelli <f.fainelli@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     bcm-kernel-feedback-list@broadcom.com
 T:     git git://github.com/broadcom/stblinux.git
 S:     Maintained
 F:     arch/arm/mach-bcm/*brcmstb*
@@ -2396,6 +2420,8 @@ F:        arch/mips/kernel/*bmips*
 F:     arch/mips/boot/dts/brcm/bcm*.dts*
 F:     drivers/irqchip/irq-bcm7*
 F:     drivers/irqchip/irq-brcmstb*
+F:     include/linux/bcm963xx_nvram.h
+F:     include/linux/bcm963xx_tag.h
 
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 M:     Prashant Sreedharan <prashant@broadcom.com>
@@ -2450,7 +2476,7 @@ N:        bcm88312
 
 BROADCOM BRCMSTB GPIO DRIVER
 M:     Gregory Fong <gregory.0xf0@gmail.com>
-L:     bcm-kernel-feedback-list@broadcom.com>
+L:     bcm-kernel-feedback-list@broadcom.com
 S:     Supported
 F:     drivers/gpio/gpio-brcmstb.c
 F:     Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
@@ -2796,6 +2822,7 @@ F:        drivers/input/touchscreen/chipone_icn8318.c
 CHROME HARDWARE PLATFORM SUPPORT
 M:     Olof Johansson <olof@lixom.net>
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/olof/chrome-platform.git
 F:     drivers/platform/chrome/
 
 CISCO VIC ETHERNET NIC DRIVER
@@ -3094,6 +3121,7 @@ M:        Mikael Starvik <starvik@axis.com>
 M:     Jesper Nilsson <jesper.nilsson@axis.com>
 L:     linux-cris-kernel@axis.com
 W:     http://developer.axis.com
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jesper/cris.git
 S:     Maintained
 F:     arch/cris/
 F:     drivers/tty/serial/crisv10.*
@@ -3102,6 +3130,7 @@ CRYPTO API
 M:     Herbert Xu <herbert@gondor.apana.org.au>
 M:     "David S. Miller" <davem@davemloft.net>
 L:     linux-crypto@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
 S:     Maintained
 F:     Documentation/crypto/
@@ -3434,8 +3463,21 @@ DEVICE FREQUENCY (DEVFREQ)
 M:     MyungJoo Ham <myungjoo.ham@samsung.com>
 M:     Kyungmin Park <kyungmin.park@samsung.com>
 L:     linux-pm@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
 S:     Maintained
 F:     drivers/devfreq/
+F:     include/linux/devfreq.h
+F:     Documentation/devicetree/bindings/devfreq/
+
+DEVICE FREQUENCY EVENT (DEVFREQ-EVENT)
+M:     Chanwoo Choi <cw00.choi@samsung.com>
+L:     linux-pm@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
+S:     Supported
+F:     drivers/devfreq/event/
+F:     drivers/devfreq/devfreq-event.c
+F:     include/linux/devfreq-event.h
+F:     Documentation/devicetree/bindings/devfreq/event/
 
 DEVICE NUMBER REGISTRY
 M:     Torben Mathiasen <device@lanana.org>
@@ -3551,7 +3593,7 @@ M:        Christine Caulfield <ccaulfie@redhat.com>
 M:     David Teigland <teigland@redhat.com>
 L:     cluster-devel@redhat.com
 W:     http://sources.redhat.com/cluster/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git
 S:     Supported
 F:     fs/dlm/
 
@@ -3625,13 +3667,12 @@ F:      drivers/scsi/dpt*
 F:     drivers/scsi/dpt/
 
 DRBD DRIVER
-P:     Philipp Reisner
-P:     Lars Ellenberg
-M:     drbd-dev@lists.linbit.com
-L:     drbd-user@lists.linbit.com
+M:     Philipp Reisner <philipp.reisner@linbit.com>
+M:     Lars Ellenberg <lars.ellenberg@linbit.com>
+L:     drbd-dev@lists.linbit.com
 W:     http://www.drbd.org
-T:     git git://git.drbd.org/linux-2.6-drbd.git drbd
-T:     git git://git.drbd.org/drbd-8.3.git
+T:     git git://git.linbit.com/linux-drbd.git
+T:     git git://git.linbit.com/drbd-8.4.git
 S:     Supported
 F:     drivers/block/drbd/
 F:     lib/lru_cache.c
@@ -3965,6 +4006,7 @@ M:        Tyler Hicks <tyhicks@canonical.com>
 L:     ecryptfs@vger.kernel.org
 W:     http://ecryptfs.org
 W:     https://launchpad.net/ecryptfs
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs.git
 S:     Supported
 F:     Documentation/filesystems/ecryptfs.txt
 F:     fs/ecryptfs/
@@ -4243,6 +4285,7 @@ M:        Andreas Dilger <adilger.kernel@dilger.ca>
 L:     linux-ext4@vger.kernel.org
 W:     http://ext4.wiki.kernel.org
 Q:     http://patchwork.ozlabs.org/project/linux-ext4/list/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git
 S:     Maintained
 F:     Documentation/filesystems/ext4.txt
 F:     fs/ext4/
@@ -4925,6 +4968,7 @@ F:        include/linux/hw_random.h
 HARDWARE SPINLOCK CORE
 M:     Ohad Ben-Cohen <ohad@wizery.com>
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/hwspinlock.git
 F:     Documentation/hwspinlock.txt
 F:     drivers/hwspinlock/hwspinlock_*
 F:     include/linux/hwspinlock.h
@@ -5463,6 +5507,7 @@ M:        Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
 L:     linux-ima-devel@lists.sourceforge.net
 L:     linux-ima-user@lists.sourceforge.net
 L:     linux-security-module@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
 S:     Supported
 F:     security/integrity/ima/
 
@@ -5718,11 +5763,11 @@ F:      include/linux/mic_bus.h
 F:     include/linux/scif.h
 F:     include/uapi/linux/mic_common.h
 F:     include/uapi/linux/mic_ioctl.h
-F      include/uapi/linux/scif_ioctl.h
+F:     include/uapi/linux/scif_ioctl.h
 F:     drivers/misc/mic/
 F:     drivers/dma/mic_x100_dma.c
 F:     drivers/dma/mic_x100_dma.h
-F      Documentation/mic/
+F:     Documentation/mic/
 
 INTEL PMC/P-Unit IPC DRIVER
 M:     Zha Qipeng<qipeng.zha@intel.com>
@@ -5737,10 +5782,8 @@ INTEL TELEMETRY DRIVER
 M:     Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
-F:     drivers/platform/x86/intel_telemetry_core.c
 F:     arch/x86/include/asm/intel_telemetry.h
-F:     drivers/platform/x86/intel_telemetry_pltdrv.c
-F:     drivers/platform/x86/intel_telemetry_debugfs.c
+F:     drivers/platform/x86/intel_telemetry*
 
 IOC3 ETHERNET DRIVER
 M:     Ralf Baechle <ralf@linux-mips.org>
@@ -5803,6 +5846,8 @@ M:        Julian Anastasov <ja@ssi.bg>
 L:     netdev@vger.kernel.org
 L:     lvs-devel@vger.kernel.org
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git
 F:     Documentation/networking/ipvs-sysctl.txt
 F:     include/net/ip_vs.h
 F:     include/uapi/linux/ip_vs.h
@@ -6086,6 +6131,7 @@ M:        "J. Bruce Fields" <bfields@fieldses.org>
 M:     Jeff Layton <jlayton@poochiereds.net>
 L:     linux-nfs@vger.kernel.org
 W:     http://nfs.sourceforge.net/
+T:     git git://linux-nfs.org/~bfields/linux.git
 S:     Supported
 F:     fs/nfsd/
 F:     include/uapi/linux/nfsd/
@@ -6142,6 +6188,7 @@ M:        Christian Borntraeger <borntraeger@de.ibm.com>
 M:     Cornelia Huck <cornelia.huck@de.ibm.com>
 L:     linux-s390@vger.kernel.org
 W:     http://www.ibm.com/developerworks/linux/linux390/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git
 S:     Supported
 F:     Documentation/s390/kvm.txt
 F:     arch/s390/include/asm/kvm*
@@ -6171,6 +6218,14 @@ F:       arch/arm64/include/uapi/asm/kvm*
 F:     arch/arm64/include/asm/kvm*
 F:     arch/arm64/kvm/
 
+KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
+M:     James Hogan <james.hogan@imgtec.com>
+L:     linux-mips@linux-mips.org
+S:     Supported
+F:     arch/mips/include/uapi/asm/kvm*
+F:     arch/mips/include/asm/kvm*
+F:     arch/mips/kvm/
+
 KEXEC
 M:     Eric Biederman <ebiederm@xmission.com>
 W:     http://kernel.org/pub/linux/utils/kernel/kexec/
@@ -6215,6 +6270,7 @@ KGDB / KDB /debug_core
 M:     Jason Wessel <jason.wessel@windriver.com>
 W:     http://kgdb.wiki.kernel.org/
 L:     kgdb-bugreport@lists.sourceforge.net
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb.git
 S:     Maintained
 F:     Documentation/DocBook/kgdb.tmpl
 F:     drivers/misc/kgdbts.c
@@ -6267,6 +6323,12 @@ S:       Maintained
 F:     net/l3mdev
 F:     include/net/l3mdev.h
 
+LANTIQ MIPS ARCHITECTURE
+M:     John Crispin <blogic@openwrt.org>
+L:     linux-mips@linux-mips.org
+S:     Maintained
+F:     arch/mips/lantiq
+
 LAPB module
 L:     linux-x25@vger.kernel.org
 S:     Orphan
@@ -6386,6 +6448,7 @@ LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
 M:     Dan Williams <dan.j.williams@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
 S:     Supported
 F:     drivers/nvdimm/*
 F:     include/linux/nd.h
@@ -7055,6 +7118,7 @@ F:        Documentation/hwmon/menf21bmc
 METAG ARCHITECTURE
 M:     James Hogan <james.hogan@imgtec.com>
 L:     linux-metag@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git
 S:     Odd Fixes
 F:     arch/metag/
 F:     Documentation/metag/
@@ -7101,27 +7165,45 @@ W:      https://linuxtv.org
 S:     Odd Fixes
 F:     drivers/media/radio/radio-miropcm20*
 
-Mellanox MLX5 core VPI driver
-M:     Eli Cohen <eli@mellanox.com>
+MELLANOX MLX4 core VPI driver
+M:     Yishai Hadas <yishaih@mellanox.com>
 L:     netdev@vger.kernel.org
 L:     linux-rdma@vger.kernel.org
 W:     http://www.mellanox.com
 Q:     http://patchwork.ozlabs.org/project/netdev/list/
+S:     Supported
+F:     drivers/net/ethernet/mellanox/mlx4/
+F:     include/linux/mlx4/
+
+MELLANOX MLX4 IB driver
+M:     Yishai Hadas <yishaih@mellanox.com>
+L:     linux-rdma@vger.kernel.org
+W:     http://www.mellanox.com
 Q:     http://patchwork.kernel.org/project/linux-rdma/list/
-T:     git git://openfabrics.org/~eli/connect-ib.git
+S:     Supported
+F:     drivers/infiniband/hw/mlx4/
+F:     include/linux/mlx4/
+
+MELLANOX MLX5 core VPI driver
+M:     Matan Barak <matanb@mellanox.com>
+M:     Leon Romanovsky <leonro@mellanox.com>
+L:     netdev@vger.kernel.org
+L:     linux-rdma@vger.kernel.org
+W:     http://www.mellanox.com
+Q:     http://patchwork.ozlabs.org/project/netdev/list/
 S:     Supported
 F:     drivers/net/ethernet/mellanox/mlx5/core/
 F:     include/linux/mlx5/
 
-Mellanox MLX5 IB driver
-M:     Eli Cohen <eli@mellanox.com>
+MELLANOX MLX5 IB driver
+M:     Matan Barak <matanb@mellanox.com>
+M:     Leon Romanovsky <leonro@mellanox.com>
 L:     linux-rdma@vger.kernel.org
 W:     http://www.mellanox.com
 Q:     http://patchwork.kernel.org/project/linux-rdma/list/
-T:     git git://openfabrics.org/~eli/connect-ib.git
 S:     Supported
-F:     include/linux/mlx5/
 F:     drivers/infiniband/hw/mlx5/
+F:     include/linux/mlx5/
 
 MELEXIS MLX90614 DRIVER
 M:     Crt Mori <cmo@melexis.com>
@@ -7536,7 +7618,8 @@ NETWORKING DRIVERS (WIRELESS)
 M:     Kalle Valo <kvalo@codeaurora.org>
 L:     linux-wireless@vger.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-wireless/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
 S:     Maintained
 F:     drivers/net/wireless/
 
@@ -7651,6 +7734,12 @@ W:       https://github.com/jonmason/ntb/wiki
 T:     git git://github.com/jonmason/ntb.git
 F:     drivers/ntb/hw/intel/
 
+NTB AMD DRIVER
+M:     Xiangliang Yu <Xiangliang.Yu@amd.com>
+L:     linux-ntb@googlegroups.com
+S:     Supported
+F:     drivers/ntb/hw/amd/
+
 NTFS FILESYSTEM
 M:     Anton Altaparmakov <anton@tuxera.com>
 L:     linux-ntfs-dev@lists.sourceforge.net
@@ -7942,6 +8031,7 @@ M:        Mark Rutland <mark.rutland@arm.com>
 M:     Ian Campbell <ijc+devicetree@hellion.org.uk>
 M:     Kumar Gala <galak@codeaurora.org>
 L:     devicetree@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
 S:     Maintained
 F:     Documentation/devicetree/
 F:     arch/*/boot/dts/
@@ -8285,6 +8375,12 @@ S:       Maintained
 F:     Documentation/devicetree/bindings/pci/host-generic-pci.txt
 F:     drivers/pci/host/pci-host-generic.c
 
+PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
+M:     Keith Busch <keith.busch@intel.com>
+L:     linux-pci@vger.kernel.org
+S:     Supported
+F:     arch/x86/pci/vmd.c
+
 PCIE DRIVER FOR ST SPEAR13XX
 M:     Pratyush Anand <pratyush.anand@gmail.com>
 L:     linux-pci@vger.kernel.org
@@ -8309,16 +8405,24 @@ F:      drivers/pci/host/pci-xgene-msi.c
 
 PCIE DRIVER FOR HISILICON
 M:     Zhou Wang <wangzhou1@hisilicon.com>
+M:     Gabriele Paoloni <gabriele.paoloni@huawei.com>
 L:     linux-pci@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 F:     drivers/pci/host/pcie-hisi.c
 
+PCIE DRIVER FOR QUALCOMM MSM
+M:     Stanimir Varbanov <svarbanov@mm-sol.com>
+L:     linux-pci@vger.kernel.org
+L:     linux-arm-msm@vger.kernel.org
+S:     Maintained
+F:     drivers/pci/host/*qcom*
+
 PCMCIA SUBSYSTEM
 P:     Linux PCMCIA Team
 L:     linux-pcmcia@lists.infradead.org
 W:     http://lists.infradead.org/mailman/listinfo/linux-pcmcia
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia.git
 S:     Maintained
 F:     Documentation/pcmcia/
 F:     drivers/pcmcia/
@@ -8640,7 +8744,7 @@ M:        Colin Cross <ccross@android.com>
 M:     Kees Cook <keescook@chromium.org>
 M:     Tony Luck <tony.luck@intel.com>
 S:     Maintained
-T:     git git://git.infradead.org/users/cbou/linux-pstore.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git
 F:     fs/pstore/
 F:     include/linux/pstore*
 F:     drivers/firmware/efi/efi-pstore.c
@@ -8849,13 +8953,14 @@ QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
 M:     Kalle Valo <kvalo@qca.qualcomm.com>
 L:     ath10k@lists.infradead.org
 W:     http://wireless.kernel.org/en/users/Drivers/ath10k
-T:     git git://github.com/kvalo/ath.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
 S:     Supported
 F:     drivers/net/wireless/ath/ath10k/
 
 QUALCOMM HEXAGON ARCHITECTURE
 M:     Richard Kuo <rkuo@codeaurora.org>
 L:     linux-hexagon@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel.git
 S:     Supported
 F:     arch/hexagon/
 
@@ -8908,6 +9013,12 @@ L:       linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/fbdev/aty/aty128fb.c
 
+RALINK MIPS ARCHITECTURE
+M:     John Crispin <blogic@openwrt.org>
+L:     linux-mips@linux-mips.org
+S:     Maintained
+F:     arch/mips/ralink
+
 RALINK RT2X00 WIRELESS LAN DRIVER
 P:     rt2x00 project
 M:     Stanislaw Gruszka <sgruszka@redhat.com>
@@ -9054,6 +9165,7 @@ F:        drivers/phy/phy-rcar-gen3-usb2.c
 
 RESET CONTROLLER FRAMEWORK
 M:     Philipp Zabel <p.zabel@pengutronix.de>
+T:     git git://git.pengutronix.de/git/pza/linux
 S:     Maintained
 F:     drivers/reset/
 F:     Documentation/devicetree/bindings/reset/
@@ -9201,6 +9313,7 @@ M:        Martin Schwidefsky <schwidefsky@de.ibm.com>
 M:     Heiko Carstens <heiko.carstens@de.ibm.com>
 L:     linux-s390@vger.kernel.org
 W:     http://www.ibm.com/developerworks/linux/linux390/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git
 S:     Supported
 F:     arch/s390/
 F:     drivers/s390/
@@ -9393,7 +9506,7 @@ M:        Lukasz Majewski <l.majewski@samsung.com>
 L:     linux-pm@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org
 S:     Supported
-T:     https://github.com/lmajewski/linux-samsung-thermal.git
+T:     git https://github.com/lmajewski/linux-samsung-thermal.git
 F:     drivers/thermal/samsung/
 
 SAMSUNG USB2 PHY DRIVER
@@ -10046,6 +10159,7 @@ F:      drivers/media/pci/solo6x10/
 
 SOFTWARE RAID (Multiple Disks) SUPPORT
 L:     linux-raid@vger.kernel.org
+T:     git git://neil.brown.name/md
 S:     Supported
 F:     drivers/md/
 F:     include/linux/raid/
@@ -10217,6 +10331,7 @@ SQUASHFS FILE SYSTEM
 M:     Phillip Lougher <phillip@squashfs.org.uk>
 L:     squashfs-devel@lists.sourceforge.net (subscribers-only)
 W:     http://squashfs.org.uk
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next.git
 S:     Maintained
 F:     Documentation/filesystems/squashfs.txt
 F:     fs/squashfs/
@@ -10382,9 +10497,11 @@ S:     Maintained
 F:     drivers/net/ethernet/dlink/sundance.c
 
 SUPERH
+M:     Yoshinori Sato <ysato@users.sourceforge.jp>
+M:     Rich Felker <dalias@libc.org>
 L:     linux-sh@vger.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-sh/list/
-S:     Orphan
+S:     Maintained
 F:     Documentation/sh/
 F:     arch/sh/
 F:     drivers/sh/
@@ -10413,6 +10530,7 @@ F:      arch/x86/boot/video*
 SWIOTLB SUBSYSTEM
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 L:     linux-kernel@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb.git
 S:     Supported
 F:     lib/swiotlb.c
 F:     arch/*/kernel/pci-swiotlb.c
@@ -10676,6 +10794,7 @@ TENSILICA XTENSA PORT (xtensa)
 M:     Chris Zankel <chris@zankel.net>
 M:     Max Filippov <jcmvbkbc@gmail.com>
 L:     linux-xtensa@linux-xtensa.org
+T:     git git://github.com/czankel/xtensa-linux.git
 S:     Maintained
 F:     arch/xtensa/
 F:     drivers/irqchip/irq-xtensa-*
@@ -10958,7 +11077,7 @@ R:      Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
 W:     http://tpmdd.sourceforge.net
 L:     tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
 Q:     git git://github.com/PeterHuewe/linux-tpmdd.git
-T:     https://github.com/PeterHuewe/linux-tpmdd
+T:     git https://github.com/PeterHuewe/linux-tpmdd
 S:     Maintained
 F:     drivers/char/tpm/
 
@@ -11415,6 +11534,7 @@ M:      Richard Weinberger <richard@nod.at>
 L:     user-mode-linux-devel@lists.sourceforge.net
 L:     user-mode-linux-user@lists.sourceforge.net
 W:     http://user-mode-linux.sourceforge.net
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git
 S:     Maintained
 F:     Documentation/virtual/uml/
 F:     arch/um/
@@ -11461,6 +11581,7 @@ F:      fs/fat/
 VFIO DRIVER
 M:     Alex Williamson <alex.williamson@redhat.com>
 L:     kvm@vger.kernel.org
+T:     git git://github.com/awilliam/linux-vfio.git
 S:     Maintained
 F:     Documentation/vfio.txt
 F:     drivers/vfio/
@@ -11530,6 +11651,7 @@ M:      "Michael S. Tsirkin" <mst@redhat.com>
 L:     kvm@vger.kernel.org
 L:     virtualization@lists.linux-foundation.org
 L:     netdev@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
 S:     Maintained
 F:     drivers/vhost/
 F:     include/uapi/linux/vhost.h
@@ -11946,7 +12068,7 @@ M:      Dave Chinner <david@fromorbit.com>
 M:     xfs@oss.sgi.com
 L:     xfs@oss.sgi.com
 W:     http://oss.sgi.com/projects/xfs
-T:     git git://oss.sgi.com/xfs/xfs.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git
 S:     Supported
 F:     Documentation/filesystems/xfs.txt
 F:     fs/xfs/
index 7f4ac1e..c65fe37 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
-PATCHLEVEL = 4
+PATCHLEVEL = 5
 SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
@@ -411,7 +411,7 @@ export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
-export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KASAN
+export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KASAN CFLAGS_UBSAN
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
@@ -784,6 +784,7 @@ endif
 
 include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
+include scripts/Makefile.ubsan
 
 # Add any arch overrides and user supplied CPPFLAGS, AFLAGS and CFLAGS as the
 # last assignments
index ba1b626..f6b649d 100644 (file)
@@ -205,9 +205,6 @@ config HAVE_NMI_WATCHDOG
 config HAVE_ARCH_TRACEHOOK
        bool
 
-config HAVE_DMA_ATTRS
-       bool
-
 config HAVE_DMA_CONTIGUOUS
        bool
 
@@ -632,4 +629,7 @@ config OLD_SIGACTION
 config COMPAT_OLD_SIGACTION
        bool
 
+config ARCH_NO_COHERENT_DMA_MMAP
+       bool
+
 source "kernel/gcov/Kconfig"
index f515a4d..9d8a858 100644 (file)
@@ -9,7 +9,6 @@ config ALPHA
        select HAVE_OPROFILE
        select HAVE_PCSPKR_PLATFORM
        select HAVE_PERF_EVENTS
-       select HAVE_DMA_ATTRS
        select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select AUTO_IRQ_AFFINITY if SMP
index 72a8ca7..3c3451f 100644 (file)
@@ -10,8 +10,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
        return dma_ops;
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 #define dma_cache_sync(dev, va, size, dir)               ((void)0)
 
 #endif /* _ALPHA_DMA_MAPPING_H */
index ab336c0..fec1947 100644 (file)
@@ -47,7 +47,6 @@
 #define MADV_WILLNEED  3               /* will need these pages */
 #define        MADV_SPACEAVAIL 5               /* ensure resources are available */
 #define MADV_DONTNEED  6               /* don't need these pages */
-#define MADV_FREE      7               /* free pages only if memory pressure */
 
 /* common/generic parameters */
 #define MADV_FREE      8               /* free pages only if memory pressure */
index 2d28ba9..6602054 100644 (file)
 #ifndef ASM_ARC_DMA_MAPPING_H
 #define ASM_ARC_DMA_MAPPING_H
 
-#include <asm-generic/dma-coherent.h>
-#include <asm/cacheflush.h>
+extern struct dma_map_ops arc_dma_ops;
 
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-                           dma_addr_t *dma_handle, gfp_t gfp);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
-                         dma_addr_t dma_handle);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *dma_handle, gfp_t gfp);
-
-void dma_free_coherent(struct device *dev, size_t size, void *kvaddr,
-                      dma_addr_t dma_handle);
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
-/*
- * streaming DMA Mapping API...
- * CPU accesses page via normal paddr, thus needs to explicitly made
- * consistent before each use
- */
-
-static inline void __inline_dma_cache_sync(unsigned long paddr, size_t size,
-                                          enum dma_data_direction dir)
-{
-       switch (dir) {
-       case DMA_FROM_DEVICE:
-               dma_cache_inv(paddr, size);
-               break;
-       case DMA_TO_DEVICE:
-               dma_cache_wback(paddr, size);
-               break;
-       case DMA_BIDIRECTIONAL:
-               dma_cache_wback_inv(paddr, size);
-               break;
-       default:
-               pr_err("Invalid DMA dir [%d] for OP @ %lx\n", dir, paddr);
-       }
-}
-
-void __arc_dma_cache_sync(unsigned long paddr, size_t size,
-                         enum dma_data_direction dir);
-
-#define _dma_cache_sync(addr, sz, dir)                 \
-do {                                                   \
-       if (__builtin_constant_p(dir))                  \
-               __inline_dma_cache_sync(addr, sz, dir); \
-       else                                            \
-               __arc_dma_cache_sync(addr, sz, dir);    \
-}                                                      \
-while (0);
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-              enum dma_data_direction dir)
-{
-       _dma_cache_sync((unsigned long)cpu_addr, size, dir);
-       return (dma_addr_t)cpu_addr;
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-                size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-            unsigned long offset, size_t size,
-            enum dma_data_direction dir)
-{
-       unsigned long paddr = page_to_phys(page) + offset;
-       return dma_map_single(dev, (void *)paddr, size, dir);
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
-              size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg,
-          int nents, enum dma_data_direction dir)
-{
-       struct scatterlist *s;
-       int i;
-
-       for_each_sg(sg, s, nents, i)
-               s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
-                                              s->length, dir);
-
-       return nents;
-}
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-            int nents, enum dma_data_direction dir)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       struct scatterlist *s;
-       int i;
-
-       for_each_sg(sg, s, nents, i)
-               dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                       size_t size, enum dma_data_direction dir)
-{
-       _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-                          size_t size, enum dma_data_direction dir)
-{
-       _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction)
-{
-       _dma_cache_sync(dma_handle + offset, size, DMA_FROM_DEVICE);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
-{
-       _dma_cache_sync(dma_handle + offset, size, DMA_TO_DEVICE);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nelems,
-                   enum dma_data_direction dir)
-{
-       int i;
-       struct scatterlist *sg;
-
-       for_each_sg(sglist, sg, nelems, i)
-               _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
-                      int nelems, enum dma_data_direction dir)
-{
-       int i;
-       struct scatterlist *sg;
-
-       for_each_sg(sglist, sg, nelems, i)
-               _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
-}
-
-static inline int dma_supported(struct device *dev, u64 dma_mask)
-{
-       /* Support 32 bit DMA mask exclusively */
-       return dma_mask == DMA_BIT_MASK(32);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-               return -EIO;
-
-       *dev->dma_mask = dma_mask;
-
-       return 0;
+       return &arc_dma_ops;
 }
 
 #endif
index 29a46bb..01eaf88 100644 (file)
  */
 
 #include <linux/dma-mapping.h>
-#include <linux/dma-debug.h>
-#include <linux/export.h>
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
 
-/*
- * Helpers for Coherent DMA API.
- */
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-                           dma_addr_t *dma_handle, gfp_t gfp)
+
+static void *arc_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
-       void *paddr;
+       void *paddr, *kvaddr;
 
        /* This is linear addr (0x8000_0000 based) */
        paddr = alloc_pages_exact(size, gfp);
@@ -38,22 +34,6 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
        /* This is bus address, platform dependent */
        *dma_handle = (dma_addr_t)paddr;
 
-       return paddr;
-}
-EXPORT_SYMBOL(dma_alloc_noncoherent);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
-                         dma_addr_t dma_handle)
-{
-       free_pages_exact((void *)dma_handle, size);
-}
-EXPORT_SYMBOL(dma_free_noncoherent);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *dma_handle, gfp_t gfp)
-{
-       void *paddr, *kvaddr;
-
        /*
         * IOC relies on all data (even coherent DMA data) being in cache
         * Thus allocate normal cached memory
@@ -65,22 +45,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
         *   -For coherent data, Read/Write to buffers terminate early in cache
         *   (vs. always going to memory - thus are faster)
         */
-       if (is_isa_arcv2() && ioc_exists)
-               return dma_alloc_noncoherent(dev, size, dma_handle, gfp);
-
-       /* This is linear addr (0x8000_0000 based) */
-       paddr = alloc_pages_exact(size, gfp);
-       if (!paddr)
-               return NULL;
+       if ((is_isa_arcv2() && ioc_exists) ||
+           dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
+               return paddr;
 
        /* This is kernel Virtual address (0x7000_0000 based) */
        kvaddr = ioremap_nocache((unsigned long)paddr, size);
        if (kvaddr == NULL)
                return NULL;
 
-       /* This is bus address, platform dependent */
-       *dma_handle = (dma_addr_t)paddr;
-
        /*
         * Evict any existing L1 and/or L2 lines for the backing page
         * in case it was used earlier as a normal "cached" page.
@@ -95,26 +68,111 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 
        return kvaddr;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void dma_free_coherent(struct device *dev, size_t size, void *kvaddr,
-                      dma_addr_t dma_handle)
+static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
-       if (is_isa_arcv2() && ioc_exists)
-               return dma_free_noncoherent(dev, size, kvaddr, dma_handle);
-
-       iounmap((void __force __iomem *)kvaddr);
+       if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) &&
+           !(is_isa_arcv2() && ioc_exists))
+               iounmap((void __force __iomem *)vaddr);
 
        free_pages_exact((void *)dma_handle, size);
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
 /*
- * Helper for streaming DMA...
+ * streaming DMA Mapping API...
+ * CPU accesses page via normal paddr, thus needs to explicitly made
+ * consistent before each use
  */
-void __arc_dma_cache_sync(unsigned long paddr, size_t size,
-                         enum dma_data_direction dir)
+static void _dma_cache_sync(unsigned long paddr, size_t size,
+               enum dma_data_direction dir)
+{
+       switch (dir) {
+       case DMA_FROM_DEVICE:
+               dma_cache_inv(paddr, size);
+               break;
+       case DMA_TO_DEVICE:
+               dma_cache_wback(paddr, size);
+               break;
+       case DMA_BIDIRECTIONAL:
+               dma_cache_wback_inv(paddr, size);
+               break;
+       default:
+               pr_err("Invalid DMA dir [%d] for OP @ %lx\n", dir, paddr);
+       }
+}
+
+static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size, enum dma_data_direction dir,
+               struct dma_attrs *attrs)
+{
+       unsigned long paddr = page_to_phys(page) + offset;
+       _dma_cache_sync(paddr, size, dir);
+       return (dma_addr_t)paddr;
+}
+
+static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg,
+          int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+       struct scatterlist *s;
+       int i;
+
+       for_each_sg(sg, s, nents, i)
+               s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+                                              s->length, dir);
+
+       return nents;
+}
+
+static void arc_dma_sync_single_for_cpu(struct device *dev,
+               dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
+{
+       _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
+}
+
+static void arc_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
 {
-       __inline_dma_cache_sync(paddr, size, dir);
+       _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
 }
-EXPORT_SYMBOL(__arc_dma_cache_sync);
+
+static void arc_dma_sync_sg_for_cpu(struct device *dev,
+               struct scatterlist *sglist, int nelems,
+               enum dma_data_direction dir)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nelems, i)
+               _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
+}
+
+static void arc_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sglist, int nelems,
+               enum dma_data_direction dir)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nelems, i)
+               _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
+}
+
+static int arc_dma_supported(struct device *dev, u64 dma_mask)
+{
+       /* Support 32 bit DMA mask exclusively */
+       return dma_mask == DMA_BIT_MASK(32);
+}
+
+struct dma_map_ops arc_dma_ops = {
+       .alloc                  = arc_dma_alloc,
+       .free                   = arc_dma_free,
+       .map_page               = arc_dma_map_page,
+       .map_sg                 = arc_dma_map_sg,
+       .sync_single_for_device = arc_dma_sync_single_for_device,
+       .sync_single_for_cpu    = arc_dma_sync_single_for_cpu,
+       .sync_sg_for_cpu        = arc_dma_sync_sg_for_cpu,
+       .sync_sg_for_device     = arc_dma_sync_sg_for_device,
+       .dma_supported          = arc_dma_supported,
+};
+EXPORT_SYMBOL(arc_dma_ops);
index 6a889af..4f799e5 100644 (file)
@@ -47,7 +47,6 @@ config ARM
        select HAVE_C_RECORDMCOUNT
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_API_DEBUG
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_CONTIGUOUS if MMU
        select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU
        select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU
@@ -240,7 +239,6 @@ config ARM_PATCH_PHYS_VIRT
        bool "Patch physical to virtual translations at runtime" if EMBEDDED
        default y
        depends on !XIP_KERNEL && MMU
-       depends on !ARCH_REALVIEW || !SPARSEMEM
        help
          Patch phys-to-virt and virt-to-phys translation functions at
          boot and module load time according to the position of the
@@ -321,7 +319,7 @@ config ARCH_MMAP_RND_BITS_MAX
 #
 choice
        prompt "ARM system type"
-       default ARCH_VERSATILE if !MMU
+       default ARM_SINGLE_ARMV7M if !MMU
        default ARCH_MULTIPLATFORM if MMU
 
 config ARCH_MULTIPLATFORM
@@ -353,38 +351,6 @@ config ARM_SINGLE_ARMV7M
        select SPARSE_IRQ
        select USE_OF
 
-config ARCH_REALVIEW
-       bool "ARM Ltd. RealView family"
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       select ARM_AMBA
-       select ARM_TIMER_SP804
-       select COMMON_CLK
-       select COMMON_CLK_VERSATILE
-       select GENERIC_CLOCKEVENTS
-       select GPIO_PL061 if GPIOLIB
-       select ICST
-       select NEED_MACH_MEMORY_H
-       select PLAT_VERSATILE
-       select PLAT_VERSATILE_SCHED_CLOCK
-       help
-         This enables support for ARM Ltd RealView boards.
-
-config ARCH_VERSATILE
-       bool "ARM Ltd. Versatile family"
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       select ARM_AMBA
-       select ARM_TIMER_SP804
-       select ARM_VIC
-       select CLKDEV_LOOKUP
-       select GENERIC_CLOCKEVENTS
-       select HAVE_MACH_CLKDEV
-       select ICST
-       select PLAT_VERSATILE
-       select PLAT_VERSATILE_CLOCK
-       select PLAT_VERSATILE_SCHED_CLOCK
-       select VERSATILE_FPGA_IRQ
-       help
-         This enables support for ARM Ltd Versatile board.
 
 config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
@@ -519,55 +485,15 @@ config ARCH_DOVE
        select CPU_PJ4
        select GENERIC_CLOCKEVENTS
        select MIGHT_HAVE_PCI
+       select MULTI_IRQ_HANDLER
        select MVEBU_MBUS
        select PINCTRL
        select PINCTRL_DOVE
        select PLAT_ORION_LEGACY
-       help
-         Support for the Marvell Dove SoC 88AP510
-
-config ARCH_MV78XX0
-       bool "Marvell MV78xx0"
-       select ARCH_REQUIRE_GPIOLIB
-       select CPU_FEROCEON
-       select GENERIC_CLOCKEVENTS
-       select MVEBU_MBUS
-       select PCI
-       select PLAT_ORION_LEGACY
-       help
-         Support for the following Marvell MV78xx0 series SoCs:
-         MV781x0, MV782x0.
-
-config ARCH_ORION5X
-       bool "Marvell Orion"
-       depends on MMU
-       select ARCH_REQUIRE_GPIOLIB
-       select CPU_FEROCEON
-       select GENERIC_CLOCKEVENTS
-       select MVEBU_MBUS
-       select PCI
-       select PLAT_ORION_LEGACY
-       select MULTI_IRQ_HANDLER
-       help
-         Support for the following Marvell Orion 5x series SoCs:
-         Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
-         Orion-2 (5281), Orion-1-90 (6183).
-
-config ARCH_MMP
-       bool "Marvell PXA168/910/MMP2"
-       depends on MMU
-       select ARCH_REQUIRE_GPIOLIB
-       select CLKDEV_LOOKUP
-       select GENERIC_ALLOCATOR
-       select GENERIC_CLOCKEVENTS
-       select GPIO_PXA
-       select IRQ_DOMAIN
-       select MULTI_IRQ_HANDLER
-       select PINCTRL
-       select PLAT_PXA
        select SPARSE_IRQ
+       select PM_GENERIC_DOMAINS if PM
        help
-         Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
+         Support for the Marvell Dove SoC 88AP510
 
 config ARCH_KS8695
        bool "Micrel/Kendin KS8695"
@@ -692,32 +618,6 @@ config ARCH_S3C24XX
          (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
          Samsung SMDK2410 development board (and derivatives).
 
-config ARCH_S3C64XX
-       bool "Samsung S3C64XX"
-       select ARCH_REQUIRE_GPIOLIB
-       select ARM_AMBA
-       select ARM_VIC
-       select ATAGS
-       select CLKDEV_LOOKUP
-       select CLKSRC_SAMSUNG_PWM
-       select COMMON_CLK_SAMSUNG
-       select CPU_V6K
-       select GENERIC_CLOCKEVENTS
-       select GPIO_SAMSUNG
-       select HAVE_S3C2410_I2C if I2C
-       select HAVE_S3C2410_WATCHDOG if WATCHDOG
-       select HAVE_TCM
-       select NO_IOPORT_MAP
-       select PLAT_SAMSUNG
-       select PM_GENERIC_DOMAINS if PM
-       select S3C_DEV_NAND
-       select S3C_GPIO_TRACK
-       select SAMSUNG_ATAGS
-       select SAMSUNG_WAKEMASK
-       select SAMSUNG_WDT_RESET
-       help
-         Samsung S3C64XX series based systems
-
 config ARCH_DAVINCI
        bool "TI DaVinci"
        select ARCH_HAS_HOLES_MEMORYMODEL
@@ -806,7 +706,8 @@ config ARCH_MULTI_CPU_AUTO
 endmenu
 
 config ARCH_VIRT
-       bool "Dummy Virtual Machine" if ARCH_MULTI_V7
+       bool "Dummy Virtual Machine"
+       depends on ARCH_MULTI_V7
        select ARM_AMBA
        select ARM_GIC
        select ARM_GIC_V2M if PCI_MSI
@@ -929,6 +830,8 @@ source "arch/arm/mach-sunxi/Kconfig"
 
 source "arch/arm/mach-prima2/Kconfig"
 
+source "arch/arm/mach-tango/Kconfig"
+
 source "arch/arm/mach-tegra/Kconfig"
 
 source "arch/arm/mach-u300/Kconfig"
index e356357..c6b6175 100644 (file)
@@ -129,7 +129,12 @@ choice
 
        config DEBUG_BCM2835
                bool "Kernel low-level debugging on BCM2835 PL011 UART"
-               depends on ARCH_BCM2835
+               depends on ARCH_BCM2835 && ARCH_MULTI_V6
+               select DEBUG_UART_PL01X
+
+       config DEBUG_BCM2836
+               bool "Kernel low-level debugging on BCM2836 PL011 UART"
+               depends on ARCH_BCM2835 && ARCH_MULTI_V7
                select DEBUG_UART_PL01X
 
        config DEBUG_BCM_5301X
@@ -148,10 +153,9 @@ choice
                  mobile SoCs in the Kona family of chips (e.g. bcm28155,
                  bcm11351, etc...)
 
-       config DEBUG_BCM63XX
+       config DEBUG_BCM63XX_UART
                bool "Kernel low-level debugging on BCM63XX UART"
                depends on ARCH_BCM_63XX
-               select DEBUG_UART_BCM63XX
 
        config DEBUG_BERLIN_UART
                bool "Marvell Berlin SoC Debug UART"
@@ -218,23 +222,6 @@ choice
                  Say Y here if you want the debug print routines to direct
                  their output to UART0 serial port on DaVinci DMx devices.
 
-       config DEBUG_ZYNQ_UART0
-               bool "Kernel low-level debugging on Xilinx Zynq using UART0"
-               depends on ARCH_ZYNQ
-               help
-                 Say Y here if you want the debug print routines to direct
-                 their output to UART0 on the Zynq platform.
-
-       config DEBUG_ZYNQ_UART1
-               bool "Kernel low-level debugging on Xilinx Zynq using UART1"
-               depends on ARCH_ZYNQ
-               help
-                 Say Y here if you want the debug print routines to direct
-                 their output to UART1 on the Zynq platform.
-
-                 If you have a ZC702 board and want early boot messages to
-                 appear on the USB serial adaptor, select this option.
-
        config DEBUG_DC21285_PORT
                bool "Kernel low-level debugging messages via footbridge serial port"
                depends on FOOTBRIDGE
@@ -249,13 +236,30 @@ choice
                  Say Y here if you want the debug print routines to direct
                  their output to the UA0 serial port in the CX92755.
 
+       config DEBUG_EP93XX
+               bool "Kernel low-level debugging messages via ep93xx UART"
+               depends on ARCH_EP93XX
+               select DEBUG_UART_PL01X
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on Cirrus Logic EP93xx based platforms.
+
        config DEBUG_FOOTBRIDGE_COM1
                bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
                depends on FOOTBRIDGE
+               select DEBUG_UART_8250
                help
                  Say Y here if you want the debug print routines to direct
                  their output to the 8250 at PCI COM1.
 
+       config DEBUG_GEMINI
+               bool "Kernel low-level debugging messages via Cortina Systems Gemini UART"
+               depends on ARCH_GEMINI
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on Cortina Gemini based platforms.
+
        config DEBUG_HI3620_UART
                bool "Hisilicon HI3620 Debug UART"
                depends on ARCH_HI3xxx
@@ -411,6 +415,14 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on i.MX7D.
 
+       config DEBUG_INTEGRATOR
+               bool "Kernel low-level debugging messages via ARM Integrator UART"
+               depends on ARCH_INTEGRATOR
+               select DEBUG_UART_PL01X
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on ARM Integrator platforms.
+
        config DEBUG_KEYSTONE_UART0
                bool "Kernel low-level debugging on KEYSTONE2 using UART0"
                depends on ARCH_KEYSTONE
@@ -442,6 +454,14 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on NXP LPC18xx/43xx UART0.
 
+       config DEBUG_LPC32XX
+               bool "Kernel low-level debugging messages via NXP LPC32xx UART"
+               depends on ARCH_LPC32XX
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on NXP LPC32xx based platforms.
+
        config DEBUG_MESON_UARTAO
                bool "Kernel low-level debugging via Meson6 UARTAO"
                depends on ARCH_MESON
@@ -465,26 +485,10 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on MMP UART3.
 
-       config DEBUG_QCOM_UARTDM
-               bool "Kernel low-level debugging messages via QCOM UARTDM"
-               depends on ARCH_QCOM
-               help
-                 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_VIRT
-                 APQ8064   0x16640000        0xf0040000
-                 APQ8084   0xf995e000        0xfa75e000
-                 MSM8X60   0x19c40000        0xf0040000
-                 MSM8960   0x16440000        0xf0040000
-                 MSM8974   0xf991e000        0xfa71e000
-
-                 Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
-                 options based on your needs.
-
        config DEBUG_MVEBU_UART0
                bool "Kernel low-level debugging messages via MVEBU UART0 (old bootloaders)"
                depends on ARCH_MVEBU
+               depends on ARCH_MVEBU && CPU_V7
                select DEBUG_UART_8250
                help
                  Say Y here if you want kernel low-level debugging support
@@ -497,17 +501,23 @@ choice
                  Plathome OpenBlocks AX3, when using the original
                  bootloader.
 
+                 This option will not work on older Marvell platforms
+                 (Kirkwood, Dove, MV78xx0, Orion5x), which should pick
+                 the "new bootloader" variant.
+
                  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_UART0_ALTERNATE
                bool "Kernel low-level debugging messages via MVEBU UART0 (new bootloaders)"
-               depends on ARCH_MVEBU
+               depends on ARCH_MVEBU || ARCH_DOVE || ARCH_MV78XX0 || ARCH_ORION5X
                select DEBUG_UART_8250
                help
                  Say Y here if you want kernel low-level debugging support
-                 on MVEBU based platforms on UART0.
+                 on MVEBU based platforms on UART0. (Armada XP, Armada 3xx,
+                 Kirkwood, Dove, MV78xx0, Orion5x).
+
 
                  This option should be used with the new bootloaders
                  that remap the internal registers at 0xf1000000.
@@ -522,21 +532,41 @@ choice
                select DEBUG_UART_8250
                help
                  Say Y here if you want kernel low-level debugging support
-                 on MVEBU based platforms on UART1.
+                 on MVEBU based platforms on UART1. (Armada XP, Armada 3xx,
+                 Kirkwood, Dove, MV78xx0, Orion5x).
 
                  This option should be used with the new bootloaders
                  that remap the internal registers at 0xf1000000.
+                 All of the older (pre Armada XP/370) platforms also use
+                 this address, regardless of the boot loader version.
 
                  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_VF_UART
-               bool "Vybrid UART"
-               depends on SOC_VF610
+       config DEBUG_MT6589_UART0
+               bool "Mediatek mt6589 UART0"
+               depends on ARCH_MEDIATEK
+               select DEBUG_UART_8250
                help
                  Say Y here if you want kernel low-level debugging support
-                 on Vybrid based platforms.
+                 for Mediatek mt6589 based platforms on UART0.
+
+       config DEBUG_MT8127_UART0
+               bool "Mediatek mt8127/mt6592 UART0"
+               depends on ARCH_MEDIATEK
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 for Mediatek mt8127 based platforms on UART0.
+
+       config DEBUG_MT8135_UART3
+               bool "Mediatek mt8135 UART3"
+               depends on ARCH_MEDIATEK
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 for Mediatek mt8135 based platforms on UART3.
 
        config DEBUG_NETX_UART
                bool "Kernel low-level debugging messages via NetX UART"
@@ -700,6 +730,23 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on PXA UART1.
 
+       config DEBUG_QCOM_UARTDM
+               bool "Kernel low-level debugging messages via QCOM UARTDM"
+               depends on ARCH_QCOM
+               help
+                 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_VIRT
+                 APQ8064   0x16640000        0xf0040000
+                 APQ8084   0xf995e000        0xfa75e000
+                 MSM8X60   0x19c40000        0xf0040000
+                 MSM8960   0x16440000        0xf0040000
+                 MSM8974   0xf991e000        0xfa71e000
+
+                 Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
+                 options based on your needs.
+
        config DEBUG_REALVIEW_STD_PORT
                bool "RealView Default UART"
                depends on ARCH_REALVIEW
@@ -843,6 +890,7 @@ choice
                depends on PLAT_SAMSUNG
                select DEBUG_EXYNOS_UART if ARCH_EXYNOS
                select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+               select DEBUG_S3C64XX_UART if ARCH_S3C64XX
                select DEBUG_S5PV210_UART if ARCH_S5PV210
                bool "Use Samsung S3C UART 0 for low-level debug"
                help
@@ -854,6 +902,7 @@ choice
                depends on PLAT_SAMSUNG
                select DEBUG_EXYNOS_UART if ARCH_EXYNOS
                select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+               select DEBUG_S3C64XX_UART if ARCH_S3C64XX
                select DEBUG_S5PV210_UART if ARCH_S5PV210
                bool "Use Samsung S3C UART 1 for low-level debug"
                help
@@ -865,6 +914,7 @@ choice
                depends on PLAT_SAMSUNG
                select DEBUG_EXYNOS_UART if ARCH_EXYNOS
                select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+               select DEBUG_S3C64XX_UART if ARCH_S3C64XX
                select DEBUG_S5PV210_UART if ARCH_S5PV210
                bool "Use Samsung S3C UART 2 for low-level debug"
                help
@@ -875,6 +925,7 @@ choice
        config DEBUG_S3C_UART3
                depends on PLAT_SAMSUNG && (ARCH_EXYNOS || ARCH_S5PV210)
                select DEBUG_EXYNOS_UART if ARCH_EXYNOS
+               select DEBUG_S3C64XX_UART if ARCH_S3C64XX
                select DEBUG_S5PV210_UART if ARCH_S5PV210
                bool "Use Samsung S3C UART 3 for low-level debug"
                help
@@ -966,6 +1017,70 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on Allwinner A31/A23 based platforms on the R_UART.
 
+       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_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 SiRFATLAS7 devices.
+
+       config DEBUG_SPEAR3XX
+               bool "Kernel low-level debugging messages via ST SPEAr 3xx/6xx UART"
+               depends on ARCH_SPEAR3XX || ARCH_SPEAR6XX
+               select DEBUG_UART_PL01X
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on ST SPEAr based platforms.
+
+       config DEBUG_SPEAR13XX
+               bool "Kernel low-level debugging messages via ST SPEAr 13xx UART"
+               depends on ARCH_SPEAR13XX
+               select DEBUG_UART_PL01X
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on ST SPEAr13xx based platforms.
+
+       config STIH41X_DEBUG_ASC2
+               bool "Use StiH415/416 ASC2 UART for low-level debug"
+               depends on ARCH_STI
+               select DEBUG_STI_UART
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on STiH415/416 based platforms like b2000, which has
+                 default UART wired up to ASC2.
+
+                 If unsure, say N.
+
+       config STIH41X_DEBUG_SBC_ASC1
+               bool "Use StiH415/416 SBC ASC1 UART for low-level debug"
+               depends on ARCH_STI
+               select DEBUG_STI_UART
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on STiH415/416 based platforms like b2020. which has
+                 default UART wired up to SBC ASC1.
+
+                 If unsure, say N.
+
        config TEGRA_DEBUG_UART_AUTO_ODMDATA
                bool "Kernel low-level debugging messages via Tegra UART via ODMDATA"
                depends on ARCH_TEGRA
@@ -1018,54 +1133,6 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on Tegra based platforms.
 
-       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_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 SiRFATLAS7 devices.
-
-       config STIH41X_DEBUG_ASC2
-               bool "Use StiH415/416 ASC2 UART for low-level debug"
-               depends on ARCH_STI
-               select DEBUG_STI_UART
-               help
-                 Say Y here if you want kernel low-level debugging support
-                 on STiH415/416 based platforms like b2000, which has
-                 default UART wired up to ASC2.
-
-                 If unsure, say N.
-
-       config STIH41X_DEBUG_SBC_ASC1
-               bool "Use StiH415/416 SBC ASC1 UART for low-level debug"
-               depends on ARCH_STI
-               select DEBUG_STI_UART
-               help
-                 Say Y here if you want kernel low-level debugging support
-                 on STiH415/416 based platforms like b2020. which has
-                 default UART wired up to SBC ASC1.
-
-                 If unsure, say N.
-
        config DEBUG_U300_UART
                bool "Kernel low-level debugging messages via U300 UART0"
                depends on ARCH_U300
@@ -1081,29 +1148,13 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on Ux500 based platforms.
 
-       config DEBUG_MT6589_UART0
-               bool "Mediatek mt6589 UART0"
-               depends on ARCH_MEDIATEK
-               select DEBUG_UART_8250
-               help
-                 Say Y here if you want kernel low-level debugging support
-                 for Mediatek mt6589 based platforms on UART0.
-
-       config DEBUG_MT8127_UART0
-               bool "Mediatek mt8127/mt6592 UART0"
-               depends on ARCH_MEDIATEK
-               select DEBUG_UART_8250
-               help
-                 Say Y here if you want kernel low-level debugging support
-                 for Mediatek mt8127 based platforms on UART0.
-
-       config DEBUG_MT8135_UART3
-               bool "Mediatek mt8135 UART3"
-               depends on ARCH_MEDIATEK
-               select DEBUG_UART_8250
+       config DEBUG_VERSATILE
+               bool "Kernel low-level debugging messages via ARM Versatile UART"
+               depends on ARCH_VERSATILE
+               select DEBUG_UART_PL01X
                help
                  Say Y here if you want kernel low-level debugging support
-                 for Mediatek mt8135 based platforms on UART3.
+                 on ARM Versatile platforms.
 
        config DEBUG_VEXPRESS_UART0_DETECT
                bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
@@ -1141,6 +1192,13 @@ choice
                  This option selects UART0 at 0xb0090000. This is appropriate for
                  Cortex-R series tiles and SMMs, such as Cortex-R5 and Cortex-R7
 
+       config DEBUG_VF_UART
+               bool "Vybrid UART"
+               depends on SOC_VF610
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on Vybrid based platforms.
+
        config DEBUG_VT8500_UART0
                bool "Use UART0 on VIA/Wondermedia SoCs"
                depends on ARCH_VT8500
@@ -1148,6 +1206,35 @@ choice
                  This option selects UART0 on VIA/Wondermedia System-on-a-chip
                  devices, including VT8500, WM8505, WM8650 and WM8850.
 
+       config DEBUG_ZTE_ZX
+               bool "Use ZTE ZX UART"
+               select DEBUG_UART_PL01X
+               depends on ARCH_ZX
+               help
+                 Say Y here if you are enabling ZTE ZX296702 SOC and need
+                 debug uart support.
+
+                 This option is preferred over the platform specific
+                 options; the platform specific options are deprecated
+                 and will be soon removed.
+
+       config DEBUG_ZYNQ_UART0
+               bool "Kernel low-level debugging on Xilinx Zynq using UART0"
+               depends on ARCH_ZYNQ
+               help
+                 Say Y here if you want the debug print routines to direct
+                 their output to UART0 on the Zynq platform.
+
+       config DEBUG_ZYNQ_UART1
+               bool "Kernel low-level debugging on Xilinx Zynq using UART1"
+               depends on ARCH_ZYNQ
+               help
+                 Say Y here if you want the debug print routines to direct
+                 their output to UART1 on the Zynq platform.
+
+                 If you have a ZC702 board and want early boot messages to
+                 appear on the USB serial adaptor, select this option.
+
        config DEBUG_ICEDCC
                bool "Kernel low-level debugging via EmbeddedICE DCC channel"
                help
@@ -1175,18 +1262,6 @@ choice
                  For more details about semihosting, please see
                  chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
 
-       config DEBUG_ZTE_ZX
-               bool "Use ZTE ZX UART"
-               select DEBUG_UART_PL01X
-               depends on ARCH_ZX
-               help
-                 Say Y here if you are enabling ZTE ZX296702 SOC and need
-                 debug uart support.
-
-                 This option is preferred over the platform specific
-                 options; the platform specific options are deprecated
-                 and will be soon removed.
-
        config DEBUG_LL_UART_8250
                bool "Kernel low-level debugging via 8250 UART"
                help
@@ -1239,6 +1314,9 @@ config DEBUG_S3C2410_UART
 config DEBUG_S3C24XX_UART
        bool
 
+config DEBUG_S3C64XX_UART
+       bool
+
 config DEBUG_S5PV210_UART
        bool
 
@@ -1294,6 +1372,7 @@ config DEBUG_LL_INCLUDE
        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/dc21285.S" if DEBUG_DC21285_PORT
        default "debug/meson.S" if DEBUG_MESON_UARTAO
        default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X
        default "debug/exynos.S" if DEBUG_EXYNOS_UART
@@ -1324,7 +1403,7 @@ config DEBUG_LL_INCLUDE
        default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
        default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1
        default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
-       default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
+       default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART || DEBUG_S3C64XX_UART
        default "debug/s5pv210.S" if DEBUG_S5PV210_UART
        default "debug/sirf.S" if DEBUG_SIRFSOC_UART
        default "debug/sti.S" if DEBUG_STI_UART
@@ -1334,7 +1413,7 @@ config DEBUG_LL_INCLUDE
        default "debug/vf.S" if DEBUG_VF_UART
        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/bcm63xx.S" if DEBUG_BCM63XX_UART
        default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
        default "mach/debug-macro.S"
 
@@ -1344,15 +1423,9 @@ config DEBUG_UART_PL01X
 
 # Compatibility options for 8250
 config DEBUG_UART_8250
-       def_bool ARCH_DOVE || ARCH_EBSA110 || \
-               (FOOTBRIDGE && !DEBUG_DC21285_PORT) || \
-               ARCH_GEMINI || ARCH_IOP13XX || ARCH_IOP32X || \
-               ARCH_IOP33X || ARCH_IXP4XX || \
-               ARCH_LPC32XX || ARCH_MV78XX0 || ARCH_ORION5X || ARCH_RPC
-
-# Compatibility options for BCM63xx
-config DEBUG_UART_BCM63XX
-       def_bool ARCH_BCM_63XX
+       def_bool ARCH_EBSA110 || \
+               ARCH_IOP13XX || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || \
+               ARCH_RPC
 
 config DEBUG_UART_PHYS
        hex "Physical base address of debug UART"
@@ -1373,12 +1446,12 @@ config DEBUG_UART_PHYS
        default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
        default 0x10124000 if DEBUG_RK3X_UART0
        default 0x10126000 if DEBUG_RK3X_UART1
-       default 0x101f1000 if ARCH_VERSATILE
+       default 0x101f1000 if DEBUG_VERSATILE
        default 0x101fb000 if DEBUG_NOMADIK_UART
        default 0x11002000 if DEBUG_MT8127_UART0
        default 0x11006000 if DEBUG_MT6589_UART0
        default 0x11009000 if DEBUG_MT8135_UART3
-       default 0x16000000 if ARCH_INTEGRATOR
+       default 0x16000000 if DEBUG_INTEGRATOR
        default 0x18000300 if DEBUG_BCM_5301X
        default 0x18010000 if DEBUG_SIRFATLAS7_UART0
        default 0x18020000 if DEBUG_SIRFATLAS7_UART1
@@ -1388,12 +1461,13 @@ config DEBUG_UART_PHYS
        default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
        default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
        default 0x20201000 if DEBUG_BCM2835
+       default 0x3f201000 if DEBUG_BCM2836
        default 0x3e000000 if DEBUG_BCM_KONA_UART
        default 0x4000e400 if DEBUG_LL_UART_EFM32
        default 0x40081000 if DEBUG_LPC18XX_UART0
-       default 0x40090000 if ARCH_LPC32XX
+       default 0x40090000 if DEBUG_LPC32XX
        default 0x40100000 if DEBUG_PXA_UART1
-       default 0x42000000 if ARCH_GEMINI
+       default 0x42000000 if DEBUG_GEMINI
        default 0x50000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
                                DEBUG_S3C2410_UART0)
        default 0x50004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
@@ -1401,24 +1475,28 @@ config DEBUG_UART_PHYS
        default 0x50008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
                                DEBUG_S3C2410_UART2)
        default 0x78000000 if DEBUG_CNS3XXX
-       default 0x7c0003f8 if FOOTBRIDGE
+       default 0x7c0003f8 if DEBUG_FOOTBRIDGE_COM1
+       default 0x7f005000 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART0
+       default 0x7f005400 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART1
+       default 0x7f005800 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART2
+       default 0x7f005c00 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART3
        default 0x80010000 if DEBUG_ASM9260_UART
        default 0x80070000 if DEBUG_IMX23_UART
        default 0x80074000 if DEBUG_IMX28_UART
        default 0x80230000 if DEBUG_PICOXCELL_UART
-       default 0x808c0000 if ARCH_EP93XX
+       default 0x808c0000 if DEBUG_EP93XX || ARCH_EP93XX
        default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_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 0xd0000000 if DEBUG_SPEAR3XX
        default 0xd0012000 if DEBUG_MVEBU_UART0
        default 0xc81004c0 if DEBUG_MESON_UARTAO
        default 0xd4017000 if DEBUG_MMP_UART2
        default 0xd4018000 if DEBUG_MMP_UART3
-       default 0xe0000000 if ARCH_SPEAR13XX
+       default 0xe0000000 if DEBUG_SPEAR13XX
        default 0xe4007000 if DEBUG_HIP04_UART
        default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0
        default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1
@@ -1430,8 +1508,6 @@ config DEBUG_UART_PHYS
        default 0xf040ab00 if DEBUG_BRCMSTB_UART
        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
        default 0xf8b00000 if DEBUG_HIX5HD2_UART
        default 0xf991e000 if DEBUG_QCOM_UARTDM
@@ -1448,7 +1524,7 @@ config DEBUG_UART_PHYS
        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 0xfffe8600 if DEBUG_BCM63XX_UART
        default 0xfffff700 if ARCH_IOP33X
        depends on ARCH_EP93XX || \
                DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
@@ -1460,7 +1536,8 @@ config DEBUG_UART_PHYS
                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_S3C64XX_UART || \
+               DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
                DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
                DEBUG_AT91_UART
 
@@ -1471,22 +1548,27 @@ config DEBUG_UART_VIRT
        default 0xf0000be0 if ARCH_EBSA110
        default 0xf0010000 if DEBUG_ASM9260_UART
        default 0xf01fb000 if DEBUG_NOMADIK_UART
-       default 0xf0201000 if DEBUG_BCM2835
+       default 0xf0201000 if DEBUG_BCM2835 || DEBUG_BCM2836
        default 0xf1000300 if DEBUG_BCM_5301X
        default 0xf1002000 if DEBUG_MT8127_UART0
        default 0xf1006000 if DEBUG_MT6589_UART0
        default 0xf1009000 if DEBUG_MT8135_UART3
-       default 0xf11f1000 if ARCH_VERSATILE
-       default 0xf1600000 if ARCH_INTEGRATOR
+       default 0xf11f1000 if DEBUG_VERSATILE
+       default 0xf1600000 if DEBUG_INTEGRATOR
        default 0xf1c28000 if DEBUG_SUNXI_UART0
        default 0xf1c28400 if DEBUG_SUNXI_UART1
        default 0xf1f02800 if DEBUG_SUNXI_R_UART
+       default 0xf31004c0 if DEBUG_MESON_UARTAO
+       default 0xf4090000 if DEBUG_LPC32XX
+       default 0xf4200000 if DEBUG_GEMINI
        default 0xf6200000 if DEBUG_PXA_UART1
-       default 0xf4090000 if ARCH_LPC32XX
-       default 0xf4200000 if ARCH_GEMINI
        default 0xf7000000 if DEBUG_SUN9I_UART0
+       default 0xf7000000 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART0
        default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
                                DEBUG_S3C2410_UART0)
+       default 0xf7000400 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART1
+       default 0xf7000800 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART2
+       default 0xf7000c00 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART3
        default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
                                DEBUG_S3C2410_UART1)
        default 0xf7008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
@@ -1501,14 +1583,12 @@ config DEBUG_UART_VIRT
        default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
        default 0xfc40ab00 if DEBUG_BRCMSTB_UART
        default 0xfc705000 if DEBUG_ZTE_ZX
-       default 0xfcfe8600 if DEBUG_UART_BCM63XX
-       default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
-       default 0xfd000000 if ARCH_SPEAR13XX
-       default 0xfd012000 if ARCH_MV78XX0
+       default 0xfcfe8600 if DEBUG_BCM63XX_UART
+       default 0xfd000000 if DEBUG_SPEAR3XX || DEBUG_SPEAR13XX
+       default 0xfd012000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_MV78XX0
        default 0xfd883000 if DEBUG_ALPINE_UART0
-       default 0xfde12000 if ARCH_DOVE
-       default 0xfe012000 if ARCH_ORION5X
-       default 0xf31004c0 if DEBUG_MESON_UARTAO
+       default 0xfde12000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_DOVE
+       default 0xfe012000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_ORION5X
        default 0xfe017000 if DEBUG_MMP_UART2
        default 0xfe018000 if DEBUG_MMP_UART3
        default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
@@ -1522,7 +1602,7 @@ config DEBUG_UART_VIRT
        default 0xfeb31000 if DEBUG_KEYSTONE_UART1
        default 0xfec02000 if DEBUG_SOCFPGA_UART0
        default 0xfec02100 if DEBUG_SOCFPGA_UART1
-       default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
+       default 0xfec12000 if (DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE) && ARCH_MVEBU
        default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
        default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
        default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
@@ -1534,8 +1614,8 @@ config DEBUG_UART_VIRT
        default 0xfed60000 if DEBUG_RK29_UART0
        default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
        default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
-       default 0xfedc0000 if ARCH_EP93XX
-       default 0xfee003f8 if FOOTBRIDGE
+       default 0xfedc0000 if DEBUG_EP93XX
+       default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1
        default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
        default 0xfee82340 if ARCH_IOP13XX
        default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
@@ -1552,13 +1632,14 @@ config DEBUG_UART_VIRT
                DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
                DEBUG_NETX_UART || \
                DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
-               DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+               DEBUG_S3C64XX_UART || \
+               DEBUG_BCM63XX_UART || 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 DEBUG_FOOTBRIDGE_COM1 || ARCH_IOP32X || DEBUG_BCM_5301X || \
                DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || DEBUG_OMAP7XXUART3
        default 2
 
@@ -1566,8 +1647,9 @@ config DEBUG_UART_8250_WORD
        bool "Use 32-bit accesses for 8250 UART"
        depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
        depends on DEBUG_UART_8250_SHIFT >= 2
-       default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART0 || \
-               DEBUG_SOCFPGA_UART1 || ARCH_KEYSTONE || \
+       default y if DEBUG_PICOXCELL_UART || \
+               DEBUG_SOCFPGA_UART0 || DEBUG_SOCFPGA_UART1 || \
+               DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
                DEBUG_ALPINE_UART0 || \
                DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
                DEBUG_DAVINCI_DA8XX_UART2 || \
@@ -1577,7 +1659,7 @@ config DEBUG_UART_8250_WORD
 config DEBUG_UART_8250_FLOW_CONTROL
        bool "Enable flow control for 8250 UART"
        depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
-       default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_GEMINI || ARCH_RPC
+       default y if ARCH_EBSA110 || DEBUG_FOOTBRIDGE_COM1 || DEBUG_GEMINI || ARCH_RPC
 
 config DEBUG_UNCOMPRESS
        bool
index 2c2b28e..fe25410 100644 (file)
@@ -30,9 +30,8 @@ GZFLAGS               :=-9
 # Never generate .eh_frame
 KBUILD_CFLAGS  += $(call cc-option,-fno-dwarf2-cfi-asm)
 
-# Do not use arch/arm/defconfig - it's always outdated.
-# Select a platform tht is kept up-to-date
-KBUILD_DEFCONFIG := versatile_defconfig
+# This should work on most of the modern platforms
+KBUILD_DEFCONFIG := multi_v7_defconfig
 
 # defines filename extension depending memory management type.
 ifeq ($(CONFIG_MMU),)
@@ -211,6 +210,7 @@ machine-$(CONFIG_ARCH_SOCFPGA)              += socfpga
 machine-$(CONFIG_ARCH_STI)             += sti
 machine-$(CONFIG_ARCH_STM32)           += stm32
 machine-$(CONFIG_ARCH_SUNXI)           += sunxi
+machine-$(CONFIG_ARCH_TANGO)           += tango
 machine-$(CONFIG_ARCH_TEGRA)           += tegra
 machine-$(CONFIG_ARCH_U300)            += u300
 machine-$(CONFIG_ARCH_U8500)           += ux500
index 30bbc37..a4a6d70 100644 (file)
@@ -48,8 +48,10 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
        sama5d34ek.dtb \
        sama5d35ek.dtb \
        sama5d36ek.dtb \
+       at91-sama5d4_ma5d4evk.dtb \
        at91-sama5d4_xplained.dtb \
-       at91-sama5d4ek.dtb
+       at91-sama5d4ek.dtb \
+       at91-vinco.dtb
 dtb-$(CONFIG_ARCH_ATLAS6) += \
        atlas6-evb.dtb
 dtb-$(CONFIG_ARCH_ATLAS7) += \
@@ -60,7 +62,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
        bcm2835-rpi-b.dtb \
        bcm2835-rpi-b-rev2.dtb \
        bcm2835-rpi-b-plus.dtb \
-       bcm2835-rpi-a-plus.dtb
+       bcm2835-rpi-a-plus.dtb \
+       bcm2836-rpi-2-b.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm4708-asus-rt-ac56u.dtb \
        bcm4708-asus-rt-ac68u.dtb \
@@ -75,7 +78,10 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm4709-asus-rt-ac87u.dtb \
        bcm4709-buffalo-wxr-1900dhp.dtb \
        bcm4709-netgear-r7000.dtb \
-       bcm4709-netgear-r8000.dtb
+       bcm4709-netgear-r8000.dtb \
+       bcm94708.dtb \
+       bcm94709.dtb \
+       bcm953012k.dtb
 dtb-$(CONFIG_ARCH_BCM_63XX) += \
        bcm963138dvt.dtb
 dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
@@ -200,12 +206,14 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
        kirkwood-ns2mini.dtb \
        kirkwood-nsa310.dtb \
        kirkwood-nsa310a.dtb \
+       kirkwood-nsa325.dtb \
        kirkwood-openblocks_a6.dtb \
        kirkwood-openblocks_a7.dtb \
        kirkwood-openrd-base.dtb \
        kirkwood-openrd-client.dtb \
        kirkwood-openrd-ultimate.dtb \
        kirkwood-pogo_e02.dtb \
+       kirkwood-pogoplug-series-4.dtb \
        kirkwood-rd88f6192.dtb \
        kirkwood-rd88f6281-z0.dtb \
        kirkwood-rd88f6281-a.dtb \
@@ -268,7 +276,8 @@ dtb-$(CONFIG_SOC_IMX51) += \
        imx51-apf51dev.dtb \
        imx51-babbage.dtb \
        imx51-digi-connectcore-jsk.dtb \
-       imx51-eukrea-mbimxsd51-baseboard.dtb
+       imx51-eukrea-mbimxsd51-baseboard.dtb \
+       imx51-ts4800.dtb
 dtb-$(CONFIG_SOC_IMX53) += \
        imx53-ard.dtb \
        imx53-m53evk.dtb \
@@ -325,6 +334,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
        imx6q-hummingboard.dtb \
        imx6q-nitrogen6x.dtb \
        imx6q-nitrogen6_max.dtb \
+       imx6q-novena.dtb \
        imx6q-phytec-pbab01.dtb \
        imx6q-rex-pro.dtb \
        imx6q-sabreauto.dtb \
@@ -350,6 +360,8 @@ dtb-$(CONFIG_SOC_IMX6SX) += \
 dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ul-14x14-evk.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
+       imx7d-cl-som-imx7.dtb \
+       imx7d-sbc-imx7.dtb \
        imx7d-sdb.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
        ls1021a-qds.dtb \
@@ -359,6 +371,7 @@ dtb-$(CONFIG_SOC_VF610) += \
        vf610-colibri-eval-v3.dtb \
        vf610m4-colibri.dtb \
        vf610-cosmic.dtb \
+       vf610m4-cosmic.dtb \
        vf610-twr.dtb
 dtb-$(CONFIG_ARCH_MXS) += \
        imx23-evk.dtb \
@@ -452,20 +465,24 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
 dtb-$(CONFIG_SOC_TI81XX) += \
        dm8148-evm.dtb \
        dm8148-t410.dtb \
-       dm8168-evm.dtb
+       dm8168-evm.dtb \
+       dra62x-j5eco-evm.dtb
 dtb-$(CONFIG_SOC_AM33XX) += \
        am335x-baltos-ir5221.dtb \
        am335x-base0033.dtb \
        am335x-bone.dtb \
        am335x-boneblack.dtb \
        am335x-bonegreen.dtb \
-       am335x-sl50.dtb \
+       am335x-chiliboard.dtb \
+       am335x-cm-t335.dtb \
        am335x-evm.dtb \
        am335x-evmsk.dtb \
+       am335x-lxm.dtb \
        am335x-nano.dtb \
        am335x-pepper.dtb \
-       am335x-lxm.dtb \
-       am335x-chiliboard.dtb \
+       am335x-shc.dtb \
+       am335x-sbc-t335.dtb \
+       am335x-sl50.dtb \
        am335x-wega-rdk.dtb
 dtb-$(CONFIG_ARCH_OMAP4) += \
        omap4-duovero-parlor.dtb \
@@ -478,17 +495,21 @@ dtb-$(CONFIG_ARCH_OMAP4) += \
        omap4-var-stk-om44.dtb
 dtb-$(CONFIG_SOC_AM43XX) += \
        am43x-epos-evm.dtb \
-       am437x-sk-evm.dtb \
+       am437x-cm-t43.dtb \
+       am437x-gp-evm.dtb \
        am437x-idk-evm.dtb \
-       am437x-gp-evm.dtb
+       am437x-sbc-t43.dtb \
+       am437x-sk-evm.dtb
 dtb-$(CONFIG_SOC_OMAP5) += \
        omap5-cm-t54.dtb \
        omap5-igep0050.dtb \
        omap5-sbc-t54.dtb \
        omap5-uevm.dtb
 dtb-$(CONFIG_SOC_DRA7XX) += \
-       dra7-evm.dtb \
        am57xx-beagle-x15.dtb \
+       am57xx-cl-som-am57x.dtb \
+       am57xx-sbc-am57x.dtb \
+       dra7-evm.dtb \
        dra72-evm.dtb
 dtb-$(CONFIG_ARCH_ORION5X) += \
        orion5x-lacie-d2-network.dtb \
@@ -502,6 +523,7 @@ dtb-$(CONFIG_ARCH_PRIMA2) += \
 dtb-$(CONFIG_ARCH_QCOM) += \
        qcom-apq8064-cm-qs600.dtb \
        qcom-apq8064-ifc6410.dtb \
+       qcom-apq8064-sony-xperia-yuga.dtb \
        qcom-apq8074-dragonboard.dtb \
        qcom-apq8084-ifc6540.dtb \
        qcom-apq8084-mtp.dtb \
@@ -510,12 +532,16 @@ dtb-$(CONFIG_ARCH_QCOM) += \
        qcom-msm8960-cdp.dtb \
        qcom-msm8974-sony-xperia-honami.dtb
 dtb-$(CONFIG_ARCH_REALVIEW) += \
-       arm-realview-pb1176.dtb
+       arm-realview-pb1176.dtb \
+       arm-realview-pb11mp.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+       rk3036-evb.dtb \
+       rk3036-kylin.dtb \
        rk3066a-bqcurie2.dtb \
        rk3066a-marsboard.dtb \
        rk3066a-rayeager.dtb \
        rk3188-radxarock.dtb \
+       rk3228-evb.dtb \
        rk3288-evb-act8846.dtb \
        rk3288-evb-rk808.dtb \
        rk3288-firefly-beta.dtb \
@@ -523,8 +549,10 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3288-popmetal.dtb \
        rk3288-r89.dtb \
        rk3288-rock2-square.dtb \
+       rk3288-veyron-brain.dtb \
        rk3288-veyron-jaq.dtb \
        rk3288-veyron-jerry.dtb \
+       rk3288-veyron-mickey.dtb \
        rk3288-veyron-minnie.dtb \
        rk3288-veyron-pinky.dtb \
        rk3288-veyron-speedy.dtb
@@ -547,7 +575,6 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
        r8a7778-bockw.dtb \
        r8a7779-marzen.dtb \
        r8a7790-lager.dtb \
-       r8a7791-henninger.dtb \
        r8a7791-koelsch.dtb \
        r8a7791-porter.dtb \
        r8a7793-gose.dtb \
@@ -557,6 +584,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
 dtb-$(CONFIG_ARCH_SOCFPGA) += \
        socfpga_arria5_socdk.dtb \
        socfpga_arria10_socdk_sdmmc.dtb \
+       socfpga_cyclone5_mcvevk.dtb \
        socfpga_cyclone5_socdk.dtb \
        socfpga_cyclone5_de0_sockit.dtb \
        socfpga_cyclone5_sockit.dtb \
@@ -612,6 +640,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
        sun5i-a10s-olinuxino-micro.dtb \
        sun5i-a10s-r7-tv-dongle.dtb \
        sun5i-a10s-wobo-i5.dtb \
+       sun5i-a13-empire-electronix-d709.dtb \
        sun5i-a13-hsg-h702.dtb \
        sun5i-a13-inet-98v-rev2.dtb \
        sun5i-a13-olinuxino.dtb \
@@ -638,6 +667,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
        sun7i-a20-cubietruck.dtb \
        sun7i-a20-hummingbird.dtb \
        sun7i-a20-i12-tvbox.dtb \
+       sun7i-a20-icnova-swac.dtb \
        sun7i-a20-m3.dtb \
        sun7i-a20-mk808c.dtb \
        sun7i-a20-olimex-som-evb.dtb \
@@ -660,10 +690,13 @@ dtb-$(CONFIG_MACH_SUN8I) += \
        sun8i-a33-ga10h-v1.1.dtb \
        sun8i-a33-ippo-q8h-v1.2.dtb \
        sun8i-a33-q8-tablet.dtb \
-       sun8i-a33-sinlinx-sina33.dtb
+       sun8i-a33-sinlinx-sina33.dtb \
+       sun8i-h3-orangepi-plus.dtb
 dtb-$(CONFIG_MACH_SUN9I) += \
        sun9i-a80-optimus.dtb \
        sun9i-a80-cubieboard4.dtb
+dtb-$(CONFIG_ARCH_TANGO) += \
+       tango4-vantage-1172.dtb
 dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
        tegra20-harmony.dtb \
        tegra20-iris-512.dtb \
@@ -748,6 +781,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
        armada-385-db-ap.dtb \
        armada-385-linksys-caiman.dtb \
        armada-385-linksys-cobra.dtb \
+       armada-388-clearfog.dtb \
        armada-388-db.dtb \
        armada-388-gp.dtb \
        armada-388-rd.dtb
@@ -771,6 +805,7 @@ dtb-$(CONFIG_MACH_DOVE) += \
        dove-dove-db.dtb \
        dove-sbc-a510.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += \
+       mt2701-evb.dtb \
        mt6580-evbp1.dtb \
        mt6589-aquaris5.dtb \
        mt6592-evb.dtb \
index 7d36601..ded1eb6 100644 (file)
 &am33xx_pinmux {
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x020 (PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad8.mmc1_dat0_mux0 */
-                       0x024 (PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad9.mmc1_dat1_mux0 */
-                       0x028 (PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad10.mmc1_dat2_mux0 */
-                       0x02c (PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad11.mmc1_dat3_mux0 */
-                       0x080 (PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_csn1.mmc1_clk_mux0 */
-                       0x084 (PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_csn2.mmc1_cmd_mux0 */
-                       0x1e4 (PIN_INPUT_PULLUP | MUX_MODE7)      /* emu0.gpio3[7] */
+                       AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad8.mmc1_dat0_mux0 */
+                       AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad9.mmc1_dat1_mux0 */
+                       AM33XX_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad10.mmc1_dat2_mux0 */
+                       AM33XX_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_ad11.mmc1_dat3_mux0 */
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_csn1.mmc1_clk_mux0 */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2)      /* gpmc_csn2.mmc1_cmd_mux0 */
+                       AM33XX_IOPAD(0x9e4, PIN_INPUT_PULLUP | MUX_MODE7)      /* emu0.gpio3[7] */
                >;
        };
 
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0x1e8 (PIN_OUTPUT_PULLUP | MUX_MODE7)      /* emu1.gpio3[8] */
+                       AM33XX_IOPAD(0x9e8, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* emu1.gpio3[8] */
                >;
        };
 
        tps65910_pins: pinmux_tps65910_pins {
                pinctrl-single,pins = <
-                       0x078 (PIN_INPUT_PULLUP | MUX_MODE7)      /* gpmc_ben1.gpio1[28] */
+                       AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE7)      /* gpmc_ben1.gpio1[28] */
                >;
        };
 
        tca6416_pins: pinmux_tca6416_pins {
                pinctrl-single,pins = <
-                       0x1b4 (PIN_INPUT_PULLUP | MUX_MODE7)      /* xdma_event_intr1.gpio0[20] tca6416 stuff */
+                       AM33XX_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE7)      /* xdma_event_intr1.gpio0[20] tca6416 stuff */
                >;
        };
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0x158 0x2a      /* spi0_d1.i2c1_sda_mux3, INPUT | MODE2 */
-                       0x15c 0x2a      /* spi0_cs0.i2c1_scl_mux3, INPUT | MODE2 */
+                       AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE2)      /* spi0_d1.i2c1_sda_mux3 */
+                       AM33XX_IOPAD(0x95c, PIN_INPUT | MUX_MODE2)      /* spi0_cs0.i2c1_scl_mux3 */
                >;
        };
 
        dcan1_pins: pinmux_dcan1_pins {
                pinctrl-single,pins = <
-                       0x168 0x0a      /* uart0_ctsn.dcan1_tx_mux0, OUTPUT | MODE2 */
-                       0x16c 0x2a      /* uart0_rtsn.dcan1_rx_mux0, INPUT | MODE2 */
+                       AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE2)      /* uart0_ctsn.dcan1_tx_mux0 */
+                       AM33XX_IOPAD(0x96c, PIN_INPUT | MUX_MODE2)      /* uart0_rtsn.dcan1_rx_mux0 */
                >;
        };
 
        uart0_pins: pinmux_uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)         /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)            /* uart0_txd.uart0_txd */
                >;
        };
 
        uart1_pins: pinmux_uart1_pins {
                pinctrl-single,pins = <
-                       0x180 0x28      /* uart1_rxd, INPUT | MODE0 */
-                       0x184 0x28      /* uart1_txd, INPUT | MODE0 */
-                       /*0x178 0x28*/      /* uart1_ctsn, INPUT | MODE0 */
-                       /*0x17c 0x08*/      /* uart1_rtsn, OUTPUT | MODE0 */
-                       0x178 (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* uart1_ctsn, INPUT | MODE0 */
-                       0x17c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* uart1_rtsn, OUTPUT | MODE0 */
-                       0x0e0 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* lcd_vsync.gpio2[22] DTR */
-                       0x0e4 (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* lcd_hsync.gpio2[23] DSR */
-                       0x0e8 (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* lcd_pclk.gpio2[24] DCD */
-                       0x0ec (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* lcd_ac_bias_en.gpio2[25] RI */
+                       AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE0)      /* uart1_rxd */
+                       AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE0)      /* uart1_txd */
+                       AM33XX_IOPAD(0x978, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* uart1_ctsn, INPUT | MODE0 */
+                       AM33XX_IOPAD(0x97c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* uart1_rtsn, OUTPUT | MODE0 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* lcd_vsync.gpio2[22] DTR */
+                       AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* lcd_hsync.gpio2[23] DSR */
+                       AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* lcd_pclk.gpio2[24] DCD */
+                       AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* lcd_ac_bias_en.gpio2[25] RI */
                >;
        };
 
        uart2_pins: pinmux_uart2_pins {
                pinctrl-single,pins = <
-                       0x150 0x29      /* spi0_sclk.uart2_rxd_mux3, INPUT | MODE1 */
-                       0x154 0x09      /* spi0_d0.uart2_txd_mux3, OUTPUT | MODE1 */
-                       /*0x188 0x2a*/      /* i2c0_sda.uart2_ctsn_mux0, INPUT | MODE2 */
-                       /*0x18c 0x2a*/      /* i2c0_scl.uart2_rtsn_mux0, INPUT | MODE2 */
-                       0x188 (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* i2c0_sda.uart2_ctsn_mux0 */
-                       0x18c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* i2c0_scl.uart2_rtsn_mux0 */
-                       0x030 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* gpmc_ad12.gpio1[12] DTR */
-                       0x034 (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* gpmc_ad13.gpio1[13] DSR */
-                       0x038 (PIN_INPUT_PULLDOWN | MUX_MODE7)      /* gpmc_ad14.gpio1[14] DCD */
-                       0x03c (PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad15.gpio1[15] RI */
-
-                       0x1a0 (PIN_INPUT_PULLUP | MUX_MODE7)      /* mcasp0_aclkr.gpio3[18], INPUT_PULLDOWN | MODE7 */
+                       AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)      /* spi0_sclk.uart2_rxd_mux3 */
+                       AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)      /* spi0_d0.uart2_txd_mux3 */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* i2c0_sda.uart2_ctsn_mux0 */
+                       AM33XX_IOPAD(0x98c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* i2c0_scl.uart2_rtsn_mux0 */
+                       AM33XX_IOPAD(0x830, PIN_OUTPUT_PULLDOWN | MUX_MODE7)      /* gpmc_ad12.gpio1[12] DTR */
+                       AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* gpmc_ad13.gpio1[13] DSR */
+                       AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7)      /* gpmc_ad14.gpio1[14] DCD */
+                       AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad15.gpio1[15] RI */
+
+                       AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7)      /* mcasp0_aclkr.gpio3[18], INPUT_PULLDOWN | MODE7 */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)       /* mii1_crs.rmii1_crs_dv */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_tx_en.rmii1_txen */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd1.rmii1_txd1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd0.rmii1_txd0 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd1.rmii1_rxd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd0.rmii1_rxd0 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)      /* rmii1_ref_clk.rmii1_refclk */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)       /* mii1_crs.rmii1_crs_dv */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_tx_en.rmii1_txen */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd1.rmii1_txd1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd0.rmii1_txd0 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd1.rmii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd0.rmii1_rxd0 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* rmii1_ref_clk.rmii1_refclk */
 
 
                        /* Slave 2 */
-                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a0.rgmii2_tctl */
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a1.rgmii2_rctl */
-                       0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a2.rgmii2_td3 */
-                       0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a3.rgmii2_td2 */
-                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a4.rgmii2_td1 */
-                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a5.rgmii2_td0 */
-                       0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a6.rgmii2_tclk */
-                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a7.rgmii2_rclk */
-                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a8.rgmii2_rd3 */
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a9.rgmii2_rd2 */
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a10.rgmii2_rd1 */
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a11.rgmii2_rd0 */
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a0.rgmii2_tctl */
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a1.rgmii2_rctl */
+                       AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a2.rgmii2_td3 */
+                       AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a3.rgmii2_td2 */
+                       AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a4.rgmii2_td1 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a5.rgmii2_td0 */
+                       AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a6.rgmii2_tclk */
+                       AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a7.rgmii2_rclk */
+                       AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a8.rgmii2_rd3 */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a9.rgmii2_rd2 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a10.rgmii2_rd1 */
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a11.rgmii2_rd0 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
 
                        /* Slave 2 reset value*/
-                       0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        nandflash_pins_s0: nandflash_pins_s0 {
                pinctrl-single,pins = <
-                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
-                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
-                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
-                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
-                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_wpn.gpio0_30 */
-                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
-                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad0.gpmc_ad0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad1.gpmc_ad1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad2.gpmc_ad2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad3.gpmc_ad3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad4.gpmc_ad4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad5.gpmc_ad5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad6.gpmc_ad6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad7.gpmc_ad7 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7)       /* gpmc_wpn.gpio0_30 */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn0.gpmc_csn0  */
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)             /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)             /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)             /* gpmc_wen.gpmc_wen */
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_be0n_cle.gpmc_be0n_cle */
                >;
        };
 };
index 5d370d5..f3db13d 100644 (file)
 
        user_leds_s0: user_leds_s0 {
                pinctrl-single,pins = <
-                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
-                       0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a6.gpio1_22 */
-                       0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a7.gpio1_23 */
-                       0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a8.gpio1_24 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a5.gpio1_21 */
+                       AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_a6.gpio1_22 */
+                       AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a7.gpio1_23 */
+                       AM33XX_IOPAD(0x860, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_a8.gpio1_24 */
                >;
        };
 
        i2c0_pins: pinmux_i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
                >;
        };
 
        i2c2_pins: pinmux_i2c2_pins {
                pinctrl-single,pins = <
-                       0x178 (PIN_INPUT_PULLUP | MUX_MODE3)    /* uart1_ctsn.i2c2_sda */
-                       0x17c (PIN_INPUT_PULLUP | MUX_MODE3)    /* uart1_rtsn.i2c2_scl */
+                       AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3)       /* uart1_ctsn.i2c2_sda */
+                       AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3)       /* uart1_rtsn.i2c2_scl */
                >;
        };
 
        uart0_pins: pinmux_uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
                >;
        };
 
        clkout2_pin: pinmux_clkout2_pin {
                pinctrl-single,pins = <
-                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+                       AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr1.clkout2 */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x110 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxerr.mii1_rxerr */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */
-                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxdv.mii1_rxdv */
-                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */
-                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */
-                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_txclk.mii1_txclk */
-                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxclk.mii1_rxclk */
-                       0x134 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd3.mii1_rxd3 */
-                       0x138 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd2.mii1_rxd2 */
-                       0x13c (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd1.mii1_rxd1 */
-                       0x140 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd0.mii1_rxd0 */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxerr.mii1_rxerr */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txen.mii1_txen */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxdv.mii1_rxdv */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd3.mii1_txd3 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd2.mii1_txd2 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd1.mii1_txd1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd0.mii1_txd0 */
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_txclk.mii1_txclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxclk.mii1_rxclk */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxd3.mii1_rxd3 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxd2.mii1_rxd2 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxd1.mii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE0)       /* mii1_rxd0.mii1_rxd0 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x160 (PIN_INPUT | MUX_MODE7) /* GPIO0_6 */
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* GPIO0_6 */
                >;
        };
 
        emmc_pins: pinmux_emmc_pins {
                pinctrl-single,pins = <
-                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
-                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
-                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
-                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
-                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
-                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
                >;
        };
 };
        };
 };
 
-
-/include/ "tps65217.dtsi"
-
 &tps {
+       compatible = "ti,tps65217";
        /*
         * Configure pmic to enter OFF-state instead of SLEEP-state ("RTC-only
         * mode") at poweroff.  Most BeagleBone versions do not support RTC-only
        ti,pmic-shutdown-controller;
 
        regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                dcdc1_reg: regulator@0 {
+                       reg = <0>;
                        regulator-name = "vdds_dpr";
                        regulator-always-on;
                };
 
                dcdc2_reg: regulator@1 {
+                       reg = <1>;
                        /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
                        regulator-name = "vdd_mpu";
                        regulator-min-microvolt = <925000>;
                };
 
                dcdc3_reg: regulator@2 {
+                       reg = <2>;
                        /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
                        regulator-name = "vdd_core";
                        regulator-min-microvolt = <925000>;
                };
 
                ldo1_reg: regulator@3 {
+                       reg = <3>;
                        regulator-name = "vio,vrtc,vdds";
                        regulator-always-on;
                };
 
                ldo2_reg: regulator@4 {
+                       reg = <4>;
                        regulator-name = "vdd_3v3aux";
                        regulator-always-on;
                };
 
                ldo3_reg: regulator@5 {
+                       reg = <5>;
                        regulator-name = "vdd_1v8";
                        regulator-always-on;
                };
 
                ldo4_reg: regulator@6 {
+                       reg = <6>;
                        regulator-name = "vdd_3v3a";
                        regulator-always-on;
                };
index eadbba3..55c0e95 100644 (file)
 &am33xx_pinmux {
        nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
                pinctrl-single,pins = <
-                       0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
-                       0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xa8 0x08       /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xac 0x08       /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xb0 0x08       /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xb4 0x08       /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xb8 0x08       /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xbc 0x08       /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xc0 0x08       /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xc4 0x08       /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xc8 0x08       /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xcc 0x08       /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xd0 0x08       /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xd4 0x08       /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xd8 0x08       /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xdc 0x08       /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
-                       0xe0 0x00       /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
-                       0xe4 0x00       /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
-                       0xe8 0x00       /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
-                       0xec 0x00       /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+                       AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr0 */
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)             /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_ac_bias_en.lcd_ac_bias_en */
                >;
        };
        nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
                pinctrl-single,pins = <
-                       0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+                       AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr0 */
                >;
        };
 };
index 0f65bda..dce3c86 100644 (file)
@@ -36,8 +36,8 @@
 &am33xx_pinmux {
        uart2_pins: uart2_pins {
                pinctrl-single,pins = <
-                       0x150 (PIN_INPUT | MUX_MODE1)   /* spi0_sclk.uart2_rxd */
-                       0x154 (PIN_OUTPUT | MUX_MODE1)  /* spi0_d0.uart2_txd */
+                       AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)      /* spi0_sclk.uart2_rxd */
+                       AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)     /* spi0_d0.uart2_txd */
                >;
        };
 };
index 310da20..15d47ab 100644 (file)
 &am33xx_pinmux {
        usb1_drvvbus: usb1_drvvbus {
                pinctrl-single,pins = <
-                       0x234 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usb1_drvvbus.usb1_drvvbus */
+                       AM33XX_IOPAD(0xa34, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usb1_drvvbus.usb1_drvvbus */
                >;
        };
 
        sd_pins: pinmux_sd_card {
                pinctrl-single,pins = <
-                       0xf0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
-                       0xf4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
-                       0xf8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
-                       0xfc (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
-                       0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
-                       0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
-                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+                       AM33XX_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+                       AM33XX_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                >;
        };
 
        led_gpio_pins: led_gpio_pins {
                pinctrl-single,pins = <
-                       0x1e4 (PIN_OUTPUT | MUX_MODE7) /* emu0.gpio3_7 */
-                       0x1e8 (PIN_OUTPUT | MUX_MODE7) /* emu1.gpio3_8 */
+                       AM33XX_IOPAD(0x9e4, PIN_OUTPUT | MUX_MODE7) /* emu0.gpio3_7 */
+                       AM33XX_IOPAD(0x9e8, PIN_OUTPUT | MUX_MODE7) /* emu1.gpio3_8 */
                >;
        };
 };
index 7e9a34d..fda457b 100644 (file)
 
        i2c0_pins: pinmux_i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
                >;
        };
 
        uart0_pins: pinmux_uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs */
-                       0x110 (PIN_INPUT_PULLUP | MUX_MODE1)    /* mii1_rxerr.rmii1_rxerr */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
-                       0x13c (PIN_INPUT_PULLUP | MUX_MODE1)    /* mii1_rxd1.rmii1_rxd1 */
-                       0x140 (PIN_INPUT_PULLUP | MUX_MODE1)    /* mii1_rxd0.rmii1_rxd0 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* rmii1_ref_clk.rmii_ref_clk */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1)       /* mii1_rxerr.rmii1_rxerr */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txen.rmii1_txen */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txd1.rmii1_txd1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txd0.rmii1_txd0 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1)       /* mii1_rxd1.rmii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1)       /* mii1_rxd0.rmii1_rxd0 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* rmii1_ref_clk.rmii_ref_clk */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* mdio_data.mdio_data */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
                        /* mdio_clk.mdio_clk */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        nandflash_pins: nandflash_pins {
                pinctrl-single,pins = <
-                       0x00 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad0.gpmc_ad0 */
-                       0x04 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad1.gpmc_ad1 */
-                       0x08 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad2.gpmc_ad2 */
-                       0x0c (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad3.gpmc_ad3 */
-                       0x10 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad4.gpmc_ad4 */
-                       0x14 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad5.gpmc_ad5 */
-                       0x18 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad6.gpmc_ad6 */
-                       0x1c (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad7.gpmc_ad7 */
-
-                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                       0x7c (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* gpmc_csn0.gpmc_csn0 */
-                       0x90 (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* gpmc_advn_ale.gpmc_advn_ale */
-                       0x94 (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* gpmc_oen_ren.gpmc_oen_ren */
-                       0x98 (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* gpmc_wen.gpmc_wen */
-                       0x9c (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* gpmc_be0n_cle.gpmc_be0n_cle */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad0.gpmc_ad0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad1.gpmc_ad1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad2.gpmc_ad2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad3.gpmc_ad3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE0)      /* gpmc_csn0.gpmc_csn0 */
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT_PULLUP | MUX_MODE0)      /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT_PULLUP | MUX_MODE0)      /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT_PULLUP | MUX_MODE0)      /* gpmc_wen.gpmc_wen */
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT_PULLUP | MUX_MODE0)      /* gpmc_be0n_cle.gpmc_be0n_cle */
                >;
        };
 };
 
 };
 
-/include/ "tps65217.dtsi"
-
 &tps {
+       compatible = "ti,tps65217";
+
        regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                dcdc1_reg: regulator@0 {
+                       reg = <0>;
                        regulator-name = "vdds_dpr";
                        regulator-always-on;
                };
 
                dcdc2_reg: regulator@1 {
+                       reg = <1>;
                        /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
                        regulator-name = "vdd_mpu";
                        regulator-min-microvolt = <925000>;
                };
 
                dcdc3_reg: regulator@2 {
+                       reg = <2>;
                        /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
                        regulator-name = "vdd_core";
                        regulator-min-microvolt = <925000>;
                };
 
                ldo1_reg: regulator@3 {
+                       reg = <3>;
                        regulator-name = "vio,vrtc,vdds";
                        regulator-boot-on;
                        regulator-always-on;
                };
 
                ldo2_reg: regulator@4 {
+                       reg = <4>;
                        regulator-name = "vdd_3v3aux";
                        regulator-boot-on;
                        regulator-always-on;
                };
 
                ldo3_reg: regulator@5 {
+                       reg = <5>;
                        regulator-name = "vdd_1v8";
                        regulator-boot-on;
                        regulator-always-on;
                };
 
                ldo4_reg: regulator@6 {
+                       reg = <6>;
                        regulator-name = "vdd_3v3d";
                        regulator-boot-on;
                        regulator-always-on;
diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts
new file mode 100644 (file)
index 0000000..42e9b66
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * am335x-cm-t335.dts - Device Tree file for Compulab CM-T335
+ *
+ * Copyright (C) 2014 - 2015 CompuLab Ltd. - http://www.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.
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+       model = "CompuLab CM-T335";
+       compatible = "compulab,cm-t335", "ti,am33xx";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x8000000>;   /* 128 MB */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_led_pins>;
+               led@0 {
+                       label = "cm_t335:green";
+                       gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;     /* gpio2_0 */
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       /* regulator for mmc */
+       vmmc_fixed: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmc_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&ecap0 0 50000 0>;
+               brightness-levels = <0 51 53 56 62 75 101 152 255>;
+               default-brightness-level = <8>;
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&bluetooth_pins>;
+
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       /* uart0_ctsn.i2c1_sda */
+                       AM33XX_IOPAD(0x968, PIN_INPUT_PULLUP | MUX_MODE2)
+                       /* uart0_rtsn.i2c1_scl */
+                       AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE2)
+               >;
+       };
+
+       gpio_led_pins: pinmux_gpio_led_pins {
+               pinctrl-single,pins = <
+                       /* gpmc_csn3.gpio2_0 */
+                       AM33XX_IOPAD(0x888, PIN_OUTPUT | MUX_MODE7)
+               >;
+       };
+
+       nandflash_pins: pinmux_nandflash_pins {
+               pinctrl-single,pins = <
+                       /* gpmc_ad0.gpmc_ad0 */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad1.gpmc_ad1 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad2.gpmc_ad2 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad3.gpmc_ad3 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad4.gpmc_ad4 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad5.gpmc_ad5 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad6.gpmc_ad6 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_ad7.gpmc_ad7 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_wait0.gpmc_wait0 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* gpmc_wpn.gpio0_30 */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7)
+                       /* gpmc_csn0.gpmc_csn0  */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)
+                       /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)
+                       /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)
+                       /* gpmc_wen.gpmc_wen */
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)
+                       /* gpmc_ben0_cle.gpmc_ben0_cle */
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                       /* uart1_ctsn.uart1_ctsn */
+                       AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0)
+                       /* uart1_rtsn.uart1_rtsn */
+                       AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       /* uart1_rxd.uart1_rxd */
+                       AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* uart1_txd.uart1_txd */
+                       AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+
+       ecap0_pins: pinmux_ecap0_pins {
+               pinctrl-single,pins = <
+                       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+                       AM33XX_IOPAD(0x964, 0x0)
+               >;
+       };
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       /* mii1_tx_en.rgmii1_tctl */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_rxdv.rgmii1_rctl */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_txd3.rgmii1_td3 */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_txd2.rgmii1_td2 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_txd1.rgmii1_td1 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_txd0.rgmii1_td0 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_txclk.rgmii1_tclk */
+                       AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_rxclk.rgmii1_rclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_rxd3.rgmii1_rd3 */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_rxd2.rgmii1_rd2 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_rxd1.rgmii1_rd1 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)
+                       /* mii1_rxd0.rgmii1_rd0 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)
+               >;
+       };
+
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+                       /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       /* mmc0_dat3.mmc0_dat3 */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* mmc0_dat2.mmc0_dat2 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* mmc0_dat1.mmc0_dat1 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* mmc0_dat0.mmc0_dat0 */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* mmc0_clk.mmc0_clk */
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)
+                       /* mmc0_cmd.mmc0_cmd */
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       /* wl1271 bluetooth */
+       bluetooth_pins: pinmux_bluetooth_pins {
+               pinctrl-single,pins = <
+                       /* XDMA_EVENT_INTR0.gpio0_19 - bluetooth enable */
+                       AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7)
+               >;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+
+       status = "okay";
+};
+
+/* WLS1271 bluetooth */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+
+status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       status = "okay";
+       clock-frequency = <400000>;
+       /* CM-T335 board EEPROM */
+       eeprom: 24c02@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+       /* Real Time Clock */
+       ext_rtc: em3027@56 {
+               compatible = "emmicro,em3027";
+               reg = <0x56>;
+       };
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_ctrl_mod {
+       status = "okay";
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&cppi41dma  {
+       status = "okay";
+};
+
+&epwmss0 {
+       status = "okay";
+
+       ecap0: ecap@48300100 {
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&ecap0_pins>;
+       };
+};
+
+&gpmc {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&nandflash_pins>;
+       ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
+       nand@0,0 {
+               reg = <0 0 0>; /* CS0, offset 0 */
+               ti,nand-ecc-opt = "bch8";
+               ti,elm-id = <&elm>;
+               nand-bus-width = <8>;
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,wait-on-read = "true";
+               gpmc,wait-on-write = "true";
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+               /* MTD partition table */
+               #address-cells = <1>;
+               #size-cells = <1>;
+               partition@0 {
+                       label = "spl";
+                       reg = <0x00000000 0x00200000>;
+               };
+               partition@1 {
+                       label = "uboot";
+                       reg = <0x00200000 0x00100000>;
+               };
+               partition@2 {
+                       label = "uboot environment";
+                       reg = <0x00300000 0x00100000>;
+               };
+               partition@3 {
+                       label = "dtb";
+                       reg = <0x00400000 0x00100000>;
+               };
+               partition@4 {
+                       label = "splash";
+                       reg = <0x00500000 0x00400000>;
+               };
+               partition@5 {
+                       label = "linux";
+                       reg = <0x00900000 0x00600000>;
+               };
+               partition@6 {
+                       label = "rootfs";
+                       reg = <0x00F00000 0>;
+               };
+       };
+};
+
+&elm {
+       status = "okay";
+};
+
+&mac {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_default>;
+       pinctrl-1 = <&cpsw_sleep>;
+       slaves = <1>;
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_default>;
+       pinctrl-1 = <&davinci_mdio_sleep>;
+       status = "okay";
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       phy-mode = "rgmii-txid";
+};
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&vmmc_fixed>;
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+};
index d9d00ab..0d6a68c 100644 (file)
                        label = "volume-up";
                        linux,code = <115>;
                        gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                switch@10 {
                        label = "volume-down";
                        linux,code = <114>;
                        gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
 
        matrix_keypad_s0: matrix_keypad_s0 {
                pinctrl-single,pins = <
-                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a5.gpio1_21 */
-                       0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a6.gpio1_22 */
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a9.gpio1_25 */
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a10.gpio1_26 */
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a11.gpio1_27 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a5.gpio1_21 */
+                       AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a6.gpio1_22 */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a9.gpio1_25 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a10.gpio1_26 */
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a11.gpio1_27 */
                >;
        };
 
        volume_keys_s0: volume_keys_s0 {
                pinctrl-single,pins = <
-                       0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* spi0_sclk.gpio0_2 */
-                       0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* spi0_d0.gpio0_3 */
+                       AM33XX_IOPAD(0x950, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* spi0_sclk.gpio0_2 */
+                       AM33XX_IOPAD(0x954, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* spi0_d0.gpio0_3 */
                >;
        };
 
        i2c0_pins: pinmux_i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
                >;
        };
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0x158 (PIN_INPUT_PULLUP | MUX_MODE2)    /* spi0_d1.i2c1_sda */
-                       0x15c (PIN_INPUT_PULLUP | MUX_MODE2)    /* spi0_cs0.i2c1_scl */
+                       AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE2)       /* spi0_d1.i2c1_sda */
+                       AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE2)       /* spi0_cs0.i2c1_scl */
                >;
        };
 
        uart0_pins: pinmux_uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
                >;
        };
 
        uart1_pins: pinmux_uart1_pins {
                pinctrl-single,pins = <
-                       0x178 (PIN_INPUT | MUX_MODE0)           /* uart1_ctsn.uart1_ctsn */
-                       0x17C (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
-                       0x180 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_rxd.uart1_rxd */
-                       0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
+                       AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0)              /* uart1_ctsn.uart1_ctsn */
+                       AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_rtsn.uart1_rtsn */
+                       AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart1_rxd.uart1_rxd */
+                       AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_txd.uart1_txd */
                >;
        };
 
        clkout2_pin: pinmux_clkout2_pin {
                pinctrl-single,pins = <
-                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+                       AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr1.clkout2 */
                >;
        };
 
        nandflash_pins_s0: nandflash_pins_s0 {
                pinctrl-single,pins = <
-                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
-                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
-                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
-                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
-                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_wpn.gpio0_30 */
-                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
-                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad0.gpmc_ad0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad1.gpmc_ad1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad2.gpmc_ad2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad3.gpmc_ad3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad4.gpmc_ad4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad5.gpmc_ad5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad6.gpmc_ad6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad7.gpmc_ad7 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7)       /* gpmc_wpn.gpio0_30 */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn0.gpmc_csn0  */
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)             /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)             /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)             /* gpmc_wen.gpmc_wen */
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_be0n_cle.gpmc_be0n_cle */
                >;
        };
 
        ecap0_pins: backlight_pins {
                pinctrl-single,pins = <
-                       0x164 0x0       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+                       AM33XX_IOPAD(0x964, MUX_MODE0)  /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
-                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
-                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
-                       0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rgmii1_rclk */
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd3.rgmii1_rd3 */
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd2.rgmii1_rd2 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_tctl */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxdv.rgmii1_rctl */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd3.rgmii1_td3 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd2.rgmii1_td2 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_td1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_td0 */
+                       AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rgmii1_tclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxclk.rgmii1_rclk */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd3.rgmii1_rd3 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd2.rgmii1_rd2 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rd0 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                >;
        };
 
        mmc3_pins: pinmux_mmc3_pins {
                pinctrl-single,pins = <
-                       0x44 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a1.mmc2_dat0, INPUT_PULLUP | MODE3 */
-                       0x48 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a2.mmc2_dat1, INPUT_PULLUP | MODE3 */
-                       0x4C (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a3.mmc2_dat2, INPUT_PULLUP | MODE3 */
-                       0x78 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_ben1.mmc2_dat3, INPUT_PULLUP | MODE3 */
-                       0x88 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_csn3.mmc2_cmd, INPUT_PULLUP | MODE3 */
-                       0x8C (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_clk.mmc2_clk, INPUT_PULLUP | MODE3 */
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_a1.mmc2_dat0, INPUT_PULLUP | MODE3 */
+                       AM33XX_IOPAD(0x848, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_a2.mmc2_dat1, INPUT_PULLUP | MODE3 */
+                       AM33XX_IOPAD(0x84c, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_a3.mmc2_dat2, INPUT_PULLUP | MODE3 */
+                       AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_ben1.mmc2_dat3, INPUT_PULLUP | MODE3 */
+                       AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_csn3.mmc2_cmd, INPUT_PULLUP | MODE3 */
+                       AM33XX_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_clk.mmc2_clk, INPUT_PULLUP | MODE3 */
                >;
        };
 
        wlan_pins: pinmux_wlan_pins {
                pinctrl-single,pins = <
-                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a0.gpio1_16 */
-                       0x19C (PIN_INPUT | MUX_MODE7)           /* mcasp0_ahclkr.gpio3_17 */
-                       0x1AC (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahclkx.gpio3_21 */
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a0.gpio1_16 */
+                       AM33XX_IOPAD(0x99c, PIN_INPUT | MUX_MODE7)              /* mcasp0_ahclkr.gpio3_17 */
+                       AM33XX_IOPAD(0x9ac, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* mcasp0_ahclkx.gpio3_21 */
                >;
        };
 
        lcd_pins_s0: lcd_pins_s0 {
                pinctrl-single,pins = <
-                       0x20 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad8.lcd_data23 */
-                       0x24 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad9.lcd_data22 */
-                       0x28 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad10.lcd_data21 */
-                       0x2c (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad11.lcd_data20 */
-                       0x30 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad12.lcd_data19 */
-                       0x34 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad13.lcd_data18 */
-                       0x38 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad14.lcd_data17 */
-                       0x3c (PIN_OUTPUT | MUX_MODE1)           /* gpmc_ad15.lcd_data16 */
-                       0xa0 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data0.lcd_data0 */
-                       0xa4 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data1.lcd_data1 */
-                       0xa8 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data2.lcd_data2 */
-                       0xac (PIN_OUTPUT | MUX_MODE0)           /* lcd_data3.lcd_data3 */
-                       0xb0 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data4.lcd_data4 */
-                       0xb4 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data5.lcd_data5 */
-                       0xb8 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data6.lcd_data6 */
-                       0xbc (PIN_OUTPUT | MUX_MODE0)           /* lcd_data7.lcd_data7 */
-                       0xc0 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data8.lcd_data8 */
-                       0xc4 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data9.lcd_data9 */
-                       0xc8 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data10.lcd_data10 */
-                       0xcc (PIN_OUTPUT | MUX_MODE0)           /* lcd_data11.lcd_data11 */
-                       0xd0 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data12.lcd_data12 */
-                       0xd4 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data13.lcd_data13 */
-                       0xd8 (PIN_OUTPUT | MUX_MODE0)           /* lcd_data14.lcd_data14 */
-                       0xdc (PIN_OUTPUT | MUX_MODE0)           /* lcd_data15.lcd_data15 */
-                       0xe0 (PIN_OUTPUT | MUX_MODE0)           /* lcd_vsync.lcd_vsync */
-                       0xe4 (PIN_OUTPUT | MUX_MODE0)           /* lcd_hsync.lcd_hsync */
-                       0xe8 (PIN_OUTPUT | MUX_MODE0)           /* lcd_pclk.lcd_pclk */
-                       0xec (PIN_OUTPUT | MUX_MODE0)           /* lcd_ac_bias_en.lcd_ac_bias_en */
+                       AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad8.lcd_data23 */
+                       AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad9.lcd_data22 */
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad10.lcd_data21 */
+                       AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad11.lcd_data20 */
+                       AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad12.lcd_data19 */
+                       AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad13.lcd_data18 */
+                       AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad14.lcd_data17 */
+                       AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)             /* gpmc_ad15.lcd_data16 */
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)             /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)             /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)             /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)             /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)             /* lcd_ac_bias_en.lcd_ac_bias_en */
                >;
        };
 
        mcasp1_pins: mcasp1_pins {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
-                       0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+                       AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
                >;
        };
 
        mcasp1_pins_sleep: mcasp1_pins_sleep {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        dcan1_pins_default: dcan1_pins_default {
                pinctrl-single,pins = <
-                       0x168 (PIN_OUTPUT | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
-                       0x16c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
+                       AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
+                       AM33XX_IOPAD(0x96c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
                >;
        };
 };
 &mmc3 {
        /* these are on the crossbar and are outlined in the
           xbar-event-map element */
-       dmas = <&edma 12
-               &edma 13>;
+       dmas = <&edma_xbar 12 0 1
+               &edma_xbar 13 0 2>;
        dma-names = "tx", "rx";
        status = "okay";
        vmmc-supply = <&wlan_en_reg>;
        };
 };
 
-&edma {
-       ti,edma-xbar-event-map = /bits/ 16 <1 12
-                                           2 13>;
-};
-
 &sham {
        status = "okay";
 };
index 89442e9..282fe1b 100644 (file)
                        label = "button2";
                        linux,code = <0x102>;
                        gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                switch@4 {
 
        lcd_pins_default: lcd_pins_default {
                pinctrl-single,pins = <
-                       0x20 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad8.lcd_data23 */
-                       0x24 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad9.lcd_data22 */
-                       0x28 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad10.lcd_data21 */
-                       0x2c (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad11.lcd_data20 */
-                       0x30 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad12.lcd_data19 */
-                       0x34 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad13.lcd_data18 */
-                       0x38 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad14.lcd_data17 */
-                       0x3c (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad15.lcd_data16 */
-                       0xa0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data0.lcd_data0 */
-                       0xa4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data1.lcd_data1 */
-                       0xa8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data2.lcd_data2 */
-                       0xac (PIN_OUTPUT | MUX_MODE0)   /* lcd_data3.lcd_data3 */
-                       0xb0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data4.lcd_data4 */
-                       0xb4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data5.lcd_data5 */
-                       0xb8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data6.lcd_data6 */
-                       0xbc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data7.lcd_data7 */
-                       0xc0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data8.lcd_data8 */
-                       0xc4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data9.lcd_data9 */
-                       0xc8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data10.lcd_data10 */
-                       0xcc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data11.lcd_data11 */
-                       0xd0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data12.lcd_data12 */
-                       0xd4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data13.lcd_data13 */
-                       0xd8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data14.lcd_data14 */
-                       0xdc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data15.lcd_data15 */
-                       0xe0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_vsync.lcd_vsync */
-                       0xe4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_hsync.lcd_hsync */
-                       0xe8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_pclk.lcd_pclk */
-                       0xec (PIN_OUTPUT | MUX_MODE0)   /* lcd_ac_bias_en.lcd_ac_bias_en */
+                       AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad8.lcd_data23 */
+                       AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad9.lcd_data22 */
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad10.lcd_data21 */
+                       AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad11.lcd_data20 */
+                       AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad12.lcd_data19 */
+                       AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad13.lcd_data18 */
+                       AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad14.lcd_data17 */
+                       AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad15.lcd_data16 */
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)     /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)     /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)     /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)     /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)     /* lcd_ac_bias_en.lcd_ac_bias_en */
                >;
        };
 
        lcd_pins_sleep: lcd_pins_sleep {
                pinctrl-single,pins = <
-                       0x20 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad8.lcd_data23 */
-                       0x24 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad9.lcd_data22 */
-                       0x28 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad10.lcd_data21 */
-                       0x2c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad11.lcd_data20 */
-                       0x30 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad12.lcd_data19 */
-                       0x34 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad13.lcd_data18 */
-                       0x38 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad14.lcd_data17 */
-                       0x3c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ad15.lcd_data16 */
-                       0xa0 (PULL_DISABLE | MUX_MODE7) /* lcd_data0.lcd_data0 */
-                       0xa4 (PULL_DISABLE | MUX_MODE7) /* lcd_data1.lcd_data1 */
-                       0xa8 (PULL_DISABLE | MUX_MODE7) /* lcd_data2.lcd_data2 */
-                       0xac (PULL_DISABLE | MUX_MODE7) /* lcd_data3.lcd_data3 */
-                       0xb0 (PULL_DISABLE | MUX_MODE7) /* lcd_data4.lcd_data4 */
-                       0xb4 (PULL_DISABLE | MUX_MODE7) /* lcd_data5.lcd_data5 */
-                       0xb8 (PULL_DISABLE | MUX_MODE7) /* lcd_data6.lcd_data6 */
-                       0xbc (PULL_DISABLE | MUX_MODE7) /* lcd_data7.lcd_data7 */
-                       0xc0 (PULL_DISABLE | MUX_MODE7) /* lcd_data8.lcd_data8 */
-                       0xc4 (PULL_DISABLE | MUX_MODE7) /* lcd_data9.lcd_data9 */
-                       0xc8 (PULL_DISABLE | MUX_MODE7) /* lcd_data10.lcd_data10 */
-                       0xcc (PULL_DISABLE | MUX_MODE7) /* lcd_data11.lcd_data11 */
-                       0xd0 (PULL_DISABLE | MUX_MODE7) /* lcd_data12.lcd_data12 */
-                       0xd4 (PULL_DISABLE | MUX_MODE7) /* lcd_data13.lcd_data13 */
-                       0xd8 (PULL_DISABLE | MUX_MODE7) /* lcd_data14.lcd_data14 */
-                       0xdc (PULL_DISABLE | MUX_MODE7) /* lcd_data15.lcd_data15 */
-                       0xe0 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* lcd_vsync.lcd_vsync */
-                       0xe4 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* lcd_hsync.lcd_hsync */
-                       0xe8 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* lcd_pclk.lcd_pclk */
-                       0xec (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* lcd_ac_bias_en.lcd_ac_bias_en */
+                       AM33XX_IOPAD(0x820, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad8.lcd_data23 */
+                       AM33XX_IOPAD(0x824, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad9.lcd_data22 */
+                       AM33XX_IOPAD(0x828, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad10.lcd_data21 */
+                       AM33XX_IOPAD(0x82c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad11.lcd_data20 */
+                       AM33XX_IOPAD(0x830, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad12.lcd_data19 */
+                       AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad13.lcd_data18 */
+                       AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad14.lcd_data17 */
+                       AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ad15.lcd_data16 */
+                       AM33XX_IOPAD(0x8a0, PULL_DISABLE | MUX_MODE7)   /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PULL_DISABLE | MUX_MODE7)   /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PULL_DISABLE | MUX_MODE7)   /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PULL_DISABLE | MUX_MODE7)   /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PULL_DISABLE | MUX_MODE7)   /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PULL_DISABLE | MUX_MODE7)   /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PULL_DISABLE | MUX_MODE7)   /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PULL_DISABLE | MUX_MODE7)   /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PULL_DISABLE | MUX_MODE7)   /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PULL_DISABLE | MUX_MODE7)   /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PULL_DISABLE | MUX_MODE7)   /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PULL_DISABLE | MUX_MODE7)   /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PULL_DISABLE | MUX_MODE7)   /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PULL_DISABLE | MUX_MODE7)   /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PULL_DISABLE | MUX_MODE7)   /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PULL_DISABLE | MUX_MODE7)   /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* lcd_ac_bias_en.lcd_ac_bias_en */
                >;
        };
 
 
        user_leds_s0: user_leds_s0 {
                pinctrl-single,pins = <
-                       0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad4.gpio1_4 */
-                       0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad5.gpio1_5 */
-                       0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad6.gpio1_6 */
-                       0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad7.gpio1_7 */
+                       AM33XX_IOPAD(0x810, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_ad4.gpio1_4 */
+                       AM33XX_IOPAD(0x814, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_ad5.gpio1_5 */
+                       AM33XX_IOPAD(0x818, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_ad6.gpio1_6 */
+                       AM33XX_IOPAD(0x81c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_ad7.gpio1_7 */
                >;
        };
 
        gpio_keys_s0: gpio_keys_s0 {
                pinctrl-single,pins = <
-                       0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_oen_ren.gpio2_3 */
-                       0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_advn_ale.gpio2_2 */
-                       0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_wait0.gpio0_30 */
-                       0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_ben0_cle.gpio2_5 */
+                       AM33XX_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_oen_ren.gpio2_3 */
+                       AM33XX_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_advn_ale.gpio2_2 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_wait0.gpio0_30 */
+                       AM33XX_IOPAD(0x89c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_ben0_cle.gpio2_5 */
                >;
        };
 
        i2c0_pins: pinmux_i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
                >;
        };
 
        uart0_pins: pinmux_uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)         /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
                >;
        };
 
        clkout2_pin: pinmux_clkout2_pin {
                pinctrl-single,pins = <
-                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)         /* xdma_event_intr1.clkout2 */
+                       AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr1.clkout2 */
                >;
        };
 
        ecap2_pins: backlight_pins {
                pinctrl-single,pins = <
-                       0x19c 0x4       /* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */
+                       AM33XX_IOPAD(0x99c, MUX_MODE4)  /* mcasp0_ahclkr.ecap2_in_pwm2_out */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
-                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
-                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
-                       0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rgmii1_rclk */
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd3.rgmii1_rd3 */
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd2.rgmii1_rd2 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_tctl */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxdv.rgmii1_rctl */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd3.rgmii1_td3 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd2.rgmii1_td2 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_td1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_td0 */
+                       AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rgmii1_tclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxclk.rgmii1_rclk */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd3.rgmii1_rd3 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd2.rgmii1_rd2 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rd0 */
 
                        /* Slave 2 */
-                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a0.rgmii2_tctl */
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a1.rgmii2_rctl */
-                       0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a2.rgmii2_td3 */
-                       0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a3.rgmii2_td2 */
-                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a4.rgmii2_td1 */
-                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a5.rgmii2_td0 */
-                       0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a6.rgmii2_tclk */
-                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a7.rgmii2_rclk */
-                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a8.rgmii2_rd3 */
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a9.rgmii2_rd2 */
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a10.rgmii2_rd1 */
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a11.rgmii2_rd0 */
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a0.rgmii2_tctl */
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a1.rgmii2_rctl */
+                       AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a2.rgmii2_td3 */
+                       AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a3.rgmii2_td2 */
+                       AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a4.rgmii2_td1 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a5.rgmii2_td0 */
+                       AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a6.rgmii2_tclk */
+                       AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a7.rgmii2_rclk */
+                       AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a8.rgmii2_rd3 */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a9.rgmii2_rd2 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a10.rgmii2_rd1 */
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* gpmc_a11.rgmii2_rd0 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
 
                        /* Slave 2 reset value*/
-                       0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                >;
        };
 
        mcasp1_pins: mcasp1_pins {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
-                       0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+                       AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
                >;
        };
 
        mcasp1_pins_sleep: mcasp1_pins_sleep {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
-                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
-                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
-                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
-                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
-                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
-                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
                >;
        };
 
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0x7c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
                >;
        };
 };
index 5c5667a..d97b0ef 100644 (file)
 &am33xx_pinmux {
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat3 */
-                       0xf4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat2 */
-                       0xf8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat1 */
-                       0xfc (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat0 */
-                       0x100 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_clk */
-                       0x104 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_cmd */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat3 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat2 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat1 */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat0 */
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_clk */
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_cmd */
                >;
        };
 
        i2c0_pins: pinmux_i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT | MUX_MODE0)   /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT | MUX_MODE0)   /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT | MUX_MODE0)      /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT | MUX_MODE0)      /* i2c0_scl.i2c0_scl */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii1_int */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* rmii1_crs_dv */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* rmii1_rxer */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_txen */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_td1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_td0 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* rmii1_rd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* rmii1_rd0 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* rmii1_refclk */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_int */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* rmii1_crs_dv */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* rmii1_rxer */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* rmii1_txen */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* rmii1_td1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* rmii1_td0 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* rmii1_rd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* rmii1_rd0 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* rmii1_refclk */
 
                        /* Slave 2 */
-                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)  /* rmii2_txen */
-                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)  /* rmii2_td1 */
-                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)  /* rmii2_td0 */
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE3)   /* rmii2_rd1 */
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE3)   /* rmii2_rd0 */
-                       0x70 (PIN_INPUT_PULLDOWN | MUX_MODE3)   /* rmii2_crs_dv */
-                       0x74 (PIN_INPUT_PULLDOWN | MUX_MODE3)   /* rmii2_rxer */
-                       0x78 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_int */
-                       0x108 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* rmii2_refclk */
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* rmii2_txen */
+                       AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* rmii2_td1 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* rmii2_td0 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE3)     /* rmii2_rd1 */
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE3)     /* rmii2_rd0 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE3)     /* rmii2_crs_dv */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE3)     /* rmii2_rxer */
+                       AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_int */
+                       AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* rmii2_refclk */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii1_int */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_crs_dv */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_rxer */
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_txen */
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_td1 */
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_td0 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_rd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_rd0 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii1_refclk */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_int */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_crs_dv */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_rxer */
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_txen */
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_td1 */
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_td0 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_rd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_rd0 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii1_refclk */
 
                        /* Slave 2 reset value*/
-                       0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_txen */
-                       0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_td1 */
-                       0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_td0 */
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_rd1 */
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_rd0 */
-                       0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_crs_dv */
-                       0x74 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_rxer */
-                       0x78 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* rmii2_int */
-                       0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)  /* rmii2_refclk */
+                       AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_txen */
+                       AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_td1 */
+                       AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_td0 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_rd1 */
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_rd0 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_crs_dv */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_rxer */
+                       AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_int */
+                       AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* rmii2_refclk */
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        emmc_pins: pinmux_emmc_pins {
                pinctrl-single,pins = <
-                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
-                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
-                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
-                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
-                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
-                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
                >;
        };
 
        uart0_pins: pinmux_uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
                >;
        };
 };
index 5ed4ca6..77559a1 100644 (file)
 
        misc_pins: misc_pins {
                pinctrl-single,pins = <
-                       0x15c (PIN_OUTPUT | MUX_MODE7)  /* spi0_cs0.gpio0_5 */
+                       AM33XX_IOPAD(0x95c, PIN_OUTPUT | MUX_MODE7)     /* spi0_cs0.gpio0_5 */
                >;
        };
 
        gpmc_pins: gpmc_pins {
                pinctrl-single,pins = <
-                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
-                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
-                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
-                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
-                       0x20 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad8.gpmc_ad8 */
-                       0x24 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad9.gpmc_ad9 */
-                       0x28 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad10.gpmc_ad10 */
-                       0x2c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad11.gpmc_ad11 */
-                       0x30 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad12.gpmc_ad12 */
-                       0x34 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad13.gpmc_ad13 */
-                       0x38 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad14.gpmc_ad14 */
-                       0x3c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad15.gpmc_ad15 */
-
-                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0 */
-                       0x80 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn1.gpmc_csn1 */
-                       0x84 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn2.gpmc_csn2 */
-                       0x88 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn3.gpmc_csn3 */
-
-                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_ben0_cle.gpmc_ben0_cle */
-
-                       0xa4 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data1.gpmc_a1 */
-                       0xa8 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data2.gpmc_a2 */
-                       0xac (PIN_OUTPUT | MUX_MODE1)           /* lcd_data3.gpmc_a3 */
-                       0xb0 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data4.gpmc_a4 */
-                       0xb4 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data5.gpmc_a5 */
-                       0xb8 (PIN_OUTPUT | MUX_MODE1)           /* lcd_data6.gpmc_a6 */
-                       0xbc (PIN_OUTPUT | MUX_MODE1)           /* lcd_data7.gpmc_a7 */
-
-                       0xe0 (PIN_OUTPUT | MUX_MODE1)           /* lcd_vsync.gpmc_a8 */
-                       0xe4 (PIN_OUTPUT | MUX_MODE1)           /* lcd_hsync.gpmc_a9 */
-                       0xe8 (PIN_OUTPUT | MUX_MODE1)           /* lcd_pclk.gpmc_a10 */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad0.gpmc_ad0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad1.gpmc_ad1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad2.gpmc_ad2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad3.gpmc_ad3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad4.gpmc_ad4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad5.gpmc_ad5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad6.gpmc_ad6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad7.gpmc_ad7 */
+                       AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad8.gpmc_ad8 */
+                       AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad9.gpmc_ad9 */
+                       AM33XX_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad10.gpmc_ad10 */
+                       AM33XX_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad11.gpmc_ad11 */
+                       AM33XX_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad12.gpmc_ad12 */
+                       AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad13.gpmc_ad13 */
+                       AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad14.gpmc_ad14 */
+                       AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad15.gpmc_ad15 */
+
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn0.gpmc_csn0 */
+                       AM33XX_IOPAD(0x880, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn1.gpmc_csn1 */
+                       AM33XX_IOPAD(0x884, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn2.gpmc_csn2 */
+                       AM33XX_IOPAD(0x888, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn3.gpmc_csn3 */
+
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)             /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)             /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)             /* gpmc_wen.gpmc_wen */
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_ben0_cle.gpmc_ben0_cle */
+
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE1)             /* lcd_data1.gpmc_a1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE1)             /* lcd_data2.gpmc_a2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE1)             /* lcd_data3.gpmc_a3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE1)             /* lcd_data4.gpmc_a4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE1)             /* lcd_data5.gpmc_a5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE1)             /* lcd_data6.gpmc_a6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE1)             /* lcd_data7.gpmc_a7 */
+
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE1)             /* lcd_vsync.gpmc_a8 */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE1)             /* lcd_hsync.gpmc_a9 */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE1)             /* lcd_pclk.gpmc_a10 */
                >;
        };
 
        i2c0_pins: i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* i2c0_scl.i2c0_scl */
                >;
        };
 
        uart0_pins: uart0_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT | MUX_MODE0)          /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT | MUX_MODE0)             /* uart0_txd.uart0_txd */
                >;
        };
 
        uart1_pins: uart1_pins {
                pinctrl-single,pins = <
-                       0x178 (PIN_OUTPUT | MUX_MODE7)          /* uart1_ctsn.uart1_ctsn */
-                       0x17c (PIN_OUTPUT | MUX_MODE7)          /* uart1_rtsn.uart1_rtsn */
-                       0x180 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_rxd.uart1_rxd */
-                       0x184 (PIN_OUTPUT | MUX_MODE0)          /* uart1_txd.uart1_txd */
+                       AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE7)             /* uart1_ctsn.uart1_ctsn */
+                       AM33XX_IOPAD(0x97c, PIN_OUTPUT | MUX_MODE7)             /* uart1_rtsn.uart1_rtsn */
+                       AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart1_rxd.uart1_rxd */
+                       AM33XX_IOPAD(0x984, PIN_OUTPUT | MUX_MODE0)             /* uart1_txd.uart1_txd */
                >;
        };
 
        uart2_pins: uart2_pins {
                pinctrl-single,pins = <
-                       0xc0 (PIN_INPUT_PULLUP | MUX_MODE7)     /* lcd_data8.gpio2[14] */
-                       0xc4 (PIN_OUTPUT | MUX_MODE7)           /* lcd_data9.gpio2[15] */
-                       0x150 (PIN_INPUT | MUX_MODE1)           /* spi0_sclk.uart2_rxd */
-                       0x154 (PIN_OUTPUT | MUX_MODE1)          /* spi0_d0.uart2_txd */
+                       AM33XX_IOPAD(0x8c0, PIN_INPUT_PULLUP | MUX_MODE7)       /* lcd_data8.gpio2[14] */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE7)             /* lcd_data9.gpio2[15] */
+                       AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)              /* spi0_sclk.uart2_rxd */
+                       AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)             /* spi0_d0.uart2_txd */
                >;
        };
 
        uart3_pins: uart3_pins {
                pinctrl-single,pins = <
-                       0xc8 (PIN_INPUT_PULLUP | MUX_MODE6)     /* lcd_data10.uart3_ctsn */
-                       0xcc (PIN_OUTPUT | MUX_MODE6)           /* lcd_data11.uart3_rtsn */
-                       0x160 (PIN_INPUT | MUX_MODE1)           /* spi0_cs1.uart3_rxd */
-                       0x164 (PIN_OUTPUT | MUX_MODE1)          /* ecap0_in_pwm0_out.uart3_txd */
+                       AM33XX_IOPAD(0x8c8, PIN_INPUT_PULLUP | MUX_MODE6)       /* lcd_data10.uart3_ctsn */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE6)             /* lcd_data11.uart3_rtsn */
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE1)              /* spi0_cs1.uart3_rxd */
+                       AM33XX_IOPAD(0x964, PIN_OUTPUT | MUX_MODE1)             /* ecap0_in_pwm0_out.uart3_txd */
                >;
        };
 
        uart4_pins: uart4_pins {
                pinctrl-single,pins = <
-                       0xd0 (PIN_INPUT_PULLUP | MUX_MODE6)     /* lcd_data12.uart4_ctsn */
-                       0xd4 (PIN_OUTPUT | MUX_MODE6)           /* lcd_data13.uart4_rtsn */
-                       0x168 (PIN_INPUT | MUX_MODE1)           /* uart0_ctsn.uart4_rxd */
-                       0x16c (PIN_OUTPUT | MUX_MODE1)          /* uart0_rtsn.uart4_txd */
+                       AM33XX_IOPAD(0x8d0, PIN_INPUT_PULLUP | MUX_MODE6)       /* lcd_data12.uart4_ctsn */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE6)             /* lcd_data13.uart4_rtsn */
+                       AM33XX_IOPAD(0x968, PIN_INPUT | MUX_MODE1)              /* uart0_ctsn.uart4_rxd */
+                       AM33XX_IOPAD(0x96c, PIN_OUTPUT | MUX_MODE1)             /* uart0_rtsn.uart4_txd */
                >;
        };
 
        uart5_pins: uart5_pins {
                pinctrl-single,pins = <
-                       0xd8 (PIN_INPUT | MUX_MODE4)            /* lcd_data14.uart5_rxd */
-                       0x144 (PIN_OUTPUT | MUX_MODE3)          /* rmiii1_refclk.uart5_txd */
+                       AM33XX_IOPAD(0x8d8, PIN_INPUT | MUX_MODE4)              /* lcd_data14.uart5_rxd */
+                       AM33XX_IOPAD(0x944, PIN_OUTPUT | MUX_MODE3)             /* rmiii1_refclk.uart5_txd */
                >;
        };
 
        mmc1_pins: mmc1_pins {
                pinctrl-single,pins = <
-                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat0.mmc0_dat0 */
-                       0xf4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat1.mmc0_dat1 */
-                       0xf8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat2.mmc0_dat2 */
-                       0xfc (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat3.mmc0_dat3 */
-                       0x100 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_clk.mmc0_clk */
-                       0x104 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_cmd.mmc0_cmd */
-                       0x1e8 (PIN_INPUT_PULLUP | MUX_MODE7)    /* emu1.gpio3[8] */
-                       0x1a0 (PIN_INPUT_PULLUP | MUX_MODE7)    /* mcasp0_aclkr.gpio3[18] */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat0.mmc0_dat0 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat1.mmc0_dat1 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat2.mmc0_dat2 */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat3.mmc0_dat3 */
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_clk.mmc0_clk */
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_cmd.mmc0_cmd */
+                       AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7)       /* emu1.gpio3[8] */
+                       AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7)       /* mcasp0_aclkr.gpio3[18] */
                >;
        };
 };
        wp-gpios = <&gpio3 18 0>;
 };
 
-#include "tps65217.dtsi"
-
 &tps {
+       compatible = "ti,tps65217";
+
        regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                dcdc1_reg: regulator@0 {
+                       reg = <0>;
                        /* +1.5V voltage with Â±4% tolerance */
                        regulator-min-microvolt = <1450000>;
                        regulator-max-microvolt = <1550000>;
                };
 
                dcdc2_reg: regulator@1 {
+                       reg = <1>;
                        /* VDD_MPU voltage limits 0.95V - 1.1V with Â±4% tolerance */
                        regulator-name = "vdd_mpu";
                        regulator-min-microvolt = <915000>;
                };
 
                dcdc3_reg: regulator@2 {
+                       reg = <2>;
                        /* VDD_CORE voltage limits 0.95V - 1.1V with Â±4% tolerance */
                        regulator-name = "vdd_core";
                        regulator-min-microvolt = <915000>;
                };
 
                ldo1_reg: regulator@3 {
+                       reg = <3>;
                        /* +1.8V voltage with Â±4% tolerance */
                        regulator-min-microvolt = <1750000>;
                        regulator-max-microvolt = <1870000>;
                };
 
                ldo2_reg: regulator@4 {
+                       reg = <4>;
                        /* +3.3V voltage with Â±4% tolerance */
                        regulator-min-microvolt = <3175000>;
                        regulator-max-microvolt = <3430000>;
                };
 
                ldo3_reg: regulator@5 {
+                       reg = <5>;
                        /* +1.8V voltage with Â±4% tolerance */
                        regulator-min-microvolt = <1750000>;
                        regulator-max-microvolt = <1870000>;
                };
 
                ldo4_reg: regulator@6 {
+                       reg = <6>;
                        /* +3.3V voltage with Â±4% tolerance */
                        regulator-min-microvolt = <3175000>;
                        regulator-max-microvolt = <3430000>;
index 7106114..471a3a7 100644 (file)
 &am33xx_pinmux {
        i2c0_pins: pinmux_i2c0 {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
                >;
        };
        i2c1_pins: pinmux_i2c1 {
                pinctrl-single,pins = <
-                       0x10C (PIN_INPUT_PULLUP | MUX_MODE3)    /* mii1_crs,i2c1_sda */
-                       0x110 (PIN_INPUT_PULLUP | MUX_MODE3)    /* mii1_rxerr,i2c1_scl */
+                       AM33XX_IOPAD(0x90C, PIN_INPUT_PULLUP | MUX_MODE3)       /* mii1_crs,i2c1_sda */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE3)       /* mii1_rxerr,i2c1_scl */
                >;
        };
 };
 &am33xx_pinmux {
        accel_pins: pinmux_accel {
                pinctrl-single,pins = <
-                       0x98 (PIN_INPUT | MUX_MODE7)   /* gpmc_wen.gpio2_4 */
+                       AM33XX_IOPAD(0x898, PIN_INPUT | MUX_MODE7)   /* gpmc_wen.gpio2_4 */
                >;
        };
 };
 &am33xx_pinmux {
        audio_pins: pinmux_audio {
                pinctrl-single,pins = <
-                       0x1AC (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_ahcklx.mcasp0_ahclkx */
-                       0x194 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_fsx.mcasp0_fsx */
-                       0x190 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_aclkx.mcasp0_aclkx */
-                       0x198 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_axr0.mcasp0_axr0 */
-                       0x1A8 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_axr1.mcasp0_axr1 */
-                       0x40 (PIN_OUTPUT | MUX_MODE7)   /* gpmc_a0.gpio1_16 */
+                       AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_ahcklx.mcasp0_ahclkx */
+                       AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_fsx.mcasp0_fsx */
+                       AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_aclkx.mcasp0_aclkx */
+                       AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_axr0.mcasp0_axr0 */
+                       AM33XX_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_axr1.mcasp0_axr1 */
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE7)     /* gpmc_a0.gpio1_16 */
                >;
        };
 };
 &am33xx_pinmux {
        lcd_pins: pinmux_lcd {
                pinctrl-single,pins = <
-                       0xa0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data0.lcd_data0 */
-                       0xa4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data1.lcd_data1 */
-                       0xa8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data2.lcd_data2 */
-                       0xac (PIN_OUTPUT | MUX_MODE0)   /* lcd_data3.lcd_data3 */
-                       0xb0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data4.lcd_data4 */
-                       0xb4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data5.lcd_data5 */
-                       0xb8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data6.lcd_data6 */
-                       0xbc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data7.lcd_data7 */
-                       0xc0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data8.lcd_data8 */
-                       0xc4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data9.lcd_data9 */
-                       0xc8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data10.lcd_data10 */
-                       0xcc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data11.lcd_data11 */
-                       0xd0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data12.lcd_data12 */
-                       0xd4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data13.lcd_data13 */
-                       0xd8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_data14.lcd_data14 */
-                       0xdc (PIN_OUTPUT | MUX_MODE0)   /* lcd_data15.lcd_data15 */
-                       0x20 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad8.lcd_data16 */
-                       0x24 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad9.lcd_data17 */
-                       0x28 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad10.lcd_data18 */
-                       0x2c (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad11.lcd_data19 */
-                       0x30 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad12.lcd_data20 */
-                       0x34 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad13.lcd_data21 */
-                       0x38 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad14.lcd_data22 */
-                       0x3c (PIN_OUTPUT | MUX_MODE1)   /* gpmc_ad15.lcd_data23 */
-                       0xe0 (PIN_OUTPUT | MUX_MODE0)   /* lcd_vsync.lcd_vsync */
-                       0xe4 (PIN_OUTPUT | MUX_MODE0)   /* lcd_hsync.lcd_hsync */
-                       0xe8 (PIN_OUTPUT | MUX_MODE0)   /* lcd_pclk.lcd_pclk */
-                       0xec (PIN_OUTPUT | MUX_MODE0)   /* lcd_ac_bias_en.lcd_ac_bias_en */
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)     /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad8.lcd_data16 */
+                       AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad9.lcd_data17 */
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad10.lcd_data18 */
+                       AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad11.lcd_data19 */
+                       AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad12.lcd_data20 */
+                       AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad13.lcd_data21 */
+                       AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad14.lcd_data22 */
+                       AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)     /* gpmc_ad15.lcd_data23 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)     /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)     /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)     /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)     /* lcd_ac_bias_en.lcd_ac_bias_en */
                        /* Display Enable */
-                       0x6c (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a11.gpio1_27 */
+                       AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_a11.gpio1_27 */
                >;
        };
 };
 &am33xx_pinmux {
        ethernet_pins: pinmux_ethernet {
                pinctrl-single,pins = <
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
-                       0x118 (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_rxdv.rgmii1_rctl */
-                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
-                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
-                       0x12c (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_txclk.rgmii1_tclk */
-                       0x130 (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_rxclk.rgmii1_rclk */
-                       0x134 (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_rxd3.rgmii1_rxd3 */
-                       0x138 (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_rxd2.rgmii1_rxd2 */
-                       0x13c (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_rxd1.rgmii1_rxd1 */
-                       0x140 (PIN_INPUT_PULLUP | MUX_MODE2)    /* mii1_rxd0.rgmii1_rxd0 */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_tctl */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_rxdv.rgmii1_rctl */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd3.rgmii1_td3 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd2.rgmii1_td2 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_td1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_td0 */
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_txclk.rgmii1_tclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_rxclk.rgmii1_rclk */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_rxd3.rgmii1_rxd3 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_rxd2.rgmii1_rxd2 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_rxd1.rgmii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE2)       /* mii1_rxd0.rgmii1_rxd0 */
                        /* ethernet interrupt */
-                       0x144 (PIN_INPUT_PULLUP | MUX_MODE7)    /* rmii2_refclk.gpio0_29 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLUP | MUX_MODE7)       /* rmii2_refclk.gpio0_29 */
                        /* ethernet PHY nReset */
-                       0x108 (PIN_OUTPUT_PULLUP | MUX_MODE7)   /* mii1_col.gpio3_0 */
+                       AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* mii1_col.gpio3_0 */
                >;
        };
 
        mdio_pins: pinmux_mdio {
                pinctrl-single,pins = <
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 };
        ti,non-removable;
 };
 
-&edma {
-       /* Map eDMA MMC2 Events from Crossbar */
-       ti,edma-xbar-event-map = /bits/ 16 <1 12
-                                            2 13>;
-};
-
-
 &mmc3 {
        /* Wifi & Bluetooth on MMC #3 */
        status = "okay";
        vmmmc-supply = <&v3v3c_reg>;
        bus-width = <4>;
        ti,non-removable;
-       dmas = <&edma 12
-               &edma 13>;
+       dmas = <&edma_xbar 12 0 1
+               &edma_xbar 13 0 2>;
        dma-names = "tx", "rx";
 };
 
 &am33xx_pinmux {
        sd_pins: pinmux_sd_card {
                pinctrl-single,pins = <
-                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat0.mmc0_dat0 */
-                       0xf4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat1.mmc0_dat1 */
-                       0xf8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat2.mmc0_dat2 */
-                       0xfc (PIN_INPUT_PULLUP | MUX_MODE0)     /* mmc0_dat3.mmc0_dat3 */
-                       0x100 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_clk.mmc0_clk */
-                       0x104 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_cmd.mmc0_cmd */
-                       0x160 (PIN_INPUT | MUX_MODE7)           /* spi0_cs1.gpio0_6 */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat0.mmc0_dat0 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat1.mmc0_dat1 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat2.mmc0_dat2 */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat3.mmc0_dat3 */
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_clk.mmc0_clk */
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_cmd.mmc0_cmd */
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7)              /* spi0_cs1.gpio0_6 */
                >;
        };
        emmc_pins: pinmux_emmc {
                pinctrl-single,pins = <
-                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2)     /* gpmc_csn1.mmc1_clk */
-                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2)     /* gpmc_csn2.mmc1_cmd */
-                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad0.mmc1_dat0 */
-                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad1.mmc1_dat1 */
-                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad2.mmc1_dat2 */
-                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad3.mmc1_dat3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad4.mmc1_dat4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad5.mmc1_dat5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad6.mmc1_dat6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE1)     /* gpmc_ad7.mmc1_dat7 */
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2)       /* gpmc_csn1.mmc1_clk */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2)       /* gpmc_csn2.mmc1_cmd */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad0.mmc1_dat0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad1.mmc1_dat1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad2.mmc1_dat2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad3.mmc1_dat3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad4.mmc1_dat4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad5.mmc1_dat5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad6.mmc1_dat6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad7.mmc1_dat7 */
                        /* EMMC nReset */
-                       0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_wpn.gpio0_31 */
+                       AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_wpn.gpio0_31 */
                >;
        };
        wireless_pins: pinmux_wireless {
                pinctrl-single,pins = <
-                       0x44 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a1.mmc2_dat0 */
-                       0x48 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a2.mmc2_dat1 */
-                       0x4c (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a3.mmc2_dat2 */
-                       0x78 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_ben1.mmc2_dat3 */
-                       0x88 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_csn3.mmc2_cmd */
-                       0x8c (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_clk.mmc1_clk */
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_a1.mmc2_dat0 */
+                       AM33XX_IOPAD(0x848, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_a2.mmc2_dat1 */
+                       AM33XX_IOPAD(0x84c, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_a3.mmc2_dat2 */
+                       AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_ben1.mmc2_dat3 */
+                       AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_csn3.mmc2_cmd */
+                       AM33XX_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_clk.mmc1_clk */
                        /* WLAN nReset */
-                       0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a8.gpio1_24 */
+                       AM33XX_IOPAD(0x860, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_a8.gpio1_24 */
                        /* WLAN nPower down */
-                       0x70 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_wait0.gpio0_30 */
+                       AM33XX_IOPAD(0x870, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_wait0.gpio0_30 */
                        /* 32kHz Clock */
-                       0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+                       AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr1.clkout2 */
                >;
        };
 };
        vin-supply = <&vbat>;
 };
 
-/include/ "tps65217.dtsi"
-
 &tps {
+       compatible = "ti,tps65217";
+
        backlight {
                isel = <1>; /* ISET1 */
                fdim = <200>; /* TPS65217_BL_FDIM_200HZ */
        };
 
        regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                dcdc1_reg: regulator@0 {
+                       reg = <0>;
                        /* VDD_1V8 system supply */
                        regulator-always-on;
                };
 
                dcdc2_reg: regulator@1 {
+                       reg = <1>;
                        /* VDD_CORE voltage limits 0.95V - 1.26V with +/-4% tolerance */
                        regulator-name = "vdd_core";
                        regulator-min-microvolt = <925000>;
                };
 
                dcdc3_reg: regulator@2 {
+                       reg = <2>;
                        /* VDD_MPU voltage limits 0.95V - 1.1V with +/-4% tolerance */
                        regulator-name = "vdd_mpu";
                        regulator-min-microvolt = <925000>;
                };
 
                ldo1_reg: regulator@3 {
+                       reg = <3>;
                        /* VRTC 1.8V always-on supply */
                        regulator-name = "vrtc,vdds";
                        regulator-always-on;
                };
 
                ldo2_reg: regulator@4 {
+                       reg = <4>;
                        /* 3.3V rail */
                        regulator-name = "vdd_3v3aux";
                        regulator-always-on;
                };
 
                ldo3_reg: regulator@5 {
+                       reg = <5>;
                        /* VDD_3V3A 3.3V rail */
                        regulator-name = "vdd_3v3a";
                        regulator-min-microvolt = <3300000>;
                };
 
                ldo4_reg: regulator@6 {
+                       reg = <6>;
                        /* VDD_3V3B 3.3V rail */
                        regulator-name = "vdd_3v3b";
                        regulator-always-on;
 &am33xx_pinmux {
        spi0_pins: pinmux_spi0 {
                pinctrl-single,pins = <
-                       0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
-                       0x15C (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
-                       0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
-                       0x158 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
+                       AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
+                       AM33XX_IOPAD(0x95C, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+                       AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
+                       AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
                >;
        };
 };
 &am33xx_pinmux {
        uart0_pins: pinmux_uart0 {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
                >;
        };
        uart1_pins: pinmux_uart1 {
                pinctrl-single,pins = <
-                       0x178 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_ctsn.uart1_ctsn */
-                       0x17C (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
-                       0x180 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_rxd.uart1_rxd */
-                       0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
+                       AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart1_ctsn.uart1_ctsn */
+                       AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_rtsn.uart1_rtsn */
+                       AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart1_rxd.uart1_rxd */
+                       AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_txd.uart1_txd */
                >;
        };
 };
        usb_pins: pinmux_usb {
                pinctrl-single,pins = <
                        /* USB0 Over-Current (active low) */
-                       0x64 (PIN_INPUT | MUX_MODE7)    /* gpmc_a9.gpio1_25 */
+                       AM33XX_IOPAD(0x864, PIN_INPUT | MUX_MODE7)      /* gpmc_a9.gpio1_25 */
                        /* USB1 Over-Current (active low) */
-                       0x68 (PIN_INPUT | MUX_MODE7)    /* gpmc_a10.gpio1_26 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT | MUX_MODE7)      /* gpmc_a10.gpio1_26 */
                >;
        };
 };
                label = "home";
                linux,code = <KEY_HOME>;
                gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
-               gpio-key,wakeup;
+               wakeup-source;
        };
 
        button@1 {
                label = "menu";
                linux,code = <KEY_MENU>;
                gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
-               gpio-key,wakeup;
+               wakeup-source;
        };
 
        buttons@2 {
                label = "power";
                linux,code = <KEY_POWER>;
                gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
-               gpio-key,wakeup;
+               wakeup-source;
        };
 };
 
 &am33xx_pinmux {
        user_leds_pins: pinmux_user_leds {
                pinctrl-single,pins = <
-                       0x50 (PIN_OUTPUT | MUX_MODE7)   /* gpmc_a4.gpio1_20 */
-                       0x54 (PIN_OUTPUT | MUX_MODE7)   /* gpmc_a5.gpio1_21 */
+                       AM33XX_IOPAD(0x850, PIN_OUTPUT | MUX_MODE7)     /* gpmc_a4.gpio1_20 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7)     /* gpmc_a5.gpio1_21 */
                >;
        };
 
        user_buttons_pins: pinmux_user_buttons {
                pinctrl-single,pins = <
-                       0x58 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_a6.gpio1_22 */
-                       0x5C (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_a7.gpio1_21 */
-                       0x164 (PIN_INPUT_PULLUP | MUX_MODE7)    /* gpmc_a8.gpio0_7 */
+                       AM33XX_IOPAD(0x858, PIN_INPUT_PULLUP | MUX_MODE7)       /* gpmc_a6.gpio1_22 */
+                       AM33XX_IOPAD(0x85C, PIN_INPUT_PULLUP | MUX_MODE7)       /* gpmc_a7.gpio1_21 */
+                       AM33XX_IOPAD(0x964, PIN_INPUT_PULLUP | MUX_MODE7)       /* gpmc_a8.gpio0_7 */
                >;
        };
 };
index 2f43e45..c20ae6c 100644 (file)
 &am33xx_pinmux {
        ethernet0_pins: pinmux_ethernet0 {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs_dv */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxerr.rmii1_rxerr */
-                       0x114 (PIN_OUTPUT | MUX_MODE1)          /* mii1_txen.rmii1_txen */
-                       0x124 (PIN_OUTPUT | MUX_MODE1)          /* mii1_txd1.rmii1_txd1 */
-                       0x128 (PIN_OUTPUT | MUX_MODE1)          /* mii1_txd0.rmii1_txd0 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd1.rmii1_rxd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd0.rmii1_rxd0 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* rmii1_refclk.rmii1_refclk */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_crs.rmii1_crs_dv */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxerr.rmii1_rxerr */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT | MUX_MODE1)             /* mii1_txen.rmii1_txen */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT | MUX_MODE1)             /* mii1_txd1.rmii1_txd1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE1)             /* mii1_txd0.rmii1_txd0 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxd1.rmii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxd0.rmii1_rxd0 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* rmii1_refclk.rmii1_refclk */
                >;
        };
 
        mdio_pins: pinmux_mdio {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 };
 &am33xx_pinmux {
        i2c0_pins: pinmux_i2c0 {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT | MUX_MODE0)   /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT | MUX_MODE0)   /* i2c0_scl.i2c0_scl */
+                       AM33XX_IOPAD(0x988, PIN_INPUT | MUX_MODE0)      /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT | MUX_MODE0)      /* i2c0_scl.i2c0_scl */
                >;
        };
 };
 &am33xx_pinmux {
                nandflash_pins: pinmux_nandflash {
                        pinctrl-single,pins = <
-                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
-                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
-                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
-                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
-                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0 */
-                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad0.gpmc_ad0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad1.gpmc_ad1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad2.gpmc_ad2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad3.gpmc_ad3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad4.gpmc_ad4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad5.gpmc_ad5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad6.gpmc_ad6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_ad7.gpmc_ad7 */
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn0.gpmc_csn0 */
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)             /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)             /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)             /* gpmc_wen.gpmc_wen */
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_be0n_cle.gpmc_be0n_cle */
                >;
        };
 };
 &am33xx_pinmux {
        spi0_pins: pinmux_spi0 {
                pinctrl-single,pins = <
-                       0x150 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* spi0_clk.spi0_clk */
-                       0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* spi0_d0.spi0_d0 */
-                       0x158 (PIN_INPUT_PULLUP | MUX_MODE0)    /* spi0_d1.spi0_d1 */
-                       0x15c (PIN_INPUT_PULLUP | MUX_MODE0)    /* spi0_cs0.spi0_cs0 */
+                       AM33XX_IOPAD(0x950, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* spi0_clk.spi0_clk */
+                       AM33XX_IOPAD(0x954, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* spi0_d0.spi0_d0 */
+                       AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0)       /* spi0_d1.spi0_d1 */
+                       AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE0)       /* spi0_cs0.spi0_cs0 */
                >;
        };
 };
diff --git a/arch/arm/boot/dts/am335x-sbc-t335.dts b/arch/arm/boot/dts/am335x-sbc-t335.dts
new file mode 100644 (file)
index 0000000..917d7cc
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * am335x-sbc-t335.dts - Device Tree file for Compulab SBC-T335
+ *
+ * Copyright (C) 2014 - 2015 CompuLab Ltd. - http://www.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.
+ */
+
+#include "am335x-cm-t335.dts"
+
+/ {
+       model = "CompuLab CM-T335 on SB-T335";
+       compatible = "compulab,sbc-t335", "compulab,cm-t335", "ti,am33xx";
+
+       /* DRM display driver */
+       panel {
+               compatible = "ti,tilcdc,panel";
+               status = "okay";
+               pinctrl-names = "default", "sleep";
+               pinctrl-0 = <&lcd_pins_default>;
+               pinctrl-1 = <&lcd_pins_sleep>;
+
+               panel-info {
+                       ac-bias           = <255>;
+                       ac-bias-intrpt    = <0>;
+                       dma-burst-sz      = <16>;
+                       bpp               = <32>;
+                       fdd               = <0x80>;
+                       sync-edge         = <0>;
+                       sync-ctrl         = <1>;
+                       raster-order      = <0>;
+                       fifo-th           = <0>;
+               };
+               display-timings {
+                       /* Timing selection performed by U-Boot */
+                       timing0: lcd {/* 800x480p62 */
+                               clock-frequency = <30000000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hfront-porch = <39>;
+                               hback-porch = <39>;
+                               hsync-len = <47>;
+                               vback-porch = <29>;
+                               vfront-porch = <13>;
+                               vsync-len = <2>;
+                               hsync-active = <1>;
+                               vsync-active = <1>;
+                       };
+                       timing1: dvi { /* 1024x768p60 */
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               hfront-porch = <24>;
+                               hback-porch = <160>;
+                               hsync-len = <136>;
+                               vactive = <768>;
+                               vfront-porch = <3>;
+                               vback-porch = <29>;
+                               vsync-len = <6>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                       };
+               };
+       };
+};
+
+&am33xx_pinmux {
+       /* Display */
+       lcd_pins_default: lcd_pins_default {
+               pinctrl-single,pins = <
+                       /* gpmc_ad8.lcd_data23 */
+                       AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad9.lcd_data22 */
+                       AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad10.lcd_data21 */
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad11.lcd_data20 */
+                       AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad12.lcd_data19 */
+                       AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad13.lcd_data18 */
+                       AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad14.lcd_data17 */
+                       AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)
+                       /* gpmc_ad15.lcd_data16 */
+                       AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)
+                       /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)
+                       /* lcd_ac_bias_en.lcd_ac_bias_en */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)
+               >;
+       };
+
+       lcd_pins_sleep: lcd_pins_sleep {
+               pinctrl-single,pins = <
+                       /* gpmc_ad8.lcd_data23 */
+                       AM33XX_IOPAD(0x820, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad9.lcd_data22 */
+                       AM33XX_IOPAD(0x824, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad10.lcd_data21 */
+                       AM33XX_IOPAD(0x828, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad11.lcd_data20 */
+                       AM33XX_IOPAD(0x82c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad12.lcd_data19 */
+                       AM33XX_IOPAD(0x830, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad13.lcd_data18 */
+                       AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad14.lcd_data17 */
+                       AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* gpmc_ad15.lcd_data16 */
+                       AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a0, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a4, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8a8, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8ac, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b0, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b4, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8b8, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8bc, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c0, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c4, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8c8, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8cc, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d0, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d4, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8d8, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8dc, PULL_DISABLE | MUX_MODE7)
+                       /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       /* lcd_ac_bias_en.lcd_ac_bias_en */
+                       AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+};
+
+&i2c0 {
+       /* GPIO extender */
+       gpio_ext: pca9555@26 {
+               compatible = "nxp,pca9555";
+               pinctrl-names = "default";
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0x26>;
+               dvi_ena {
+                       gpio-hog;
+                       gpios = <13 GPIO_ACTIVE_HIGH>;
+                       output-high;
+                       line-name = "dvi-enable";
+               };
+               lcd_ena {
+                       gpio-hog;
+                       gpios = <11 GPIO_ACTIVE_HIGH>;
+                       output-high;
+                       line-name = "lcd-enable";
+               };
+       };
+};
+
+/* Display */
+&lcdc {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-shc.dts b/arch/arm/boot/dts/am335x-shc.dts
new file mode 100644 (file)
index 0000000..1b5b044
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * support for the bosch am335x based shc c3 board
+ *
+ * Copyright, C) 2015 Heiko Schocher <hs@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Bosch SHC";
+       compatible = "ti,am335x-shc", "ti,am335x-bone", "ti,am33xx";
+
+       aliases {
+               mmcblk0 = &mmc1;
+               mmcblk1 = &mmc2;
+       };
+
+       cpus {
+               cpu@0 {
+                       /*
+                        * To consider voltage drop between PMIC and SoC,
+                        * tolerance value is reduced to 2% from 4% and
+                        * voltage value is increased as a precaution.
+                        */
+                       operating-points = <
+                               /* kHz    uV */
+                               594000  1225000
+                               294000  1125000
+                       >;
+                       voltage-tolerance = <2>; /* 2 percentage */
+                       cpu0-supply = <&dcdc2_reg>;
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               back_button {
+                       label = "Back Button";
+                       gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_BACK>;
+                       debounce-interval = <1000>;
+                       gpio-key,wakeup;
+               };
+
+               front_button {
+                       label = "Front Button";
+                       gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_FRONT>;
+                       debounce-interval = <1000>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&user_leds_s0>;
+
+               compatible = "gpio-leds";
+
+               led@1 {
+                       label = "shc:power:red";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               led@2 {
+                       label = "shc:power:bl";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "timer";
+                       default-state = "on";
+               };
+
+               led@3 {
+                       label = "shc:lan:red";
+                       gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               led@4 {
+                       label = "shc:lan:bl";
+                       gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               led@5 {
+                       label = "shc:cloud:red";
+                       gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               led@6 {
+                       label = "shc:cloud:bl";
+                       gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>; /* 512 MB */
+       };
+
+       vmmcsd_fixed: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&aes {
+       status = "okay";
+};
+
+&cppi41dma  {
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_default>;
+       pinctrl-1 = <&davinci_mdio_sleep>;
+       status = "okay";
+
+       ethernetphy0: ethernet-phy@0 {
+               reg = <0>;
+               smsc,disable-energy-detect;
+       };
+};
+
+&epwmss1 {
+       status = "okay";
+
+       ehrpwm1: ehrpwm@48302200 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&ehrpwm1_pins>;
+               status = "okay";
+       };
+};
+
+&gpio1 {
+       hmtc_rst {
+               gpio-hog;
+               gpios = <24 GPIO_ACTIVE_LOW>;
+               output-high;
+               line-name = "homematic_reset";
+       };
+
+       hmtc_prog {
+               gpio-hog;
+               gpios = <27 GPIO_ACTIVE_LOW>;
+               output-high;
+               line-name = "homematic_program";
+       };
+};
+
+&gpio3 {
+       zgb_rst {
+               gpio-hog;
+               gpios = <18 GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "zigbee_reset";
+       };
+
+       zgb_boot {
+               gpio-hog;
+               gpios = <19 GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "zigbee_boot";
+       };
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       status = "okay";
+       clock-frequency = <400000>;
+
+       tps: tps@24 {
+               reg = <0x24>;
+       };
+
+       at24@50 {
+               compatible = "at24,24c32";
+               pagesize = <32>;
+               reg = <0x50>;
+       };
+
+       pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&mac {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_default>;
+       pinctrl-1 = <&cpsw_sleep>;
+       status = "okay";
+       slaves = <1>;
+       cpsw_emac0: slave@4a100200  {
+               phy_id = <&davinci_mdio>, <0>;
+               phy-mode = "mii";
+               phy-handle = <&ethernetphy0>;
+       };
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       bus-width = <0x4>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+       cd-inverted;
+       max-frequency = <26000000>;
+       vmmc-supply = <&vmmcsd_fixed>;
+       status = "okay";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>;
+       bus-width = <8>;
+       max-frequency = <26000000>;
+       sd-uhs-sdr25;
+       vmmc-supply = <&vmmcsd_fixed>;
+       status = "okay";
+};
+
+&mmc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc3_pins>;
+       bus-width = <4>;
+       cap-power-off-card;
+       max-frequency = <26000000>;
+       sd-uhs-sdr25;
+       vmmc-supply = <&vmmcsd_fixed>;
+       status = "okay";
+};
+
+&rtc {
+       ti,no-init;
+};
+
+&sham {
+       status = "okay";
+};
+
+&tps {
+       compatible = "ti,tps65217";
+       ti,pmic-shutdown-controller;
+
+       regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dcdc1_reg: regulator@0 {
+                       reg = <0>;
+                       regulator-name = "vdds_dpr";
+                       regulator-compatible = "dcdc1";
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1450000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc2_reg: regulator@1 {
+                       reg = <1>;
+                       /*
+                        * VDD_MPU voltage limits 0.95V - 1.26V with
+                        * +/-4% tolerance
+                        */
+                       regulator-compatible = "dcdc2";
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <1375000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+                       regulator-ramp-delay = <70000>;
+               };
+
+               dcdc3_reg: regulator@2 {
+                       reg = <2>;
+                       /*
+                        * VDD_CORE voltage limits 0.95V - 1.1V with
+                        * +/-4% tolerance
+                        */
+                       regulator-name = "vdd_core";
+                       regulator-compatible = "dcdc3";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <1125000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo1_reg: regulator@3 {
+                       reg = <3>;
+                       regulator-name = "vio,vrtc,vdds";
+                       regulator-compatible = "ldo1";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               ldo2_reg: regulator@4 {
+                       reg = <4>;
+                       regulator-name = "vdd_3v3aux";
+                       regulator-compatible = "ldo2";
+                       regulator-min-microvolt = <900000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               ldo3_reg: regulator@5 {
+                       reg = <5>;
+                       regulator-name = "vdd_1v8";
+                       regulator-compatible = "ldo3";
+                       regulator-min-microvolt = <900000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               ldo4_reg: regulator@6 {
+                       reg = <6>;
+                       regulator-name = "vdd_3v3a";
+                       regulator-compatible = "ldo4";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_pins>;
+       status = "okay";
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_ctrl_mod {
+       status = "okay";
+};
+
+&usb1_phy {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&clkout2_pin>;
+
+       clkout2_pin: pinmux_clkout2_pin {
+               pinctrl-single,pins = <
+                       /* xdma_event_intr1.clkout2 */
+                       AM33XX_IOPAD(0x9b4, PIN_INPUT | MUX_MODE6)
+               >;
+       };
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+                       /* mdio_clk.mdio_clk */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       ehrpwm1_pins: pinmux_ehrpwm1 {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE6) /* gpmc_a3.gpio1_19 */
+               >;
+       };
+
+       emmc_pins: pinmux_emmc_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x880, PIN_INPUT | MUX_MODE2)
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2)
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1)
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1)
+               >;
+       };
+
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x988, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x98c, PIN_INPUT | MUX_MODE0)
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE5)
+               >;
+       };
+
+       mmc3_pins: pinmux_mmc3_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x830, PIN_INPUT | MUX_MODE3)
+                       AM33XX_IOPAD(0x834, PIN_INPUT | MUX_MODE3)
+                       AM33XX_IOPAD(0x838, PIN_INPUT | MUX_MODE3)
+                       AM33XX_IOPAD(0x83c, PIN_INPUT | MUX_MODE3)
+                       AM33XX_IOPAD(0x888, PIN_INPUT | MUX_MODE3)
+                       AM33XX_IOPAD(0x88c, PIN_INPUT | MUX_MODE3)
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x968, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x96c, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT | MUX_MODE0)
+               >;
+       };
+
+       uart1_pins: pinmux_uart1 {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x978, PIN_INPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x97C, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x984, PIN_OUTPUT | MUX_MODE0)
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)
+                       AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)
+               >;
+       };
+
+       uart4_pins: pinmux_uart4_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE6)
+                       AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE6)
+               >;
+       };
+
+       user_leds_s0: user_leds_s0 {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x844, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x858, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLUP | MUX_MODE7)
+                       AM33XX_IOPAD(0x860, PIN_INPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x864, PIN_INPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x868, PIN_INPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x86c, PIN_INPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x878, PIN_OUTPUT_PULLUP | MUX_MODE7)
+                       AM33XX_IOPAD(0x87c, PIN_INPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x894, PIN_INPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x958, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x95c, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x964, PIN_OUTPUT_PULLUP | MUX_MODE7)
+                       AM33XX_IOPAD(0x9a0, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x9a4, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE7)
+               >;
+       };
+};
index 3303c28..d38edfa 100644 (file)
        pinctrl-0 = <&uart4_pins>;
 };
 
-#include "tps65217.dtsi"
-
 &tps {
+       compatible = "ti,tps65217";
        ti,pmic-shutdown-controller;
 
        interrupt-parent = <&intc>;
        interrupts = <7>;       /* NNMI */
 
        regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                dcdc1_reg: regulator@0 {
+                       reg = <0>;
                        /* VDDS_DDR */
                        regulator-min-microvolt = <1500000>;
                        regulator-max-microvolt = <1500000>;
                };
 
                dcdc2_reg: regulator@1 {
+                       reg = <1>;
                        /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
                        regulator-name = "vdd_mpu";
                        regulator-min-microvolt = <925000>;
                };
 
                dcdc3_reg: regulator@2 {
+                       reg = <2>;
                        /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
                        regulator-name = "vdd_core";
                        regulator-min-microvolt = <925000>;
                };
 
                ldo1_reg: regulator@3 {
+                       reg = <3>;
                        /* VRTC / VIO / VDDS*/
                        regulator-always-on;
                        regulator-min-microvolt = <1800000>;
                };
 
                ldo2_reg: regulator@4 {
+                       reg = <4>;
                        /* VDD_3V3AUX */
                        regulator-always-on;
                        regulator-min-microvolt = <3300000>;
                };
 
                ldo3_reg: regulator@5 {
+                       reg = <5>;
                        /* VDD_1V8 */
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                };
 
                ldo4_reg: regulator@6 {
+                       reg = <6>;
                        /* VDD_3V3A */
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index 2cecb39..282f6d4 100644 (file)
@@ -28,8 +28,8 @@
 &am33xx_pinmux {
        dcan1_pins: pinmux_dcan1 {
                pinctrl-single,pins = <
-                       0x168 (PIN_OUTPUT_PULLUP | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
-                       0x16c (PIN_INPUT_PULLUP | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
+                       AM33XX_IOPAD(0x968, PIN_OUTPUT_PULLUP | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
+                       AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
                >;
        };
 };
 &am33xx_pinmux {
        ethernet1_pins: pinmux_ethernet1 {
                pinctrl-single,pins = <
-                       0x40 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_a0.mii2_txen */
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a1.mii2_rxdv */
-                       0x48 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_a2.mii2_txd3 */
-                       0x4c (PIN_OUTPUT | MUX_MODE1)           /* gpmc_a3.mii2_txd2 */
-                       0x50 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_a4.mii2_txd1 */
-                       0x54 (PIN_OUTPUT | MUX_MODE1)           /* gpmc_a5.mii2_txd0 */
-                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a6.mii2_txclk */
-                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a7.mii2_rxclk */
-                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a8.mii2_rxd3 */
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a9.mii2_rxd2 */
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a10.mii2_rxd1 */
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_a11.mii2_rxd0 */
-                       0x74 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_wpn.mii2_rxerr */
-                       0x78 (PIN_INPUT_PULLDOWN | MUX_MODE1)   /* gpmc_ben1.mii2_col */
+                       AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE1)             /* gpmc_a0.mii2_txen */
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a1.mii2_rxdv */
+                       AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE1)             /* gpmc_a2.mii2_txd3 */
+                       AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE1)             /* gpmc_a3.mii2_txd2 */
+                       AM33XX_IOPAD(0x850, PIN_OUTPUT | MUX_MODE1)             /* gpmc_a4.mii2_txd1 */
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE1)             /* gpmc_a5.mii2_txd0 */
+                       AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a6.mii2_txclk */
+                       AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a7.mii2_rxclk */
+                       AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a8.mii2_rxd3 */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a9.mii2_rxd2 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a10.mii2_rxd1 */
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_a11.mii2_rxd0 */
+                       AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_wpn.mii2_rxerr */
+                       AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* gpmc_ben1.mii2_col */
                >;
        };
 };
 &am33xx_pinmux {
        mmc1_pins: pinmux_mmc1 {
                pinctrl-single,pins = <
-                       0x0F0 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat3.mmc0_dat3 */
-                       0x0F4 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat2.mmc0_dat2 */
-                       0x0F8 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat1.mmc0_dat1 */
-                       0x0FC (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat0.mmc0_dat0 */
-                       0x100 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_clk.mmc0_clk */
-                       0x104 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_cmd.mmc0_cmd */
-                       0x160 (PIN_INPUT_PULLUP | MUX_MODE7)    /* spi0_cs1.mmc0_sdcd */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat3.mmc0_dat3 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat2.mmc0_dat2 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat1.mmc0_dat1 */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_dat0.mmc0_dat0 */
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_clk.mmc0_clk */
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)       /* mmc0_cmd.mmc0_cmd */
+                       AM33XX_IOPAD(0x960, PIN_INPUT_PULLUP | MUX_MODE7)       /* spi0_cs1.mmc0_sdcd */
                >;
        };
 };
 &am33xx_pinmux {
        uart0_pins: pinmux_uart0 {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
                >;
        };
 
        uart1_pins: pinmux_uart1_pins {
                pinctrl-single,pins = <
-                       0x180 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_rxd.uart1_rxd */
-                       0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
-                       0x178 (PIN_INPUT | MUX_MODE0)           /* uart1_ctsn.uart1_ctsn */
-                       0x17c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)         /* uart1_rtsn.uart1_rtsn */
+                       AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart1_rxd.uart1_rxd */
+                       AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_txd.uart1_txd */
+                       AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0)              /* uart1_ctsn.uart1_ctsn */
+                       AM33XX_IOPAD(0x97c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_rtsn.uart1_rtsn */
                >;
        };
 };
index d23e252..04885f9 100644 (file)
                                        mboxes = <&mailbox &mbox_wkupm3>;
                                };
 
+                               edma_xbar: dma-router@f90 {
+                                       compatible = "ti,am335x-edma-crossbar";
+                                       reg = <0xf90 0x40>;
+                                       #dma-cells = <3>;
+                                       dma-requests = <32>;
+                                       dma-masters = <&edma>;
+                               };
+
                                scm_clockdomains: clockdomains {
                                };
                        };
                };
 
                edma: edma@49000000 {
-                       compatible = "ti,edma3";
-                       ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
-                       reg =   <0x49000000 0x10000>,
-                               <0x44e10f90 0x40>;
+                       compatible = "ti,edma3-tpcc";
+                       ti,hwmods = "tpcc";
+                       reg =   <0x49000000 0x10000>;
+                       reg-names = "edma3_cc";
                        interrupts = <12 13 14>;
-                       #dma-cells = <1>;
+                       interrupt-names = "edma3_ccint", "emda3_mperr",
+                                         "edma3_ccerrint";
+                       dma-requests = <64>;
+                       #dma-cells = <2>;
+
+                       ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
+                                  <&edma_tptc2 0>;
+
+                       ti,edma-memcpy-channels = <20 21>;
+               };
+
+               edma_tptc0: tptc@49800000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc0";
+                       reg =   <0x49800000 0x100000>;
+                       interrupts = <112>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc1: tptc@49900000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc1";
+                       reg =   <0x49900000 0x100000>;
+                       interrupts = <113>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc2: tptc@49a00000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc2";
+                       reg =   <0x49a00000 0x100000>;
+                       interrupts = <114>;
+                       interrupt-names = "edma3_tcerrint";
                };
 
                gpio0: gpio@44e07000 {
                        reg = <0x44e09000 0x2000>;
                        interrupts = <72>;
                        status = "disabled";
-                       dmas = <&edma 26>, <&edma 27>;
+                       dmas = <&edma 26 0>, <&edma 27 0>;
                        dma-names = "tx", "rx";
                };
 
                        reg = <0x48022000 0x2000>;
                        interrupts = <73>;
                        status = "disabled";
-                       dmas = <&edma 28>, <&edma 29>;
+                       dmas = <&edma 28 0>, <&edma 29 0>;
                        dma-names = "tx", "rx";
                };
 
                        reg = <0x48024000 0x2000>;
                        interrupts = <74>;
                        status = "disabled";
-                       dmas = <&edma 30>, <&edma 31>;
+                       dmas = <&edma 30 0>, <&edma 31 0>;
                        dma-names = "tx", "rx";
                };
 
                        ti,dual-volt;
                        ti,needs-special-reset;
                        ti,needs-special-hs-handling;
-                       dmas = <&edma 24
-                               &edma 25>;
+                       dmas = <&edma_xbar 24 0 0
+                               &edma_xbar 25 0 0>;
                        dma-names = "tx", "rx";
                        interrupts = <64>;
                        interrupt-parent = <&intc>;
                        compatible = "ti,omap4-hsmmc";
                        ti,hwmods = "mmc2";
                        ti,needs-special-reset;
-                       dmas = <&edma 2
-                               &edma 3>;
+                       dmas = <&edma 2 0
+                               &edma 3 0>;
                        dma-names = "tx", "rx";
                        interrupts = <28>;
                        interrupt-parent = <&intc>;
                        interrupts = <65>;
                        ti,spi-num-cs = <2>;
                        ti,hwmods = "spi0";
-                       dmas = <&edma 16
-                               &edma 17
-                               &edma 18
-                               &edma 19>;
+                       dmas = <&edma 16 0
+                               &edma 17 0
+                               &edma 18 0
+                               &edma 19 0>;
                        dma-names = "tx0", "rx0", "tx1", "rx1";
                        status = "disabled";
                };
                        interrupts = <125>;
                        ti,spi-num-cs = <2>;
                        ti,hwmods = "spi1";
-                       dmas = <&edma 42
-                               &edma 43
-                               &edma 44
-                               &edma 45>;
+                       dmas = <&edma 42 0
+                               &edma 43 0
+                               &edma 44 0
+                               &edma 45 0>;
                        dma-names = "tx0", "rx0", "tx1", "rx1";
                        status = "disabled";
                };
                        ti,no-idle-on-init;
                        reg = <0x50000000 0x2000>;
                        interrupts = <100>;
+                       dmas = <&edma 52>;
+                       dma-names = "rxtx";
                        gpmc,num-cs = <7>;
                        gpmc,num-waitpins = <2>;
                        #address-cells = <2>;
                        ti,hwmods = "sham";
                        reg = <0x53100000 0x200>;
                        interrupts = <109>;
-                       dmas = <&edma 36>;
+                       dmas = <&edma 36 0>;
                        dma-names = "rx";
                };
 
                        ti,hwmods = "aes";
                        reg = <0x53500000 0xa0>;
                        interrupts = <103>;
-                       dmas = <&edma 6>,
-                              <&edma 5>;
+                       dmas = <&edma 6 0>,
+                              <&edma 5 0>;
                        dma-names = "tx", "rx";
                };
 
                        interrupts = <80>, <81>;
                        interrupt-names = "tx", "rx";
                        status = "disabled";
-                       dmas = <&edma 8>,
-                               <&edma 9>;
+                       dmas = <&edma 8 2>,
+                               <&edma 9 2>;
                        dma-names = "tx", "rx";
                };
 
                        interrupts = <82>, <83>;
                        interrupt-names = "tx", "rx";
                        status = "disabled";
-                       dmas = <&edma 10>,
-                               <&edma 11>;
+                       dmas = <&edma 10 2>,
+                               <&edma 11 2>;
                        dma-names = "tx", "rx";
                };
 
index 2d40b3f..cb7de1d 100644 (file)
@@ -77,7 +77,7 @@
 &omap3_pmx_core {
        tps_pins: pinmux_tps_pins {
                pinctrl-single,pins = <
-                       0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq.sys_nirq */
+                       OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq.sys_nirq */
                >;
        };
 };
index de8791a..df955ba 100644 (file)
@@ -30,6 +30,7 @@
                serial5 = &uart5;
                ethernet0 = &cpsw_emac0;
                ethernet1 = &cpsw_emac1;
+               spi0 = &qspi;
        };
 
        cpus {
                                        mboxes = <&mailbox &mbox_wkupm3>;
                                };
 
+                               edma_xbar: dma-router@f90 {
+                                       compatible = "ti,am335x-edma-crossbar";
+                                       reg = <0xf90 0x40>;
+                                       #dma-cells = <3>;
+                                       dma-requests = <64>;
+                                       dma-masters = <&edma>;
+                               };
+
                                scm_clockdomains: clockdomains {
                                };
                        };
                };
 
                edma: edma@49000000 {
-                       compatible = "ti,edma3";
-                       ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
-                       reg =   <0x49000000 0x10000>,
-                               <0x44e10f90 0x10>;
+                       compatible = "ti,edma3-tpcc";
+                       ti,hwmods = "tpcc";
+                       reg =   <0x49000000 0x10000>;
+                       reg-names = "edma3_cc";
                        interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-                                       <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-                                       <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
-                       #dma-cells = <1>;
+                                    <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "edma3_ccint", "emda3_mperr",
+                                         "edma3_ccerrint";
+                       dma-requests = <64>;
+                       #dma-cells = <2>;
+
+                       ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
+                                  <&edma_tptc2 0>;
+
+                       ti,edma-memcpy-channels = <32 33>;
+               };
+
+               edma_tptc0: tptc@49800000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc0";
+                       reg =   <0x49800000 0x100000>;
+                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc1: tptc@49900000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc1";
+                       reg =   <0x49900000 0x100000>;
+                       interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc2: tptc@49a00000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc2";
+                       reg =   <0x49a00000 0x100000>;
+                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "edma3_tcerrint";
                };
 
                uart0: serial@44e09000 {
                        ti,hwmods = "mmc1";
                        ti,dual-volt;
                        ti,needs-special-reset;
-                       dmas = <&edma 24
-                               &edma 25>;
+                       dmas = <&edma 24 0>,
+                               <&edma 25 0>;
                        dma-names = "tx", "rx";
                        interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                        reg = <0x481d8000 0x1000>;
                        ti,hwmods = "mmc2";
                        ti,needs-special-reset;
-                       dmas = <&edma 2
-                               &edma 3>;
+                       dmas = <&edma 2 0>,
+                               <&edma 3 0>;
                        dma-names = "tx", "rx";
                        interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                        compatible = "ti,omap5-sham";
                        ti,hwmods = "sham";
                        reg = <0x53100000 0x300>;
-                       dmas = <&edma 36>;
+                       dmas = <&edma 36 0>;
                        dma-names = "rx";
                        interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
                };
                        ti,hwmods = "aes";
                        reg = <0x53501000 0xa0>;
                        interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma 6
-                               &edma 5>;
+                       dmas = <&edma 6 0>,
+                               <&edma 5 0>;
                        dma-names = "tx", "rx";
                };
 
                        ti,hwmods = "des";
                        reg = <0x53701000 0xa0>;
                        interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma 34
-                               &edma 33>;
+                       dmas = <&edma 34 0>,
+                               <&edma 33 0>;
                        dma-names = "tx", "rx";
                };
 
                        interrupts = <80>, <81>;
                        interrupt-names = "tx", "rx";
                        status = "disabled";
-                       dmas = <&edma 8>,
-                              <&edma 9>;
+                       dmas = <&edma 8 2>,
+                              <&edma 9 2>;
                        dma-names = "tx", "rx";
                };
 
                        interrupts = <82>, <83>;
                        interrupt-names = "tx", "rx";
                        status = "disabled";
-                       dmas = <&edma 10>,
-                              <&edma 11>;
+                       dmas = <&edma 10 2>,
+                              <&edma 11 2>;
                        dma-names = "tx", "rx";
                };
 
                gpmc: gpmc@50000000 {
                        compatible = "ti,am3352-gpmc";
                        ti,hwmods = "gpmc";
+                       dmas = <&edma 52>;
+                       dma-names = "rxtx";
                        clocks = <&l3s_gclk>;
                        clock-names = "fck";
                        reg = <0x50000000 0x2000>;
 
                qspi: qspi@47900000 {
                        compatible = "ti,am4372-qspi";
-                       reg = <0x47900000 0x100>;
+                       reg = <0x47900000 0x100>,
+                             <0x30000000 0x4000000>;
+                       reg-names = "qspi_base", "qspi_mmap";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "qspi";
diff --git a/arch/arm/boot/dts/am437x-cm-t43.dts b/arch/arm/boot/dts/am437x-cm-t43.dts
new file mode 100644 (file)
index 0000000..8677f4c
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2015 CompuLab, Ltd. - http://www.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "am4372.dtsi"
+
+/ {
+       model = "CompuLab CM-T43";
+       compatible = "compulab,am437x-cm-t43", "ti,am4372", "ti,am43";
+
+       leds {
+               compatible = "gpio-leds";
+
+               ledb {
+                       label = "cm-t43:green";
+                       gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       vmmc_3v3: fixedregulator-v3_3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmc_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               enable-active-high;
+       };
+};
+
+&am43xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cm_t43_led_pins>;
+
+       cm_t43_led_pins: cm_t43_led_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0xa78, MUX_MODE7)
+               >;
+       };
+
+       i2c0_pins: i2c0_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x988, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
+                       AM4372_IOPAD(0x98c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       emmc_pins: emmc_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad8.mmc1_dat0 */
+                       AM4372_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad9.mmc1_dat1 */
+                       AM4372_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad10.mmc1_dat2 */
+                       AM4372_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad11.mmc1_dat3 */
+                       AM4372_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad12.mmc1_dat4 */
+                       AM4372_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad13.mmc1_dat5 */
+                       AM4372_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad14.mmc1_dat6 */
+                       AM4372_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad15.mmc1_dat7 */
+                       AM4372_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       AM4372_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+               >;
+       };
+
+       spi0_pins: pinmux_spi0_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x950, PIN_INPUT | MUX_MODE0) /* spi0_sclk.spi0_sclk */
+                       AM4372_IOPAD(0x954, PIN_INPUT | MUX_MODE0) /* spi0_d0.spi0_d0 */
+                       AM4372_IOPAD(0x958, PIN_OUTPUT | MUX_MODE0) /* spi0_d1.spi0_d1 */
+                       AM4372_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+               >;
+       };
+
+       nand_flash_x8: nand_flash_x8 {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x800, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x804, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x808, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x80c, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x810, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x814, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x818, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x81c, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+                       AM4372_IOPAD(0x870, PIN_INPUT_PULLUP  | MUX_MODE0)
+                       AM4372_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x898, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM4372_IOPAD(0x894, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM4372_IOPAD(0x890, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM4372_IOPAD(0x89c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_txen */
+                       AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxdv.rgmii1_rxctl */
+                       AM4372_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_txd3 */
+                       AM4372_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_txd2 */
+                       AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_txd1 */
+                       AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_txd0 */
+                       AM4372_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rmii1_tclk */
+                       AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxclk.rmii1_rclk */
+                       AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rxd3 */
+                       AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rxd2 */
+                       AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rxd1 */
+                       AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rxd0 */
+                       AM4372_IOPAD(0xa74, MUX_MODE3)
+                       /* Slave 2 */
+                       AM4372_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a0.txen */
+                       AM4372_IOPAD(0x844, PIN_INPUT_PULLDOWN  | MUX_MODE2)    /* gpmc_a1.rxctl */
+                       AM4372_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a2.txd3 */
+                       AM4372_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a3.txd2 */
+                       AM4372_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a4.txd1 */
+                       AM4372_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a5.txd0 */
+                       AM4372_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* gpmc_a6.tclk */
+                       AM4372_IOPAD(0x85c, PIN_INPUT_PULLDOWN  | MUX_MODE2)    /* gpmc_a7.rclk */
+                       AM4372_IOPAD(0x860, PIN_INPUT_PULLDOWN  | MUX_MODE2)    /* gpmc_a8.rxd3 */
+                       AM4372_IOPAD(0x864, PIN_INPUT_PULLDOWN  | MUX_MODE2)    /* gpmc_a9.rxd2 */
+                       AM4372_IOPAD(0x868, PIN_INPUT_PULLDOWN  | MUX_MODE2)    /* gpmc_a10.rxd1 */
+                       AM4372_IOPAD(0x86c, PIN_INPUT_PULLDOWN  | MUX_MODE2)    /* gpmc_a11.rxd0 */
+                       AM4372_IOPAD(0xa38, MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM4372_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
+               >;
+       };
+};
+
+&gpmc {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_flash_x8>;
+       ranges = <0 0 0x08000000 0x1000000>;
+       nand@0,0 {
+               reg = <0 0 0>;
+               ti,nand-ecc-opt = "bch8";
+               ti,elm-id = <&elm>;
+
+               nand-bus-width = <8>;
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,wait-on-read = "true";
+               gpmc,wait-on-write = "true";
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+
+               gpmc,wait-pin = <0>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+               /* MTD partition table */
+               partition@0 {
+                       label = "kernel";
+                       reg = <0x0 0x00980000>;
+               };
+               partition@980000 {
+                       label = "dtb";
+                       reg = <0x00980000 0x00080000>;
+               };
+               partition@a00000 {
+                       label = "rootfs";
+                       reg = <0x00a00000 0x0>;
+               };
+       };
+};
+
+&i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       clock-frequency = <100000>;
+
+       tps65218: tps65218@24 {
+               compatible = "ti,tps65218";
+               reg = <0x24>;
+               interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
+               interrupt-parent = <&gic>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+
+               dcdc1: regulator-dcdc1 {
+                       compatible = "ti,tps65218-dcdc1";
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <1144000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc2: regulator-dcdc2 {
+                       compatible = "ti,tps65218-dcdc2";
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <1378000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc3: regulator-dcdc3 {
+                       compatible = "ti,tps65218-dcdc3";
+                       regulator-name = "vdcdc3";
+                       regulator-suspend-enable;
+                       regulator-min-microvolt = <1500000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc5: regulator-dcdc5 {
+                       compatible = "ti,tps65218-dcdc5";
+                       regulator-name = "v1_0bat";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc6: regulator-dcdc6 {
+                       compatible = "ti,tps65218-dcdc6";
+                       regulator-name = "v1_8bat";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo1: regulator-ldo1 {
+                       compatible = "ti,tps65218-ldo1";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+
+       eeprom_module: at24@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
+
+&gpio0 {
+       status = "okay";
+};
+
+&gpio1 {
+       status = "okay";
+};
+
+&gpio2 {
+       status = "okay";
+};
+
+&gpio3 {
+       status = "okay";
+};
+
+&gpio4 {
+       status = "okay";
+};
+
+&gpio5 {
+       status = "okay";
+};
+
+&mmc2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>;
+       vmmc-supply = <&vmmc_3v3>;
+       bus-width = <8>;
+       ti,non-removable;
+};
+
+&spi0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi0_pins>;
+       dmas = <&edma 16
+               &edma 17>;
+       dma-names = "tx0", "rx0";
+
+       flash: w25q64cvzpig@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <20000000>;
+               partition@0 {
+                       label = "uboot";
+                       reg = <0x0 0xc0000>;
+               };
+
+               partition@c0000 {
+                       label = "uboot environment";
+                       reg = <0xc0000 0x40000>;
+               };
+
+               partition@100000 {
+                       label = "reserved";
+                       reg = <0x100000 0x100000>;
+               };
+       };
+};
+
+&mac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cpsw_default>;
+       dual_emac = <1>;
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&davinci_mdio_default>;
+       status = "okay";
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       phy-mode = "rgmii-txid";
+       dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <1>;
+       phy-mode = "rgmii-txid";
+       dual_emac_res_vlan = <2>;
+};
+
+&dwc3_1 {
+       status = "okay";
+};
+
+&usb2_phy1 {
+       status = "okay";
+};
+
+&usb1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&dwc3_2 {
+       status = "okay";
+};
+
+&usb2_phy2 {
+       status = "okay";
+};
+
+&usb2 {
+       dr_mode = "host";
+       status = "okay";
+       interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+       interrupt-names = "peripheral", "host", "otg";
+};
+
+&elm {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&tscadc {
+       status = "okay";
+       tsc {
+               ti,wires = <4>;
+               ti,x-plate-resistance = <200>;
+               ti,coordiante-readouts = <5>;
+               ti,wire-config = <0x00 0x11 0x22 0x33>;
+       };
+
+       adc {
+               ti,adc-channels = <4 5 6 7>;
+       };
+};
+
+&cpu {
+       cpu0-supply = <&dcdc2>;
+       operating-points = <1000000 1330000>,
+                          <800000 1260000>,
+                          <720000 1200000>,
+                          <600000 1100000>,
+                          <300000 950000>;
+};
index d2450ab..64d4332 100644 (file)
 
        i2c0_pins: i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
+                       AM4372_IOPAD(0x988, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
+                       AM4372_IOPAD(0x98c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
                >;
        };
 
        i2c1_pins: i2c1_pins {
                pinctrl-single,pins = <
-                       0x15c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_cs0.i2c1_scl */
-                       0x158 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_d1.i2c1_sda  */
+                       AM4372_IOPAD(0x95c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_cs0.i2c1_scl */
+                       AM4372_IOPAD(0x958, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_d1.i2c1_sda  */
                >;
        };
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM4372_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                >;
        };
 
        ecap0_pins: backlight_pins {
                pinctrl-single,pins = <
-                       0x164 MUX_MODE0       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+                       AM4372_IOPAD(0x964, MUX_MODE0)       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
                >;
        };
 
        pixcir_ts_pins: pixcir_ts_pins {
                pinctrl-single,pins = <
-                       0x264 (PIN_INPUT_PULLUP | MUX_MODE7)  /* spi2_d0.gpio3_22 */
+                       AM4372_IOPAD(0xa64, PIN_INPUT_PULLUP | MUX_MODE7)  /* spi2_d0.gpio3_22 */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_txen */
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rxctl */
-                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd3 */
-                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd2 */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd1 */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd0 */
-                       0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rmii1_rclk */
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rxd3 */
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rxd2 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rxd1 */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rxd0 */
+                       AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_txen */
+                       AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxdv.rgmii1_rxctl */
+                       AM4372_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_txd3 */
+                       AM4372_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_txd2 */
+                       AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_txd1 */
+                       AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_txd0 */
+                       AM4372_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rmii1_tclk */
+                       AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxclk.rmii1_rclk */
+                       AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rxd3 */
+                       AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rxd2 */
+                       AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rxd1 */
+                       AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rxd0 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM4372_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        nand_flash_x8: nand_flash_x8 {
                pinctrl-single,pins = <
-                       0x0  (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad0.gpmc_ad0 */
-                       0x4  (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad1.gpmc_ad1 */
-                       0x8  (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad2.gpmc_ad2 */
-                       0xc  (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad3.gpmc_ad3 */
-                       0x10 (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad4.gpmc_ad4 */
-                       0x14 (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad5.gpmc_ad5 */
-                       0x18 (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad6.gpmc_ad6 */
-                       0x1c (PIN_INPUT  | MUX_MODE0)   /* gpmc_ad7.gpmc_ad7 */
-                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                       0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_wpn.gpmc_wpn */
-                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
-                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+                       AM4372_IOPAD(0x800, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad0.gpmc_ad0 */
+                       AM4372_IOPAD(0x804, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad1.gpmc_ad1 */
+                       AM4372_IOPAD(0x808, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad2.gpmc_ad2 */
+                       AM4372_IOPAD(0x80c, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad3.gpmc_ad3 */
+                       AM4372_IOPAD(0x810, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                       AM4372_IOPAD(0x814, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                       AM4372_IOPAD(0x818, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                       AM4372_IOPAD(0x81c, PIN_INPUT  | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+                       AM4372_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                       AM4372_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_wpn.gpmc_wpn */
+                       AM4372_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn0.gpmc_csn0  */
+                       AM4372_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)             /* gpmc_advn_ale.gpmc_advn_ale */
+                       AM4372_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)             /* gpmc_oen_ren.gpmc_oen_ren */
+                       AM4372_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)             /* gpmc_wen.gpmc_wen */
+                       AM4372_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_be0n_cle.gpmc_be0n_cle */
                >;
        };
 
        dss_pins: dss_pins {
                pinctrl-single,pins = <
-                       0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
-                       0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                       0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                       0x02c (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                       0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                       0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                       0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                       0x03c (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
-                       0x0a0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
-                       0x0a4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0a8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0ac (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0b0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0b4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0b8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0bc (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0c0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0c4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0c8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0cc (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0d0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0d4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0d8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                       0x0dc (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
-                       0x0e0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
-                       0x0e4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
-                       0x0e8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
-                       0x0ec (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+                       AM4372_IOPAD(0x820, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
+                       AM4372_IOPAD(0x824, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                       AM4372_IOPAD(0x828, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                       AM4372_IOPAD(0x82c, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                       AM4372_IOPAD(0x830, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                       AM4372_IOPAD(0x834, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                       AM4372_IOPAD(0x838, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                       AM4372_IOPAD(0x83c, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
+                       AM4372_IOPAD(0x8a0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+                       AM4372_IOPAD(0x8a4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8a8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8ac, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8b0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8b4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8b8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8bc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8c0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8c4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8c8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8cc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8d0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8d4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8d8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8dc, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+                       AM4372_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+                       AM4372_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+                       AM4372_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+                       AM4372_IOPAD(0x8ec, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
 
                >;
        };
        display_mux_pins: display_mux_pins {
                pinctrl-single,pins = <
                        /* GPIO 5_8 to select LCD / HDMI */
-                       0x238 (PIN_OUTPUT_PULLUP | MUX_MODE7)
+                       AM4372_IOPAD(0xa38, PIN_OUTPUT_PULLUP | MUX_MODE7)
                >;
        };
 
        dcan0_default: dcan0_default_pins {
                pinctrl-single,pins = <
-                       0x178 (PIN_OUTPUT | MUX_MODE2)          /* uart1_ctsn.d_can0_tx */
-                       0x17c (PIN_INPUT_PULLUP | MUX_MODE2)    /* uart1_rtsn.d_can0_rx */
+                       AM4372_IOPAD(0x978, PIN_OUTPUT | MUX_MODE2)             /* uart1_ctsn.d_can0_tx */
+                       AM4372_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE2)       /* uart1_rtsn.d_can0_rx */
                >;
        };
 
        dcan0_sleep: dcan0_sleep_pins {
                pinctrl-single,pins = <
-                       0x178 (PIN_INPUT_PULLUP | MUX_MODE7)    /* uart1_ctsn.gpio0_12 */
-                       0x17c (PIN_INPUT_PULLUP | MUX_MODE7)    /* uart1_rtsn.gpio0_13 */
+                       AM4372_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE7)       /* uart1_ctsn.gpio0_12 */
+                       AM4372_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE7)       /* uart1_rtsn.gpio0_13 */
                >;
        };
 
        dcan1_default: dcan1_default_pins {
                pinctrl-single,pins = <
-                       0x180 (PIN_OUTPUT | MUX_MODE2)          /* uart1_rxd.d_can1_tx */
-                       0x184 (PIN_INPUT_PULLUP | MUX_MODE2)    /* uart1_txd.d_can1_rx */
+                       AM4372_IOPAD(0x980, PIN_OUTPUT | MUX_MODE2)             /* uart1_rxd.d_can1_tx */
+                       AM4372_IOPAD(0x984, PIN_INPUT_PULLUP | MUX_MODE2)       /* uart1_txd.d_can1_rx */
                >;
        };
 
        dcan1_sleep: dcan1_sleep_pins {
                pinctrl-single,pins = <
-                       0x180 (PIN_INPUT_PULLUP | MUX_MODE7)    /* uart1_rxd.gpio0_14 */
-                       0x184 (PIN_INPUT_PULLUP | MUX_MODE7)    /* uart1_txd.gpio0_15 */
+                       AM4372_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE7)       /* uart1_rxd.gpio0_14 */
+                       AM4372_IOPAD(0x984, PIN_INPUT_PULLUP | MUX_MODE7)       /* uart1_txd.gpio0_15 */
                >;
        };
 
        vpfe0_pins_default: vpfe0_pins_default {
                pinctrl-single,pins = <
-                       0x1B0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_hd mode 0*/
-                       0x1B4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_vd mode 0*/
-                       0x1C0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_pclk mode 0*/
-                       0x1C4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data8 mode 0*/
-                       0x1C8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data9 mode 0*/
-                       0x208 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data0 mode 0*/
-                       0x20C (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data1 mode 0*/
-                       0x210 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data2 mode 0*/
-                       0x214 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data3 mode 0*/
-                       0x218 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data4 mode 0*/
-                       0x21C (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data5 mode 0*/
-                       0x220 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data6 mode 0*/
-                       0x224 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data7 mode 0*/
+                       AM4372_IOPAD(0x9b0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_hd mode 0*/
+                       AM4372_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_vd mode 0*/
+                       AM4372_IOPAD(0x9c0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_pclk mode 0*/
+                       AM4372_IOPAD(0x9c4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data8 mode 0*/
+                       AM4372_IOPAD(0x9c8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data9 mode 0*/
+                       AM4372_IOPAD(0xa08, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data0 mode 0*/
+                       AM4372_IOPAD(0xa0c, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data1 mode 0*/
+                       AM4372_IOPAD(0xa10, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data2 mode 0*/
+                       AM4372_IOPAD(0xa14, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data3 mode 0*/
+                       AM4372_IOPAD(0xa18, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data4 mode 0*/
+                       AM4372_IOPAD(0xa1c, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data5 mode 0*/
+                       AM4372_IOPAD(0xa20, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data6 mode 0*/
+                       AM4372_IOPAD(0xa24, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data7 mode 0*/
                >;
        };
 
        vpfe0_pins_sleep: vpfe0_pins_sleep {
                pinctrl-single,pins = <
-                       0x1B0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_hd mode 0*/
-                       0x1B4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_vd mode 0*/
-                       0x1C0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_pclk mode 0*/
-                       0x1C4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data8 mode 0*/
-                       0x1C8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data9 mode 0*/
-                       0x208 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data0 mode 0*/
-                       0x20C (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data1 mode 0*/
-                       0x210 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data2 mode 0*/
-                       0x214 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data3 mode 0*/
-                       0x218 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data4 mode 0*/
-                       0x21C (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data5 mode 0*/
-                       0x220 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data6 mode 0*/
-                       0x224 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data7 mode 0*/
+                       AM4372_IOPAD(0x9b0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_hd mode 0*/
+                       AM4372_IOPAD(0x9b4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_vd mode 0*/
+                       AM4372_IOPAD(0x9c0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_pclk mode 0*/
+                       AM4372_IOPAD(0x9c4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data8 mode 0*/
+                       AM4372_IOPAD(0x9c8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data9 mode 0*/
+                       AM4372_IOPAD(0xa08, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data0 mode 0*/
+                       AM4372_IOPAD(0xa0c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data1 mode 0*/
+                       AM4372_IOPAD(0xa10, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data2 mode 0*/
+                       AM4372_IOPAD(0xa14, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data3 mode 0*/
+                       AM4372_IOPAD(0xa18, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data4 mode 0*/
+                       AM4372_IOPAD(0xa1c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data5 mode 0*/
+                       AM4372_IOPAD(0xa20, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data6 mode 0*/
+                       AM4372_IOPAD(0xa24, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam0_data7 mode 0*/
                >;
        };
 
        vpfe1_pins_default: vpfe1_pins_default {
                pinctrl-single,pins = <
-                       0x1CC (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data9 mode 0*/
-                       0x1D0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data8 mode 0*/
-                       0x1D4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_hd mode 0*/
-                       0x1D8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_vd mode 0*/
-                       0x1DC (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_pclk mode 0*/
-                       0x1E8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data0 mode 0*/
-                       0x1EC (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data1 mode 0*/
-                       0x1F0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data2 mode 0*/
-                       0x1F4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data3 mode 0*/
-                       0x1F8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data4 mode 0*/
-                       0x1FC (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data5 mode 0*/
-                       0x200 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data6 mode 0*/
-                       0x204 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data7 mode 0*/
+                       AM4372_IOPAD(0x9cc, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data9 mode 0*/
+                       AM4372_IOPAD(0x9d0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data8 mode 0*/
+                       AM4372_IOPAD(0x9d4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_hd mode 0*/
+                       AM4372_IOPAD(0x9d8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_vd mode 0*/
+                       AM4372_IOPAD(0x9dC, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_pclk mode 0*/
+                       AM4372_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data0 mode 0*/
+                       AM4372_IOPAD(0x9ec, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data1 mode 0*/
+                       AM4372_IOPAD(0x9f0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data2 mode 0*/
+                       AM4372_IOPAD(0x9f4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data3 mode 0*/
+                       AM4372_IOPAD(0x9f8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data4 mode 0*/
+                       AM4372_IOPAD(0x9fc, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data5 mode 0*/
+                       AM4372_IOPAD(0xa00, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data6 mode 0*/
+                       AM4372_IOPAD(0xa04, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data7 mode 0*/
                >;
        };
 
        vpfe1_pins_sleep: vpfe1_pins_sleep {
                pinctrl-single,pins = <
-                       0x1CC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data9 mode 0*/
-                       0x1D0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data8 mode 0*/
-                       0x1D4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_hd mode 0*/
-                       0x1D8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_vd mode 0*/
-                       0x1DC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_pclk mode 0*/
-                       0x1E8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data0 mode 0*/
-                       0x1EC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data1 mode 0*/
-                       0x1F0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data2 mode 0*/
-                       0x1F4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data3 mode 0*/
-                       0x1F8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data4 mode 0*/
-                       0x1FC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data5 mode 0*/
-                       0x200 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data6 mode 0*/
-                       0x204 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data7 mode 0*/
+                       AM4372_IOPAD(0x9cc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data9 mode 0*/
+                       AM4372_IOPAD(0x9d0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data8 mode 0*/
+                       AM4372_IOPAD(0x9d4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_hd mode 0*/
+                       AM4372_IOPAD(0x9d8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_vd mode 0*/
+                       AM4372_IOPAD(0x9dc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_pclk mode 0*/
+                       AM4372_IOPAD(0x9e8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data0 mode 0*/
+                       AM4372_IOPAD(0x9ec, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data1 mode 0*/
+                       AM4372_IOPAD(0x9f0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data2 mode 0*/
+                       AM4372_IOPAD(0x9f4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data3 mode 0*/
+                       AM4372_IOPAD(0x9f8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data4 mode 0*/
+                       AM4372_IOPAD(0x9fc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data5 mode 0*/
+                       AM4372_IOPAD(0xa00, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data6 mode 0*/
+                       AM4372_IOPAD(0xa04, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)  /* cam1_data7 mode 0*/
                >;
        };
 
        mmc3_pins_default: pinmux_mmc3_pins_default {
                pinctrl-single,pins = <
-                       0x8c (PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_clk.mmc2_clk */
-                       0x88 (PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_csn3.mmc2_cmd */
-                       0x44 (PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_a1.mmc2_dat0 */
-                       0x48 (PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_a2.mmc2_dat1 */
-                       0x4c (PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_a3.mmc2_dat2 */
-                       0x78 (PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_be1n.mmc2_dat3 */
+                       AM4372_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_clk.mmc2_clk */
+                       AM4372_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_csn3.mmc2_cmd */
+                       AM4372_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_a1.mmc2_dat0 */
+                       AM4372_IOPAD(0x848, PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_a2.mmc2_dat1 */
+                       AM4372_IOPAD(0x84c, PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_a3.mmc2_dat2 */
+                       AM4372_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE3)      /* gpmc_be1n.mmc2_dat3 */
                >;
        };
 
        mmc3_pins_sleep: pinmux_mmc3_pins_sleep {
                pinctrl-single,pins = <
-                       0x8c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_clk.mmc2_clk */
-                       0x88 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_csn3.mmc2_cmd */
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a1.mmc2_dat0 */
-                       0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a2.mmc2_dat1 */
-                       0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_a3.mmc2_dat2 */
-                       0x78 (PIN_INPUT_PULLDOWN | MUX_MODE7)   /* gpmc_be1n.mmc2_dat3 */
+                       AM4372_IOPAD(0x88c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_clk.mmc2_clk */
+                       AM4372_IOPAD(0x888, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_csn3.mmc2_cmd */
+                       AM4372_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a1.mmc2_dat0 */
+                       AM4372_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a2.mmc2_dat1 */
+                       AM4372_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a3.mmc2_dat2 */
+                       AM4372_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_be1n.mmc2_dat3 */
                >;
        };
 
        wlan_pins_default: pinmux_wlan_pins_default {
                pinctrl-single,pins = <
-                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)          /* gpmc_a4.gpio1_20 WL_EN */
-                       0x5c (PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7)    /* gpmc_a7.gpio1_23 WL_IRQ*/
-                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)          /* gpmc_a0.gpio1_16 BT_EN*/
+                       AM4372_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE7)            /* gpmc_a4.gpio1_20 WL_EN */
+                       AM4372_IOPAD(0x85c, PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7)      /* gpmc_a7.gpio1_23 WL_IRQ*/
+                       AM4372_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE7)            /* gpmc_a0.gpio1_16 BT_EN*/
                >;
        };
 
        wlan_pins_sleep: pinmux_wlan_pins_sleep {
                pinctrl-single,pins = <
-                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)          /* gpmc_a4.gpio1_20 WL_EN */
-                       0x5c (PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7)    /* gpmc_a7.gpio1_23 WL_IRQ*/
-                       0x40 (PIN_OUTPUT_PULLUP | MUX_MODE7)            /* gpmc_a0.gpio1_16 BT_EN*/
+                       AM4372_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE7)            /* gpmc_a4.gpio1_20 WL_EN */
+                       AM4372_IOPAD(0x85c, PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7)      /* gpmc_a7.gpio1_23 WL_IRQ*/
+                       AM4372_IOPAD(0x840, PIN_OUTPUT_PULLUP | MUX_MODE7)              /* gpmc_a0.gpio1_16 BT_EN*/
                >;
        };
 
        uart3_pins: uart3_pins {
                pinctrl-single,pins = <
-                       0x228 (PIN_INPUT | MUX_MODE0)           /* uart3_rxd.uart3_rxd */
-                       0x22c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_txd.uart3_txd */
-                       0x230 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart3_ctsn.uart3_ctsn */
-                       0x234 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_rtsn.uart3_rtsn */
+                       AM4372_IOPAD(0xa28, PIN_INPUT | MUX_MODE0)              /* uart3_rxd.uart3_rxd */
+                       AM4372_IOPAD(0xa2c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_txd.uart3_txd */
+                       AM4372_IOPAD(0xa30, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart3_ctsn.uart3_ctsn */
+                       AM4372_IOPAD(0xa34, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_rtsn.uart3_rtsn */
                >;
        };
 
        mcasp1_pins: mcasp1_pins {
                pinctrl-single,pins = <
-                       0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4)  /* mii1_crs.mcasp1_aclkx */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4)  /* mii1_rxerr.mcasp1_fsx */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4)  /* rmii1_ref_clk.mcasp1_axr3 */
+                       AM4372_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4)    /* mii1_col.mcasp1_axr2 */
+                       AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4)     /* mii1_crs.mcasp1_aclkx */
+                       AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4)     /* mii1_rxerr.mcasp1_fsx */
+                       AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4)     /* rmii1_ref_clk.mcasp1_axr3 */
                >;
        };
 
        mcasp1_sleep_pins: mcasp1_sleep_pins {
                pinctrl-single,pins = <
-                       0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        gpio0_pins: gpio0_pins {
                pinctrl-single,pins = <
-                       0x26c (PIN_OUTPUT | MUX_MODE9) /* spi2_cs0.gpio0_23 SEL_eMMCorNANDn */
+                       AM4372_IOPAD(0xa6c, PIN_OUTPUT | MUX_MODE9) /* spi2_cs0.gpio0_23 SEL_eMMCorNANDn */
                >;
        };
 
        emmc_pins_default: emmc_pins_default {
                pinctrl-single,pins = <
-                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
-                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
-                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
-                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
-                       0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
-                       0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
-                       0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
-                       0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
-                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
-                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       AM4372_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       AM4372_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       AM4372_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       AM4372_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+                       AM4372_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+                       AM4372_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+                       AM4372_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+                       AM4372_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+                       AM4372_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       AM4372_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
                >;
        };
 
        emmc_pins_sleep: emmc_pins_sleep {
                pinctrl-single,pins = <
-                       0x00 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad0.gpio1_0 */
-                       0x04 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad1.gpio1_1 */
-                       0x08 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad2.gpio1_2 */
-                       0x0c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad3.gpio1_3 */
-                       0x10 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */
-                       0x14 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */
-                       0x18 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */
-                       0x1c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */
-                       0x80 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn1.gpio1_30 */
-                       0x84 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn2.gpio1_31 */
+                       AM4372_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad0.gpio1_0 */
+                       AM4372_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad1.gpio1_1 */
+                       AM4372_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad2.gpio1_2 */
+                       AM4372_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad3.gpio1_3 */
+                       AM4372_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */
+                       AM4372_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */
+                       AM4372_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */
+                       AM4372_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */
+                       AM4372_IOPAD(0x880, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn1.gpio1_30 */
+                       AM4372_IOPAD(0x884, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn2.gpio1_31 */
                >;
        };
 };
        status = "okay";
        /* these are on the crossbar and are outlined in the
           xbar-event-map element */
-       dmas = <&edma 30
-               &edma 31>;
+       dmas = <&edma_xbar 30 0 1>,
+               <&edma_xbar 31 0 2>;
        dma-names = "tx", "rx";
        vmmc-supply = <&vmmcwl_fixed>;
        bus-width = <4>;
        };
 };
 
-&edma {
-       ti,edma-xbar-event-map = /bits/ 16 <1 30
-                                           2 31>;
-};
-
 &uart3 {
        status = "okay";
        pinctrl-names = "default";
index 337fb91..76dcfc6 100644 (file)
 &am43xx_pinmux {
        gpio_keys_pins_default: gpio_keys_pins_default {
                pinctrl-single,pins = <
-                       0x1b8 (PIN_INPUT | MUX_MODE7)   /* cam0_field.gpio4_2 */
+                       AM4372_IOPAD(0x9b8, PIN_INPUT | MUX_MODE7)      /* cam0_field.gpio4_2 */
                >;
        };
 
        i2c0_pins_default: i2c0_pins_default {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+                       AM4372_IOPAD(0x988, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+                       AM4372_IOPAD(0x98c, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
                >;
        };
 
        i2c0_pins_sleep: i2c0_pins_sleep {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x18c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x988, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x98c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        i2c2_pins_default: i2c2_pins_default {
                pinctrl-single,pins = <
-                       0x1e8 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data1.i2c2_scl */
-                       0x1ec (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data0.i2c2_sda */
+                       AM4372_IOPAD(0x9e8, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data1.i2c2_scl */
+                       AM4372_IOPAD(0x9ec, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data0.i2c2_sda */
                >;
        };
 
        i2c2_pins_sleep: i2c2_pins_sleep {
                pinctrl-single,pins = <
-                       0x1e8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x1ec (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x9e8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x9ec, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        mmc1_pins_default: pinmux_mmc1_pins_default {
                pinctrl-single,pins = <
-                       0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
-                       0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
-                       0x1f0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
-                       0x1f4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
-                       0x1f8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
-                       0x1fc (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
-                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM4372_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+                       AM4372_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+                       AM4372_IOPAD(0x9f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+                       AM4372_IOPAD(0x9f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+                       AM4372_IOPAD(0x9f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+                       AM4372_IOPAD(0x9fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+                       AM4372_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                >;
        };
 
        mmc1_pins_sleep: pinmux_mmc1_pins_sleep {
                pinctrl-single,pins = <
-                       0x100 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x104 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x1f0 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x1f4 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x1f8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x1fc (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x160 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x900, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x904, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x9f0, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x9f4, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x9f8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x9fc, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x960, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        ecap0_pins_default: backlight_pins_default {
                pinctrl-single,pins = <
-                       0x164 (PIN_OUTPUT | MUX_MODE0) /* ecap0_in_pwm0_out.ecap0_in_pwm0_out */
+                       AM4372_IOPAD(0x964, PIN_OUTPUT | MUX_MODE0) /* ecap0_in_pwm0_out.ecap0_in_pwm0_out */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
-                       0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
-                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
-                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
-                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
-                       0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
-                       0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxclk.rmii1_rclk */
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxdv.rgmii1_rctl */
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd0 */
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd1 */
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd0.rgmii1_rd2 */
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)  /* mii1_rxd1.rgmii1_rd3 */
+                       AM4372_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rgmii1_tclk */
+                       AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_tctl */
+                       AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_td0 */
+                       AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_td1 */
+                       AM4372_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_td2 */
+                       AM4372_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_td3 */
+                       AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxclk.rmii1_rclk */
+                       AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxdv.rgmii1_rctl */
+                       AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rd0 */
+                       AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rd1 */
+                       AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rd2 */
+                       AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rd3 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
-                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                       AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM4372_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        qspi_pins_default: qspi_pins_default {
                pinctrl-single,pins = <
-                       0x7c (PIN_OUTPUT_PULLUP | MUX_MODE3)    /* gpmc_csn0.qspi_csn */
-                       0x88 (PIN_OUTPUT | MUX_MODE2)           /* gpmc_csn3.qspi_clk */
-                       0x90 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_advn_ale.qspi_d0 */
-                       0x94 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_oen_ren.qspi_d1 */
-                       0x98 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_wen.qspi_d2 */
-                       0x9c (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_be0n_cle.qspi_d3 */
+                       AM4372_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE3)      /* gpmc_csn0.qspi_csn */
+                       AM4372_IOPAD(0x888, PIN_OUTPUT | MUX_MODE2)             /* gpmc_csn3.qspi_clk */
+                       AM4372_IOPAD(0x890, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_advn_ale.qspi_d0 */
+                       AM4372_IOPAD(0x894, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_oen_ren.qspi_d1 */
+                       AM4372_IOPAD(0x898, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_wen.qspi_d2 */
+                       AM4372_IOPAD(0x89c, PIN_INPUT_PULLUP | MUX_MODE3)       /* gpmc_be0n_cle.qspi_d3 */
                >;
        };
 
        qspi_pins_sleep: qspi_pins_sleep{
                pinctrl-single,pins = <
-                       0x7c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x88 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x98 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x87c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x888, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x898, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x89c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 };
diff --git a/arch/arm/boot/dts/am437x-sbc-t43.dts b/arch/arm/boot/dts/am437x-sbc-t43.dts
new file mode 100644 (file)
index 0000000..5f750c0
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2015 CompuLab, Ltd. - http://www.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.
+ */
+
+#include "am437x-cm-t43.dts"
+#include "compulab-sb-som.dtsi"
+
+/ {
+       model = "CompuLab CM-T43 on SB-SOM-T43";
+       compatible = "compulab,am437x-sbc-t43", "compulab,am437x-cm-t43", "ti,am4372", "ti,am43";
+
+       aliases {
+               display0 = &lcd0;
+       };
+};
+
+&am43xx_pinmux {
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+                       AM4372_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+                       AM4372_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+                       AM4372_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+                       AM4372_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+                       AM4372_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+                       AM4372_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM4372_IOPAD(0x964, PIN_INPUT | MUX_MODE7) /* ecap0_in_pwm0_out.gpio0_7 */
+               >;
+       };
+
+       dss_pinctrl_default: dss_pinctrl_default {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE2) /* cam0 hd -> DSS DATA 23 */
+                       AM4372_IOPAD(0x9b4, PIN_OUTPUT_PULLUP | MUX_MODE2)
+                       AM4372_IOPAD(0x9b8, PIN_OUTPUT_PULLUP | MUX_MODE2)
+                       AM4372_IOPAD(0x9bc, PIN_OUTPUT_PULLUP | MUX_MODE2)
+                       AM4372_IOPAD(0x9c0, PIN_OUTPUT_PULLUP | MUX_MODE2)
+                       AM4372_IOPAD(0x9c4, PIN_OUTPUT_PULLUP | MUX_MODE2)
+                       AM4372_IOPAD(0x9c8, PIN_OUTPUT_PULLUP | MUX_MODE2)
+                       AM4372_IOPAD(0x9cc, PIN_OUTPUT_PULLUP | MUX_MODE2) /* cam1 data 9 -> DSS DATA 16 */
+
+                       AM4372_IOPAD(0x8a0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+                       AM4372_IOPAD(0x8a4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8a8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8ac, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8b0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8b4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8b8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8bc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8c0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8c4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8c8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8cc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8d0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8d4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8d8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM4372_IOPAD(0x8dc, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+                       AM4372_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+                       AM4372_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+                       AM4372_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+                       AM4372_IOPAD(0x8ec, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+                       AM4372_IOPAD(0xa20, PIN_OUTPUT_PULLUP | MUX_MODE7)
+               >;
+       };
+
+       uart0_pins_default: uart0_pins_default {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x968, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE0)
+                       AM4372_IOPAD(0x96C, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE0)
+                       AM4372_IOPAD(0x970, PIN_INPUT_PULLUP | SLEWCTRL_FAST | DS0_PULL_UP_DOWN_EN | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+                       AM4372_IOPAD(0x974, PIN_INPUT | PULL_DISABLE | SLEWCTRL_FAST | DS0_PULL_UP_DOWN_EN | MUX_MODE0) /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       i2c1_pins: i2c1_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0xa6c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE1)  /* spi2_cs0.i2c1_sda  */
+                       AM4372_IOPAD(0xa60, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE1)  /* spi2_sclk.i2c1_scl */
+               >;
+       };
+
+       i2c2_pins: i2c2_pins {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0x978, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE3)  /* uart1_ctsn.i2c2_sda  */
+                       AM4372_IOPAD(0x97c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE3)  /* uart1_rtsn.i2c2_scl */
+               >;
+       };
+
+       usb2_phy1_default: usb2_phy1_default {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0xac0, DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+
+       usb2_phy2_default: usb2_phy2_default {
+               pinctrl-single,pins = <
+                       AM4372_IOPAD(0xac4, DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+};
+
+&i2c1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       pca9555: pca9555@20 {
+               compatible = "nxp,pca9555";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       eeprom_base: at24@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
+
+&i2c2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+};
+
+&mmc1 {
+       status = "okay";
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&vsb_3v3>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+       wp-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+};
+
+&dss {
+       status = "ok";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&dss_pinctrl_default>;
+
+       port {
+               dpi_lcd_out: endpoint@0 {
+                       remote-endpoint = <&lcd_in>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_default>;
+};
+
+&dwc3_1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb2_phy1_default>;
+};
+
+&dwc3_2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb2_phy2_default>;
+};
+
+&lcd0 {
+       enable-gpios = <&pca9555 14 GPIO_ACTIVE_HIGH
+                       &gpio4 28 GPIO_ACTIVE_HIGH>;
+
+       port {
+               lcd_in: endpoint {
+                       remote-endpoint = <&dpi_lcd_out>;
+                       data-lines = <24>;
+               };
+       };
+};
index 63de2a1..d82dd6e 100644 (file)
 &am43xx_pinmux {
        matrix_keypad_pins: matrix_keypad_pins {
                pinctrl-single,pins = <
-                       0x24c (PIN_OUTPUT | MUX_MODE7)  /* gpio5_13.gpio5_13 */
-                       0x250 (PIN_OUTPUT | MUX_MODE7)  /* spi4_sclk.gpio5_4 */
-                       0x254 (PIN_INPUT | MUX_MODE7)   /* spi4_d0.gpio5_5 */
-                       0x258 (PIN_INPUT | MUX_MODE7)   /* spi4_d1.gpio5_5 */
+                       AM4372_IOPAD(0xa4c, PIN_OUTPUT | MUX_MODE7)     /* gpio5_13.gpio5_13 */
+                       AM4372_IOPAD(0xa50, PIN_OUTPUT | MUX_MODE7)     /* spi4_sclk.gpio5_4 */
+                       AM4372_IOPAD(0xa54, PIN_INPUT | MUX_MODE7)      /* spi4_d0.gpio5_5 */
+                       AM4372_IOPAD(0xa58, PIN_INPUT | MUX_MODE7)      /* spi4_d1.gpio5_5 */
                >;
        };
 
        leds_pins: leds_pins {
                pinctrl-single,pins = <
-                       0x228 (PIN_OUTPUT | MUX_MODE7)  /* uart3_rxd.gpio5_2 */
-                       0x22c (PIN_OUTPUT | MUX_MODE7)  /* uart3_txd.gpio5_3 */
-                       0x230 (PIN_OUTPUT | MUX_MODE7)  /* uart3_ctsn.gpio5_0 */
-                       0x234 (PIN_OUTPUT | MUX_MODE7)  /* uart3_rtsn.gpio5_1 */
+                       AM4372_IOPAD(0xa28, PIN_OUTPUT | MUX_MODE7)     /* uart3_rxd.gpio5_2 */
+                       AM4372_IOPAD(0xa2c, PIN_OUTPUT | MUX_MODE7)     /* uart3_txd.gpio5_3 */
+                       AM4372_IOPAD(0xa30, PIN_OUTPUT | MUX_MODE7)     /* uart3_ctsn.gpio5_0 */
+                       AM4372_IOPAD(0xa34, PIN_OUTPUT | MUX_MODE7)     /* uart3_rtsn.gpio5_1 */
                >;
        };
 
        i2c0_pins: i2c0_pins {
                pinctrl-single,pins = <
-                       0x188 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
-                       0x18c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
+                       AM4372_IOPAD(0x988, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
+                       AM4372_IOPAD(0x98c, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
                >;
        };
 
        i2c1_pins: i2c1_pins {
                pinctrl-single,pins = <
-                       0x15c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_cs0.i2c1_scl */
-                       0x158 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_d1.i2c1_sda  */
+                       AM4372_IOPAD(0x95c, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_cs0.i2c1_scl */
+                       AM4372_IOPAD(0x958, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_d1.i2c1_sda  */
                >;
        };
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x0f0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
-                       0x0f4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
-                       0x0f8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
-                       0x0fc (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
-                       0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
-                       0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
-                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       AM4372_IOPAD(0x8f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+                       AM4372_IOPAD(0x8f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+                       AM4372_IOPAD(0x8f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+                       AM4372_IOPAD(0x8fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+                       AM4372_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+                       AM4372_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+                       AM4372_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                >;
        };
 
        ecap0_pins: backlight_pins {
                pinctrl-single,pins = <
-                       0x164 (PIN_OUTPUT | MUX_MODE0) /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out */
+                       AM4372_IOPAD(0x964, PIN_OUTPUT | MUX_MODE0) /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out */
                >;
        };
 
        edt_ft5306_ts_pins: edt_ft5306_ts_pins {
                pinctrl-single,pins = <
-                       0x74 (PIN_INPUT | MUX_MODE7)    /* gpmc_wpn.gpio0_31 */
-                       0x78 (PIN_OUTPUT | MUX_MODE7)   /* gpmc_be1n.gpio1_28 */
+                       AM4372_IOPAD(0x874, PIN_INPUT | MUX_MODE7)      /* gpmc_wpn.gpio0_31 */
+                       AM4372_IOPAD(0x878, PIN_OUTPUT | MUX_MODE7)     /* gpmc_be1n.gpio1_28 */
                >;
        };
 
        vpfe0_pins_default: vpfe0_pins_default {
                pinctrl-single,pins = <
-                       0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_hd mode 0*/
-                       0x1b4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_vd mode 0*/
-                       0x1b8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_field mode 0*/
-                       0x1bc (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_wen mode 0*/
-                       0x1c0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_pclk mode 0*/
-                       0x1c4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data8 mode 0*/
-                       0x1c8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data9 mode 0*/
-                       0x208 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data0 mode 0*/
-                       0x20c (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data1 mode 0*/
-                       0x210 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data2 mode 0*/
-                       0x214 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data3 mode 0*/
-                       0x218 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data4 mode 0*/
-                       0x21c (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data5 mode 0*/
-                       0x220 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data6 mode 0*/
-                       0x224 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data7 mode 0*/
+                       AM4372_IOPAD(0x9b0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_hd mode 0*/
+                       AM4372_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_vd mode 0*/
+                       AM4372_IOPAD(0x9b8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_field mode 0*/
+                       AM4372_IOPAD(0x9bc, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_wen mode 0*/
+                       AM4372_IOPAD(0x9c0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_pclk mode 0*/
+                       AM4372_IOPAD(0x9c4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data8 mode 0*/
+                       AM4372_IOPAD(0x9c8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data9 mode 0*/
+                       AM4372_IOPAD(0xa08, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data0 mode 0*/
+                       AM4372_IOPAD(0xa0c, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data1 mode 0*/
+                       AM4372_IOPAD(0xa10, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data2 mode 0*/
+                       AM4372_IOPAD(0xa14, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data3 mode 0*/
+                       AM4372_IOPAD(0xa18, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data4 mode 0*/
+                       AM4372_IOPAD(0xa1c, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data5 mode 0*/
+                       AM4372_IOPAD(0xa20, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data6 mode 0*/
+                       AM4372_IOPAD(0xa24, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam0_data7 mode 0*/
                >;
        };
 
        vpfe0_pins_sleep: vpfe0_pins_sleep {
                pinctrl-single,pins = <
-                       0x1b0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x1b4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x1b8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x1bc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x1c0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x1c4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x1c8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x208 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x20c (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x210 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x214 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x218 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x21c (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x220 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                       0x224 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9b0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9b4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9b8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9bc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9c0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9c4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0x9c8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa08, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa0c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa10, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa14, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa18, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa1c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa20, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                       AM4372_IOPAD(0xa24, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x12c (PIN_OUTPUT | MUX_MODE2)  /* mii1_txclk.rmii1_tclk */
-                       0x114 (PIN_OUTPUT | MUX_MODE2)  /* mii1_txen.rgmii1_tctl */
-                       0x128 (PIN_OUTPUT | MUX_MODE2)  /* mii1_txd0.rgmii1_td0 */
-                       0x124 (PIN_OUTPUT | MUX_MODE2)  /* mii1_txd1.rgmii1_td1 */
-                       0x120 (PIN_OUTPUT | MUX_MODE2)  /* mii1_txd0.rgmii1_td2 */
-                       0x11c (PIN_OUTPUT | MUX_MODE2)  /* mii1_txd1.rgmii1_td3 */
-                       0x130 (PIN_INPUT | MUX_MODE2)   /* mii1_rxclk.rmii1_rclk */
-                       0x118 (PIN_INPUT | MUX_MODE2)   /* mii1_rxdv.rgmii1_rctl */
-                       0x140 (PIN_INPUT | MUX_MODE2)   /* mii1_rxd0.rgmii1_rd0 */
-                       0x13c (PIN_INPUT | MUX_MODE2)   /* mii1_rxd1.rgmii1_rd1 */
-                       0x138 (PIN_INPUT | MUX_MODE2)   /* mii1_rxd0.rgmii1_rd2 */
-                       0x134 (PIN_INPUT | MUX_MODE2)   /* mii1_rxd1.rgmii1_rd3 */
+                       AM4372_IOPAD(0x92c, PIN_OUTPUT | MUX_MODE2)     /* mii1_txclk.rmii1_tclk */
+                       AM4372_IOPAD(0x914, PIN_OUTPUT | MUX_MODE2)     /* mii1_txen.rgmii1_tctl */
+                       AM4372_IOPAD(0x928, PIN_OUTPUT | MUX_MODE2)     /* mii1_txd0.rgmii1_td0 */
+                       AM4372_IOPAD(0x924, PIN_OUTPUT | MUX_MODE2)     /* mii1_txd1.rgmii1_td1 */
+                       AM4372_IOPAD(0x920, PIN_OUTPUT | MUX_MODE2)     /* mii1_txd0.rgmii1_td2 */
+                       AM4372_IOPAD(0x91c, PIN_OUTPUT | MUX_MODE2)     /* mii1_txd1.rgmii1_td3 */
+                       AM4372_IOPAD(0x930, PIN_INPUT | MUX_MODE2)      /* mii1_rxclk.rmii1_rclk */
+                       AM4372_IOPAD(0x918, PIN_INPUT | MUX_MODE2)      /* mii1_rxdv.rgmii1_rctl */
+                       AM4372_IOPAD(0x940, PIN_INPUT | MUX_MODE2)      /* mii1_rxd0.rgmii1_rd0 */
+                       AM4372_IOPAD(0x93c, PIN_INPUT | MUX_MODE2)      /* mii1_rxd1.rgmii1_rd1 */
+                       AM4372_IOPAD(0x938, PIN_INPUT | MUX_MODE2)      /* mii1_rxd0.rgmii1_rd2 */
+                       AM4372_IOPAD(0x934, PIN_INPUT | MUX_MODE2)      /* mii1_rxd1.rgmii1_rd3 */
 
                        /* Slave 2 */
-                       0x58 (PIN_OUTPUT | MUX_MODE2)   /* gpmc_a6.rgmii2_tclk */
-                       0x40 (PIN_OUTPUT | MUX_MODE2)   /* gpmc_a0.rgmii2_tctl */
-                       0x54 (PIN_OUTPUT | MUX_MODE2)   /* gpmc_a5.rgmii2_td0 */
-                       0x50 (PIN_OUTPUT | MUX_MODE2)   /* gpmc_a4.rgmii2_td1 */
-                       0x4c (PIN_OUTPUT | MUX_MODE2)   /* gpmc_a3.rgmii2_td2 */
-                       0x48 (PIN_OUTPUT | MUX_MODE2)   /* gpmc_a2.rgmii2_td3 */
-                       0x5c (PIN_INPUT | MUX_MODE2)    /* gpmc_a7.rgmii2_rclk */
-                       0x44 (PIN_INPUT | MUX_MODE2)    /* gpmc_a1.rgmii2_rtcl */
-                       0x6c (PIN_INPUT | MUX_MODE2)    /* gpmc_a11.rgmii2_rd0 */
-                       0x68 (PIN_INPUT | MUX_MODE2)    /* gpmc_a10.rgmii2_rd1 */
-                       0x64 (PIN_INPUT | MUX_MODE2)    /* gpmc_a9.rgmii2_rd2 */
-                       0x60 (PIN_INPUT | MUX_MODE2)    /* gpmc_a8.rgmii2_rd3 */
+                       AM4372_IOPAD(0x858, PIN_OUTPUT | MUX_MODE2)     /* gpmc_a6.rgmii2_tclk */
+                       AM4372_IOPAD(0x840, PIN_OUTPUT | MUX_MODE2)     /* gpmc_a0.rgmii2_tctl */
+                       AM4372_IOPAD(0x854, PIN_OUTPUT | MUX_MODE2)     /* gpmc_a5.rgmii2_td0 */
+                       AM4372_IOPAD(0x850, PIN_OUTPUT | MUX_MODE2)     /* gpmc_a4.rgmii2_td1 */
+                       AM4372_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE2)     /* gpmc_a3.rgmii2_td2 */
+                       AM4372_IOPAD(0x848, PIN_OUTPUT | MUX_MODE2)     /* gpmc_a2.rgmii2_td3 */
+                       AM4372_IOPAD(0x85c, PIN_INPUT | MUX_MODE2)      /* gpmc_a7.rgmii2_rclk */
+                       AM4372_IOPAD(0x844, PIN_INPUT | MUX_MODE2)      /* gpmc_a1.rgmii2_rtcl */
+                       AM4372_IOPAD(0x86c, PIN_INPUT | MUX_MODE2)      /* gpmc_a11.rgmii2_rd0 */
+                       AM4372_IOPAD(0x868, PIN_INPUT | MUX_MODE2)      /* gpmc_a10.rgmii2_rd1 */
+                       AM4372_IOPAD(0x864, PIN_INPUT | MUX_MODE2)      /* gpmc_a9.rgmii2_rd2 */
+                       AM4372_IOPAD(0x860, PIN_INPUT | MUX_MODE2)      /* gpmc_a8.rgmii2_rd3 */
                >;
        };
 
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 reset value */
-                       0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
 
                        /* Slave 2 reset value */
-                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x148 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0)   /* mdio_data.mdio_data */
-                       0x14c (PIN_OUTPUT | MUX_MODE0)                  /* mdio_clk.mdio_clk */
+                       AM4372_IOPAD(0x948, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0)      /* mdio_data.mdio_data */
+                       AM4372_IOPAD(0x94c, PIN_OUTPUT | MUX_MODE0)                     /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
                        /* MDIO reset value */
-                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        dss_pins: dss_pins {
                pinctrl-single,pins = <
-                       0x020 (PIN_OUTPUT | MUX_MODE1)  /* gpmc ad 8 -> DSS DATA 23 */
-                       0x024 (PIN_OUTPUT | MUX_MODE1)
-                       0x028 (PIN_OUTPUT | MUX_MODE1)
-                       0x02c (PIN_OUTPUT | MUX_MODE1)
-                       0x030 (PIN_OUTPUT | MUX_MODE1)
-                       0x034 (PIN_OUTPUT | MUX_MODE1)
-                       0x038 (PIN_OUTPUT | MUX_MODE1)
-                       0x03c (PIN_OUTPUT | MUX_MODE1)  /* gpmc ad 15 -> DSS DATA 16 */
-                       0x0a0 (PIN_OUTPUT | MUX_MODE0)  /* DSS DATA 0 */
-                       0x0a4 (PIN_OUTPUT | MUX_MODE0)
-                       0x0a8 (PIN_OUTPUT | MUX_MODE0)
-                       0x0ac (PIN_OUTPUT | MUX_MODE0)
-                       0x0b0 (PIN_OUTPUT | MUX_MODE0)
-                       0x0b4 (PIN_OUTPUT | MUX_MODE0)
-                       0x0b8 (PIN_OUTPUT | MUX_MODE0)
-                       0x0bc (PIN_OUTPUT | MUX_MODE0)
-                       0x0c0 (PIN_OUTPUT | MUX_MODE0)
-                       0x0c4 (PIN_OUTPUT | MUX_MODE0)
-                       0x0c8 (PIN_OUTPUT | MUX_MODE0)
-                       0x0cc (PIN_OUTPUT | MUX_MODE0)
-                       0x0d0 (PIN_OUTPUT | MUX_MODE0)
-                       0x0d4 (PIN_OUTPUT | MUX_MODE0)
-                       0x0d8 (PIN_OUTPUT | MUX_MODE0)
-                       0x0dc (PIN_OUTPUT | MUX_MODE0)  /* DSS DATA 15 */
-                       0x0e0 (PIN_OUTPUT | MUX_MODE0)  /* DSS VSYNC */
-                       0x0e4 (PIN_OUTPUT | MUX_MODE0)  /* DSS HSYNC */
-                       0x0e8 (PIN_OUTPUT | MUX_MODE0)  /* DSS PCLK */
-                       0x0ec (PIN_OUTPUT | MUX_MODE0)  /* DSS AC BIAS EN */
+                       AM4372_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)     /* gpmc ad 8 -> DSS DATA 23 */
+                       AM4372_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)
+                       AM4372_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)
+                       AM4372_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)
+                       AM4372_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)
+                       AM4372_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)
+                       AM4372_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)
+                       AM4372_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)     /* gpmc ad 15 -> DSS DATA 16 */
+                       AM4372_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)     /* DSS DATA 0 */
+                       AM4372_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)
+                       AM4372_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)     /* DSS DATA 15 */
+                       AM4372_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)     /* DSS VSYNC */
+                       AM4372_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)     /* DSS HSYNC */
+                       AM4372_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)     /* DSS PCLK */
+                       AM4372_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)     /* DSS AC BIAS EN */
 
                >;
        };
 
        qspi_pins: qspi_pins {
                pinctrl-single,pins = <
-                       0x7c (PIN_OUTPUT | MUX_MODE3)   /* gpmc_csn0.qspi_csn */
-                       0x88 (PIN_OUTPUT | MUX_MODE2)   /* gpmc_csn3.qspi_clk */
-                       0x90 (PIN_INPUT | MUX_MODE3)    /* gpmc_advn_ale.qspi_d0 */
-                       0x94 (PIN_INPUT | MUX_MODE3)    /* gpmc_oen_ren.qspi_d1 */
-                       0x98 (PIN_INPUT | MUX_MODE3)    /* gpmc_wen.qspi_d2 */
-                       0x9c (PIN_INPUT | MUX_MODE3)    /* gpmc_be0n_cle.qspi_d3 */
+                       AM4372_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE3)     /* gpmc_csn0.qspi_csn */
+                       AM4372_IOPAD(0x888, PIN_OUTPUT | MUX_MODE2)     /* gpmc_csn3.qspi_clk */
+                       AM4372_IOPAD(0x890, PIN_INPUT | MUX_MODE3)      /* gpmc_advn_ale.qspi_d0 */
+                       AM4372_IOPAD(0x894, PIN_INPUT | MUX_MODE3)      /* gpmc_oen_ren.qspi_d1 */
+                       AM4372_IOPAD(0x898, PIN_INPUT | MUX_MODE3)      /* gpmc_wen.qspi_d2 */
+                       AM4372_IOPAD(0x89c, PIN_INPUT | MUX_MODE3)      /* gpmc_be0n_cle.qspi_d3 */
                >;
        };
 
        mcasp1_pins: mcasp1_pins {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4)  /* mii1_crs.mcasp1_aclkx */
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4)  /* mii1_rxerr.mcasp1_fsx */
-                       0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4)  /* rmii1_ref_clk.mcasp1_axr3 */
+                       AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4)     /* mii1_crs.mcasp1_aclkx */
+                       AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4)     /* mii1_rxerr.mcasp1_fsx */
+                       AM4372_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4)    /* mii1_col.mcasp1_axr2 */
+                       AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4)     /* rmii1_ref_clk.mcasp1_axr3 */
                >;
        };
 
        mcasp1_pins_sleep: mcasp1_pins_sleep {
                pinctrl-single,pins = <
-                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
 
        lcd_pins: lcd_pins {
                pinctrl-single,pins = <
-                       0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpcm_ad7.gpio1_7 */
+                       AM4372_IOPAD(0x81c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpcm_ad7.gpio1_7 */
                >;
        };
 
        usb1_pins: usb1_pins {
                pinctrl-single,pins = <
-                       0x2c0 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+                       AM4372_IOPAD(0xac0, PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
                >;
        };
 
        usb2_pins: usb2_pins {
                pinctrl-single,pins = <
-                       0x2c4 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+                       AM4372_IOPAD(0xac4, PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
                >;
        };
 };
index 47954ed..746fd2b 100644 (file)
                cpsw_default: cpsw_default {
                        pinctrl-single,pins = <
                                /* Slave 1 */
-                               0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_crs.rmii1_crs */
-                               0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxerr.rmii1_rxerr */
-                               0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxdv.rmii1_rxdv */
-                               0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
-                               0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd1.rmii1_rxd1 */
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd0.rmii1_rxd0 */
-                               0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* rmii1_refclk.rmii1_refclk */
+                               AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_crs.rmii1_crs */
+                               AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxerr.rmii1_rxerr */
+                               AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txen.rmii1_txen */
+                               AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxdv.rmii1_rxdv */
+                               AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txd1.rmii1_txd1 */
+                               AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txd0.rmii1_txd0 */
+                               AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxd1.rmii1_rxd1 */
+                               AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_rxd0.rmii1_rxd0 */
+                               AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* rmii1_refclk.rmii1_refclk */
                        >;
                };
 
                cpsw_sleep: cpsw_sleep {
                        pinctrl-single,pins = <
                                /* Slave 1 reset value */
-                               0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                        >;
                };
 
                davinci_mdio_default: davinci_mdio_default {
                        pinctrl-single,pins = <
                                /* MDIO */
-                               0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
-                               0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+                               AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                               AM4372_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
                        >;
                };
 
                davinci_mdio_sleep: davinci_mdio_sleep {
                        pinctrl-single,pins = <
                                /* MDIO reset value */
-                               0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                        >;
                };
 
                i2c0_pins: pinmux_i2c0_pins {
                        pinctrl-single,pins = <
-                               0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-                               0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+                               AM4372_IOPAD(0x988, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                               AM4372_IOPAD(0x98c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
                        >;
                };
 
                nand_flash_x8: nand_flash_x8 {
                        pinctrl-single,pins = <
-                               0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a0.SELQSPIorNAND/GPIO */
-                               0x0  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad0.gpmc_ad0 */
-                               0x4  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad1.gpmc_ad1 */
-                               0x8  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad2.gpmc_ad2 */
-                               0xc  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad3.gpmc_ad3 */
-                               0x10 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad4.gpmc_ad4 */
-                               0x14 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad5.gpmc_ad5 */
-                               0x18 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad6.gpmc_ad6 */
-                               0x1c (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad7.gpmc_ad7 */
-                               0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
-                               0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_wpn.gpmc_wpn */
-                               0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
-                               0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
-                               0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
-                               0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
-                               0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+                               AM4372_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a0.SELQSPIorNAND/GPIO */
+                               AM4372_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad0.gpmc_ad0 */
+                               AM4372_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad1.gpmc_ad1 */
+                               AM4372_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad2.gpmc_ad2 */
+                               AM4372_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad3.gpmc_ad3 */
+                               AM4372_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                               AM4372_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                               AM4372_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                               AM4372_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+                               AM4372_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)       /* gpmc_wait0.gpmc_wait0 */
+                               AM4372_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_wpn.gpmc_wpn */
+                               AM4372_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_csn0.gpmc_csn0  */
+                               AM4372_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)             /* gpmc_advn_ale.gpmc_advn_ale */
+                               AM4372_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)             /* gpmc_oen_ren.gpmc_oen_ren */
+                               AM4372_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)             /* gpmc_wen.gpmc_wen */
+                               AM4372_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)             /* gpmc_be0n_cle.gpmc_be0n_cle */
                        >;
                };
 
                ecap0_pins: backlight_pins {
                        pinctrl-single,pins = <
-                               0x164 MUX_MODE0         /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+                               AM4372_IOPAD(0x964, MUX_MODE0)         /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
                        >;
                };
 
                i2c2_pins: pinmux_i2c2_pins {
                        pinctrl-single,pins = <
-                               0x1c0 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8)    /* i2c2_sda.i2c2_sda */
-                               0x1c4 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8)    /* i2c2_scl.i2c2_scl */
+                               AM4372_IOPAD(0x9c0, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8)    /* i2c2_sda.i2c2_sda */
+                               AM4372_IOPAD(0x9c4, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8)    /* i2c2_scl.i2c2_scl */
                        >;
                };
 
                spi0_pins: pinmux_spi0_pins {
                        pinctrl-single,pins = <
-                               0x150 (PIN_INPUT | MUX_MODE0)           /* spi0_clk.spi0_clk */
-                               0x154 (PIN_OUTPUT | MUX_MODE0)           /* spi0_d0.spi0_d0 */
-                               0x158 (PIN_INPUT | MUX_MODE0)           /* spi0_d1.spi0_d1 */
-                               0x15c (PIN_OUTPUT | MUX_MODE0)          /* spi0_cs0.spi0_cs0 */
+                               AM4372_IOPAD(0x950, PIN_INPUT | MUX_MODE0)           /* spi0_clk.spi0_clk */
+                               AM4372_IOPAD(0x954, PIN_OUTPUT | MUX_MODE0)           /* spi0_d0.spi0_d0 */
+                               AM4372_IOPAD(0x958, PIN_INPUT | MUX_MODE0)           /* spi0_d1.spi0_d1 */
+                               AM4372_IOPAD(0x95c, PIN_OUTPUT | MUX_MODE0)          /* spi0_cs0.spi0_cs0 */
                        >;
                };
 
                spi1_pins: pinmux_spi1_pins {
                        pinctrl-single,pins = <
-                               0x190 (PIN_INPUT | MUX_MODE3)           /* mcasp0_aclkx.spi1_clk */
-                               0x194 (PIN_OUTPUT | MUX_MODE3)           /* mcasp0_fsx.spi1_d0 */
-                               0x198 (PIN_INPUT | MUX_MODE3)           /* mcasp0_axr0.spi1_d1 */
-                               0x19c (PIN_OUTPUT | MUX_MODE3)          /* mcasp0_ahclkr.spi1_cs0 */
+                               AM4372_IOPAD(0x990, PIN_INPUT | MUX_MODE3)           /* mcasp0_aclkx.spi1_clk */
+                               AM4372_IOPAD(0x994, PIN_OUTPUT | MUX_MODE3)           /* mcasp0_fsx.spi1_d0 */
+                               AM4372_IOPAD(0x998, PIN_INPUT | MUX_MODE3)           /* mcasp0_axr0.spi1_d1 */
+                               AM4372_IOPAD(0x99c, PIN_OUTPUT | MUX_MODE3)          /* mcasp0_ahclkr.spi1_cs0 */
                        >;
                };
 
                mmc1_pins: pinmux_mmc1_pins {
                        pinctrl-single,pins = <
-                               0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                               AM4372_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
                        >;
                };
 
                qspi1_default: qspi1_default {
                        pinctrl-single,pins = <
-                               0x7c (PIN_INPUT_PULLUP | MUX_MODE3)
-                               0x88 (PIN_INPUT_PULLUP | MUX_MODE2)
-                               0x90 (PIN_INPUT_PULLUP | MUX_MODE3)
-                               0x94 (PIN_INPUT_PULLUP | MUX_MODE3)
-                               0x98 (PIN_INPUT_PULLUP | MUX_MODE3)
-                               0x9c (PIN_INPUT_PULLUP | MUX_MODE3)
+                               AM4372_IOPAD(0x87c, PIN_INPUT_PULLUP | MUX_MODE3)
+                               AM4372_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE2)
+                               AM4372_IOPAD(0x890, PIN_INPUT_PULLUP | MUX_MODE3)
+                               AM4372_IOPAD(0x894, PIN_INPUT_PULLUP | MUX_MODE3)
+                               AM4372_IOPAD(0x898, PIN_INPUT_PULLUP | MUX_MODE3)
+                               AM4372_IOPAD(0x89c, PIN_INPUT_PULLUP | MUX_MODE3)
                        >;
                };
 
                pixcir_ts_pins: pixcir_ts_pins {
                        pinctrl-single,pins = <
-                               0x44 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_a1.gpio1_17 */
+                               AM4372_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE7)       /* gpmc_a1.gpio1_17 */
                        >;
                };
 
                hdq_pins: pinmux_hdq_pins {
                        pinctrl-single,pins = <
-                               0x234 (PIN_INPUT_PULLUP | MUX_MODE1)    /* cam1_wen.hdq_gpio */
+                               AM4372_IOPAD(0xa34, PIN_INPUT_PULLUP | MUX_MODE1)    /* cam1_wen.hdq_gpio */
                        >;
                };
 
                dss_pins: dss_pins {
                        pinctrl-single,pins = <
-                               0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
-                               0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                               0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                               0x02C (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                               0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                               0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                               0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1)
-                               0x03C (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
-                               0x0A0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
-                               0x0A4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0A8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0AC (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0B0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0B4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0B8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0BC (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0C0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0C4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0C8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0CC (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0D0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0D4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0D8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
-                               0x0DC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
-                               0x0E0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
-                               0x0E4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
-                               0x0E8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
-                               0x0EC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+                               AM4372_IOPAD(0x820, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
+                               AM4372_IOPAD(0x824, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                               AM4372_IOPAD(0x828, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                               AM4372_IOPAD(0x82c, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                               AM4372_IOPAD(0x830, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                               AM4372_IOPAD(0x834, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                               AM4372_IOPAD(0x838, PIN_OUTPUT_PULLUP | MUX_MODE1)
+                               AM4372_IOPAD(0x83c, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
+                               AM4372_IOPAD(0x8a0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+                               AM4372_IOPAD(0x8a4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8a8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8ac, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8b0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8b4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8B8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8bc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8c0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8c4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8c8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8cc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8d0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8d4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8d8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                               AM4372_IOPAD(0x8dc, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+                               AM4372_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+                               AM4372_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+                               AM4372_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+                               AM4372_IOPAD(0x8ec, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
                        >;
                };
 
                display_mux_pins: display_mux_pins {
                        pinctrl-single,pins = <
                                /* GPMC CLK -> GPIO 2_1 to select LCD / HDMI */
-                               0x08C (PIN_OUTPUT_PULLUP | MUX_MODE7)
+                               AM4372_IOPAD(0x88C, PIN_OUTPUT_PULLUP | MUX_MODE7)
                        >;
                };
 
                vpfe1_pins_default: vpfe1_pins_default {
                        pinctrl-single,pins = <
-                               0x1cc (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data9 mode 0 */
-                               0x1d0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data8 mode 0 */
-                               0x1d4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_hd mode 0 */
-                               0x1d8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_vd mode 0 */
-                               0x1dc (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_pclk mode 0 */
-                               0x1e8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data0 mode 0 */
-                               0x1ec (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data1 mode 0 */
-                               0x1f0 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data2 mode 0 */
-                               0x1f4 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data3 mode 0 */
-                               0x1f8 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data4 mode 0 */
-                               0x1fc (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data5 mode 0 */
-                               0x200 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data6 mode 0 */
-                               0x204 (PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data7 mode 0 */
+                               AM4372_IOPAD(0x9cc, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data9 mode 0 */
+                               AM4372_IOPAD(0x9d0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data8 mode 0 */
+                               AM4372_IOPAD(0x9d4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_hd mode 0 */
+                               AM4372_IOPAD(0x9d8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_vd mode 0 */
+                               AM4372_IOPAD(0x9dc, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_pclk mode 0 */
+                               AM4372_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data0 mode 0 */
+                               AM4372_IOPAD(0x9ec, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data1 mode 0 */
+                               AM4372_IOPAD(0x9f0, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data2 mode 0 */
+                               AM4372_IOPAD(0x9f4, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data3 mode 0 */
+                               AM4372_IOPAD(0x9f8, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data4 mode 0 */
+                               AM4372_IOPAD(0x9fc, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data5 mode 0 */
+                               AM4372_IOPAD(0xa00, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data6 mode 0 */
+                               AM4372_IOPAD(0xa04, PIN_INPUT_PULLUP | MUX_MODE0)  /* cam1_data7 mode 0 */
                        >;
                };
 
                vpfe1_pins_sleep: vpfe1_pins_sleep {
                        pinctrl-single,pins = <
-                               0x1cc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1d0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1d4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1d8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1dc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1e8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1ec (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1f0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1f4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1f8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x1fc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x200 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
-                               0x204 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9cc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9d0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9d4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9d8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9dc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9e8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9ec, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9f0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9f4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9f8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0x9fc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0xa00, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+                               AM4372_IOPAD(0xa04, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
                        >;
                };
 
                mcasp1_pins: mcasp1_pins {
                        pinctrl-single,pins = <
-                               0x1a0 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_ACLKR/MCASP1_ACLKX */
-                               0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_FSR/MCASP1_FSX */
-                               0x1a8 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)/* MCASP0_AXR1/MCASP1_AXR0 */
-                               0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_AHCLKX/MCASP1_AXR1 */
+                               AM4372_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_ACLKR/MCASP1_ACLKX */
+                               AM4372_IOPAD(0x9a4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_FSR/MCASP1_FSX */
+                               AM4372_IOPAD(0x9a8, PIN_OUTPUT_PULLDOWN | MUX_MODE3)/* MCASP0_AXR1/MCASP1_AXR0 */
+                               AM4372_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_AHCLKX/MCASP1_AXR1 */
                        >;
                };
 
                mcasp1_sleep_pins: mcasp1_sleep_pins {
                        pinctrl-single,pins = <
-                               0x1a0 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
-                               0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x9a4, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                               AM4372_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE7)
                        >;
                };
 };
index 00352e7..36c0fa6 100644 (file)
 &dra7_pmx_core {
        leds_pins_default: leds_pins_default {
                pinctrl-single,pins = <
-                       0x3a8 (PIN_OUTPUT | MUX_MODE14) /* spi1_d1.gpio7_8 */
-                       0x3ac (PIN_OUTPUT | MUX_MODE14) /* spi1_d0.gpio7_9 */
-                       0x3c0 (PIN_OUTPUT | MUX_MODE14) /* spi2_sclk.gpio7_14 */
-                       0x3c4 (PIN_OUTPUT | MUX_MODE14) /* spi2_d1.gpio7_15 */
+                       DRA7XX_CORE_IOPAD(0x37a8, PIN_OUTPUT | MUX_MODE14)      /* spi1_d1.gpio7_8 */
+                       DRA7XX_CORE_IOPAD(0x37ac, PIN_OUTPUT | MUX_MODE14)      /* spi1_d0.gpio7_9 */
+                       DRA7XX_CORE_IOPAD(0x37c0, PIN_OUTPUT | MUX_MODE14)      /* spi2_sclk.gpio7_14 */
+                       DRA7XX_CORE_IOPAD(0x37c4, PIN_OUTPUT | MUX_MODE14)      /* spi2_d1.gpio7_15 */
                >;
        };
 
        i2c1_pins_default: i2c1_pins_default {
                pinctrl-single,pins = <
-                       0x400 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda.sda */
-                       0x404 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl.scl */
+                       DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda.sda */
+                       DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl.scl */
                >;
        };
 
        hdmi_pins: pinmux_hdmi_pins {
                pinctrl-single,pins = <
-                       0x408 (PIN_INPUT | MUX_MODE1)   /* i2c2_sda.hdmi1_ddc_scl */
-                       0x40c (PIN_INPUT | MUX_MODE1)   /* i2c2_scl.hdmi1_ddc_sda */
+                       DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1)        /* i2c2_sda.hdmi1_ddc_scl */
+                       DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE1)        /* i2c2_scl.hdmi1_ddc_sda */
                >;
        };
 
        i2c3_pins_default: i2c3_pins_default {
                pinctrl-single,pins = <
-                       0x2a4 (PIN_INPUT| MUX_MODE10)   /* mcasp1_aclkx.i2c3_sda */
-                       0x2a8 (PIN_INPUT| MUX_MODE10)   /* mcasp1_fsx.i2c3_scl */
+                       DRA7XX_CORE_IOPAD(0x36a4, PIN_INPUT| MUX_MODE10)        /* mcasp1_aclkx.i2c3_sda */
+                       DRA7XX_CORE_IOPAD(0x36a8, PIN_INPUT| MUX_MODE10)        /* mcasp1_fsx.i2c3_scl */
                >;
        };
 
        uart3_pins_default: uart3_pins_default {
                pinctrl-single,pins = <
-                       0x3f8 (PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */
-                       0x3fc (PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */
+                       DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */
+                       DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */
                >;
        };
 
        mmc1_pins_default: mmc1_pins_default {
                pinctrl-single,pins = <
-                       0x36c (PIN_INPUT | MUX_MODE14)  /* mmc1sdcd.gpio219 */
-                       0x354 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
-                       0x358 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
-                       0x35c (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
-                       0x360 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
-                       0x364 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
-                       0x368 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+                       DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14)       /* mmc1sdcd.gpio219 */
+                       DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+                       DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+                       DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+                       DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+                       DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+                       DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
                >;
        };
 
        mmc2_pins_default: mmc2_pins_default {
                pinctrl-single,pins = <
-                       0x9c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
-                       0xb0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
-                       0xa0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
-                       0xa4 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
-                       0xa8 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
-                       0xac (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
-                       0x8c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
-                       0x90 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
-                       0x94 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
-                       0x98 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+                       DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+                       DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+                       DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+                       DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+                       DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+                       DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+                       DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+                       DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+                       DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+                       DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
                >;
        };
 
        cpsw_pins_default: cpsw_pins_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x250 (PIN_OUTPUT | MUX_MODE0)  /* rgmii1_tclk */
-                       0x254 (PIN_OUTPUT | MUX_MODE0)  /* rgmii1_tctl */
-                       0x258 (PIN_OUTPUT | MUX_MODE0)  /* rgmii1_td3 */
-                       0x25c (PIN_OUTPUT | MUX_MODE0)  /* rgmii1_td2 */
-                       0x260 (PIN_OUTPUT | MUX_MODE0)  /* rgmii1_td1 */
-                       0x264 (PIN_OUTPUT | MUX_MODE0)  /* rgmii1_td0 */
-                       0x268 (PIN_INPUT | MUX_MODE0)   /* rgmii1_rclk */
-                       0x26c (PIN_INPUT | MUX_MODE0)   /* rgmii1_rctl */
-                       0x270 (PIN_INPUT | MUX_MODE0)   /* rgmii1_rd3 */
-                       0x274 (PIN_INPUT | MUX_MODE0)   /* rgmii1_rd2 */
-                       0x278 (PIN_INPUT | MUX_MODE0)   /* rgmii1_rd1 */
-                       0x27c (PIN_INPUT | MUX_MODE0)   /* rgmii1_rd0 */
+                       DRA7XX_CORE_IOPAD(0x3650, PIN_OUTPUT | MUX_MODE0)       /* rgmii1_tclk */
+                       DRA7XX_CORE_IOPAD(0x3654, PIN_OUTPUT | MUX_MODE0)       /* rgmii1_tctl */
+                       DRA7XX_CORE_IOPAD(0x3658, PIN_OUTPUT | MUX_MODE0)       /* rgmii1_td3 */
+                       DRA7XX_CORE_IOPAD(0x365c, PIN_OUTPUT | MUX_MODE0)       /* rgmii1_td2 */
+                       DRA7XX_CORE_IOPAD(0x3660, PIN_OUTPUT | MUX_MODE0)       /* rgmii1_td1 */
+                       DRA7XX_CORE_IOPAD(0x3664, PIN_OUTPUT | MUX_MODE0)       /* rgmii1_td0 */
+                       DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE0)        /* rgmii1_rclk */
+                       DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE0)        /* rgmii1_rctl */
+                       DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE0)        /* rgmii1_rd3 */
+                       DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE0)        /* rgmii1_rd2 */
+                       DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE0)        /* rgmii1_rd1 */
+                       DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT | MUX_MODE0)        /* rgmii1_rd0 */
 
                        /* Slave 2 */
-                       0x198 (PIN_OUTPUT | MUX_MODE3)  /* rgmii2_tclk */
-                       0x19c (PIN_OUTPUT | MUX_MODE3)  /* rgmii2_tctl */
-                       0x1a0 (PIN_OUTPUT | MUX_MODE3)  /* rgmii2_td3 */
-                       0x1a4 (PIN_OUTPUT | MUX_MODE3)  /* rgmii2_td2 */
-                       0x1a8 (PIN_OUTPUT | MUX_MODE3)  /* rgmii2_td1 */
-                       0x1ac (PIN_OUTPUT | MUX_MODE3)  /* rgmii2_td0 */
-                       0x1b0 (PIN_INPUT | MUX_MODE3)   /* rgmii2_rclk */
-                       0x1b4 (PIN_INPUT | MUX_MODE3)   /* rgmii2_rctl */
-                       0x1b8 (PIN_INPUT | MUX_MODE3)   /* rgmii2_rd3 */
-                       0x1bc (PIN_INPUT | MUX_MODE3)   /* rgmii2_rd2 */
-                       0x1c0 (PIN_INPUT | MUX_MODE3)   /* rgmii2_rd1 */
-                       0x1c4 (PIN_INPUT | MUX_MODE3)   /* rgmii2_rd0 */
+                       DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3)       /* rgmii2_tclk */
+                       DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3)       /* rgmii2_tctl */
+                       DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3)       /* rgmii2_td3 */
+                       DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3)       /* rgmii2_td2 */
+                       DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3)       /* rgmii2_td1 */
+                       DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3)       /* rgmii2_td0 */
+                       DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE3)        /* rgmii2_rclk */
+                       DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE3)        /* rgmii2_rctl */
+                       DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE3)        /* rgmii2_rd3 */
+                       DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE3)        /* rgmii2_rd2 */
+                       DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE3)        /* rgmii2_rd1 */
+                       DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE3)        /* rgmii2_rd0 */
                >;
 
        };
        cpsw_pins_sleep: cpsw_pins_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x250 (PIN_INPUT | MUX_MODE15)
-                       0x254 (PIN_INPUT | MUX_MODE15)
-                       0x258 (PIN_INPUT | MUX_MODE15)
-                       0x25c (PIN_INPUT | MUX_MODE15)
-                       0x260 (PIN_INPUT | MUX_MODE15)
-                       0x264 (PIN_INPUT | MUX_MODE15)
-                       0x268 (PIN_INPUT | MUX_MODE15)
-                       0x26c (PIN_INPUT | MUX_MODE15)
-                       0x270 (PIN_INPUT | MUX_MODE15)
-                       0x274 (PIN_INPUT | MUX_MODE15)
-                       0x278 (PIN_INPUT | MUX_MODE15)
-                       0x27c (PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3650, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3654, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3658, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x365c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3660, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3664, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT | MUX_MODE15)
 
                        /* Slave 2 */
-                       0x198 (PIN_INPUT | MUX_MODE15)
-                       0x19c (PIN_INPUT | MUX_MODE15)
-                       0x1a0 (PIN_INPUT | MUX_MODE15)
-                       0x1a4 (PIN_INPUT | MUX_MODE15)
-                       0x1a8 (PIN_INPUT | MUX_MODE15)
-                       0x1ac (PIN_INPUT | MUX_MODE15)
-                       0x1b0 (PIN_INPUT | MUX_MODE15)
-                       0x1b4 (PIN_INPUT | MUX_MODE15)
-                       0x1b8 (PIN_INPUT | MUX_MODE15)
-                       0x1bc (PIN_INPUT | MUX_MODE15)
-                       0x1c0 (PIN_INPUT | MUX_MODE15)
-                       0x1c4 (PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3598, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x359c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a0, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a4, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a8, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35ac, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE15)
                >;
        };
 
        davinci_mdio_pins_default: davinci_mdio_pins_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* mdio_mclk */
-                       0x240 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mdio_d */
+                       DRA7XX_CORE_IOPAD(0x363c, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* mdio_mclk */
+                       DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_d */
                >;
        };
 
        davinci_mdio_pins_sleep: davinci_mdio_pins_sleep {
                pinctrl-single,pins = <
-                       0x23c (PIN_INPUT | MUX_MODE15)
-                       0x240 (PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x363c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT | MUX_MODE15)
                >;
        };
 
        tps659038_pins_default: tps659038_pins_default {
                pinctrl-single,pins = <
-                       0x418 (PIN_INPUT_PULLUP | MUX_MODE14)   /* wakeup0.gpio1_0 */
+                       DRA7XX_CORE_IOPAD(0x3818, PIN_INPUT_PULLUP | MUX_MODE14)        /* wakeup0.gpio1_0 */
                >;
        };
 
        tmp102_pins_default: tmp102_pins_default {
                pinctrl-single,pins = <
-                       0x3C8 (PIN_INPUT_PULLUP | MUX_MODE14)   /* spi2_d0.gpio7_16 */
+                       DRA7XX_CORE_IOPAD(0x37c8, PIN_INPUT_PULLUP | MUX_MODE14)        /* spi2_d0.gpio7_16 */
                >;
        };
 
        mcp79410_pins_default: mcp79410_pins_default {
                pinctrl-single,pins = <
-                       0x424 (PIN_INPUT_PULLUP | MUX_MODE1)    /* wakeup3.sys_nirq1 */
+                       DRA7XX_CORE_IOPAD(0x3824, PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
                >;
        };
 
        usb1_pins: pinmux_usb1_pins {
                pinctrl-single,pins = <
-                       0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+                       DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
                >;
        };
 
        extcon_usb1_pins: extcon_usb1_pins {
                pinctrl-single,pins = <
-                       0x3ec (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */
+                       DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */
                >;
        };
 
        tpd12s015_pins: pinmux_tpd12s015_pins {
                pinctrl-single,pins = <
-                       0x3b0 (PIN_OUTPUT | MUX_MODE14)         /* gpio7_10 CT_CP_HPD */
-                       0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
-                       0x370 (PIN_OUTPUT | MUX_MODE14)         /* gpio6_28 LS_OE */
+                       DRA7XX_CORE_IOPAD(0x37b0, PIN_OUTPUT | MUX_MODE14)              /* gpio7_10 CT_CP_HPD */
+                       DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_PULLDOWN | MUX_MODE14)      /* gpio7_12 HPD */
+                       DRA7XX_CORE_IOPAD(0x3770, PIN_OUTPUT | MUX_MODE14)              /* gpio6_28 LS_OE */
                >;
        };
 
        clkout2_pins_default: clkout2_pins_default {
                pinctrl-single,pins = <
-                       0x294 (PIN_OUTPUT_PULLDOWN | MUX_MODE9) /* xref_clk0.clkout2 */
+                       DRA7XX_CORE_IOPAD(0x3694, PIN_OUTPUT_PULLDOWN | MUX_MODE9)      /* xref_clk0.clkout2 */
                >;
        };
 
        clkout2_pins_sleep: clkout2_pins_sleep {
                pinctrl-single,pins = <
-                       0x294 (PIN_INPUT | MUX_MODE15)  /* xref_clk0.clkout2 */
+                       DRA7XX_CORE_IOPAD(0x3694, PIN_INPUT | MUX_MODE15)       /* xref_clk0.clkout2 */
                >;
        };
 
        mcasp3_pins_default: mcasp3_pins_default {
                pinctrl-single,pins = <
-                       0x324 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
-                       0x328 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
-                       0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
-                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
                >;
        };
 
        mcasp3_pins_sleep: mcasp3_pins_sleep {
                pinctrl-single,pins = <
-                       0x324 (PIN_INPUT | MUX_MODE15)
-                       0x328 (PIN_INPUT | MUX_MODE15)
-                       0x32c (PIN_INPUT | MUX_MODE15)
-                       0x330 (PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT | MUX_MODE15)
                >;
        };
 };
diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts
new file mode 100644 (file)
index 0000000..c538826
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ * Support for CompuLab CL-SOM-AM57x System-on-Module
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Dmitry Lifshitz <lifshitz@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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "dra74x.dtsi"
+
+/ {
+       model = "CompuLab CL-SOM-AM57x";
+       compatible = "compulab,cl-som-am57x", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>; /* 512 MB - minimal configuration */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&leds_pins_default>;
+
+               led@0 {
+                       label = "cl-som-am57x:green";
+                       gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
+               };
+       };
+
+       vdd_3v3: fixedregulator-vdd_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       ads7846reg: fixedregulator-ads7846-reg {
+               compatible = "regulator-fixed";
+               regulator-name = "ads7846-reg";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       sound0: sound@0 {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "CL-SOM-AM57x-Sound-Card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,bitclock-master = <&dailink0_master>;
+               simple-audio-card,frame-master = <&dailink0_master>;
+               simple-audio-card,widgets =
+                                       "Headphone", "Headphone Jack",
+                                       "Microphone", "Microphone Jack",
+                                       "Line", "Line Jack";
+               simple-audio-card,routing =
+                                       "Headphone Jack", "RHPOUT",
+                                       "Headphone Jack", "LHPOUT",
+                                       "LLINEIN", "Line Jack",
+                                       "MICIN", "Mic Bias",
+                                       "Mic Bias", "Microphone Jack";
+
+               dailink0_master: simple-audio-card,cpu {
+                       sound-dai = <&mcasp3>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&wm8731>;
+                       system-clock-frequency = <12000000>;
+               };
+       };
+};
+
+&dra7_pmx_core {
+       leds_pins_default: leds_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x347c, PIN_OUTPUT | MUX_MODE14)      /* gpmc_a15.gpio2_5 */
+               >;
+       };
+
+       i2c1_pins_default: i2c1_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda.sda */
+                       DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl.scl */
+               >;
+       };
+
+       i2c3_pins_default: i2c3_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x36a4, PIN_INPUT| MUX_MODE10)        /* mcasp1_aclkx.i2c3_sda */
+                       DRA7XX_CORE_IOPAD(0x36a8, PIN_INPUT| MUX_MODE10)        /* mcasp1_fsx.i2c3_scl */
+               >;
+       };
+
+       i2c4_pins_default: i2c4_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x36ac, PIN_INPUT| MUX_MODE10)        /* mcasp1_acl.i2c4_sda */
+                       DRA7XX_CORE_IOPAD(0x36b0, PIN_INPUT| MUX_MODE10)        /* mcasp1_fsr.i2c4_scl */
+               >;
+       };
+
+       tps659038_pins_default: tps659038_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3818, PIN_INPUT_PULLUP | MUX_MODE14) /* wakeup0.gpio1_0 */
+               >;
+       };
+
+       mmc2_pins_default: mmc2_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+                       DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+                       DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+                       DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+                       DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+                       DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+                       DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+                       DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+                       DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+                       DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+               >;
+       };
+
+       qspi1_pins: pinmux_qspi1_pins {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3474, PIN_INPUT | MUX_MODE1)        /* gpmc_a13.qspi1_rtclk */
+                       DRA7XX_CORE_IOPAD(0x3480, PIN_INPUT | MUX_MODE1)        /* gpmc_a16.qspi1_d0 */
+                       DRA7XX_CORE_IOPAD(0x3484, PIN_INPUT | MUX_MODE1)        /* gpmc_a17.qspi1_d1 */
+                       DRA7XX_CORE_IOPAD(0x3488, PIN_INPUT | MUX_MODE1)        /* qpmc_a18.qspi1_sclk */
+                       DRA7XX_CORE_IOPAD(0x34b8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
+                       DRA7XX_CORE_IOPAD(0x34bc, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs3.qspi1_cs1 */
+               >;
+       };
+
+       cpsw_pins_default: cpsw_pins_default {
+               pinctrl-single,pins = <
+                       /* Slave at addr 0x0 */
+                       DRA7XX_CORE_IOPAD(0x3650, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_tclk */
+                       DRA7XX_CORE_IOPAD(0x3654, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_tctl */
+                       DRA7XX_CORE_IOPAD(0x3658, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_td3 */
+                       DRA7XX_CORE_IOPAD(0x365c, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_td2 */
+                       DRA7XX_CORE_IOPAD(0x3660, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_td1 */
+                       DRA7XX_CORE_IOPAD(0x3664, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_td0 */
+                       DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rclk */
+                       DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rctl */
+                       DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd3 */
+                       DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd2 */
+                       DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd1 */
+                       DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd0 */
+
+                       /* Slave at addr 0x1 */
+                       DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d12.rgmii1_tclk */
+                       DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d13.rgmii1_tctl */
+                       DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d14.rgmii1_td3 */
+                       DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d15.rgmii1_td2 */
+                       DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d16.rgmii1_td1 */
+                       DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d17.rgmii1_td0 */
+                       DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d18.rgmii1_rclk */
+                       DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d19.rgmii1_rctl */
+                       DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */
+                       DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */
+                       DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */
+                       DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT_PULLUP | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */
+               >;
+       };
+
+       cpsw_pins_sleep: cpsw_pins_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       DRA7XX_CORE_IOPAD(0x3650, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3654, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3658, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x365c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3660, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3664, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT | MUX_MODE15)
+
+                       /* Slave 2 */
+                       DRA7XX_CORE_IOPAD(0x3598, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x359c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a0, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a4, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a8, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35ac, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE15)
+               >;
+       };
+
+       davinci_mdio_pins_default: davinci_mdio_pins_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       DRA7XX_CORE_IOPAD(0x3590, PIN_OUTPUT_PULLUP | MUX_MODE3)/* vin2a_d10.mdio_mclk */
+                       DRA7XX_CORE_IOPAD(0x3594, PIN_INPUT_PULLUP | MUX_MODE3) /* vin2a_d11.mdio_d */
+               >;
+       };
+
+       davinci_mdio_pins_sleep: davinci_mdio_pins_sleep {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3590, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3594, PIN_INPUT | MUX_MODE15)
+               >;
+       };
+
+       ads7846_pins: pinmux_ads7846_pins {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3464, PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpmc_a9.gpio1_31 */
+               >;
+       };
+
+       mcasp3_pins_default: mcasp3_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
+               >;
+       };
+
+       mcasp3_pins_sleep: mcasp3_pins_sleep {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_INPUT | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT | MUX_MODE15)
+               >;
+       };
+};
+
+&i2c1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins_default>;
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins_default>;
+       clock-frequency = <400000>;
+};
+
+&i2c4 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins_default>;
+       clock-frequency = <400000>;
+
+       tps659038: tps659038@58 {
+               compatible = "ti,tps659038";
+               reg = <0x58>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&tps659038_pins_default>;
+
+               #interrupt-cells = <2>;
+               interrupt-controller;
+
+               ti,system-power-controller;
+
+               tps659038_pmic {
+                       compatible = "ti,tps659038-pmic";
+
+                       regulators {
+                               smps12_reg: smps12 {
+                                       /* VDD_MPU */
+                                       regulator-name = "smps12";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps3_reg: smps3 {
+                                       /* VDD_DDR */
+                                       regulator-name = "smps3";
+                                       regulator-min-microvolt = <1500000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps45_reg: smps45 {
+                                       /* VDD_DSPEVE */
+                                       regulator-name = "smps45";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps6_reg: smps6 {
+                                       /* VDD_GPU */
+                                       regulator-name = "smps6";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps7_reg: smps7 {
+                                       /* VDD_CORE */
+                                       regulator-name = "smps7";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1160000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps8_reg: smps8 {
+                                       /* VDD_IVA */
+                                       regulator-name = "smps8";
+                                       regulator-min-microvolt = < 850000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               smps9_reg: smps9 {
+                                       /* PMIC_3V3 */
+                                       regulator-name = "smps9";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+
+                               ldo1_reg: ldo1 {
+                                       /* VDD_SD / VDDSHV8  */
+                                       regulator-name = "ldo1";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-boot-on;
+                                       regulator-always-on;
+                               };
+
+                               ldo2_reg: ldo2 {
+                                       /* VDD_1V8 */
+                                       regulator-name = "ldo2";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo3_reg: ldo3 {
+                                       /* VDDA_1V8_PHYA - supplies VDDA_SATA, VDDA_USB1/2/3 */
+                                       regulator-name = "ldo3";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo4_reg: ldo4 {
+                                       /* VDDA_1V8_PHYB - supplies VDDA_HDMI, VDDA_PCIE/0/1 */
+                                       regulator-name = "ldo4";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo9_reg: ldo9 {
+                                       /* VDD_RTC */
+                                       regulator-name = "ldo9";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldoln_reg: ldoln {
+                                       /* VDDA_1V8_PLL */
+                                       regulator-name = "ldoln";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldousb_reg: ldousb {
+                                       /* VDDA_3V_USB: VDDA_USBHS33 */
+                                       regulator-name = "ldousb";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               /* regen1 not used */
+                       };
+               };
+
+               tps659038_pwr_button: tps659038_pwr_button {
+                       compatible = "ti,palmas-pwrbutton";
+                       interrupt-parent = <&tps659038>;
+                       interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+                       wakeup-source;
+                       ti,palmas-long-press-seconds = <12>;
+               };
+
+               tps659038_gpio: tps659038_gpio {
+                       compatible = "ti,palmas-gpio";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+       };
+
+       rtc0: rtc@56 {
+               compatible = "emmicro,em3027";
+               reg = <0x56>;
+       };
+
+       eeprom_module: atmel@50 {
+               compatible = "atmel,24c08";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       wm8731: wm8731@1a {
+               #sound-dai-cells = <0>;
+               compatible = "wlf,wm8731";
+               reg = <0x1a>;
+               status = "okay";
+       };
+};
+
+&cpu0 {
+       cpu0-supply = <&smps12_reg>;
+       voltage-tolerance = <1>;
+};
+
+&sata {
+       status = "okay";
+};
+
+&mailbox5 {
+       status = "okay";
+       mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+               status = "okay";
+       };
+       mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+               status = "okay";
+       };
+};
+
+&mailbox6 {
+       status = "okay";
+       mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+               status = "okay";
+       };
+       mbox_dsp2_ipc3x: mbox_dsp2_ipc3x {
+               status = "okay";
+       };
+};
+
+&mmc2 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins_default>;
+
+       vmmc-supply = <&vdd_3v3>;
+       bus-width = <8>;
+       ti,non-removable;
+       cap-mmc-dual-data-rate;
+};
+
+&qspi {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&qspi1_pins>;
+
+       spi-max-frequency = <20000000>;
+
+       spi_flash: spi_flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spansion,m25p80", "jedec,spi-nor";
+               reg = <0>;                              /* CS0 */
+               spi-max-frequency = <20000000>;
+
+               partition@0 {
+                       label = "uboot";
+                       reg = <0x0 0xc0000>;
+               };
+
+               partition@c0000 {
+                       label = "uboot environment";
+                       reg = <0xc0000 0x40000>;
+               };
+
+               partition@100000 {
+                       label = "reserved";
+                       reg = <0x100000 0x0>;
+               };
+       };
+
+       /* touch controller */
+       ads7846@0 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&ads7846_pins>;
+
+               compatible = "ti,ads7846";
+               vcc-supply = <&ads7846reg>;
+
+               reg = <1>;                              /* CS1 */
+               spi-max-frequency = <1500000>;
+
+               interrupt-parent = <&gpio1>;
+               interrupts = <31 0>;
+               pendown-gpio = <&gpio1 31 0>;
+
+
+               ti,x-min = /bits/ 16 <0x0>;
+               ti,x-max = /bits/ 16 <0x0fff>;
+               ti,y-min = /bits/ 16 <0x0>;
+               ti,y-max = /bits/ 16 <0x0fff>;
+
+               ti,x-plate-ohms = /bits/ 16 <180>;
+               ti,pressure-max = /bits/ 16 <255>;
+
+               ti,debounce-max = /bits/ 16 <30>;
+               ti,debounce-tol = /bits/ 16 <10>;
+               ti,debounce-rep = /bits/ 16 <1>;
+
+               linux,wakeup;
+       };
+};
+
+&mac {
+       status = "okay";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_pins_default>;
+       pinctrl-1 = <&cpsw_pins_sleep>;
+       dual_emac;
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       phy-mode = "rgmii";
+       dual_emac_res_vlan = <0>;
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <1>;
+       phy-mode = "rgmii";
+       dual_emac_res_vlan = <1>;
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_pins_default>;
+       pinctrl-1 = <&davinci_mdio_pins_sleep>;
+};
+
+&usb2_phy1 {
+       phy-supply = <&ldousb_reg>;
+};
+
+&usb2_phy2 {
+       phy-supply = <&ldousb_reg>;
+};
+
+&usb1 {
+       dr_mode = "host";
+};
+
+&usb2 {
+       dr_mode = "peripheral";
+};
+
+&mcasp3 {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&mcasp3_pins_default>;
+       pinctrl-1 = <&mcasp3_pins_sleep>;
+       status = "okay";
+
+       op-mode = <0>;  /* MCASP_IIS_MODE */
+       tdm-slots = <2>;
+       /* 4 serializers */
+       serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+               1 2 0 0
+       >;
+};
+
+&gpio3 {
+       status = "okay";
+       ti,no-reset-on-init;
+};
+
+&gpio2 {
+       status = "okay";
+       ti,no-reset-on-init;
+};
diff --git a/arch/arm/boot/dts/am57xx-sbc-am57x.dts b/arch/arm/boot/dts/am57xx-sbc-am57x.dts
new file mode 100644 (file)
index 0000000..77bb8e1
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Support for CompuLab SBC-AM57x single board computer
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Dmitry Lifshitz <lifshitz@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.
+ */
+
+#include "am57xx-cl-som-am57x.dts"
+#include "compulab-sb-som.dtsi"
+
+/ {
+       model = "CompuLab CL-SOM-AM57x on SB-SOM-AM57x";
+       compatible = "compulab,sbc-am57x", "compulab,cl-som-am57x", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7";
+
+       aliases {
+               display0 = &lcd0;
+               display1 = &hdmi;
+       };
+};
+
+&dra7_pmx_core {
+       uart3_pins_default: uart3_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_SLEW | MUX_MODE2)   /* uart2_ctsn.uart3_rxd */
+                       DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_SLEW | MUX_MODE1)   /* uart2_rtsn.uart3_txd */
+               >;
+       };
+
+       mmc1_pins_default: mmc1_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+                       DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+                       DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+                       DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+                       DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+                       DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+                       DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14)       /* mmc1_sdcd.gpio6_27 */
+                       DRA7XX_CORE_IOPAD(0x377c, PIN_INPUT | MUX_MODE14)       /* mmc1_sdwp.gpio6_28 */
+               >;
+       };
+
+       usb1_pins: pinmux_usb1_pins {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+               >;
+       };
+
+       i2c5_pins_default: i2c5_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x36b4, PIN_INPUT| MUX_MODE10)        /* mcasp1_axr0.i2c5_sda */
+                       DRA7XX_CORE_IOPAD(0x36b8, PIN_INPUT| MUX_MODE10)        /* mcasp1_axr1.i2c5_scl */
+               >;
+       };
+
+       lcd_pins_default: lcd_pins_default {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3564, PIN_OUTPUT | MUX_MODE14)      /* vin2a_vsync0.gpio4_0 */
+               >;
+       };
+
+       hdmi_pins: pinmux_hdmi_pins {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1)        /* i2c2_sda.hdmi1_ddc_scl */
+                       DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE1)        /* i2c2_scl.hdmi1_ddc_sda */
+               >;
+       };
+
+       hdmi_conn_pins: pinmux_hdmi_conn_pins {
+               pinctrl-single,pins = <
+                       DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT | MUX_MODE14)       /* spi1_cs2.gpio7_12 */
+               >;
+       };
+};
+
+&uart3 {
+       status = "okay";
+       interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+                             <&dra7_pmx_core 0x3f8>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins_default>;
+};
+
+&mmc1 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins_default>;
+
+       vmmc-supply = <&ldo1_reg>;
+       bus-width = <4>;
+       cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio6 28 GPIO_ACTIVE_HIGH>;
+};
+
+&usb1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb1_pins>;
+};
+
+&i2c5 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c5_pins_default>;
+       clock-frequency = <400000>;
+
+       eeprom_base: atmel@50 {
+               compatible = "atmel,24c08";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       pca9555: pca9555@20 {
+               compatible = "nxp,pca9555";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&dss {
+       status = "ok";
+
+       vdda_video-supply = <&ldoln_reg>;
+
+       port {
+               dpi_lcd_out: endpoint@0 {
+                       remote-endpoint = <&lcd_in>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&lcd0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&lcd_pins_default>;
+
+       enable-gpios = <&pca9555 14 GPIO_ACTIVE_HIGH
+                       &gpio4 0 GPIO_ACTIVE_HIGH>;
+
+       port {
+               lcd_in: endpoint {
+                       remote-endpoint = <&dpi_lcd_out>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&hdmi {
+       status = "ok";
+       vdda-supply = <&ldo4_reg>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_pins>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&hdmi_connector_in>;
+                       lanes = <1 0 3 2 5 4 7 6>;
+               };
+       };
+};
+
+&hdmi_conn {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_conn_pins>;
+
+       hpd-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+
+       port {
+               hdmi_connector_in: endpoint {
+                       remote-endpoint = <&hdmi_out>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm-realview-pb11mp.dts
new file mode 100644 (file)
index 0000000..da755c9
--- /dev/null
@@ -0,0 +1,681 @@
+/*
+ * Copyright 2015 Linaro Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+       model = "ARM RealView PB11MPcore";
+       compatible = "arm,realview-pb11mp";
+
+       chosen { };
+
+       aliases {
+               serial0 = &pb11mp_serial0;
+               serial1 = &pb11mp_serial1;
+               serial2 = &pb11mp_serial2;
+               serial3 = &pb11mp_serial3;
+       };
+
+       memory {
+               /*
+                * The PB11MPCore has 512 MiB memory @ 0x70000000
+                * and the first 256 are also remapped @ 0x00000000
+                */
+               reg = <0x70000000 0x20000000>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "arm,realview-smp";
+
+               MP11_0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,arm11mpcore";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+               };
+
+               MP11_1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,arm11mpcore";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+               };
+
+               MP11_2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,arm11mpcore";
+                       reg = <2>;
+                       next-level-cache = <&L2>;
+               };
+
+               MP11_3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,arm11mpcore";
+                       reg = <3>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       /* Primary TestChip GIC synthesized with the CPU */
+       intc_tc11mp: interrupt-controller@1f000100 {
+               compatible = "arm,tc11mp-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <1>;
+               interrupt-controller;
+               reg = <0x1f001000 0x1000>,
+                     <0x1f000100 0x100>;
+       };
+
+       L2: l2-cache {
+               compatible = "arm,l220-cache";
+               reg = <0x1f002000 0x1000>;
+               interrupt-parent = <&intc_tc11mp>;
+               interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 30 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 31 IRQ_TYPE_LEVEL_HIGH>;
+               cache-unified;
+               cache-level = <2>;
+               /*
+                * Override default cache size, sets and
+                * associativity as these may be erroneously set
+                * up by boot loader(s), probably for safety
+                * since th outer sync operation can cause the
+                * cache to hang unless disabled.
+                */
+               cache-size = <1048576>; // 1MB
+               cache-sets = <4096>;
+               cache-line-size = <32>;
+               arm,shared-override;
+               arm,parity-enable;
+               arm,outer-sync-disable;
+       };
+
+       scu@1f000000 {
+               compatible = "arm,arm11mp-scu";
+               reg = <0x1f000000 0x100>;
+       };
+
+       timer@1f000600 {
+               compatible = "arm,arm11mp-twd-timer";
+               reg = <0x1f000600 0x20>;
+               interrupt-parent = <&intc_tc11mp>;
+               interrupts = <1 13 0xf04>;
+       };
+
+       watchdog@1f000620 {
+               compatible = "arm,arm11mp-twd-wdt";
+               reg = <0x1f000620 0x20>;
+               interrupt-parent = <&intc_tc11mp>;
+               interrupts = <1 14 0xf04>;
+       };
+
+       /* PMU with one IRQ line per core */
+       pmu {
+               compatible = "arm,arm11mpcore-pmu";
+               interrupt-parent = <&intc_tc11mp>;
+               interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 18 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 19 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 20 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&MP11_0>, <&MP11_1>, <&MP11_2>, <&MP11_3>;
+       };
+
+       /* The voltage to the MMC card is hardwired at 3.3V */
+       vmmc: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+        };
+
+       veth: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "veth";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+       };
+
+       xtal24mhz: xtal24mhz@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+       };
+
+       refclk32khz: refclk32khz {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
+
+       timclk: timclk@1M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <24>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       mclk: mclk@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <1>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       kmiclk: kmiclk@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <1>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       sspclk: sspclk@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <1>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       uartclk: uartclk@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <1>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       wdogclk: wdogclk@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <1>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       /* FIXME: this actually hangs off the PLL clocks */
+       pclk: pclk@0 {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+       };
+
+       flash0@40000000 {
+               /* 2 * 32MiB NOR Flash memory */
+               compatible = "arm,vexpress-flash", "cfi-flash";
+               reg = <0x40000000 0x04000000>;
+               bank-width = <4>;
+       };
+
+       flash1@44000000 {
+               // 2 * 32MiB NOR Flash memory
+               compatible = "arm,vexpress-flash", "cfi-flash";
+               reg = <0x44000000 0x04000000>;
+               bank-width = <4>;
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "arm,realview-pb11mp-soc", "simple-bus";
+               regmap = <&pb11mp_syscon>;
+               ranges;
+
+               pb11mp_syscon: syscon@10000000 {
+                       compatible = "arm,realview-pb11mp-syscon", "syscon", "simple-mfd";
+                       reg = <0x10000000 0x1000>;
+
+                       led@08.0 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x01>;
+                               label = "versatile:0";
+                               linux,default-trigger = "heartbeat";
+                               default-state = "on";
+                       };
+                       led@08.1 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x02>;
+                               label = "versatile:1";
+                               linux,default-trigger = "mmc0";
+                               default-state = "off";
+                       };
+                       led@08.2 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x04>;
+                               label = "versatile:2";
+                               linux,default-trigger = "cpu0";
+                               default-state = "off";
+                       };
+                       led@08.3 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x08>;
+                               label = "versatile:3";
+                               linux,default-trigger = "cpu1";
+                               default-state = "off";
+                       };
+                       led@08.4 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x10>;
+                               label = "versatile:4";
+                               linux,default-trigger = "cpu2";
+                               default-state = "off";
+                       };
+                       led@08.5 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x20>;
+                               label = "versatile:5";
+                               linux,default-trigger = "cpu3";
+                               default-state = "off";
+                       };
+                       led@08.6 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x40>;
+                               label = "versatile:6";
+                               default-state = "off";
+                       };
+                       led@08.7 {
+                               compatible = "register-bit-led";
+                               offset = <0x08>;
+                               mask = <0x80>;
+                               label = "versatile:7";
+                               default-state = "off";
+                       };
+
+                       oscclk0: osc0@0c {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0x0C>;
+                               clocks = <&xtal24mhz>;
+                       };
+                       oscclk1: osc1@10 {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0x10>;
+                               clocks = <&xtal24mhz>;
+                       };
+                       oscclk2: osc2@14 {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0x14>;
+                               clocks = <&xtal24mhz>;
+                       };
+                       oscclk3: osc3@18 {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0x18>;
+                               clocks = <&xtal24mhz>;
+                       };
+                       oscclk4: osc4@1c {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0x1c>;
+                               clocks = <&xtal24mhz>;
+                       };
+                       oscclk5: osc5@d4 {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0xd4>;
+                               clocks = <&xtal24mhz>;
+                       };
+                       oscclk6: osc6@d8 {
+                               compatible = "arm,syscon-icst307";
+                               #clock-cells = <0>;
+                               lock-offset = <0x20>;
+                               vco-offset = <0xd8>;
+                               clocks = <&xtal24mhz>;
+                       };
+               };
+
+               sp810_syscon: sysctl@10001000 {
+                       compatible = "arm,sp810", "arm,primecell";
+                       reg = <0x10001000 0x1000>;
+                       clocks = <&refclk32khz>, <&timclk>, <&xtal24mhz>;
+                       clock-names = "refclk", "timclk", "apb_pclk";
+                       #clock-cells = <1>;
+                       clock-output-names = "timerclk0",
+                                            "timerclk1",
+                                            "timerclk2",
+                                            "timerclk3";
+                       assigned-clocks = <&sp810_syscon 0>,
+                                         <&sp810_syscon 1>,
+                                         <&sp810_syscon 2>,
+                                         <&sp810_syscon 3>;
+                       assigned-clock-parents = <&timclk>,
+                                              <&timclk>,
+                                              <&timclk>,
+                                              <&timclk>;
+               };
+
+               i2c0: i2c@10002000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "arm,versatile-i2c";
+                       reg = <0x10002000 0x1000>;
+
+                       rtc@68 {
+                               compatible = "dallas,ds1338";
+                               reg = <0x68>;
+                       };
+               };
+
+               aaci: aaci@10004000 {
+                       compatible = "arm,pl041", "arm,primecell";
+                       reg = <0x10004000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
+               };
+
+               mci: mmcsd@10005000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x10005000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0 15 IRQ_TYPE_LEVEL_HIGH>;
+                       /* Due to frequent FIFO overruns, use just 500 kHz */
+                       max-frequency = <500000>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       cap-mmc-highspeed;
+                       clocks = <&mclk>, <&pclk>;
+                       clock-names = "mclk", "apb_pclk";
+                       vmmc-supply = <&vmmc>;
+                       cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+                       wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+               };
+
+               kmi0: kmi@10006000 {
+                       compatible = "arm,pl050", "arm,primecell";
+                       reg = <0x10006000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&kmiclk>, <&pclk>;
+                       clock-names = "KMIREFCLK", "apb_pclk";
+               };
+
+               kmi1: kmi@10007000 {
+                       compatible = "arm,pl050", "arm,primecell";
+                       reg = <0x10007000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&kmiclk>, <&pclk>;
+                       clock-names = "KMIREFCLK", "apb_pclk";
+               };
+
+               pb11mp_serial0: serial@10009000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x10009000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
+               };
+
+               pb11mp_serial1: serial@1000a000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x1000a000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
+               };
+
+               pb11mp_serial2: serial@1000b000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x1000b000 0x1000>;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
+               };
+
+               pb11mp_serial3: serial@1000c000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x1000c000 0x1000>;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
+               };
+
+               ssp@1000d000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x1000d000 0x1000>;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&sspclk>, <&pclk>;
+                       clock-names = "SSPCLK", "apb_pclk";
+               };
+
+               watchdog@1000f000 {
+                       compatible = "arm,sp805", "arm,primecell";
+                       reg = <0x1000f000 0x1000>;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&wdogclk>, <&pclk>;
+                       clock-names = "wdogclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               watchdog@10010000 {
+                       compatible = "arm,sp805", "arm,primecell";
+                       reg = <0x10010000 0x1000>;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&wdogclk>, <&pclk>;
+                       clock-names = "wdogclk", "apb_pclk";
+               };
+
+               timer01: timer@10011000 {
+                       compatible = "arm,sp804", "arm,primecell";
+                       reg = <0x10011000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH>;
+                       arm,sp804-has-irq = <1>;
+                       clocks = <&sp810_syscon 0>,
+                                <&sp810_syscon 1>,
+                                <&pclk>;
+                       clock-names = "timerclk0",
+                                   "timerclk1",
+                                   "apb_pclk";
+               };
+
+               timer23: timer@10012000 {
+                       compatible = "arm,sp804", "arm,primecell";
+                       reg = <0x10012000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
+                       arm,sp804-has-irq = <1>;
+                       clocks = <&sp810_syscon 2>,
+                                <&sp810_syscon 3>,
+                                <&pclk>;
+                       clock-names = "timerclk2",
+                                   "timerclk3",
+                                   "apb_pclk";
+               };
+
+               gpio0: gpio@10013000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x10013000 0x1000>;
+                       gpio-controller;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
+               };
+
+               gpio1: gpio@10014000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x10014000 0x1000>;
+                       gpio-controller;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
+               };
+
+               gpio2: gpio@10015000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x10015000 0x1000>;
+                       gpio-controller;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
+               };
+
+               rtc: rtc@10017000 {
+                       compatible = "arm,pl031", "arm,primecell";
+                       reg = <0x10017000 0x1000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
+               };
+
+               timer45: timer@10018000 {
+                       compatible = "arm,sp804", "arm,primecell";
+                       reg = <0x10018000 0x1000>;
+                       clocks = <&timclk>, <&pclk>;
+                       clock-names = "timer", "apb_pclk";
+                       status = "disabled";
+               };
+
+               timer67: timer@10019000 {
+                       compatible = "arm,sp804", "arm,primecell";
+                       reg = <0x10019000 0x1000>;
+                       clocks = <&timclk>, <&pclk>;
+                       clock-names = "timer", "apb_pclk";
+                       status = "disabled";
+               };
+
+
+               clcd@10020000 {
+                       compatible = "arm,pl111", "arm,primecell";
+                       reg = <0x10020000 0x1000>;
+                       interrupt-parent = <&intc_pb11mp>;
+                       interrupt-names = "combined";
+                       interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&oscclk4>, <&pclk>;
+                       clock-names = "clcdclk", "apb_pclk";
+                       max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
+
+                       port {
+                               clcd_pads: endpoint {
+                                       remote-endpoint = <&clcd_panel>;
+                                       arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+                               };
+                       };
+
+                       panel {
+                               compatible = "panel-dpi";
+
+                               port {
+                                       clcd_panel: endpoint {
+                                               remote-endpoint = <&clcd_pads>;
+                                       };
+                               };
+
+                               panel-timing {
+                                       clock-frequency = <63500127>;
+                                       hactive = <1024>;
+                                       hback-porch = <152>;
+                                       hfront-porch = <48>;
+                                       hsync-len = <104>;
+                                       vactive = <768>;
+                                       vback-porch = <23>;
+                                       vfront-porch = <3>;
+                                       vsync-len = <4>;
+                               };
+                       };
+               };
+
+               /*
+                * This GIC on the Platform Baseboard is cascaded off the
+                * TestChip GIC
+                */
+               intc_pb11mp: interrupt-controller@1e000000 {
+                       compatible = "arm,arm11mp-gic";
+                       #interrupt-cells = <3>;
+                       #address-cells = <1>;
+                       interrupt-controller;
+                       reg = <0x1e001000 0x1000>,
+                             <0x1e000000 0x100>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               /* SMSC 9118 ethernet with PHY and EEPROM */
+               ethernet@4e000000 {
+                       compatible = "smsc,lan9118", "smsc,lan9115";
+                       reg = <0x4e000000 0x10000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+                       phy-mode = "mii";
+                       reg-io-width = <4>;
+                       smsc,irq-active-high;
+                       smsc,irq-push-pull;
+                       vdd33a-supply = <&veth>;
+                       vddvario-supply = <&veth>;
+               };
+
+               usb@4f000000 {
+                       compatible = "nxp,usb-isp1761";
+                       reg = <0x4f000000 0x20000>;
+                       interrupt-parent = <&intc_tc11mp>;
+                       interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>;
+                       port1-otg;
+               };
+       };
+};
index 5555875..39181b3 100644 (file)
                                isl12057: isl12057@68 {
                                        compatible = "isil,isl12057";
                                        reg = <0x68>;
-                                       isil,irq2-can-wakeup-machine;
+                                       wakeup-source;
                                };
 
                                g762: g762@3e {
index 78b563c..faa4748 100644 (file)
                                isl12057: isl12057@68 {
                                        compatible = "isil,isl12057";
                                        reg = <0x68>;
-                                       isil,irq2-can-wakeup-machine;
+                                       wakeup-source;
                                };
 
                                g762: g762@3e {
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
new file mode 100644 (file)
index 0000000..c6e180e
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * Device Tree file for SolidRun Clearfog revision A1 rev 2.0 (88F6828)
+ *
+ *  Copyright (C) 2015 Russell King
+ *
+ * This board is in development; the contents of this file work with
+ * the A1 rev 2.0 of the board, which does not represent final
+ * production board.  Things will change, don't expect this file to
+ * remain compatible info the future.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful
+ *     but 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.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+#include "armada-38x-solidrun-microsom.dtsi"
+
+/ {
+       model = "SolidRun Clearfog A1";
+       compatible = "solidrun,clearfog-a1", "marvell,armada388",
+               "marvell,armada385", "marvell,armada380";
+
+       aliases {
+               /* So that mvebu u-boot can update the MAC addresses */
+               ethernet1 = &eth0;
+               ethernet2 = &eth1;
+               ethernet3 = &eth2;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       soc {
+               internal-regs {
+                       ethernet@30000 {
+                               phy-mode = "sgmii";
+                               status = "okay";
+
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                               };
+                       };
+
+                       ethernet@34000 {
+                               phy-mode = "sgmii";
+                               status = "okay";
+
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                               };
+                       };
+
+                       i2c@11000 {
+                               /* Is there anything on this? */
+                               clock-frequency = <100000>;
+                               pinctrl-0 = <&i2c0_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+
+                               /*
+                                * PCA9655 GPIO expander, up to 1MHz clock.
+                                *  0-CON3 CLKREQ#
+                                *  1-CON3 PERST#
+                                *  2-CON2 PERST#
+                                *  3-CON3 W_DISABLE
+                                *  4-CON2 CLKREQ#
+                                *  5-USB3 overcurrent
+                                *  6-USB3 power
+                                *  7-CON2 W_DISABLE
+                                *  8-JP4 P1
+                                *  9-JP4 P4
+                                * 10-JP4 P5
+                                * 11-m.2 DEVSLP
+                                * 12-SFP_LOS
+                                * 13-SFP_TX_FAULT
+                                * 14-SFP_TX_DISABLE
+                                * 15-SFP_MOD_DEF0
+                                */
+                               expander0: gpio-expander@20 {
+                                       /*
+                                        * This is how it should be:
+                                        * compatible = "onnn,pca9655",
+                                        *       "nxp,pca9555";
+                                        * but you can't do this because of
+                                        * the way I2C works.
+                                        */
+                                       compatible = "nxp,pca9555";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       reg = <0x20>;
+
+                                       pcie1_0_clkreq {
+                                               gpio-hog;
+                                               gpios = <0 GPIO_ACTIVE_LOW>;
+                                               input;
+                                               line-name = "pcie1.0-clkreq";
+                                       };
+                                       pcie1_0_w_disable {
+                                               gpio-hog;
+                                               gpios = <3 GPIO_ACTIVE_LOW>;
+                                               output-low;
+                                               line-name = "pcie1.0-w-disable";
+                                       };
+                                       pcie2_0_clkreq {
+                                               gpio-hog;
+                                               gpios = <4 GPIO_ACTIVE_LOW>;
+                                               input;
+                                               line-name = "pcie2.0-clkreq";
+                                       };
+                                       pcie2_0_w_disable {
+                                               gpio-hog;
+                                               gpios = <7 GPIO_ACTIVE_LOW>;
+                                               output-low;
+                                               line-name = "pcie2.0-w-disable";
+                                       };
+                                       usb3_ilimit {
+                                               gpio-hog;
+                                               gpios = <5 GPIO_ACTIVE_LOW>;
+                                               input;
+                                               line-name = "usb3-current-limit";
+                                       };
+                                       usb3_power {
+                                               gpio-hog;
+                                               gpios = <6 GPIO_ACTIVE_HIGH>;
+                                               output-high;
+                                               line-name = "usb3-power";
+                                       };
+                                       m2_devslp {
+                                               gpio-hog;
+                                               gpios = <11 GPIO_ACTIVE_HIGH>;
+                                               output-low;
+                                               line-name = "m.2 devslp";
+                                       };
+                                       sfp_los {
+                                               /* SFP loss of signal */
+                                               gpio-hog;
+                                               gpios = <12 GPIO_ACTIVE_HIGH>;
+                                               input;
+                                               line-name = "sfp-los";
+                                       };
+                                       sfp_tx_fault {
+                                               /* SFP laser fault */
+                                               gpio-hog;
+                                               gpios = <13 GPIO_ACTIVE_HIGH>;
+                                               input;
+                                               line-name = "sfp-tx-fault";
+                                       };
+                                       sfp_tx_disable {
+                                               /* SFP transmit disable */
+                                               gpio-hog;
+                                               gpios = <14 GPIO_ACTIVE_HIGH>;
+                                               output-low;
+                                               line-name = "sfp-tx-disable";
+                                       };
+                                       sfp_mod_def0 {
+                                               /* SFP module present */
+                                               gpio-hog;
+                                               gpios = <15 GPIO_ACTIVE_LOW>;
+                                               input;
+                                               line-name = "sfp-mod-def0";
+                                       };
+                               };
+
+                               /* The MCP3021 is 100kHz clock only */
+                               mikrobus_adc: mcp3021@4c {
+                                       compatible = "microchip,mcp3021";
+                                       reg = <0x4c>;
+                               };
+
+                               /* Also something at 0x64 */
+                       };
+
+                       i2c@11100 {
+                               /*
+                                * Routed to SFP, mikrobus, and PCIe.
+                                * SFP limits this to 100kHz, and requires
+                                *  an AT24C01A/02/04 with address pins tied
+                                *  low, which takes addresses 0x50 and 0x51.
+                                * Mikrobus doesn't specify beyond an I2C
+                                *  bus being present.
+                                * PCIe uses ARP to assign addresses, or
+                                *  0x63-0x64.
+                                */
+                               clock-frequency = <100000>;
+                               pinctrl-0 = <&clearfog_i2c1_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
+                       mdio@72004 {
+                               pinctrl-0 = <&mdio_pins>;
+                               pinctrl-names = "default";
+
+                               phy_dedicated: ethernet-phy@0 {
+                                       /*
+                                        * Annoyingly, the marvell phy driver
+                                        * configures the LED register, rather
+                                        * than preserving reset-loaded setting.
+                                        * We undo that rubbish here.
+                                        */
+                                       marvell,reg-init = <3 16 0 0x101e>;
+                                       reg = <0>;
+                               };
+                       };
+
+                       pinctrl@18000 {
+                               clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins {
+                                       marvell,pins = "mpp46";
+                                       marvell,function = "ref";
+                               };
+                               clearfog_dsa0_pins: clearfog-dsa0-pins {
+                                       marvell,pins = "mpp23", "mpp41";
+                                       marvell,function = "gpio";
+                               };
+                               clearfog_i2c1_pins: i2c1-pins {
+                                       /* SFP, PCIe, mSATA, mikrobus */
+                                       marvell,pins = "mpp26", "mpp27";
+                                       marvell,function = "i2c1";
+                               };
+                               clearfog_sdhci_cd_pins: clearfog-sdhci-cd-pins {
+                                       marvell,pins = "mpp20";
+                                       marvell,function = "gpio";
+                               };
+                               clearfog_sdhci_pins: clearfog-sdhci-pins {
+                                       marvell,pins = "mpp21", "mpp28",
+                                                      "mpp37", "mpp38",
+                                                      "mpp39", "mpp40";
+                                       marvell,function = "sd0";
+                               };
+                               clearfog_spi1_cs_pins: spi1-cs-pins {
+                                       marvell,pins = "mpp55";
+                                       marvell,function = "spi1";
+                               };
+                               mikro_pins: mikro-pins {
+                                       /* int: mpp22 rst: mpp29 */
+                                       marvell,pins = "mpp22", "mpp29";
+                                       marvell,function = "gpio";
+                               };
+                               mikro_spi_pins: mikro-spi-pins {
+                                       marvell,pins = "mpp43";
+                                       marvell,function = "spi1";
+                               };
+                               mikro_uart_pins: mikro-uart-pins {
+                                       marvell,pins = "mpp24", "mpp25";
+                                       marvell,function = "ua1";
+                               };
+                               rear_button_pins: rear-button-pins {
+                                       marvell,pins = "mpp34";
+                                       marvell,function = "gpio";
+                               };
+                       };
+
+                       sata@a8000 {
+                               /* pinctrl? */
+                               status = "okay";
+                       };
+
+                       sata@e0000 {
+                               /* pinctrl? */
+                               status = "okay";
+                       };
+
+                       sdhci@d8000 {
+                               bus-width = <4>;
+                               cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+                               no-1-8-v;
+                               pinctrl-0 = <&clearfog_sdhci_pins
+                                            &clearfog_sdhci_cd_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                               vmmc = <&reg_3p3v>;
+                               wp-inverted;
+                       };
+
+                       serial@12100 {
+                               /* mikrobus uart */
+                               pinctrl-0 = <&mikro_uart_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
+                       spi@10680 {
+                               /*
+                                * We don't seem to have the W25Q32 on the
+                                * A1 Rev 2.0 boards, so disable SPI.
+                                * CS0: W25Q32 (doesn't appear to be present)
+                                * CS1:
+                                * CS2: mikrobus
+                                */
+                               pinctrl-0 = <&spi1_pins
+                                            &clearfog_spi1_cs_pins
+                                            &mikro_spi_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+
+                               spi-flash@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "w25q32", "jedec,spi-nor";
+                                       reg = <0>; /* Chip select 0 */
+                                       spi-max-frequency = <3000000>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       usb@58000 {
+                               /* CON3, nearest  power. */
+                               status = "okay";
+                       };
+
+                       usb3@f0000 {
+                               /* CON2, nearest CPU, USB2 only. */
+                               status = "okay";
+                       };
+
+                       usb3@f8000 {
+                               /* CON7 */
+                               status = "okay";
+                       };
+               };
+
+               pcie-controller {
+                       status = "okay";
+                       /*
+                        * The two PCIe units are accessible through
+                        * the mini-PCIe connectors on the board.
+                        */
+                       pcie@2,0 {
+                               /* Port 1, Lane 0. CON3, nearest power. */
+                               reset-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
+                               status = "okay";
+                       };
+                       pcie@3,0 {
+                               /* Port 2, Lane 0. CON2, nearest CPU. */
+                               reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>;
+                               status = "okay";
+                       };
+               };
+       };
+
+       dsa@0 {
+               compatible = "marvell,dsa";
+               dsa,ethernet = <&eth1>;
+               dsa,mii-bus = <&mdio>;
+               pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>;
+               pinctrl-names = "default";
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               switch@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <4 0>;
+
+                       port@0 {
+                               reg = <0>;
+                               label = "lan1";
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               label = "lan2";
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan3";
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan4";
+                       };
+
+                       port@4 {
+                               reg = <4>;
+                               label = "lan5";
+                       };
+
+                       port@5 {
+                               reg = <5>;
+                               label = "cpu";
+                       };
+
+                       port@6 {
+                               /* 88E1512 external phy */
+                               reg = <6>;
+                               label = "lan6";
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                               };
+                       };
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&rear_button_pins>;
+               pinctrl-names = "default";
+
+               button_0 {
+                       /* The rear SW3 button */
+                       label = "Rear Button";
+                       gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+                       linux,can-disable;
+                       linux,code = <BTN_0>;
+               };
+       };
+};
index a633be3..cd31602 100644 (file)
                gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
        };
 
-       reg_usb2_1_vbus: v5-vbus1 {
-               compatible = "regulator-fixed";
-               regulator-name = "v5.0-vbus1";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               enable-active-high;
-               regulator-always-on;
-               gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
-       };
-
        reg_sata0: pwr-sata0 {
                compatible = "regulator-fixed";
                regulator-name = "pwr_en_sata0";
diff --git a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
new file mode 100644 (file)
index 0000000..3f792a5
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Device Tree file for SolidRun Armada 38x Microsom
+ *
+ *  Copyright (C) 2015 Russell King
+ *
+ * This board is in development; the contents of this file work with
+ * the A1 rev 2.0 of the board, which does not represent final
+ * production board.  Things will change, don't expect this file to
+ * remain compatible info the future.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful
+ *     but 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.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>; /* 256 MB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+                         MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+                         MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+
+               internal-regs {
+                       ethernet@70000 {
+                               pinctrl-0 = <&ge0_rgmii_pins>;
+                               pinctrl-names = "default";
+                               phy = <&phy_dedicated>;
+                               phy-mode = "rgmii-id";
+                               status = "okay";
+                       };
+
+                       mdio@72004 {
+                               /*
+                                * Add the phy clock here, so the phy can be
+                                * accessed to read its IDs prior to binding
+                                * with the driver.
+                                */
+                               pinctrl-0 = <&mdio_pins &microsom_phy_clk_pins>;
+                               pinctrl-names = "default";
+
+                               phy_dedicated: ethernet-phy@0 {
+                                       /*
+                                        * Annoyingly, the marvell phy driver
+                                        * configures the LED register, rather
+                                        * than preserving reset-loaded setting.
+                                        * We undo that rubbish here.
+                                        */
+                                       marvell,reg-init = <3 16 0 0x101e>;
+                                       reg = <0>;
+                               };
+                       };
+
+                       pinctrl@18000 {
+                               microsom_phy_clk_pins: microsom-phy-clk-pins {
+                                       marvell,pins = "mpp45";
+                                       marvell,function = "ref";
+                               };
+                       };
+
+                       rtc@a3800 {
+                               /*
+                                * If the rtc doesn't work, run "date reset"
+                                * twice in u-boot.
+                                */
+                               status = "okay";
+                       };
+
+                       serial@12000 {
+                               pinctrl-0 = <&uart0_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+               };
+       };
+};
index 58b5008..13cf69a 100644 (file)
                                marvell,nand-enable-arbiter;
                                nand-on-flash-bbt;
 
-                               partition@0 {
-                                       label = "u-boot";
-                                       reg = <0x0000000 0xe0000>;
-                                       read-only;
-                               };
-
-                               partition@e0000 {
-                                       label = "u-boot-env";
-                                       reg = <0xe0000 0x20000>;
-                                       read-only;
-                               };
-
-                               partition@100000 {
-                                       label = "u-boot-env2";
-                                       reg = <0x100000 0x20000>;
-                                       read-only;
-                               };
-
-                               partition@120000 {
-                                       label = "zImage";
-                                       reg = <0x120000 0x400000>;
-                               };
-
-                               partition@520000 {
-                                       label = "initrd";
-                                       reg = <0x520000 0x400000>;
-                               };
-
-                               partition@xE00000 {
-                                       label = "boot";
-                                       reg = <0xE00000 0x3F200000>;
-                               };
-
-                               partition@flash {
-                                       label = "flash";
-                                       reg = <0x0 0x40000000>;
+                               partitions {
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       partition@0 {
+                                               label = "u-boot";
+                                               reg = <0x00000000 0x000e0000>;
+                                               read-only;
+                                       };
+
+                                       partition@e0000 {
+                                               label = "u-boot-env";
+                                               reg = <0x000e0000 0x00020000>;
+                                               read-only;
+                                       };
+
+                                       partition@100000 {
+                                               label = "u-boot-env2";
+                                               reg = <0x00100000 0x00020000>;
+                                               read-only;
+                                       };
+
+                                       partition@120000 {
+                                               label = "zImage";
+                                               reg = <0x00120000 0x00400000>;
+                                       };
+
+                                       partition@520000 {
+                                               label = "initrd";
+                                               reg = <0x00520000 0x00400000>;
+                                       };
+
+                                       partition@e00000 {
+                                               label = "boot";
+                                               reg = <0x00e00000 0x3f200000>;
+                                       };
                                };
                        };
                };
index 6fe8972..62175a8 100644 (file)
                                isl12057: isl12057@68 {
                                        compatible = "isil,isl12057";
                                        reg = <0x68>;
-                                       isil,irq2-can-wakeup-machine;
+                                       wakeup-source;
                                };
                        };
 
index e74df32..77ddff0 100644 (file)
                                status = "okay";
                        };
 
+                       pdmic@f8018000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_pdmic_default>;
+                               atmel,model = "PDMIC @ sama5d2_xplained";
+                               atmel,mic-min-freq = <1000000>;
+                               atmel,mic-max-freq = <3246000>;
+                               atmel,mic-offset = <0x0>;
+                               status = "okay";
+                       };
+
                        uart1: serial@f8020000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_uart1_default>;
                                dmas = <0>, <0>;
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_i2c0_default>;
+                               i2c-sda-hold-time-ns = <350>;
                                status = "okay";
 
                                pmic: act8865@5b {
                                };
                        };
 
+                       watchdog@f8048040 {
+                               status = "okay";
+                       };
+
                        uart3: serial@fc008000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_uart3_default>;
                                        bias-disable;
                                };
 
+                               pinctrl_pdmic_default: pdmic_default {
+                                       pinmux = <PIN_PB26__PDMIC_DAT>,
+                                               <PIN_PB27__PDMIC_CLK>;
+                                       bias-disable;
+                               };
+
                                pinctrl_sdmmc0_default: sdmmc0_default {
                                        cmd_data {
                                                pinmux = <PIN_PA1__SDMMC0_CMD>,
diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi
new file mode 100644 (file)
index 0000000..e7b2109
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "sama5d4.dtsi"
+
+/ {
+       model = "DENX MA5D4";
+       compatible = "denx,ma5d4", "atmel,sama5d4", "atmel,sama5";
+
+       memory {
+               reg = <0x20000000 0x10000000>;
+       };
+
+       clocks {
+               main_clock: main_clock {
+                       compatible = "atmel,osc", "fixed-clock";
+                       clock-frequency = <12000000>;
+               };
+
+               clk20m: clk20m {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <20000000>;
+                       clock-output-names = "clk20m";
+               };
+       };
+
+       ahb {
+               apb {
+                       mmc0: mmc@f8000000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7>;
+                               vmmc-supply = <&vcc_mmc0_reg>;
+                               vqmmc-supply = <&vcc_3v3_reg>;
+                               status = "okay";
+                               slot@0 {
+                                       reg = <0>;
+                                       bus-width = <8>;
+                                       broken-cd;
+                               };
+                       };
+
+                       spi0: spi@f8010000 {
+                               cs-gpios = <&pioC 3 0>, <0>, <0>, <0>;
+                               status = "okay";
+
+                               m25p80@0 {
+                                       compatible = "atmel,at25df321a";
+                                       spi-max-frequency = <50000000>;
+                                       reg = <0>;
+                               };
+                       };
+
+                       i2c0: i2c@f8014000 {
+                               status = "okay";
+                       };
+
+                       spi1: spi@fc018000 {
+                               cs-gpios = <&pioB 22 0>, <&pioB 23 0>, <0>, <0>;
+                               status = "okay";
+
+                               can0: can@0 {
+                                       compatible = "microchip,mcp2515";
+                                       reg = <0>;
+                                       clocks = <&clk20m>;
+                                       interrupt-parent = <&pioE>;
+                                       interrupts = <6 GPIO_ACTIVE_LOW>;
+                                       spi-max-frequency = <10000000>;
+                               };
+
+                               can1: can@1 {
+                                       compatible = "microchip,mcp2515";
+                                       reg = <1>;
+                                       clocks = <&clk20m>;
+                                       interrupt-parent = <&pioE>;
+                                       interrupts = <7 GPIO_ACTIVE_LOW>;
+                                       spi-max-frequency = <10000000>;
+                               };
+                       };
+
+                       adc0: adc@fc034000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <
+                                       /* external trigger conflicts with USBA_VBUS */
+                                       &pinctrl_adc0_ad0
+                                       &pinctrl_adc0_ad1
+                                       &pinctrl_adc0_ad2
+                                       &pinctrl_adc0_ad3
+                                       &pinctrl_adc0_ad4
+                                       >;
+                               atmel,adc-vref = <3300>;
+                               status = "okay";
+                       };
+
+                       watchdog@fc068640 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       vcc_3v3_reg: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC 3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vcc_mmc0_reg: fixedregulator@1 {
+               compatible = "regulator-fixed";
+               gpio = <&pioE 15 GPIO_ACTIVE_HIGH>;
+               regulator-name = "RST_n MCI0";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc_3v3_reg>;
+               regulator-boot-on;
+       };
+};
diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts
new file mode 100644 (file)
index 0000000..abaaba5
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "at91-sama5d4_ma5d4.dtsi"
+
+/ {
+       model = "DENX MA5D4EVK";
+       compatible = "denx,ma5d4evk", "atmel,sama5d4", "atmel,sama5";
+
+       chosen {
+               stdout-path = "serial3:115200n8";
+       };
+
+       ahb {
+               usb0: gadget@00400000 {
+                       atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usba_vbus>;
+                       status = "okay";
+               };
+
+               usb1: ohci@00500000 {
+                       num-ports = <3>;
+                       atmel,vbus-gpio = <0
+                                          &pioE 11 GPIO_ACTIVE_LOW
+                                          &pioE 14 GPIO_ACTIVE_LOW
+                                         >;
+                       status = "okay";
+               };
+
+               usb2: ehci@00600000 {
+                       status = "okay";
+               };
+
+               apb {
+                       hlcdc: hlcdc@f0000000 {
+                               status = "okay";
+
+                               hlcdc-display-controller {
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
+
+                                       port@0 {
+                                               hlcdc_panel_output: endpoint@0 {
+                                                       reg = <0>;
+                                                       remote-endpoint = <&panel_input>;
+                                               };
+                                       };
+                               };
+
+                       };
+
+                       macb0: ethernet@f8020000 {
+                               phy-mode = "rmii";
+                               status = "okay";
+
+                               phy0: ethernet-phy@0 {
+                                       reg = <0>;
+                               };
+                       };
+
+                       usart0: serial@f802c000 {
+                               status = "okay";
+                       };
+
+                       usart1: serial@f8030000 {
+                               status = "okay";
+                       };
+
+                       mmc1: mmc@fc000000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+                               vmmc-supply = <&vcc_mmc1_reg>;
+                               vqmmc-supply = <&vcc_3v3_reg>;
+                               status = "okay";
+                               slot@0 {
+                                       reg = <0>;
+                                       bus-width = <4>;
+                                       cd-gpios = <&pioE 5 0>;
+                               };
+                       };
+
+                       adc0: adc@fc034000 {
+                               atmel,adc-ts-wires = <4>;
+                               atmel,adc-ts-pressure-threshold = <10000>;
+                       };
+
+
+                       pinctrl@fc06a000 {
+                               board {
+                                       pinctrl_mmc1_cd: mmc1_cd {
+                                               atmel,pins = <AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+                                       };
+                                       pinctrl_usba_vbus: usba_vbus {
+                                               atmel,pins =
+                                                       <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+                                       };
+                               };
+                       };
+               };
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&hlcdc_pwm 0 50000 0>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               status = "okay";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               status = "okay";
+
+               user1 {
+                       label = "user1";
+                       gpios = <&pioD 28 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               user2 {
+                       label = "user2";
+                       gpios = <&pioD 29 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               user3 {
+                       label = "user3";
+                       gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       panel: panel {
+               /* Actually Ampire 800480R2 */
+               compatible = "foxlink,fl500wvr00-a0t", "simple-panel";
+               backlight = <&backlight>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "okay";
+
+               port@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       panel_input: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&hlcdc_panel_output>;
+                       };
+               };
+       };
+
+       vcc_mmc1_reg: fixedregulator@2 {
+               compatible = "regulator-fixed";
+               gpio = <&pioE 17 GPIO_ACTIVE_LOW>;
+               regulator-name = "VDD MCI1";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc_3v3_reg>;
+       };
+};
diff --git a/arch/arm/boot/dts/at91-vinco.dts b/arch/arm/boot/dts/at91-vinco.dts
new file mode 100644 (file)
index 0000000..79aec55
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Device Tree file for VInCo platform
+ *
+ *  Copyright (C) 2014 Atmel,
+ *                2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *   2015 Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+#include "sama5d4.dtsi"
+
+/ {
+       model = "L+G VInCo platform";
+       compatible = "l+g,vinco", "atmel,sama5d4", "atmel,sama5";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x20000000 0x4000000>;
+       };
+
+       clocks {
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               main_xtal {
+                       clock-frequency = <12000000>;
+               };
+       };
+
+       ahb {
+               apb {
+
+                       adc0: adc@fc034000 {
+                               status = "okay"; /* Enable ADC IIO support */
+                       };
+
+                       mmc0: mmc@f8000000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0
+                                            &pinctrl_mmc0_dat1_3
+                                            &pinctrl_mmc0_dat4_7>;
+                               vqmmc-supply = <&vcc_3v3_reg>;
+                               vmmc-supply = <&vcc_3v3_reg>;
+                               no-1-8-v;
+                               status = "okay";
+                               slot@0 {
+                                       reg = <0>;
+                                       bus-width = <8>;
+                                       non-removable;
+                                       broken-cd;
+                                       status = "okay";
+                               };
+                       };
+
+                       spi0: spi@f8010000 {
+                               cs-gpios = <&pioC 3 0>, <0>, <0>, <0>;
+                               status = "okay";
+                               m25p80@0 {
+                                       compatible = "n25q32b", "jedec,spi-nor";
+                                       spi-max-frequency = <50000000>;
+                                       reg = <0>;
+                               };
+                       };
+
+                       i2c0: i2c@f8014000 {
+                               status = "okay";
+                       };
+
+                       i2c1: i2c@f8018000 {
+                               status = "okay";
+                               /* kerkey security module */
+                       };
+
+                       macb0: ethernet@f8020000 {
+                               phy-mode = "rmii";
+                               status = "okay";
+
+                               ethernet-phy@1 {
+                                       reg = <0x1>;
+                                       reset-gpios = <&pioE 8 GPIO_ACTIVE_HIGH>;
+                                       interrupt-parent = <&pioB>;
+                                       interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+                               };
+
+                       };
+
+                       i2c2: i2c@f8024000 {
+                               status = "okay";
+
+                               rtc1: rtc@64 {
+                                       compatible = "epson,rx8900";
+                                       reg = <0x32>;
+                               };
+                       };
+
+                       usart2: serial@fc008000 {
+                               /* MBUS */
+                               status = "okay";
+                       };
+
+                       usart3: serial@fc00c000 {
+                               /* debug */
+                               status = "okay";
+                       };
+
+                       usart4: serial@fc010000 {
+                               /* LMN */
+                               pinctrl-0 = <&pinctrl_usart4 &pinctrl_usart4_rts>;
+                               linux,rs485-enabled-at-boot-time;
+                               status = "okay";
+                       };
+
+                       macb1: ethernet@fc028000 {
+                               phy-mode = "rmii";
+                               status = "okay";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "okay";
+
+                               ethernet-phy@1 {
+                                       reg = <0x1>;
+                                       interrupt-parent = <&pioB>;
+                                       interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+                                       reset-gpios = <&pioE 6 GPIO_ACTIVE_HIGH>;
+                               };
+                       };
+
+                       watchdog@fc068640 {
+                               status = "okay";
+                       };
+
+                       pinctrl@fc06a000 {
+                               board {
+                                       pinctrl_usba_vbus: usba_vbus {
+                                               atmel,pins =
+                                               <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+                                       };
+                               };
+                       };
+               };
+
+               usb0: gadget@00400000 {
+                       atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usba_vbus>;
+                       status = "disable";
+               };
+
+               usb1: ohci@00500000 {
+                       num-ports = <3>;
+                       atmel,vbus-gpio = <0
+                                          &pioE 11 GPIO_ACTIVE_LOW
+                                          &pioE 12 GPIO_ACTIVE_LOW
+                                         >;
+                       status = "disable";
+               };
+
+               usb2: ehci@00600000 {
+                       /* 4G Modem */
+                       status = "okay";
+               };
+
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               status = "okay";
+
+               led_err {
+                       label = "err";
+                       gpios = <&pioA 7 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led_rssi {
+                       label = "rssi";
+                       gpios = <&pioA 9 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led_tls {
+                       label = "tls";
+                       gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led_lmc {
+                       label = "lmc";
+                       gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led_wmt {
+                       label = "wmt";
+                       gpios = <&pioA 29 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led_pwr {
+                       label = "pwr";
+                       gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+                       default-state = "on";
+               };
+
+       };
+
+       vcc_3v3_reg: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC 3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
index 2778533..3878793 100644 (file)
                #address-cells = <1>;
                #size-cells = <1>;
 
+               pcie_phy: phy@0301d0a0 {
+                       compatible = "brcm,cygnus-pcie-phy";
+                       reg = <0x0301d0a0 0x14>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       pcie0_phy: phy@0 {
+                               reg = <0>;
+                               #phy-cells = <0>;
+                       };
+
+                       pcie1_phy: phy@1 {
+                               reg = <1>;
+                               #phy-cells = <0>;
+                       };
+               };
+
                pinctrl: pinctrl@0x0301d0c8 {
                        compatible = "brcm,cygnus-pinmux";
                        reg = <0x0301d0c8 0x30>,
                        compatible = "brcm,cygnus-crmu-gpio";
                        reg = <0x03024800 0x50>,
                              <0x03024008 0x18>;
+                       ngpios = <6>;
                        #gpio-cells = <2>;
                        gpio-controller;
                };
                        compatible = "brcm,cygnus-ccm-gpio";
                        reg = <0x1800a000 0x50>,
                              <0x0301d164 0x20>;
+                       ngpios = <24>;
                        #gpio-cells = <2>;
                        gpio-controller;
                        interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
                        ranges = <0x81000000 0 0          0x28000000 0 0x00010000
                                  0x82000000 0 0x20000000 0x20000000 0 0x04000000>;
 
+                       phys = <&pcie0_phy>;
+                       phy-names = "pcie-phy";
+
                        status = "disabled";
+
+                       msi-parent = <&msi0>;
+                       msi0: msi@18012000 {
+                               compatible = "brcm,iproc-msi";
+                               msi-controller;
+                               interrupt-parent = <&gic>;
+                               interrupts = <GIC_SPI 96 IRQ_TYPE_NONE>,
+                                            <GIC_SPI 97 IRQ_TYPE_NONE>,
+                                            <GIC_SPI 98 IRQ_TYPE_NONE>,
+                                            <GIC_SPI 99 IRQ_TYPE_NONE>;
+                       };
                };
 
                pcie1: pcie@18013000 {
                        ranges = <0x81000000 0 0          0x48000000 0 0x00010000
                                  0x82000000 0 0x40000000 0x40000000 0 0x04000000>;
 
+                       phys = <&pcie1_phy>;
+                       phy-names = "pcie-phy";
+
                        status = "disabled";
+
+                       msi-parent = <&msi1>;
+                       msi1: msi@18013000 {
+                               compatible = "brcm,iproc-msi";
+                               msi-controller;
+                               interrupt-parent = <&gic>;
+                               interrupts = <GIC_SPI 102 IRQ_TYPE_NONE>,
+                                            <GIC_SPI 103 IRQ_TYPE_NONE>,
+                                            <GIC_SPI 104 IRQ_TYPE_NONE>,
+                                            <GIC_SPI 105 IRQ_TYPE_NONE>;
+                       };
                };
 
                uart0: serial@18020000 {
                gpio_asiu: gpio@180a5000 {
                        compatible = "brcm,cygnus-asiu-gpio";
                        reg = <0x180a5000 0x668>;
+                       ngpios = <146>;
                        #gpio-cells = <2>;
                        gpio-controller;
 
-                       pinmux = <&pinctrl>;
-
                        interrupt-controller;
                        interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-ranges = <&pinctrl 0 42 1>,
+                                       <&pinctrl 1 44 3>,
+                                       <&pinctrl 4 48 1>,
+                                       <&pinctrl 5 50 3>,
+                                       <&pinctrl 8 126 1>,
+                                       <&pinctrl 9 155 1>,
+                                       <&pinctrl 10 152 1>,
+                                       <&pinctrl 11 154 1>,
+                                       <&pinctrl 12 153 1>,
+                                       <&pinctrl 13 127 3>,
+                                       <&pinctrl 16 140 1>,
+                                       <&pinctrl 17 145 7>,
+                                       <&pinctrl 24 130 10>,
+                                       <&pinctrl 34 141 4>,
+                                       <&pinctrl 38 54 1>,
+                                       <&pinctrl 39 56 3>,
+                                       <&pinctrl 42 60 3>,
+                                       <&pinctrl 45 64 3>,
+                                       <&pinctrl 48 68 2>,
+                                       <&pinctrl 50 84 6>,
+                                       <&pinctrl 56 94 6>,
+                                       <&pinctrl 62 72 1>,
+                                       <&pinctrl 63 70 1>,
+                                       <&pinctrl 64 80 1>,
+                                       <&pinctrl 65 74 3>,
+                                       <&pinctrl 68 78 1>,
+                                       <&pinctrl 69 82 1>,
+                                       <&pinctrl 70 156 17>,
+                                       <&pinctrl 87 104 12>,
+                                       <&pinctrl 99 102 2>,
+                                       <&pinctrl 101 90 4>,
+                                       <&pinctrl 105 116 6>,
+                                       <&pinctrl 111 100 2>,
+                                       <&pinctrl 113 122 4>,
+                                       <&pinctrl 123 11 1>,
+                                       <&pinctrl 124 38 4>,
+                                       <&pinctrl 128 43 1>,
+                                       <&pinctrl 129 47 1>,
+                                       <&pinctrl 130 49 1>,
+                                       <&pinctrl 131 53 1>,
+                                       <&pinctrl 132 55 1>,
+                                       <&pinctrl 133 59 1>,
+                                       <&pinctrl 134 63 1>,
+                                       <&pinctrl 135 67 1>,
+                                       <&pinctrl 136 71 1>,
+                                       <&pinctrl 137 73 1>,
+                                       <&pinctrl 138 77 1>,
+                                       <&pinctrl 139 79 1>,
+                                       <&pinctrl 140 81 1>,
+                                       <&pinctrl 141 83 1>,
+                                       <&pinctrl 142 10 1>;
                };
 
                touchscreen: tsc@180a6000 {
index 58aca27..10bdef5 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/bcm-nsp.h>
 
 #include "skeleton.dtsi"
 
        model = "Broadcom Northstar Plus SoC";
        interrupt-parent = <&gic>;
 
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       enable-method = "brcm,bcm-nsp-smp";
+                       secondary-boot-reg = <0xffff042c>;
+                       reg = <0x1>;
+               };
+       };
+
        mpcore {
                compatible = "simple-bus";
-               ranges = <0x00000000 0x19020000 0x00003000>;
+               ranges = <0x00000000 0x19000000 0x00023000>;
                #address-cells = <1>;
                #size-cells = <1>;
 
                        };
                };
 
-               L2: l2-cache {
-                       compatible = "arm,pl310-cache";
-                       reg = <0x2000 0x1000>;
-                       cache-unified;
-                       cache-level = <2>;
+               a9pll: arm_clk@00000 {
+                       #clock-cells = <0>;
+                       compatible = "brcm,nsp-armpll";
+                       clocks = <&osc>;
+                       reg = <0x00000 0x1000>;
+               };
+
+               timer@20200 {
+                       compatible = "arm,cortex-a9-global-timer";
+                       reg = <0x20200 0x100>;
+                       interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&periph_clk>;
+               };
+
+               twd-timer@20600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x20600 0x20>;
+                       interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+                                                 IRQ_TYPE_LEVEL_HIGH)>;
+                       clocks = <&periph_clk>;
+               };
+
+               twd-watchdog@20620 {
+                       compatible = "arm,cortex-a9-twd-wdt";
+                       reg = <0x20620 0x20>;
+                       interrupts = <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+                                                 IRQ_TYPE_LEVEL_HIGH)>;
+                       clocks = <&periph_clk>;
                };
 
-               gic: interrupt-controller@19021000 {
+               gic: interrupt-controller@21000 {
                        compatible = "arm,cortex-a9-gic";
                        #interrupt-cells = <3>;
                        #address-cells = <0>;
                        interrupt-controller;
-                       reg = <0x1000 0x1000>,
-                             <0x0100 0x100>;
+                       reg = <0x21000 0x1000>,
+                             <0x20100 0x100>;
                };
 
-               timer@19020200 {
-                       compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x0200 0x100>;
-                       interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&periph_clk>;
+               L2: l2-cache {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x22000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
                };
        };
 
                #size-cells = <1>;
                ranges;
 
-               periph_clk: periph_clk {
+               osc: oscillator {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+               };
+
+               iprocmed: iprocmed {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+               };
+
+               iprocslow: iprocslow {
                        #clock-cells = <0>;
-                       clock-frequency = <500000000>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+               };
+
+               periph_clk: periph_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&a9pll>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
                };
        };
 
        axi {
                compatible = "simple-bus";
-               ranges = <0x00000000 0x18000000 0x00001000>;
+               ranges = <0x00000000 0x18000000 0x0011ba08>;
                #address-cells = <1>;
                #size-cells = <1>;
 
-               uart0: serial@18000300 {
+               uart0: serial@0300 {
                        compatible = "ns16550a";
                        reg = <0x0300 0x100>;
                        interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-frequency = <62499840>;
+                       clocks = <&osc>;
                        status = "disabled";
                };
 
-               uart1: serial@18000400 {
+               uart1: serial@0400 {
                        compatible = "ns16550a";
                        reg = <0x0400 0x100>;
                        interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-frequency = <62499840>;
+                       clocks = <&osc>;
+                       status = "disabled";
+               };
+
+               pcie0: pcie@12000 {
+                       compatible = "brcm,iproc-pcie";
+                       reg = <0x12000 0x1000>;
+
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 131 IRQ_TYPE_NONE>;
+
+                       linux,pci-domain = <0>;
+
+                       bus-range = <0x00 0xff>;
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+
+                       /* Note: The HW does not support I/O resources.  So,
+                        * only the memory resource range is being specified.
+                        */
+                       ranges = <0x82000000 0 0x08000000 0x08000000 0 0x8000000>;
+
+                       status = "disabled";
+               };
+
+               pcie1: pcie@13000 {
+                       compatible = "brcm,iproc-pcie";
+                       reg = <0x13000 0x1000>;
+
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 137 IRQ_TYPE_NONE>;
+
+                       linux,pci-domain = <1>;
+
+                       bus-range = <0x00 0xff>;
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+
+                       /* Note: The HW does not support I/O resources.  So,
+                        * only the memory resource range is being specified.
+                        */
+                       ranges = <0x82000000 0 0x40000000 0x40000000 0 0x8000000>;
+
+                       status = "disabled";
+               };
+
+               pcie2: pcie@14000 {
+                       compatible = "brcm,iproc-pcie";
+                       reg = <0x14000 0x1000>;
+
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 143 IRQ_TYPE_NONE>;
+
+                       linux,pci-domain = <2>;
+
+                       bus-range = <0x00 0xff>;
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+
+                       /* Note: The HW does not support I/O resources.  So,
+                        * only the memory resource range is being specified.
+                        */
+                       ranges = <0x82000000 0 0x48000000 0x48000000 0 0x8000000>;
+
                        status = "disabled";
                };
+
+               nand: nand@26000 {
+                       compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1";
+                       reg = <0x026000 0x600>,
+                             <0x11b408 0x600>,
+                             <0x026f00 0x20>;
+                       reg-names = "nand", "iproc-idm", "iproc-ext";
+                       interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       brcm,nand-has-wp;
+               };
+
+               i2c0: i2c@38000 {
+                       compatible = "brcm,iproc-i2c";
+                       reg = <0x38000 0x50>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
+                       clock-frequency = <100000>;
+               };
+
+               lcpll0: lcpll0@3f100 {
+                       #clock-cells = <1>;
+                       compatible = "brcm,nsp-lcpll0";
+                       reg = <0x3f100 0x14>;
+                       clocks = <&osc>;
+                       clock-output-names = "lcpll0", "pcie_phy", "sdio",
+                                            "ddr_phy";
+               };
+
+               genpll: genpll@3f140 {
+                       #clock-cells = <1>;
+                       compatible = "brcm,nsp-genpll";
+                       reg = <0x3f140 0x24>;
+                       clocks = <&osc>;
+                       clock-output-names = "genpll", "phy", "ethernetclk",
+                                            "usbclk", "iprocfast", "sata1",
+                                            "sata2";
+               };
+
+               pinctrl: pinctrl@3f1c0 {
+                       compatible = "brcm,nsp-pinmux";
+                       reg = <0x3f1c0 0x04>,
+                             <0x30028 0x04>,
+                             <0x3f408 0x04>;
+               };
        };
 };
index 2ddaa51..3dc7a8c 100644 (file)
@@ -31,7 +31,6 @@
                #address-cells = <1>;
                #size-cells = <0>;
                enable-method = "brcm,bcm11351-cpu-method";
-               secondary-boot-reg = <0x3500417c>;
 
                cpu0: cpu@0 {
                        device_type = "cpu";
@@ -42,6 +41,7 @@
                cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
+                       secondary-boot-reg = <0x3500417c>;
                        reg = <1>;
                };
        };
index 2016b72..3f525be 100644 (file)
@@ -31,7 +31,6 @@
                #address-cells = <1>;
                #size-cells = <0>;
                enable-method = "brcm,bcm11351-cpu-method";
-               secondary-boot-reg = <0x35004178>;
 
                cpu0: cpu@0 {
                        device_type = "cpu";
@@ -42,6 +41,7 @@
                cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
+                       secondary-boot-reg = <0x35004178>;
                        reg = <1>;
                };
        };
index b2bff43..228614f 100644 (file)
@@ -1,4 +1,5 @@
 /dts-v1/;
+#include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
 
 / {
index 668442b..ef54050 100644 (file)
@@ -1,4 +1,5 @@
 /dts-v1/;
+#include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
 
 / {
index eab8b59..86f1f2f 100644 (file)
@@ -1,4 +1,5 @@
 /dts-v1/;
+#include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
 
 / {
index ff6b2d1..4859e9d 100644 (file)
@@ -1,4 +1,5 @@
 /dts-v1/;
+#include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
 
 / {
index 3572f03..3afb9fe 100644 (file)
@@ -1,5 +1,3 @@
-#include "bcm2835.dtsi"
-
 / {
        memory {
                reg = <0 0x10000000>;
index aef64de..b83b326 100644 (file)
-#include <dt-bindings/pinctrl/bcm2835.h>
-#include <dt-bindings/clock/bcm2835.h>
-#include "skeleton.dtsi"
+#include "bcm283x.dtsi"
 
 / {
        compatible = "brcm,bcm2835";
-       model = "BCM2835";
-       interrupt-parent = <&intc>;
-
-       chosen {
-               bootargs = "earlyprintk console=ttyAMA0";
-       };
 
        soc {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
                ranges = <0x7e000000 0x20000000 0x02000000>;
                dma-ranges = <0x40000000 0x00000000 0x20000000>;
 
-               timer@7e003000 {
-                       compatible = "brcm,bcm2835-system-timer";
-                       reg = <0x7e003000 0x1000>;
-                       interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
-                       /* This could be a reference to BCM2835_CLOCK_TIMER,
-                        * but we don't have the driver using the common clock
-                        * support yet.
-                        */
-                       clock-frequency = <1000000>;
-               };
-
-               dma: dma@7e007000 {
-                       compatible = "brcm,bcm2835-dma";
-                       reg = <0x7e007000 0xf00>;
-                       interrupts = <1 16>,
-                                    <1 17>,
-                                    <1 18>,
-                                    <1 19>,
-                                    <1 20>,
-                                    <1 21>,
-                                    <1 22>,
-                                    <1 23>,
-                                    <1 24>,
-                                    <1 25>,
-                                    <1 26>,
-                                    <1 27>,
-                                    <1 28>;
-
-                       #dma-cells = <1>;
-                       brcm,dma-channel-mask = <0x7f35>;
-               };
-
-               intc: interrupt-controller@7e00b200 {
-                       compatible = "brcm,bcm2835-armctrl-ic";
-                       reg = <0x7e00b200 0x200>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               watchdog@7e100000 {
-                       compatible = "brcm,bcm2835-pm-wdt";
-                       reg = <0x7e100000 0x28>;
-               };
-
-               clocks: cprman@7e101000 {
-                       compatible = "brcm,bcm2835-cprman";
-                       #clock-cells = <1>;
-                       reg = <0x7e101000 0x2000>;
-
-                       /* CPRMAN derives everything from the platform's
-                        * oscillator.
-                        */
-                       clocks = <&clk_osc>;
-               };
-
-               rng@7e104000 {
-                       compatible = "brcm,bcm2835-rng";
-                       reg = <0x7e104000 0x10>;
-               };
-
-               mailbox: mailbox@7e00b800 {
-                       compatible = "brcm,bcm2835-mbox";
-                       reg = <0x7e00b880 0x40>;
-                       interrupts = <0 1>;
-                       #mbox-cells = <0>;
-               };
-
-               gpio: gpio@7e200000 {
-                       compatible = "brcm,bcm2835-gpio";
-                       reg = <0x7e200000 0xb4>;
-                       /*
-                        * The GPIO IP block is designed for 3 banks of GPIOs.
-                        * Each bank has a GPIO interrupt for itself.
-                        * There is an overall "any bank" interrupt.
-                        * In order, these are GIC interrupts 17, 18, 19, 20.
-                        * Since the BCM2835 only has 2 banks, the 2nd bank
-                        * interrupt output appears to be mirrored onto the
-                        * 3rd bank's interrupt signal.
-                        * So, a bank0 interrupt shows up on 17, 20, and
-                        * a bank1 interrupt shows up on 18, 19, 20!
-                        */
-                       interrupts = <2 17>, <2 18>, <2 19>, <2 20>;
-
-                       gpio-controller;
-                       #gpio-cells = <2>;
-
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               uart0: uart@7e201000 {
-                       compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
-                       reg = <0x7e201000 0x1000>;
-                       interrupts = <2 25>;
-                       clocks = <&clocks BCM2835_CLOCK_UART>,
-                                <&clocks BCM2835_CLOCK_VPU>;
-                       clock-names = "uartclk", "apb_pclk";
-                       arm,primecell-periphid = <0x00241011>;
-               };
-
-               i2s: i2s@7e203000 {
-                       compatible = "brcm,bcm2835-i2s";
-                       reg = <0x7e203000 0x20>,
-                             <0x7e101098 0x02>;
-
-                       dmas = <&dma 2>,
-                              <&dma 3>;
-                       dma-names = "tx", "rx";
-                       status = "disabled";
-               };
-
-               spi: spi@7e204000 {
-                       compatible = "brcm,bcm2835-spi";
-                       reg = <0x7e204000 0x1000>;
-                       interrupts = <2 22>;
-                       clocks = <&clocks BCM2835_CLOCK_VPU>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               i2c0: i2c@7e205000 {
-                       compatible = "brcm,bcm2835-i2c";
-                       reg = <0x7e205000 0x1000>;
-                       interrupts = <2 21>;
-                       clocks = <&clocks BCM2835_CLOCK_VPU>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               sdhci: sdhci@7e300000 {
-                       compatible = "brcm,bcm2835-sdhci";
-                       reg = <0x7e300000 0x100>;
-                       interrupts = <2 30>;
-                       clocks = <&clocks BCM2835_CLOCK_EMMC>;
-                       status = "disabled";
-               };
-
-               i2c1: i2c@7e804000 {
-                       compatible = "brcm,bcm2835-i2c";
-                       reg = <0x7e804000 0x1000>;
-                       interrupts = <2 21>;
-                       clocks = <&clocks BCM2835_CLOCK_VPU>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               i2c2: i2c@7e805000 {
-                       compatible = "brcm,bcm2835-i2c";
-                       reg = <0x7e805000 0x1000>;
-                       interrupts = <2 21>;
-                       clocks = <&clocks BCM2835_CLOCK_VPU>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               usb@7e980000 {
-                       compatible = "brcm,bcm2835-usb";
-                       reg = <0x7e980000 0x10000>;
-                       interrupts = <1 9>;
-               };
-
                arm-pmu {
                        compatible = "arm,arm1176-pmu";
                };
        };
-
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               /* The oscillator is the root of the clock tree. */
-               clk_osc: clock@3 {
-                       compatible = "fixed-clock";
-                       reg = <3>;
-                       #clock-cells = <0>;
-                       clock-output-names = "osc";
-                       clock-frequency = <19200000>;
-               };
-
-       };
 };
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
new file mode 100644 (file)
index 0000000..ff94666
--- /dev/null
@@ -0,0 +1,35 @@
+/dts-v1/;
+#include "bcm2836.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+       compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
+       model = "Raspberry Pi 2 Model B";
+
+       memory {
+               reg = <0 0x40000000>;
+       };
+
+       leds {
+               act {
+                       gpios = <&gpio 47 0>;
+               };
+
+               pwr {
+                       label = "PWR";
+                       gpios = <&gpio 35 0>;
+                       default-state = "keep";
+                       linux,default-trigger = "default-on";
+               };
+       };
+};
+
+&gpio {
+       pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
+
+       /* I2S interface */
+       i2s_alt0: i2s_alt0 {
+               brcm,pins = <18 19 20 21>;
+               brcm,function = <BCM2835_FSEL_ALT0>;
+       };
+};
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
new file mode 100644 (file)
index 0000000..9d0651d
--- /dev/null
@@ -0,0 +1,78 @@
+#include "bcm283x.dtsi"
+
+/ {
+       compatible = "brcm,bcm2836";
+
+       soc {
+               ranges = <0x7e000000 0x3f000000 0x1000000>,
+                        <0x40000000 0x40000000 0x00001000>;
+               dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
+
+               local_intc: local_intc {
+                       compatible = "brcm,bcm2836-l1-intc";
+                       reg = <0x40000000 0x100>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&local_intc>;
+               };
+
+               arm-pmu {
+                       compatible = "arm,cortex-a7-pmu";
+                       interrupt-parent = <&local_intc>;
+                       interrupts = <9>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupt-parent = <&local_intc>;
+               interrupts = <0>, // PHYS_SECURE_PPI
+                            <1>, // PHYS_NONSECURE_PPI
+                            <3>, // VIRT_PPI
+                            <2>; // HYP_PPI
+               always-on;
+       };
+
+       cpus: cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               v7_cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf00>;
+                       clock-frequency = <800000000>;
+               };
+
+               v7_cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf01>;
+                       clock-frequency = <800000000>;
+               };
+
+               v7_cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf02>;
+                       clock-frequency = <800000000>;
+               };
+
+               v7_cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf03>;
+                       clock-frequency = <800000000>;
+               };
+       };
+};
+
+/* Make the BCM2835-style global interrupt controller be a child of the
+ * CPU-local interrupt controller.
+ */
+&intc {
+       compatible = "brcm,bcm2836-armctrl-ic";
+       reg = <0x7e00b200 0x200>;
+       interrupt-parent = <&local_intc>;
+       interrupts = <8>;
+};
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
new file mode 100644 (file)
index 0000000..971e741
--- /dev/null
@@ -0,0 +1,212 @@
+#include <dt-bindings/pinctrl/bcm2835.h>
+#include <dt-bindings/clock/bcm2835.h>
+#include "skeleton.dtsi"
+
+/* This include file covers the common peripherals and configuration between
+ * bcm2835 and bcm2836 implementations, leaving the CPU configuration to
+ * bcm2835.dtsi and bcm2836.dtsi.
+ */
+
+/ {
+       compatible = "brcm,bcm2835";
+       model = "BCM2835";
+       interrupt-parent = <&intc>;
+
+       chosen {
+               bootargs = "earlyprintk console=ttyAMA0";
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               timer@7e003000 {
+                       compatible = "brcm,bcm2835-system-timer";
+                       reg = <0x7e003000 0x1000>;
+                       interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
+                       /* This could be a reference to BCM2835_CLOCK_TIMER,
+                        * but we don't have the driver using the common clock
+                        * support yet.
+                        */
+                       clock-frequency = <1000000>;
+               };
+
+               dma: dma@7e007000 {
+                       compatible = "brcm,bcm2835-dma";
+                       reg = <0x7e007000 0xf00>;
+                       interrupts = <1 16>,
+                                    <1 17>,
+                                    <1 18>,
+                                    <1 19>,
+                                    <1 20>,
+                                    <1 21>,
+                                    <1 22>,
+                                    <1 23>,
+                                    <1 24>,
+                                    <1 25>,
+                                    <1 26>,
+                                    <1 27>,
+                                    <1 28>;
+
+                       #dma-cells = <1>;
+                       brcm,dma-channel-mask = <0x7f35>;
+               };
+
+               intc: interrupt-controller@7e00b200 {
+                       compatible = "brcm,bcm2835-armctrl-ic";
+                       reg = <0x7e00b200 0x200>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               watchdog@7e100000 {
+                       compatible = "brcm,bcm2835-pm-wdt";
+                       reg = <0x7e100000 0x28>;
+               };
+
+               clocks: cprman@7e101000 {
+                       compatible = "brcm,bcm2835-cprman";
+                       #clock-cells = <1>;
+                       reg = <0x7e101000 0x2000>;
+
+                       /* CPRMAN derives everything from the platform's
+                        * oscillator.
+                        */
+                       clocks = <&clk_osc>;
+               };
+
+               rng@7e104000 {
+                       compatible = "brcm,bcm2835-rng";
+                       reg = <0x7e104000 0x10>;
+               };
+
+               mailbox: mailbox@7e00b800 {
+                       compatible = "brcm,bcm2835-mbox";
+                       reg = <0x7e00b880 0x40>;
+                       interrupts = <0 1>;
+                       #mbox-cells = <0>;
+               };
+
+               gpio: gpio@7e200000 {
+                       compatible = "brcm,bcm2835-gpio";
+                       reg = <0x7e200000 0xb4>;
+                       /*
+                        * The GPIO IP block is designed for 3 banks of GPIOs.
+                        * Each bank has a GPIO interrupt for itself.
+                        * There is an overall "any bank" interrupt.
+                        * In order, these are GIC interrupts 17, 18, 19, 20.
+                        * Since the BCM2835 only has 2 banks, the 2nd bank
+                        * interrupt output appears to be mirrored onto the
+                        * 3rd bank's interrupt signal.
+                        * So, a bank0 interrupt shows up on 17, 20, and
+                        * a bank1 interrupt shows up on 18, 19, 20!
+                        */
+                       interrupts = <2 17>, <2 18>, <2 19>, <2 20>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               uart0: uart@7e201000 {
+                       compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+                       reg = <0x7e201000 0x1000>;
+                       interrupts = <2 25>;
+                       clocks = <&clocks BCM2835_CLOCK_UART>,
+                                <&clocks BCM2835_CLOCK_VPU>;
+                       clock-names = "uartclk", "apb_pclk";
+                       arm,primecell-periphid = <0x00241011>;
+               };
+
+               i2s: i2s@7e203000 {
+                       compatible = "brcm,bcm2835-i2s";
+                       reg = <0x7e203000 0x20>,
+                             <0x7e101098 0x02>;
+
+                       dmas = <&dma 2>,
+                              <&dma 3>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               spi: spi@7e204000 {
+                       compatible = "brcm,bcm2835-spi";
+                       reg = <0x7e204000 0x1000>;
+                       interrupts = <2 22>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@7e205000 {
+                       compatible = "brcm,bcm2835-i2c";
+                       reg = <0x7e205000 0x1000>;
+                       interrupts = <2 21>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               aux: aux@0x7e215000 {
+                       compatible = "brcm,bcm2835-aux";
+                       #clock-cells = <1>;
+                       reg = <0x7e215000 0x8>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+               };
+
+               sdhci: sdhci@7e300000 {
+                       compatible = "brcm,bcm2835-sdhci";
+                       reg = <0x7e300000 0x100>;
+                       interrupts = <2 30>;
+                       clocks = <&clocks BCM2835_CLOCK_EMMC>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@7e804000 {
+                       compatible = "brcm,bcm2835-i2c";
+                       reg = <0x7e804000 0x1000>;
+                       interrupts = <2 21>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@7e805000 {
+                       compatible = "brcm,bcm2835-i2c";
+                       reg = <0x7e805000 0x1000>;
+                       interrupts = <2 21>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               usb@7e980000 {
+                       compatible = "brcm,bcm2835-usb";
+                       reg = <0x7e980000 0x10000>;
+                       interrupts = <1 9>;
+               };
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* The oscillator is the root of the clock tree. */
+               clk_osc: clock@3 {
+                       compatible = "fixed-clock";
+                       reg = <3>;
+                       #clock-cells = <0>;
+                       clock-output-names = "osc";
+                       clock-frequency = <19200000>;
+               };
+
+       };
+};
index 31141e8..eed4dd1 100644 (file)
@@ -15,6 +15,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
+               enable-method = "brcm,bcm-nsp-smp";
 
                cpu@0 {
                        device_type = "cpu";
@@ -27,6 +28,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        next-level-cache = <&L2>;
+                       secondary-boot-reg = <0xffff0400>;
                        reg = <0x1>;
                };
        };
index 446c586..b52927c 100644 (file)
                        gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
                        linux,default-trigger = "default-off";
                };
+
+               wireless {
+                       label = "bcm53xx:white:wireless";
+                       gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "default-off";
+               };
+
+               wps {
+                       label = "bcm53xx:white:wps";
+                       gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "default-off";
+               };
+
+               5ghz-2 {
+                       label = "bcm53xx:white:5ghz-2";
+                       gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-off";
+               };
+
+               usb3 {
+                       label = "bcm53xx:white:usb3";
+                       gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-off";
+               };
+
+               usb2 {
+                       label = "bcm53xx:white:usb2";
+                       gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-off";
+               };
        };
 
        gpio-keys {
index 6f50f67..65a1309 100644 (file)
@@ -8,6 +8,7 @@
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
+#include <dt-bindings/clock/bcm-nsp.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
@@ -27,7 +28,7 @@
                        compatible = "ns16550";
                        reg = <0x0300 0x100>;
                        interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-frequency = <100000000>;
+                       clocks = <&iprocslow>;
                        status = "disabled";
                };
 
                        compatible = "ns16550";
                        reg = <0x0400 0x100>;
                        interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       clock-frequency = <100000000>;
+                       clocks = <&iprocslow>;
                        status = "disabled";
                };
        };
 
        mpcore {
                compatible = "simple-bus";
-               ranges = <0x00000000 0x19020000 0x00003000>;
+               ranges = <0x00000000 0x19000000 0x00023000>;
                #address-cells = <1>;
                #size-cells = <1>;
 
-               scu@0000 {
+               a9pll: arm_clk@00000 {
+                       #clock-cells = <0>;
+                       compatible = "brcm,nsp-armpll";
+                       clocks = <&osc>;
+                       reg = <0x00000 0x1000>;
+               };
+
+               scu@20000 {
                        compatible = "arm,cortex-a9-scu";
-                       reg = <0x0000 0x100>;
+                       reg = <0x20000 0x100>;
                };
 
-               timer@0200 {
+               timer@20200 {
                        compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x0200 0x100>;
+                       reg = <0x20200 0x100>;
                        interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clk_periph>;
+                       clocks = <&periph_clk>;
                };
 
-               local-timer@0600 {
+               local-timer@20600 {
                        compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x0600 0x100>;
+                       reg = <0x20600 0x100>;
                        interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clk_periph>;
+                       clocks = <&periph_clk>;
                };
 
-               gic: interrupt-controller@1000 {
+               gic: interrupt-controller@21000 {
                        compatible = "arm,cortex-a9-gic";
                        #interrupt-cells = <3>;
                        #address-cells = <0>;
                        interrupt-controller;
-                       reg = <0x1000 0x1000>,
-                             <0x0100 0x100>;
+                       reg = <0x21000 0x1000>,
+                             <0x20100 0x100>;
                };
 
-               L2: cache-controller@2000 {
+               L2: cache-controller@22000 {
                        compatible = "arm,pl310-cache";
-                       reg = <0x2000 0x1000>;
+                       reg = <0x22000 0x1000>;
                        cache-unified;
                        arm,shared-override;
                        prefetch-data = <1>;
 
        clocks {
                #address-cells = <1>;
-               #size-cells = <0>;
+               #size-cells = <1>;
+               ranges;
 
-               /* As long as we do not have a real clock driver us this
-                * fixed clock */
-               clk_periph: periph {
+               osc: oscillator {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+               };
+
+               iprocmed: iprocmed {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+               };
+
+               iprocslow: iprocslow {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+               };
+
+               periph_clk: periph_clk {
                        #clock-cells = <0>;
-                       clock-frequency = <400000000>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&a9pll>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
                };
        };
 
                };
        };
 
+       lcpll0: lcpll0@1800c100 {
+               #clock-cells = <1>;
+               compatible = "brcm,nsp-lcpll0";
+               reg = <0x1800c100 0x14>;
+               clocks = <&osc>;
+               clock-output-names = "lcpll0", "pcie_phy", "sdio",
+                                    "ddr_phy";
+       };
+
+       genpll: genpll@1800c140 {
+               #clock-cells = <1>;
+               compatible = "brcm,nsp-genpll";
+               reg = <0x1800c140 0x24>;
+               clocks = <&osc>;
+               clock-output-names = "genpll", "phy", "ethernetclk",
+                                    "usbclk", "iprocfast", "sata1",
+                                    "sata2";
+       };
+
        nand: nand@18028000 {
                compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
                reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
index 34cd640..d0560e8 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
-               arm_timer_clk: arm_timer_clk {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <500000000>;
-               };
-
+               /* UBUS peripheral clock */
                periph_clk: periph_clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <50000000>;
                        clock-output-names = "periph";
                };
+
+               /* peripheral clock for system timer */
+               axi_clk: axi_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&armpll>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+               };
+
+               /* APB bus clock */
+               apb_clk: apb_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&armpll>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+               };
        };
 
        /* ARM bus */
                        compatible = "arm,cortex-a9-global-timer";
                        reg = <0x1e200 0x20>;
                        interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&arm_timer_clk>;
+                       clocks = <&axi_clk>;
                };
 
                local_timer: local-timer@1e600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0x1e600 0x20>;
                        interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&arm_timer_clk>;
+                       clocks = <&axi_clk>;
                };
 
                twd_watchdog: watchdog@1e620 {
                        interrupts = <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               armpll: armpll {
+                       #clock-cells = <0>;
+                       compatible = "brcm,bcm63138-armpll";
+                       clocks = <&periph_clk>;
+                       reg = <0x20000 0xf00>;
+               };
+
                pmb0: reset-controller@4800c0 {
                        compatible = "brcm,bcm63138-pmb";
                        reg = <0x4800c0 0x10>;
diff --git a/arch/arm/boot/dts/bcm94708.dts b/arch/arm/boot/dts/bcm94708.dts
new file mode 100644 (file)
index 0000000..251a486
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+       model = "NorthStar SVK (BCM94708)";
+       compatible = "brcm,bcm94708", "brcm,bcm4708";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x00000000 0x08000000>;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm94709.dts b/arch/arm/boot/dts/bcm94709.dts
new file mode 100644 (file)
index 0000000..b16cac9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+       model = "NorthStar SVK (BCM94709)";
+       compatible = "brcm,bcm94709", "brcm,bcm4709", "brcm,bcm4708";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x00000000 0x08000000>;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm953012k.dts b/arch/arm/boot/dts/bcm953012k.dts
new file mode 100644 (file)
index 0000000..05a985a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+       model = "NorthStar SVK (BCM953012K)";
+       compatible = "brcm,bcm953012k", "brcm,brcm53012", "brcm,bcm4708";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x00000000 0x10000000>;
+       };
+};
+
+&uart0 {
+       clock-frequency = <62499840>;
+       status = "okay";
+};
+
+&uart1 {
+       clock-frequency = <62499840>;
+       status = "okay";
+};
index 16303db..e298450 100644 (file)
 &uart1 {
        status = "okay";
 };
+
+&pcie0 {
+       status = "okay";
+};
+
+&pcie1 {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
+
+&nand {
+       nandcs@0 {
+               compatible = "brcm,nandcs";
+               reg = <0>;
+               nand-on-flash-bbt;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               nand-ecc-strength = <24>;
+               nand-ecc-step-size = <1024>;
+
+               brcm,nand-oob-sector-size = <27>;
+
+               partition@0 {
+                       label = "nboot";
+                       reg = <0x00000000 0x00200000>;
+                       read-only;
+               };
+               partition@1 {
+                       label = "nenv";
+                       reg = <0x00200000 0x00400000>;
+               };
+               partition@2 {
+                       label = "nsystem";
+                       reg = <0x00600000 0x00a00000>;
+               };
+               partition@3 {
+                       label = "nrootfs";
+                       reg = <0x01000000 0x03000000>;
+               };
+               partition@4 {
+                       label = "ncustfs";
+                       reg = <0x04000000 0x3c000000>;
+               };
+       };
+};
+
+&pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_sel>;
+       nand_sel: nand_sel {
+               function = "nand";
+               groups = "nand_grp";
+       };
+};
index eaadac3..ae81009 100644 (file)
                        ranges = <0 0xfc0000 0x10000>;
                        interrupt-parent = <&sic>;
 
+                       wdt0: watchdog@1000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x1000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <0>;
+                       };
+
+                       wdt1: watchdog@2000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x2000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <1>;
+                               status = "disabled";
+                       };
+
+                       wdt2: watchdog@3000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x3000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <2>;
+                               status = "disabled";
+                       };
+
                        sm_gpio1: gpio@5000 {
                                compatible = "snps,dw-apb-gpio";
                                reg = <0x5000 0x400>;
index b16df15..6d06b61 100644 (file)
                        ranges = <0 0xfc0000 0x10000>;
                        interrupt-parent = <&sic>;
 
+                       wdt0: watchdog@1000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x1000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <0>;
+                       };
+
+                       wdt1: watchdog@2000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x2000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <1>;
+                               status = "disabled";
+                       };
+
+                       wdt2: watchdog@3000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x3000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <2>;
+                               status = "disabled";
+                       };
+
                        sm_gpio1: gpio@5000 {
                                compatible = "snps,dw-apb-gpio";
                                reg = <0x5000 0x400>;
index da28c97..33b2875 100644 (file)
                        gpio = <&portb 12 GPIO_ACTIVE_HIGH>;
                        enable-active-high;
                };
+
+               reg_sdio1_vmmc: regulator@3 {
+                       compatible = "regulator-fixed";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-name = "sdio1_vmmc";
+                       enable-active-high;
+                       regulator-boot-on;
+                       gpio = <&portb 21 GPIO_ACTIVE_HIGH>;
+               };
+
+               reg_sdio1_vqmmc: regulator@4 {
+                       compatible = "regulator-gpio";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-name = "sdio1_vqmmc";
+                       regulator-type = "voltage";
+                       enable-active-high;
+                       gpios = <&portb 16 GPIO_ACTIVE_HIGH>;
+                       states = <3300000 0x1
+                                 1800000 0x0>;
+               };
+       };
+};
+
+&soc_pinctrl {
+       sd1gpio_pmux: sd1pwr-pmux {
+               groups = "G23", "G32";
+               function = "gpio";
        };
 };
 
 &sdhci1 {
-       broken-cd;
-       sdhci,wp-inverted;
+       vmmc-supply = <&reg_sdio1_vmmc>;
+       vqmmc-supply = <&reg_sdio1_vqmmc>;
+       cd-gpios = <&portc 30 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&portd 0 GPIO_ACTIVE_HIGH>;
+       pinctrl-0 = <&sd1gpio_pmux>, <&sd1_pmux>;
+       pinctrl-names = "default";
        status = "okay";
 };
 
 &sdhci2 {
-       broken-cd;
        bus-width = <8>;
        non-removable;
        status = "okay";
index fb1da99..2c34bfb 100644 (file)
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x1400 0x100>;
-                               interrupt-parent = <&aic>;
                                interrupts = <4>;
                                clocks = <&chip_clk CLKID_CFG>;
                                pinctrl-0 = <&twsi0_pmux>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x1800 0x100>;
-                               interrupt-parent = <&aic>;
                                interrupts = <5>;
                                clocks = <&chip_clk CLKID_CFG>;
                                pinctrl-0 = <&twsi1_pmux>;
                        soc_pinctrl: pin-controller {
                                compatible = "marvell,berlin2q-soc-pinctrl";
 
+                               sd1_pmux: sd1-pmux {
+                                       groups = "G31";
+                                       function = "sd1";
+                               };
+
                                twsi0_pmux: twsi0-pmux {
                                        groups = "G6";
                                        function = "twsi0";
                        ranges = <0 0xfc0000 0x10000>;
                        interrupt-parent = <&sic>;
 
+                       wdt0: watchdog@1000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x1000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <0>;
+                       };
+
+                       wdt1: watchdog@2000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x2000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <1>;
+                               status = "disabled";
+                       };
+
+                       wdt2: watchdog@3000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x3000 0x100>;
+                               clocks = <&refclk>;
+                               interrupts = <2>;
+                               status = "disabled";
+                       };
+
                        sm_gpio1: gpio@5000 {
                                compatible = "snps,dw-apb-gpio";
                                reg = <0x5000 0x400>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x7000 0x100>;
-                               interrupt-parent = <&sic>;
                                interrupts = <6>;
                                clocks = <&refclk>;
                                pinctrl-0 = <&twsi2_pmux>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x8000 0x100>;
-                               interrupt-parent = <&sic>;
                                interrupts = <7>;
                                clocks = <&refclk>;
                                pinctrl-0 = <&twsi3_pmux>;
                        uart0: uart@9000 {
                                compatible = "snps,dw-apb-uart";
                                reg = <0x9000 0x100>;
-                               interrupt-parent = <&sic>;
                                interrupts = <8>;
                                clocks = <&refclk>;
                                reg-shift = <2>;
                        uart1: uart@a000 {
                                compatible = "snps,dw-apb-uart";
                                reg = <0xa000 0x100>;
-                               interrupt-parent = <&sic>;
                                interrupts = <9>;
                                clocks = <&refclk>;
                                reg-shift = <2>;
diff --git a/arch/arm/boot/dts/compulab-sb-som.dtsi b/arch/arm/boot/dts/compulab-sb-som.dtsi
new file mode 100644 (file)
index 0000000..93d7e23
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 CompuLab, Ltd. - http://www.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.
+ */
+
+/ {
+       model = "CompuLab SB-SOM";
+       compatible = "compulab,sb-som";
+
+       vsb_3v3: fixedregulator-v3_3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vsb_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               enable-active-high;
+       };
+
+       lcd0: display {
+               compatible = "startek,startek-kd050c", "panel-dpi";
+               label = "lcd";
+
+               panel-timing {
+                       clock-frequency = <33000000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hfront-porch = <40>;
+                       hback-porch = <40>;
+                       hsync-len = <43>;
+                       vback-porch = <29>;
+                       vfront-porch = <13>;
+                       vsync-len = <3>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+       };
+
+       hdmi_conn: connector@0 {
+               compatible = "hdmi-connector";
+               label = "hdmi";
+
+               type = "a";
+       };
+};
index e750ab9..645549e 100644 (file)
                };
        };
 };
+
+&edma0 {
+       ti,edma-reserved-slot-ranges = <32 50>;
+};
+
+&edma1 {
+       ti,edma-reserved-slot-ranges = <32 90>;
+};
index 4f935ad..ef061e9 100644 (file)
        tx-num-evt = <32>;
        rx-num-evt = <32>;
 };
+
+&edma0 {
+       ti,edma-reserved-slot-ranges = <32 50>;
+};
+
+&edma1 {
+       ti,edma-reserved-slot-ranges = <32 90>;
+};
index 0bd98cd..226cda7 100644 (file)
 
                };
                edma0: edma@01c00000 {
-                       compatible = "ti,edma3";
-                       reg =   <0x0 0x10000>;
-                       interrupts = <11 13 12>;
-                       #dma-cells = <1>;
+                       compatible = "ti,edma3-tpcc";
+                       /* eDMA3 CC0: 0x01c0 0000 - 0x01c0 7fff */
+                       reg =   <0x0 0x8000>;
+                       reg-names = "edma3_cc";
+                       interrupts = <11 12>;
+                       interrupt-names = "edma3_ccint", "edma3_ccerrint";
+                       #dma-cells = <2>;
+
+                       ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>;
+               };
+               edma0_tptc0: tptc@01c08000 {
+                       compatible = "ti,edma3-tptc";
+                       reg =   <0x8000 0x400>;
+                       interrupts = <13>;
+                       interrupt-names = "edm3_tcerrint";
+               };
+               edma0_tptc1: tptc@01c08400 {
+                       compatible = "ti,edma3-tptc";
+                       reg =   <0x8400 0x400>;
+                       interrupts = <32>;
+                       interrupt-names = "edm3_tcerrint";
+               };
+               edma1: edma@01e30000 {
+                       compatible = "ti,edma3-tpcc";
+                       /* eDMA3 CC1: 0x01e3 0000 - 0x01e3 7fff */
+                       reg =   <0x230000 0x8000>;
+                       reg-names = "edma3_cc";
+                       interrupts = <93 94>;
+                       interrupt-names = "edma3_ccint", "edma3_ccerrint";
+                       #dma-cells = <2>;
+
+                       ti,tptcs = <&edma1_tptc0 7>;
+               };
+               edma1_tptc0: tptc@01e38000 {
+                       compatible = "ti,edma3-tptc";
+                       reg =   <0x238000 0x400>;
+                       interrupts = <95>;
+                       interrupt-names = "edm3_tcerrint";
                };
                serial0: serial@1c42000 {
                        compatible = "ns16550a";
                        compatible = "ti,da830-mmc";
                        reg = <0x40000 0x1000>;
                        interrupts = <16>;
+                       dmas = <&edma0 16 0>, <&edma0 17 0>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+               mmc1: mmc@1e1b000 {
+                       compatible = "ti,da830-mmc";
+                       reg = <0x21b000 0x1000>;
+                       interrupts = <72>;
+                       dmas = <&edma1 28 0>, <&edma1 29 0>;
+                       dma-names = "rx", "tx";
                        status = "disabled";
                };
                ehrpwm0: ehrpwm@01f00000 {
                        num-cs = <4>;
                        ti,davinci-spi-intr-line = <1>;
                        interrupts = <56>;
+                       dmas = <&edma0 18 0>, <&edma0 19 0>;
+                       dma-names = "rx", "tx";
                        status = "disabled";
                };
                mdio: mdio@1e24000 {
                        interrupts = <54>;
                        interrupt-names = "common";
                        status = "disabled";
-                       dmas = <&edma0 1>,
-                               <&edma0 0>;
+                       dmas = <&edma0 1 1>,
+                               <&edma0 0 1>;
                        dma-names = "tx", "rx";
                };
        };
index 109fd47..e070862 100644 (file)
                device_type = "memory";
                reg = <0x80000000 0x40000000>;  /* 1 GB */
        };
+
+       /* MIC94060YC6 controlled by SD1_POW pin */
+       vmmcsd_fixed: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
 };
 
 &cpsw_emac0 {
        phy_id = <&davinci_mdio>, <1>;
        phy-mode = "rgmii";
 };
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sd1_pins>;
+       vmmc-supply = <&vmmcsd_fixed>;
+       bus-width = <4>;
+       cd-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+};
+
+&pincntl {
+       sd1_pins: pinmux_sd1_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0800, PIN_INPUT | 0x1)   /* SD1_CLK */
+                       DM814X_IOPAD(0x0804, PIN_INPUT_PULLUP |  0x1)   /* SD1_CMD */
+                       DM814X_IOPAD(0x0808, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[0] */
+                       DM814X_IOPAD(0x080c, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[1] */
+                       DM814X_IOPAD(0x0810, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[2] */
+                       DM814X_IOPAD(0x0814, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[3] */
+                       DM814X_IOPAD(0x0924, PIN_OUTPUT |  0x40)        /* SD1_POW */
+                       DM814X_IOPAD(0x093C, PIN_INPUT_PULLUP |  0x80)  /* GP1[6] */
+                       >;
+       };
+
+       usb0_pins: pinmux_usb0_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0c34, PIN_OUTPUT | 0x1)  /* USB0_DRVVBUS */
+                       >;
+       };
+
+       usb1_pins: pinmux_usb1_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0834, PIN_OUTPUT | 0x80) /* USB1_DRVVBUS */
+                       >;
+       };
+};
+
+&usb0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb0_pins>;
+       dr_mode = "host";
+};
+
+&usb1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb1_pins>;
+       dr_mode = "host";
+};
index 79838dd..5d4313f 100644 (file)
                device_type = "memory";
                reg = <0x80000000 0x40000000>;  /* 1 GB */
        };
+
+       /* gpio9 seems to control USB VBUS regulator and/or hub power */
+       usb_power: regulator@9 {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_power";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
+       vmmcsd_fixed: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
 };
 
 &cpsw_emac0 {
        phy_id = <&davinci_mdio>, <1>;
        phy-mode = "rgmii";
 };
+
+&mmc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sd2_pins>;
+       vmmc-supply = <&vmmcsd_fixed>;
+       bus-width = <8>;
+       dmas = <&edma_xbar 8 0 1        /* use SDTXEVT1 instead of MCASP0TX */
+               &edma_xbar 9 0 2>;      /* use SDRXEVT1 instead of MCASP0RX */
+       dma-names = "tx", "rx";
+};
+
+&pincntl {
+       sd2_pins: pinmux_sd2_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x09c0, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[7] */
+                       DM814X_IOPAD(0x09c4, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[6] */
+                       DM814X_IOPAD(0x09c8, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[5] */
+                       DM814X_IOPAD(0x09cc, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[4] */
+                       DM814X_IOPAD(0x09d0, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[3] */
+                       DM814X_IOPAD(0x09d4, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[2] */
+                       DM814X_IOPAD(0x09d8, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[1] */
+                       DM814X_IOPAD(0x09dc, PIN_INPUT_PULLUP | 0x1)    /* SD2_DAT[0] */
+                       DM814X_IOPAD(0x09e0, PIN_INPUT | 0x1)           /* SD2_CLK */
+                       DM814X_IOPAD(0x09f4, PIN_INPUT_PULLUP | 0x2)    /* SD2_CMD */
+                       DM814X_IOPAD(0x0920, PIN_INPUT | 40)    /* SD2_SDCD */
+                       >;
+       };
+
+       usb0_pins: pinmux_usb0_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0c34, PIN_OUTPUT | 0x1)  /* USB0_DRVVBUS */
+                       >;
+       };
+
+       usb1_pins: pinmux_usb1_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0834, PIN_OUTPUT | 0x80) /* USB1_DRVVBUS */
+                       >;
+       };
+};
+
+&usb0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb0_pins>;
+       dr_mode = "host";
+};
+
+&usb1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb1_pins>;
+       dr_mode = "host";
+};
index ef1e8e7..2600158 100644 (file)
@@ -4,25 +4,74 @@
  * published by the Free Software Foundation.
  */
 
+&pllss_clocks {
+       timer1_fck: timer1_fck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+                         &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+               ti,bit-shift = <3>;
+               reg = <0x2e0>;
+       };
+
+       timer2_fck: timer2_fck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+                         &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+               ti,bit-shift = <6>;
+               reg = <0x2e0>;
+       };
+
+       sysclk18_ck: sysclk18_ck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&rtcosc_ck>, <&rtcdivider_ck>;
+               ti,bit-shift = <0>;
+               reg = <0x02f0>;
+       };
+};
+
 &scm_clocks {
+       devosc_ck: devosc_ck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&virt_20000000_ck>, <&virt_19200000_ck>;
+               ti,bit-shift = <21>;
+               reg = <0x0040>;
+       };
 
-       tclkin_ck: tclkin_ck {
+       /* Optional auxosc, 20 - 30 MHz range, assume 27 MHz by default */
+       auxosc_ck: auxosc_ck {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <27000000>;
+       };
+
+       /* Optional 32768Hz crystal or clock on RTCOSC pins */
+       rtcosc_ck: rtcosc_ck {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
        };
 
-       devosc_ck: devosc_ck {
+       /* Optional external clock on TCLKIN pin, set rate in baord dts file */
+       tclkin_ck: tclkin_ck {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+       };
+
+       virt_20000000_ck: virt_20000000_ck {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <20000000>;
        };
 
-       /* Optional auxosc, 20 - 30 MHz range, assume 27 MHz by default */
-       auxosc_ck: auxosc_ck {
+       virt_19200000_ck: virt_19200000_ck {
                #clock-cells = <0>;
                compatible = "fixed-clock";
-               clock-frequency = <27000000>;
+               clock-frequency = <19200000>;
        };
 
        mpu_ck: mpu_ck {
                clock-frequency = <48000000>;
        };
 
-       sysclk18_ck: sysclk18_ck {
-               #clock-cells = <0>;
-               compatible = "fixed-clock";
-               clock-frequency = <32768>;
-       };
-
         cpsw_125mhz_gclk: cpsw_125mhz_gclk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
 
 };
 
-&pllss_clocks {
+&prcm_clocks {
+       osc_src_ck: osc_src_ck {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&devosc_ck>;
+               clock-mult = <1>;
+               clock-div = <1>;
+       };
+
+       mpu_clksrc_ck: mpu_clksrc_ck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&devosc_ck>, <&rtcdivider_ck>;
+               ti,bit-shift = <0>;
+               reg = <0x0040>;
+       };
+
+       /* Fixed divider clock 0.0016384 * devosc */
+       rtcdivider_ck: rtcdivider_ck {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clocks = <&devosc_ck>;
+               clock-mult = <128>;
+               clock-div = <78125>;
+       };
 
        aud_clkin0_ck: aud_clkin0_ck {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <20000000>;
        };
-
-       timer1_mux_ck: timer1_mux_ck {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
-                         &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
-               ti,bit-shift = <3>;
-               reg = <0x2e0>;
-       };
-
-       timer2_mux_ck: timer2_mux_ck {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
-                         &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
-               ti,bit-shift = <6>;
-               reg = <0x2e0>;
-       };
 };
index 7988b42..a25cd51 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/pinctrl/omap.h>
+#include <dt-bindings/pinctrl/dm814x.h>
 
 #include "skeleton.dtsi"
 
                serial2 = &uart3;
                ethernet0 = &cpsw_emac0;
                ethernet1 = &cpsw_emac1;
+               usb0 = &usb0;
+               usb1 = &usb1;
+               phy0 = &usb0_phy;
+               phy1 = &usb1_phy;
        };
 
        cpus {
                ranges;
                ti,hwmods = "l3_main";
 
+               usb: usb@47400000 {
+                       compatible = "ti,am33xx-usb";
+                       reg = <0x47400000 0x1000>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ti,hwmods = "usb_otg_hs";
+
+                       usb0_phy: usb-phy@47401300 {
+                               compatible = "ti,am335x-usb-phy";
+                               reg = <0x47401300 0x100>;
+                               reg-names = "phy";
+                               ti,ctrl_mod = <&usb_ctrl_mod>;
+                       };
+
+                       usb0: usb@47401000 {
+                               compatible = "ti,musb-am33xx";
+                               reg = <0x47401400 0x400
+                                      0x47401000 0x200>;
+                               reg-names = "mc", "control";
+
+                               interrupts = <18>;
+                               interrupt-names = "mc";
+                               dr_mode = "otg";
+                               mentor,multipoint = <1>;
+                               mentor,num-eps = <16>;
+                               mentor,ram-bits = <12>;
+                               mentor,power = <500>;
+                               phys = <&usb0_phy>;
+
+                               dmas = <&cppi41dma  0 0 &cppi41dma  1 0
+                                       &cppi41dma  2 0 &cppi41dma  3 0
+                                       &cppi41dma  4 0 &cppi41dma  5 0
+                                       &cppi41dma  6 0 &cppi41dma  7 0
+                                       &cppi41dma  8 0 &cppi41dma  9 0
+                                       &cppi41dma 10 0 &cppi41dma 11 0
+                                       &cppi41dma 12 0 &cppi41dma 13 0
+                                       &cppi41dma 14 0 &cppi41dma  0 1
+                                       &cppi41dma  1 1 &cppi41dma  2 1
+                                       &cppi41dma  3 1 &cppi41dma  4 1
+                                       &cppi41dma  5 1 &cppi41dma  6 1
+                                       &cppi41dma  7 1 &cppi41dma  8 1
+                                       &cppi41dma  9 1 &cppi41dma 10 1
+                                       &cppi41dma 11 1 &cppi41dma 12 1
+                                       &cppi41dma 13 1 &cppi41dma 14 1>;
+                               dma-names =
+                                       "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+                                       "rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
+                                       "rx14", "rx15",
+                                       "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
+                                       "tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
+                                       "tx14", "tx15";
+                       };
+
+                       usb1: usb@47401800 {
+                               compatible = "ti,musb-am33xx";
+                               reg = <0x47401c00 0x400
+                                       0x47401800 0x200>;
+                               reg-names = "mc", "control";
+                               interrupts = <19>;
+                               interrupt-names = "mc";
+                               dr_mode = "otg";
+                               mentor,multipoint = <1>;
+                               mentor,num-eps = <16>;
+                               mentor,ram-bits = <12>;
+                               mentor,power = <500>;
+                               phys = <&usb1_phy>;
+
+                               dmas = <&cppi41dma 15 0 &cppi41dma 16 0
+                                       &cppi41dma 17 0 &cppi41dma 18 0
+                                       &cppi41dma 19 0 &cppi41dma 20 0
+                                       &cppi41dma 21 0 &cppi41dma 22 0
+                                       &cppi41dma 23 0 &cppi41dma 24 0
+                                       &cppi41dma 25 0 &cppi41dma 26 0
+                                       &cppi41dma 27 0 &cppi41dma 28 0
+                                       &cppi41dma 29 0 &cppi41dma 15 1
+                                       &cppi41dma 16 1 &cppi41dma 17 1
+                                       &cppi41dma 18 1 &cppi41dma 19 1
+                                       &cppi41dma 20 1 &cppi41dma 21 1
+                                       &cppi41dma 22 1 &cppi41dma 23 1
+                                       &cppi41dma 24 1 &cppi41dma 25 1
+                                       &cppi41dma 26 1 &cppi41dma 27 1
+                                       &cppi41dma 28 1 &cppi41dma 29 1>;
+                               dma-names =
+                                       "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+                                       "rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
+                                       "rx14", "rx15",
+                                       "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
+                                       "tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
+                                       "tx14", "tx15";
+                       };
+
+                       cppi41dma: dma-controller@47402000 {
+                               compatible = "ti,am3359-cppi41";
+                               reg =  <0x47400000 0x1000
+                                       0x47402000 0x1000
+                                       0x47403000 0x1000
+                                       0x47404000 0x4000>;
+                               reg-names = "glue", "controller", "scheduler", "queuemgr";
+                               interrupts = <17>;
+                               interrupt-names = "glue";
+                               #dma-cells = <2>;
+                               #dma-channels = <30>;
+                               #dma-requests = <256>;
+                       };
+               };
+
                /*
-                * See TRM "Table 1-317. L4LS Instance Summary", just deduct
-                * 0x1000 from the 1-317 addresses to get the device address
+                * See TRM "Table 1-317. L4LS Instance Summary" for hints.
+                * It shows the module target agent registers though, so the
+                * actual device is typically 0x1000 before the target agent
+                * except in cases where the module is larger than 0x1000.
                 */
                l4ls: l4ls@48000000 {
                        compatible = "ti,dm814-l4ls", "simple-bus";
                                interrupts = <65>;
                                ti,spi-num-cs = <4>;
                                ti,hwmods = "mcspi1";
-                               dmas = <&edma 16 &edma 17
-                                       &edma 18 &edma 19>;
+                               dmas = <&edma 16 0 &edma 17 0
+                                       &edma 18 0 &edma 19 0>;
                                dma-names = "tx0", "rx0", "tx1", "rx1";
                        };
 
                                reg = <0x20000 0x2000>;
                                clock-frequency = <48000000>;
                                interrupts = <72>;
-                               dmas = <&edma 26 &edma 27>;
+                               dmas = <&edma 26 0 &edma 27 0>;
                                dma-names = "tx", "rx";
                        };
 
                                reg = <0x22000 0x2000>;
                                clock-frequency = <48000000>;
                                interrupts = <73>;
-                               dmas = <&edma 28 &edma 29>;
+                               dmas = <&edma 28 0 &edma 29 0>;
                                dma-names = "tx", "rx";
                        };
 
                                reg = <0x24000 0x2000>;
                                clock-frequency = <48000000>;
                                interrupts = <74>;
-                               dmas = <&edma 30 &edma 31>;
+                               dmas = <&edma 30 0 &edma 31 0>;
                                dma-names = "tx", "rx";
                        };
 
                                ti,hwmods = "timer3";
                        };
 
+                       mmc1: mmc@60000 {
+                               compatible = "ti,omap4-hsmmc";
+                               ti,hwmods = "mmc1";
+                               dmas = <&edma 24 0
+                                       &edma 25 0>;
+                               dma-names = "tx", "rx";
+                               interrupts = <64>;
+                               interrupt-parent = <&intc>;
+                               reg = <0x60000 0x1000>;
+                       };
+
+                       mmc2: mmc@1d8000 {
+                               compatible = "ti,omap4-hsmmc";
+                               ti,hwmods = "mmc2";
+                               dmas = <&edma 2 0
+                                       &edma 3 0>;
+                               dma-names = "tx", "rx";
+                               interrupts = <28>;
+                               interrupt-parent = <&intc>;
+                               reg = <0x1d8000 0x1000>;
+                       };
+
                        control: control@140000 {
                                compatible = "ti,dm814-scm", "simple-bus";
-                               reg = <0x140000 0x16d000>;
+                               reg = <0x140000 0x20000>;
                                #address-cells = <1>;
                                #size-cells = <1>;
-                               ranges = <0 0x160000 0x16d000>;
+                               ranges = <0 0x140000 0x20000>;
 
                                scm_conf: scm_conf@0 {
                                        compatible = "syscon";
                                        };
                                };
 
+                               usb_ctrl_mod: control@620 {
+                                       compatible = "ti,am335x-usb-ctrl-module";
+                                       reg = <0x620 0x10
+                                               0x648 0x4>;
+                                       reg-names = "phy_ctrl", "wakeup";
+                               };
+
+                               edma_xbar: dma-router@f90 {
+                                       compatible = "ti,am335x-edma-crossbar";
+                                       reg = <0xf90 0x40>;
+                                       #dma-cells = <3>;
+                                       dma-requests = <32>;
+                                       dma-masters = <&edma>;
+                               };
+
+                               /*
+                                * Note that silicon revision 2.1 and older
+                                * require input enabled (bit 18 set) for all
+                                * 3.3V I/Os to avoid cumulative hardware damage.
+                                * For more info, see errata advisory 2.1.87.
+                                * We leave bit 18 out of function-mask and rely
+                                * on the bootloader for it.
+                                */
                                pincntl: pinmux@800 {
                                        compatible = "pinctrl-single";
-                                       reg = <0x800 0xc38>;
+                                       reg = <0x800 0x438>;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        pinctrl-single,register-width = <32>;
-                                       pinctrl-single,function-mask = <0x300ff>;
+                                       pinctrl-single,function-mask = <0x307ff>;
+                               };
+
+                               usb1_phy: usb-phy@1b00 {
+                                       compatible = "ti,am335x-usb-phy";
+                                       reg = <0x1b00 0x100>;
+                                       reg-names = "phy";
+                                       ti,ctrl_mod = <&usb_ctrl_mod>;
                                };
                        };
 
                        prcm: prcm@180000 {
                                compatible = "ti,dm814-prcm", "simple-bus";
-                               reg = <0x180000 0x4000>;
+                               reg = <0x180000 0x2000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x180000 0x2000>;
 
                                prcm_clocks: clocks {
                                        #address-cells = <1>;
                                };
                        };
 
+                       /* See TRM PLL_SUBSYS_BASE and "PLLSS Registers" */
                        pllss: pllss@1c5000 {
                                compatible = "ti,dm814-pllss", "simple-bus";
-                               reg = <0x1c5000 0x2000>;
+                               reg = <0x1c5000 0x1000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x1c5000 0x1000>;
 
                                pllss_clocks: clocks {
                                        #address-cells = <1>;
                        reg = <0x48200000 0x1000>;
                };
 
+               /* Board must configure evtmux with edma_xbar for EDMA */
+               mmc3: mmc@47810000 {
+                       compatible = "ti,omap4-hsmmc";
+                       ti,hwmods = "mmc3";
+                       interrupts = <29>;
+                       interrupt-parent = <&intc>;
+                       reg = <0x47810000 0x1000>;
+               };
+
                edma: edma@49000000 {
-                       compatible = "ti,edma3";
-                       ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
-                       reg =   <0x49000000 0x10000>,
-                               <0x44e10f90 0x40>;
+                       compatible = "ti,edma3-tpcc";
+                       ti,hwmods = "tpcc";
+                       reg =   <0x49000000 0x10000>;
+                       reg-names = "edma3_cc";
                        interrupts = <12 13 14>;
-                       #dma-cells = <1>;
+                       interrupt-names = "edma3_ccint", "emda3_mperr",
+                                         "edma3_ccerrint";
+                       dma-requests = <64>;
+                       #dma-cells = <2>;
+
+                       ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
+                                  <&edma_tptc2 3>, <&edma_tptc3 0>;
+
+                       ti,edma-memcpy-channels = <20 21>;
+               };
+
+               edma_tptc0: tptc@49800000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc0";
+                       reg =   <0x49800000 0x100000>;
+                       interrupts = <112>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc1: tptc@49900000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc1";
+                       reg =   <0x49900000 0x100000>;
+                       interrupts = <113>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc2: tptc@49a00000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc2";
+                       reg =   <0x49a00000 0x100000>;
+                       interrupts = <114>;
+                       interrupt-names = "edma3_tcerrint";
+               };
+
+               edma_tptc3: tptc@49b00000 {
+                       compatible = "ti,edma3-tptc";
+                       ti,hwmods = "tptc3";
+                       reg =   <0x49b00000 0x100000>;
+                       interrupts = <115>;
+                       interrupt-names = "edma3_tcerrint";
                };
 
                /* See TRM "Table 1-318. L4HS Instance Summary" */
index eee636d..c3b8811 100644 (file)
@@ -64,7 +64,6 @@
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
-               ti,hwmods = "l3_main";
 
                prcm: prcm@48180000 {
                        compatible = "ti,dm816-prcm";
                        #address-cells = <2>;
                        #size-cells = <1>;
                        interrupts = <100>;
+                       dmas = <&edma 52>;
+                       dma-names = "rxtx";
                        gpmc,num-cs = <6>;
                        gpmc,num-waitpins = <2>;
                };
                        };
                };
 
+               spinbox: spinbox@480ca000 {
+                       compatible = "ti,omap4-hwspinlock";
+                       reg = <0x480ca000 0x2000>;
+                       ti,hwmods = "spinbox";
+                       #hwlock-cells = <1>;
+               };
+
                mdio: mdio@4a100800 {
                        compatible = "ti,davinci_mdio";
                        #address-cells = <1>;
                        reg = <0x48044000 0x2000>;
                        interrupts = <92>;
                        ti,hwmods = "timer4";
+                       ti,timer-pwm;
                };
 
                timer5: timer@48046000 {
                        reg = <0x48046000 0x2000>;
                        interrupts = <93>;
                        ti,hwmods = "timer5";
+                       ti,timer-pwm;
                };
 
                timer6: timer@48048000 {
                        reg = <0x48048000 0x2000>;
                        interrupts = <94>;
                        ti,hwmods = "timer6";
+                       ti,timer-pwm;
                };
 
                timer7: timer@4804a000 {
                        reg = <0x4804a000 0x2000>;
                        interrupts = <95>;
                        ti,hwmods = "timer7";
+                       ti,timer-pwm;
                };
 
                uart1: uart@48020000 {
index e6fa251..af3cb63 100644 (file)
                pinctrl-0 = <&pmx_gpio_19>;
                pinctrl-names = "default";
        };
+
+       gpu-subsystem {
+               status = "okay";
+       };
 };
 
 &uart0 { status = "okay"; };
        reg = <1>;
 };
 
+&gpu {
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
        clock-frequency = <100000>;
index cd58c2e..698d58c 100644 (file)
                marvell,tauros2-cache-features = <0>;
        };
 
+       gpu-subsystem {
+               compatible = "marvell,dove-gpu-subsystem";
+               cores = <&gpu>;
+               status = "disabled";
+       };
+
        i2c-mux {
                compatible = "i2c-mux-pinctrl";
                #address-cells = <1>;
                                        #clock-cells = <1>;
                                };
 
+                               divider_clk: core-clock@0064 {
+                                       compatible = "marvell,dove-divider-clock";
+                                       reg = <0x0064 0x8>;
+                                       #clock-cells = <1>;
+                               };
+
                                pinctrl: pin-ctrl@0200 {
                                        compatible = "marvell,dove-pinctrl";
                                        reg = <0x0200 0x14>,
                                #address-cells = <1>;
                                #size-cells = <1>;
                        };
+
+                       gpu: gpu@840000 {
+                               clocks = <&divider_clk 1>;
+                               clock-names = "core";
+                               compatible = "vivante,gc";
+                               interrupts = <48>;
+                               power-domains = <&gpu_domain>;
+                               reg = <0x840000 0x4000>;
+                               status = "disabled";
+                       };
                };
        };
 };
diff --git a/arch/arm/boot/dts/dra62x-clocks.dtsi b/arch/arm/boot/dts/dra62x-clocks.dtsi
new file mode 100644 (file)
index 0000000..6f98dc8
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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 "dm814x-clocks.dtsi"
+
+/*
+ * Compared to dm814x, dra62x has different shifts and more mux options.
+ * Please add the extra options for ysclk_14 and 16 if really needed.
+ */
+&timer1_fck {
+       clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+                 &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+       ti,bit-shift = <4>;
+};
+
+&timer2_fck {
+       clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+                 &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+       ti,bit-shift = <8>;
+};
diff --git a/arch/arm/boot/dts/dra62x-j5eco-evm.dts b/arch/arm/boot/dts/dra62x-j5eco-evm.dts
new file mode 100644 (file)
index 0000000..7900806
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+/dts-v1/;
+
+#include "dra62x.dtsi"
+
+/ {
+       model = "DRA62x J5 Eco EVM";
+       compatible = "ti,dra62x-j5eco-evm", "ti,dra62x", "ti,dm8148";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>;  /* 1 GB */
+       };
+
+       /* MIC94060YC6 controlled by SD1_POW pin */
+       vmmcsd_fixed: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       phy-mode = "rgmii";
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <1>;
+       phy-mode = "rgmii";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sd1_pins>;
+       vmmc-supply = <&vmmcsd_fixed>;
+       bus-width = <4>;
+       cd-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+};
+
+&pincntl {
+       sd1_pins: pinmux_sd1_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0800, PIN_INPUT | 0x1)   /* SD1_CLK */
+                       DM814X_IOPAD(0x0804, PIN_INPUT_PULLUP |  0x1)   /* SD1_CMD */
+                       DM814X_IOPAD(0x0808, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[0] */
+                       DM814X_IOPAD(0x080c, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[1] */
+                       DM814X_IOPAD(0x0810, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[2] */
+                       DM814X_IOPAD(0x0814, PIN_INPUT_PULLUP |  0x1)   /* SD1_DAT[3] */
+                       DM814X_IOPAD(0x0924, PIN_OUTPUT |  0x40)        /* SD1_POW */
+                       DM814X_IOPAD(0x093C, PIN_INPUT_PULLUP |  0x80)  /* GP1[6] */
+                       >;
+       };
+
+       usb0_pins: pinmux_usb0_pins {
+               pinctrl-single,pins = <
+                       DM814X_IOPAD(0x0c34, PIN_OUTPUT | 0x1)  /* USB0_DRVVBUS */
+                       >;
+       };
+};
+
+/* USB0_ID pin state: SW10[1] = 0 cable detection, SW10[1] = 1 ID grounded */
+&usb0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb0_pins>;
+       dr_mode = "otg";
+};
+
+&usb1_phy {
+       status = "disabled";
+};
+
+&usb1 {
+       status = "disabled";
+};
diff --git a/arch/arm/boot/dts/dra62x.dtsi b/arch/arm/boot/dts/dra62x.dtsi
new file mode 100644 (file)
index 0000000..d3cbb4e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include "dm814x.dtsi"
+
+/ {
+       compatible = "ti,dra62x";
+};
+
+/* Compared to dm814x, dra62x has different offsets for Ethernet */
+&mac {
+       reg = <0x4a100000 0x800
+               0x4a101200 0x100>;
+};
+
+&davinci_mdio {
+       reg = <0x4a101000 0x100>;
+};
+
+#include "dra62x-clocks.dtsi"
index 864f600..cfc24e5 100644 (file)
 
        vtt_pin: pinmux_vtt_pin {
                pinctrl-single,pins = <
-                       0x3b4 (PIN_OUTPUT | MUX_MODE14) /* spi1_cs1.gpio7_11 */
+                       DRA7XX_CORE_IOPAD(0x37b4, PIN_OUTPUT | MUX_MODE14) /* spi1_cs1.gpio7_11 */
                >;
        };
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0x400 (PIN_INPUT | MUX_MODE0) /* i2c1_sda */
-                       0x404 (PIN_INPUT | MUX_MODE0) /* i2c1_scl */
+                       DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT | MUX_MODE0) /* i2c1_sda */
+                       DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT | MUX_MODE0) /* i2c1_scl */
                >;
        };
 
        i2c2_pins: pinmux_i2c2_pins {
                pinctrl-single,pins = <
-                       0x408 (PIN_INPUT | MUX_MODE0) /* i2c2_sda */
-                       0x40c (PIN_INPUT | MUX_MODE0) /* i2c2_scl */
+                       DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE0) /* i2c2_sda */
+                       DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE0) /* i2c2_scl */
                >;
        };
 
        i2c3_pins: pinmux_i2c3_pins {
                pinctrl-single,pins = <
-                       0x288 (PIN_INPUT | MUX_MODE9) /* gpio6_14.i2c3_sda */
-                       0x28c (PIN_INPUT | MUX_MODE9) /* gpio6_15.i2c3_scl */
+                       DRA7XX_CORE_IOPAD(0x3688, PIN_INPUT | MUX_MODE9) /* gpio6_14.i2c3_sda */
+                       DRA7XX_CORE_IOPAD(0x368c, PIN_INPUT | MUX_MODE9) /* gpio6_15.i2c3_scl */
                >;
        };
 
        mcspi1_pins: pinmux_mcspi1_pins {
                pinctrl-single,pins = <
-                       0x3a4 (PIN_INPUT | MUX_MODE0) /* spi1_sclk */
-                       0x3a8 (PIN_INPUT | MUX_MODE0) /* spi1_d1 */
-                       0x3ac (PIN_INPUT | MUX_MODE0) /* spi1_d0 */
-                       0x3b0 (PIN_INPUT_SLEW | MUX_MODE0) /* spi1_cs0 */
-                       0x3b8 (PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs2.hdmi1_hpd */
-                       0x3bc (PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs3.hdmi1_cec */
+                       DRA7XX_CORE_IOPAD(0x37a4, PIN_INPUT | MUX_MODE0) /* spi1_sclk */
+                       DRA7XX_CORE_IOPAD(0x37a8, PIN_INPUT | MUX_MODE0) /* spi1_d1 */
+                       DRA7XX_CORE_IOPAD(0x37ac, PIN_INPUT | MUX_MODE0) /* spi1_d0 */
+                       DRA7XX_CORE_IOPAD(0x37b0, PIN_INPUT_SLEW | MUX_MODE0) /* spi1_cs0 */
+                       DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs2.hdmi1_hpd */
+                       DRA7XX_CORE_IOPAD(0x37bc, PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs3.hdmi1_cec */
                >;
        };
 
        mcspi2_pins: pinmux_mcspi2_pins {
                pinctrl-single,pins = <
-                       0x3c0 (PIN_INPUT | MUX_MODE0) /* spi2_sclk */
-                       0x3c4 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
-                       0x3c8 (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
-                       0x3cc (PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */
+                       DRA7XX_CORE_IOPAD(0x37c0, PIN_INPUT | MUX_MODE0) /* spi2_sclk */
+                       DRA7XX_CORE_IOPAD(0x37c4, PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+                       DRA7XX_CORE_IOPAD(0x37c8, PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+                       DRA7XX_CORE_IOPAD(0x37cc, PIN_INPUT_SLEW | MUX_MODE0) /* spi2_cs0 */
                >;
        };
 
        uart1_pins: pinmux_uart1_pins {
                pinctrl-single,pins = <
-                       0x3e0 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_rxd */
-                       0x3e4 (PIN_INPUT_SLEW | MUX_MODE0) /* uart1_txd */
-                       0x3e8 (PIN_INPUT | MUX_MODE3) /* uart1_ctsn */
-                       0x3ec (PIN_INPUT | MUX_MODE3) /* uart1_rtsn */
+                       DRA7XX_CORE_IOPAD(0x37e0, PIN_INPUT_SLEW | MUX_MODE0) /* uart1_rxd */
+                       DRA7XX_CORE_IOPAD(0x37e4, PIN_INPUT_SLEW | MUX_MODE0) /* uart1_txd */
+                       DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT | MUX_MODE3) /* uart1_ctsn */
+                       DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT | MUX_MODE3) /* uart1_rtsn */
                >;
        };
 
        uart2_pins: pinmux_uart2_pins {
                pinctrl-single,pins = <
-                       0x3f0 (PIN_INPUT | MUX_MODE0) /* uart2_rxd */
-                       0x3f4 (PIN_INPUT | MUX_MODE0) /* uart2_txd */
-                       0x3f8 (PIN_INPUT | MUX_MODE0) /* uart2_ctsn */
-                       0x3fc (PIN_INPUT | MUX_MODE0) /* uart2_rtsn */
+                       DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT | MUX_MODE0) /* uart2_rxd */
+                       DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT | MUX_MODE0) /* uart2_txd */
+                       DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT | MUX_MODE0) /* uart2_ctsn */
+                       DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT | MUX_MODE0) /* uart2_rtsn */
                >;
        };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x248 (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */
-                       0x24c (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */
+                       DRA7XX_CORE_IOPAD(0x3648, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */
+                       DRA7XX_CORE_IOPAD(0x364c, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */
                >;
        };
 
        qspi1_pins: pinmux_qspi1_pins {
                pinctrl-single,pins = <
-                       0x4c (PIN_INPUT | MUX_MODE1)  /* gpmc_a3.qspi1_cs2 */
-                       0x50 (PIN_INPUT | MUX_MODE1)  /* gpmc_a4.qspi1_cs3 */
-                       0x74 (PIN_INPUT | MUX_MODE1)  /* gpmc_a13.qspi1_rtclk */
-                       0x78 (PIN_INPUT | MUX_MODE1)  /* gpmc_a14.qspi1_d3 */
-                       0x7c (PIN_INPUT | MUX_MODE1)  /* gpmc_a15.qspi1_d2 */
-                       0x80 (PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
-                       0x84 (PIN_INPUT | MUX_MODE1)  /* gpmc_a17.qspi1_d0 */
-                       0x88 (PIN_INPUT | MUX_MODE1)  /* qpmc_a18.qspi1_sclk */
-                       0xb8 (PIN_INPUT_PULLUP | MUX_MODE1)  /* gpmc_cs2.qspi1_cs0 */
-                       0xbc (PIN_INPUT_PULLUP | MUX_MODE1)  /* gpmc_cs3.qspi1_cs1 */
+                       DRA7XX_CORE_IOPAD(0x344c, PIN_INPUT | MUX_MODE1)  /* gpmc_a3.qspi1_cs2 */
+                       DRA7XX_CORE_IOPAD(0x3450, PIN_INPUT | MUX_MODE1)  /* gpmc_a4.qspi1_cs3 */
+                       DRA7XX_CORE_IOPAD(0x3474, PIN_INPUT | MUX_MODE1)  /* gpmc_a13.qspi1_rtclk */
+                       DRA7XX_CORE_IOPAD(0x3478, PIN_INPUT | MUX_MODE1)  /* gpmc_a14.qspi1_d3 */
+                       DRA7XX_CORE_IOPAD(0x347c, PIN_INPUT | MUX_MODE1)  /* gpmc_a15.qspi1_d2 */
+                       DRA7XX_CORE_IOPAD(0x3480, PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
+                       DRA7XX_CORE_IOPAD(0x3484, PIN_INPUT | MUX_MODE1)  /* gpmc_a17.qspi1_d0 */
+                       DRA7XX_CORE_IOPAD(0x3488, PIN_INPUT | MUX_MODE1)  /* qpmc_a18.qspi1_sclk */
+                       DRA7XX_CORE_IOPAD(0x34b8, PIN_INPUT_PULLUP | MUX_MODE1)  /* gpmc_cs2.qspi1_cs0 */
+                       DRA7XX_CORE_IOPAD(0x34bc, PIN_INPUT_PULLUP | MUX_MODE1)  /* gpmc_cs3.qspi1_cs1 */
                >;
        };
 
        usb1_pins: pinmux_usb1_pins {
                 pinctrl-single,pins = <
-                       0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+                       DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
                 >;
         };
 
        usb2_pins: pinmux_usb2_pins {
                 pinctrl-single,pins = <
-                       0x284 (PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
+                       DRA7XX_CORE_IOPAD(0x3684, PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
                 >;
         };
 
                 * SW5.9 (GPMC_WPN) = LOW
                 * SW5.1 (NAND_BOOTn) = HIGH */
                pinctrl-single,pins = <
-                       0x0     (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad0     */
-                       0x4     (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad1     */
-                       0x8     (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad2     */
-                       0xc     (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad3     */
-                       0x10    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad4     */
-                       0x14    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad5     */
-                       0x18    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad6     */
-                       0x1c    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad7     */
-                       0x20    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad8     */
-                       0x24    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad9     */
-                       0x28    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad10    */
-                       0x2c    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad11    */
-                       0x30    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad12    */
-                       0x34    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad13    */
-                       0x38    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad14    */
-                       0x3c    (PIN_INPUT  | MUX_MODE0)        /* gpmc_ad15    */
-                       0xd8    (PIN_INPUT_PULLUP  | MUX_MODE0) /* gpmc_wait0   */
-                       0xcc    (PIN_OUTPUT | MUX_MODE0)        /* gpmc_wen     */
-                       0xb4    (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0    */
-                       0xc4    (PIN_OUTPUT | MUX_MODE0)        /* gpmc_advn_ale */
-                       0xc8    (PIN_OUTPUT | MUX_MODE0)        /* gpmc_oen_ren  */
-                       0xd0    (PIN_OUTPUT | MUX_MODE0)        /* gpmc_be0n_cle */
+                       DRA7XX_CORE_IOPAD(0x3400, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad0     */
+                       DRA7XX_CORE_IOPAD(0x3404, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad1     */
+                       DRA7XX_CORE_IOPAD(0x3408, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad2     */
+                       DRA7XX_CORE_IOPAD(0x340c, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad3     */
+                       DRA7XX_CORE_IOPAD(0x3410, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad4     */
+                       DRA7XX_CORE_IOPAD(0x3414, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad5     */
+                       DRA7XX_CORE_IOPAD(0x3418, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad6     */
+                       DRA7XX_CORE_IOPAD(0x341c, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad7     */
+                       DRA7XX_CORE_IOPAD(0x3420, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad8     */
+                       DRA7XX_CORE_IOPAD(0x3424, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad9     */
+                       DRA7XX_CORE_IOPAD(0x3428, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad10    */
+                       DRA7XX_CORE_IOPAD(0x342c, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad11    */
+                       DRA7XX_CORE_IOPAD(0x3430, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad12    */
+                       DRA7XX_CORE_IOPAD(0x3434, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad13    */
+                       DRA7XX_CORE_IOPAD(0x3438, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad14    */
+                       DRA7XX_CORE_IOPAD(0x343c, PIN_INPUT  | MUX_MODE0)       /* gpmc_ad15    */
+                       DRA7XX_CORE_IOPAD(0x34d8, PIN_INPUT_PULLUP  | MUX_MODE0)        /* gpmc_wait0   */
+                       DRA7XX_CORE_IOPAD(0x34cc, PIN_OUTPUT | MUX_MODE0)       /* gpmc_wen     */
+                       DRA7XX_CORE_IOPAD(0x34b4, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* gpmc_csn0    */
+                       DRA7XX_CORE_IOPAD(0x34c4, PIN_OUTPUT | MUX_MODE0)       /* gpmc_advn_ale */
+                       DRA7XX_CORE_IOPAD(0x34c8, PIN_OUTPUT | MUX_MODE0)       /* gpmc_oen_ren  */
+                       DRA7XX_CORE_IOPAD(0x34d0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_be0n_cle */
                >;
        };
 
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x250 (PIN_OUTPUT | MUX_MODE0)  /* rgmii0_txc.rgmii0_txc */
-                       0x254 (PIN_OUTPUT | MUX_MODE0)  /* rgmii0_txctl.rgmii0_txctl */
-                       0x258 (PIN_OUTPUT | MUX_MODE0)  /* rgmii0_td3.rgmii0_txd3 */
-                       0x25c (PIN_OUTPUT | MUX_MODE0)  /* rgmii0_txd2.rgmii0_txd2 */
-                       0x260 (PIN_OUTPUT | MUX_MODE0)  /* rgmii0_txd1.rgmii0_txd1 */
-                       0x264 (PIN_OUTPUT | MUX_MODE0)  /* rgmii0_txd0.rgmii0_txd0 */
-                       0x268 (PIN_INPUT | MUX_MODE0)   /* rgmii0_rxc.rgmii0_rxc */
-                       0x26c (PIN_INPUT | MUX_MODE0)   /* rgmii0_rxctl.rgmii0_rxctl */
-                       0x270 (PIN_INPUT | MUX_MODE0)   /* rgmii0_rxd3.rgmii0_rxd3 */
-                       0x274 (PIN_INPUT | MUX_MODE0)   /* rgmii0_rxd2.rgmii0_rxd2 */
-                       0x278 (PIN_INPUT | MUX_MODE0)   /* rgmii0_rxd1.rgmii0_rxd1 */
-                       0x27c (PIN_INPUT | MUX_MODE0)   /* rgmii0_rxd0.rgmii0_rxd0 */
+                       DRA7XX_CORE_IOPAD(0x3650, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_txc.rgmii0_txc */
+                       DRA7XX_CORE_IOPAD(0x3654, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_txctl.rgmii0_txctl */
+                       DRA7XX_CORE_IOPAD(0x3658, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_td3.rgmii0_txd3 */
+                       DRA7XX_CORE_IOPAD(0x365c, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_txd2.rgmii0_txd2 */
+                       DRA7XX_CORE_IOPAD(0x3660, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_txd1.rgmii0_txd1 */
+                       DRA7XX_CORE_IOPAD(0x3664, PIN_OUTPUT | MUX_MODE0)       /* rgmii0_txd0.rgmii0_txd0 */
+                       DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE0)        /* rgmii0_rxc.rgmii0_rxc */
+                       DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE0)        /* rgmii0_rxctl.rgmii0_rxctl */
+                       DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE0)        /* rgmii0_rxd3.rgmii0_rxd3 */
+                       DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE0)        /* rgmii0_rxd2.rgmii0_rxd2 */
+                       DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE0)        /* rgmii0_rxd1.rgmii0_rxd1 */
+                       DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT | MUX_MODE0)        /* rgmii0_rxd0.rgmii0_rxd0 */
 
                        /* Slave 2 */
-                       0x198 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d12.rgmii1_txc */
-                       0x19c (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d13.rgmii1_tctl */
-                       0x1a0 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d14.rgmii1_td3 */
-                       0x1a4 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d15.rgmii1_td2 */
-                       0x1a8 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d16.rgmii1_td1 */
-                       0x1ac (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d17.rgmii1_td0 */
-                       0x1b0 (PIN_INPUT | MUX_MODE3)   /* vin2a_d18.rgmii1_rclk */
-                       0x1b4 (PIN_INPUT | MUX_MODE3)   /* vin2a_d19.rgmii1_rctl */
-                       0x1b8 (PIN_INPUT | MUX_MODE3)   /* vin2a_d20.rgmii1_rd3 */
-                       0x1bc (PIN_INPUT | MUX_MODE3)   /* vin2a_d21.rgmii1_rd2 */
-                       0x1c0 (PIN_INPUT | MUX_MODE3)   /* vin2a_d22.rgmii1_rd1 */
-                       0x1c4 (PIN_INPUT | MUX_MODE3)   /* vin2a_d23.rgmii1_rd0 */
+                       DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d12.rgmii1_txc */
+                       DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d13.rgmii1_tctl */
+                       DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d14.rgmii1_td3 */
+                       DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d15.rgmii1_td2 */
+                       DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d16.rgmii1_td1 */
+                       DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d17.rgmii1_td0 */
+                       DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE3)        /* vin2a_d18.rgmii1_rclk */
+                       DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE3)        /* vin2a_d19.rgmii1_rctl */
+                       DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE3)        /* vin2a_d20.rgmii1_rd3 */
+                       DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE3)        /* vin2a_d21.rgmii1_rd2 */
+                       DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE3)        /* vin2a_d22.rgmii1_rd1 */
+                       DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE3)        /* vin2a_d23.rgmii1_rd0 */
                >;
 
        };
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 1 */
-                       0x250 (MUX_MODE15)
-                       0x254 (MUX_MODE15)
-                       0x258 (MUX_MODE15)
-                       0x25c (MUX_MODE15)
-                       0x260 (MUX_MODE15)
-                       0x264 (MUX_MODE15)
-                       0x268 (MUX_MODE15)
-                       0x26c (MUX_MODE15)
-                       0x270 (MUX_MODE15)
-                       0x274 (MUX_MODE15)
-                       0x278 (MUX_MODE15)
-                       0x27c (MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3650, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3654, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3658, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x365c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3660, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3664, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3668, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x366c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3670, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3674, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3678, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x367c, MUX_MODE15)
 
                        /* Slave 2 */
-                       0x198 (MUX_MODE15)
-                       0x19c (MUX_MODE15)
-                       0x1a0 (MUX_MODE15)
-                       0x1a4 (MUX_MODE15)
-                       0x1a8 (MUX_MODE15)
-                       0x1ac (MUX_MODE15)
-                       0x1b0 (MUX_MODE15)
-                       0x1b4 (MUX_MODE15)
-                       0x1b8 (MUX_MODE15)
-                       0x1bc (MUX_MODE15)
-                       0x1c0 (MUX_MODE15)
-                       0x1c4 (MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3598, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x359c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a0, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a4, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a8, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35ac, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b0, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b4, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b8, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35bc, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c0, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c4, MUX_MODE15)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
-                       0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* mdio_d.mdio_d */
-                       0x240 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mdio_clk.mdio_clk */
+                       DRA7XX_CORE_IOPAD(0x363c, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* mdio_d.mdio_d */
+                       DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
-                       0x23c (MUX_MODE15)
-                       0x240 (MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x363c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3640, MUX_MODE15)
                >;
        };
 
        dcan1_pins_default: dcan1_pins_default {
                pinctrl-single,pins = <
-                       0x3d0   (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
-                       0x418   (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */
+                       DRA7XX_CORE_IOPAD(0x37d0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+                       DRA7XX_CORE_IOPAD(0x3818, PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */
                >;
        };
 
        dcan1_pins_sleep: dcan1_pins_sleep {
                pinctrl-single,pins = <
-                       0x3d0   (MUX_MODE15 | PULL_UP)  /* dcan1_tx.off */
-                       0x418   (MUX_MODE15 | PULL_UP)  /* wakeup0.off */
+                       DRA7XX_CORE_IOPAD(0x37d0, MUX_MODE15 | PULL_UP) /* dcan1_tx.off */
+                       DRA7XX_CORE_IOPAD(0x3818, MUX_MODE15 | PULL_UP) /* wakeup0.off */
                >;
        };
 
        atl_pins: pinmux_atl_pins {
                pinctrl-single,pins = <
-                       0x298 (PIN_OUTPUT | MUX_MODE5)  /* xref_clk1.atl_clk1 */
-                       0x29c (PIN_OUTPUT | MUX_MODE5)  /* xref_clk2.atl_clk2 */
+                       DRA7XX_CORE_IOPAD(0x3698, PIN_OUTPUT | MUX_MODE5)       /* xref_clk1.atl_clk1 */
+                       DRA7XX_CORE_IOPAD(0x369c, PIN_OUTPUT | MUX_MODE5)       /* xref_clk2.atl_clk2 */
                >;
        };
 
        mcasp3_pins: pinmux_mcasp3_pins {
                pinctrl-single,pins = <
-                       0x324 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx */
-                       0x328 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx */
-                       0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0 */
-                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp3_axr1 */
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_OUTPUT_PULLDOWN | MUX_MODE0)      /* mcasp3_aclkx */
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_OUTPUT_PULLDOWN | MUX_MODE0)      /* mcasp3_fsx */
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)      /* mcasp3_axr0 */
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* mcasp3_axr1 */
                >;
        };
 
        mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
                pinctrl-single,pins = <
-                       0x324 (MUX_MODE15)
-                       0x328 (MUX_MODE15)
-                       0x32c (MUX_MODE15)
-                       0x330 (MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3724, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3728, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x372c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3730, MUX_MODE15)
                >;
        };
 };
                                        regulator-max-microvolt = <1050000>;
                                        regulator-always-on;
                                        regulator-boot-on;
+                                       regulator-allow-bypass;
                                };
 
                                ldoln_reg: ldoln {
index fe99231..c4d9175 100644 (file)
@@ -41,6 +41,7 @@
                ethernet1 = &cpsw_emac1;
                d_can0 = &dcan1;
                d_can1 = &dcan2;
+               spi0 = &qspi;
        };
 
        timer {
 
                qspi: qspi@4b300000 {
                        compatible = "ti,dra7xxx-qspi";
-                       reg = <0x4b300000 0x100>;
-                       reg-names = "qspi_base";
+                       reg = <0x4b300000 0x100>,
+                             <0x5c000000 0x4000000>;
+                       reg-names = "qspi_base", "qspi_mmap";
+                       syscon-chipselects = <&scm_conf 0x558>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ti,hwmods = "qspi";
index d6104d5..00b1200 100644 (file)
 &dra7_pmx_core {
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0x400 (PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
-                       0x404 (PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+                       DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+                       DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
                >;
        };
 
        i2c5_pins: pinmux_i2c5_pins {
                pinctrl-single,pins = <
-                       0x2b4 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
-                       0x2b8 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
+                       DRA7XX_CORE_IOPAD(0x36b4, PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
+                       DRA7XX_CORE_IOPAD(0x36b8, PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
                >;
        };
 
        i2c5_pins: pinmux_i2c5_pins {
                pinctrl-single,pins = <
-                       0x2b4 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
-                       0x2b8 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
+                       DRA7XX_CORE_IOPAD(0x36b4, PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
+                       DRA7XX_CORE_IOPAD(0x36b8, PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
                >;
        };
 
        nand_default: nand_default {
                pinctrl-single,pins = <
-                       0x0     (PIN_INPUT  | MUX_MODE0) /* gpmc_ad0 */
-                       0x4     (PIN_INPUT  | MUX_MODE0) /* gpmc_ad1 */
-                       0x8     (PIN_INPUT  | MUX_MODE0) /* gpmc_ad2 */
-                       0xc     (PIN_INPUT  | MUX_MODE0) /* gpmc_ad3 */
-                       0x10    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad4 */
-                       0x14    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad5 */
-                       0x18    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad6 */
-                       0x1c    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad7 */
-                       0x20    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad8 */
-                       0x24    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad9 */
-                       0x28    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad10 */
-                       0x2c    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad11 */
-                       0x30    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad12 */
-                       0x34    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad13 */
-                       0x38    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad14 */
-                       0x3c    (PIN_INPUT  | MUX_MODE0) /* gpmc_ad15 */
-                       0xb4    (PIN_OUTPUT | MUX_MODE0) /* gpmc_cs0 */
-                       0xc4    (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale */
-                       0xcc    (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen */
-                       0xc8    (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren */
-                       0xd0    (PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0 */
-                       0xd8    (PIN_INPUT  | MUX_MODE0) /* gpmc_wait0 */
+                       DRA7XX_CORE_IOPAD(0x3400, PIN_INPUT  | MUX_MODE0) /* gpmc_ad0 */
+                       DRA7XX_CORE_IOPAD(0x3404, PIN_INPUT  | MUX_MODE0) /* gpmc_ad1 */
+                       DRA7XX_CORE_IOPAD(0x3408, PIN_INPUT  | MUX_MODE0) /* gpmc_ad2 */
+                       DRA7XX_CORE_IOPAD(0x340c, PIN_INPUT  | MUX_MODE0) /* gpmc_ad3 */
+                       DRA7XX_CORE_IOPAD(0x3410, PIN_INPUT  | MUX_MODE0) /* gpmc_ad4 */
+                       DRA7XX_CORE_IOPAD(0x3414, PIN_INPUT  | MUX_MODE0) /* gpmc_ad5 */
+                       DRA7XX_CORE_IOPAD(0x3418, PIN_INPUT  | MUX_MODE0) /* gpmc_ad6 */
+                       DRA7XX_CORE_IOPAD(0x341c, PIN_INPUT  | MUX_MODE0) /* gpmc_ad7 */
+                       DRA7XX_CORE_IOPAD(0x3420, PIN_INPUT  | MUX_MODE0) /* gpmc_ad8 */
+                       DRA7XX_CORE_IOPAD(0x3424, PIN_INPUT  | MUX_MODE0) /* gpmc_ad9 */
+                       DRA7XX_CORE_IOPAD(0x3428, PIN_INPUT  | MUX_MODE0) /* gpmc_ad10 */
+                       DRA7XX_CORE_IOPAD(0x342c, PIN_INPUT  | MUX_MODE0) /* gpmc_ad11 */
+                       DRA7XX_CORE_IOPAD(0x3430, PIN_INPUT  | MUX_MODE0) /* gpmc_ad12 */
+                       DRA7XX_CORE_IOPAD(0x3434, PIN_INPUT  | MUX_MODE0) /* gpmc_ad13 */
+                       DRA7XX_CORE_IOPAD(0x3438, PIN_INPUT  | MUX_MODE0) /* gpmc_ad14 */
+                       DRA7XX_CORE_IOPAD(0x343c, PIN_INPUT  | MUX_MODE0) /* gpmc_ad15 */
+                       DRA7XX_CORE_IOPAD(0x34b4, PIN_OUTPUT | MUX_MODE0) /* gpmc_cs0 */
+                       DRA7XX_CORE_IOPAD(0x34c4, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale */
+                       DRA7XX_CORE_IOPAD(0x34cc, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen */
+                       DRA7XX_CORE_IOPAD(0x34c8, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren */
+                       DRA7XX_CORE_IOPAD(0x34d0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0 */
+                       DRA7XX_CORE_IOPAD(0x34d8, PIN_INPUT  | MUX_MODE0) /* gpmc_wait0 */
                >;
        };
 
        usb1_pins: pinmux_usb1_pins {
                pinctrl-single,pins = <
-                       0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+                       DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
                >;
        };
 
        usb2_pins: pinmux_usb2_pins {
                pinctrl-single,pins = <
-                       0x284 (PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
+                       DRA7XX_CORE_IOPAD(0x3684, PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
                >;
        };
 
        tps65917_pins_default: tps65917_pins_default {
                pinctrl-single,pins = <
-                       0x424 (PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
+                       DRA7XX_CORE_IOPAD(0x3824, PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
                >;
        };
 
        mmc1_pins_default: mmc1_pins_default {
                pinctrl-single,pins = <
-                       0x36c (PIN_INPUT | MUX_MODE14)  /* mmc1sdcd.gpio219 */
-                       0x354 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
-                       0x358 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
-                       0x35c (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
-                       0x360 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
-                       0x364 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
-                       0x368 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+                       DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14)       /* mmc1sdcd.gpio219 */
+                       DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+                       DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+                       DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+                       DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+                       DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+                       DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
                >;
        };
 
        mmc2_pins_default: mmc2_pins_default {
                pinctrl-single,pins = <
-                       0x9c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
-                       0xb0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
-                       0xa0 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
-                       0xa4 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
-                       0xa8 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
-                       0xac (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
-                       0x8c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
-                       0x90 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
-                       0x94 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
-                       0x98 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+                       DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+                       DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+                       DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+                       DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+                       DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+                       DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+                       DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+                       DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+                       DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+                       DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
                >;
        };
 
        dcan1_pins_default: dcan1_pins_default {
                pinctrl-single,pins = <
-                       0x3d0   (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
-                       0x418   (PULL_UP | MUX_MODE1)   /* wakeup0.dcan1_rx */
+                       DRA7XX_CORE_IOPAD(0x37d0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+                       DRA7XX_CORE_IOPAD(0x3818, PULL_UP | MUX_MODE1)  /* wakeup0.dcan1_rx */
                >;
        };
 
        dcan1_pins_sleep: dcan1_pins_sleep {
                pinctrl-single,pins = <
-                       0x3d0   (MUX_MODE15 | PULL_UP)  /* dcan1_tx.off */
-                       0x418   (MUX_MODE15 | PULL_UP)  /* wakeup0.off */
+                       DRA7XX_CORE_IOPAD(0x37d0, MUX_MODE15 | PULL_UP) /* dcan1_tx.off */
+                       DRA7XX_CORE_IOPAD(0x3818, MUX_MODE15 | PULL_UP) /* wakeup0.off */
                >;
        };
 
        qspi1_pins: pinmux_qspi1_pins {
                pinctrl-single,pins = <
-                       0x74 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_a13.qspi1_rtclk */
-                       0x78 (PIN_INPUT | MUX_MODE1)    /* gpmc_a14.qspi1_d3 */
-                       0x7c (PIN_INPUT | MUX_MODE1)    /* gpmc_a15.qspi1_d2 */
-                       0x80 (PIN_INPUT | MUX_MODE1)    /* gpmc_a16.qspi1_d1 */
-                       0x84 (PIN_INPUT | MUX_MODE1)    /* gpmc_a17.qspi1_d0 */
-                       0x88 (PIN_OUTPUT | MUX_MODE1)   /* qpmc_a18.qspi1_sclk */
-                       0xb8 (PIN_OUTPUT | MUX_MODE1)   /* gpmc_cs2.qspi1_cs0 */
+                       DRA7XX_CORE_IOPAD(0x3474, PIN_OUTPUT | MUX_MODE1)       /* gpmc_a13.qspi1_rtclk */
+                       DRA7XX_CORE_IOPAD(0x3478, PIN_INPUT | MUX_MODE1)        /* gpmc_a14.qspi1_d3 */
+                       DRA7XX_CORE_IOPAD(0x347c, PIN_INPUT | MUX_MODE1)        /* gpmc_a15.qspi1_d2 */
+                       DRA7XX_CORE_IOPAD(0x3480, PIN_INPUT | MUX_MODE1)        /* gpmc_a16.qspi1_d1 */
+                       DRA7XX_CORE_IOPAD(0x3484, PIN_INPUT | MUX_MODE1)        /* gpmc_a17.qspi1_d0 */
+                       DRA7XX_CORE_IOPAD(0x3488, PIN_OUTPUT | MUX_MODE1)       /* qpmc_a18.qspi1_sclk */
+                       DRA7XX_CORE_IOPAD(0x34b8, PIN_OUTPUT | MUX_MODE1)       /* gpmc_cs2.qspi1_cs0 */
                >;
        };
 
        hdmi_pins: pinmux_hdmi_pins {
                pinctrl-single,pins = <
-                       0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
-                       0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
+                       DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
+                       DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
                >;
        };
 
        tpd12s015_pins: pinmux_tpd12s015_pins {
                pinctrl-single,pins = <
-                       0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
+                       DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
                >;
        };
 
        atl_pins: pinmux_atl_pins {
                pinctrl-single,pins = <
-                       0x298 (PIN_OUTPUT | MUX_MODE5)  /* xref_clk1.atl_clk1 */
-                       0x29c (PIN_OUTPUT | MUX_MODE5)  /* xref_clk2.atl_clk2 */
+                       DRA7XX_CORE_IOPAD(0x3698, PIN_OUTPUT | MUX_MODE5)       /* xref_clk1.atl_clk1 */
+                       DRA7XX_CORE_IOPAD(0x369c, PIN_OUTPUT | MUX_MODE5)       /* xref_clk2.atl_clk2 */
                >;
        };
 
        mcasp3_pins: pinmux_mcasp3_pins {
                pinctrl-single,pins = <
-                       0x324 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx */
-                       0x328 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx */
-                       0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0 */
-                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp3_axr1 */
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_OUTPUT_PULLDOWN | MUX_MODE0)      /* mcasp3_aclkx */
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_OUTPUT_PULLDOWN | MUX_MODE0)      /* mcasp3_fsx */
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)      /* mcasp3_axr0 */
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* mcasp3_axr1 */
                >;
        };
 
        mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
                pinctrl-single,pins = <
-                       0x324 (PIN_INPUT_PULLDOWN | MUX_MODE15)
-                       0x328 (PIN_INPUT_PULLDOWN | MUX_MODE15)
-                       0x32c (PIN_INPUT_PULLDOWN | MUX_MODE15)
-                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x372c, PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE15)
                >;
        };
 };
                                        regulator-max-microvolt = <3300000>;
                                        regulator-always-on;
                                        regulator-boot-on;
+                                       regulator-allow-bypass;
                                };
 
                                ldo2_reg: ldo2 {
                                        regulator-name = "ldo2";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <3300000>;
+                                       regulator-allow-bypass;
                                };
 
                                ldo3_reg: ldo3 {
 
 &uart1 {
        status = "okay";
+       interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+                             <&dra7_pmx_core 0x3e0>;
 };
 
 &elm {
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 2 */
-                       0x198 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d12.rgmii1_txc */
-                       0x19c (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d13.rgmii1_tctl */
-                       0x1a0 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d14.rgmii1_td3 */
-                       0x1a4 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d15.rgmii1_td2 */
-                       0x1a8 (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d16.rgmii1_td1 */
-                       0x1ac (PIN_OUTPUT | MUX_MODE3)  /* vin2a_d17.rgmii1_td0 */
-                       0x1b0 (PIN_INPUT | MUX_MODE3)   /* vin2a_d18.rgmii1_rclk */
-                       0x1b4 (PIN_INPUT | MUX_MODE3)   /* vin2a_d19.rgmii1_rctl */
-                       0x1b8 (PIN_INPUT | MUX_MODE3)   /* vin2a_d20.rgmii1_rd3 */
-                       0x1bc (PIN_INPUT | MUX_MODE3)   /* vin2a_d21.rgmii1_rd2 */
-                       0x1c0 (PIN_INPUT | MUX_MODE3)   /* vin2a_d22.rgmii1_rd1 */
-                       0x1c4 (PIN_INPUT | MUX_MODE3)   /* vin2a_d23.rgmii1_rd0 */
+                       DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d12.rgmii1_txc */
+                       DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d13.rgmii1_tctl */
+                       DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d14.rgmii1_td3 */
+                       DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d15.rgmii1_td2 */
+                       DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d16.rgmii1_td1 */
+                       DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3)       /* vin2a_d17.rgmii1_td0 */
+                       DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE3)        /* vin2a_d18.rgmii1_rclk */
+                       DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE3)        /* vin2a_d19.rgmii1_rctl */
+                       DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE3)        /* vin2a_d20.rgmii1_rd3 */
+                       DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE3)        /* vin2a_d21.rgmii1_rd2 */
+                       DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE3)        /* vin2a_d22.rgmii1_rd1 */
+                       DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE3)        /* vin2a_d23.rgmii1_rd0 */
                >;
 
        };
        cpsw_sleep: cpsw_sleep {
                pinctrl-single,pins = <
                        /* Slave 2 */
-                       0x198 (MUX_MODE15)
-                       0x19c (MUX_MODE15)
-                       0x1a0 (MUX_MODE15)
-                       0x1a4 (MUX_MODE15)
-                       0x1a8 (MUX_MODE15)
-                       0x1ac (MUX_MODE15)
-                       0x1b0 (MUX_MODE15)
-                       0x1b4 (MUX_MODE15)
-                       0x1b8 (MUX_MODE15)
-                       0x1bc (MUX_MODE15)
-                       0x1c0 (MUX_MODE15)
-                       0x1c4 (MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3598, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x359c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a0, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a4, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35a8, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35ac, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b0, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b4, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35b8, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35bc, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c0, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x35c4, MUX_MODE15)
                >;
        };
 
        davinci_mdio_default: davinci_mdio_default {
                pinctrl-single,pins = <
                        /* MDIO */
-                       0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* mdio_d.mdio_d */
-                       0x240 (PIN_INPUT_PULLUP | MUX_MODE0)    /* mdio_clk.mdio_clk */
+                       DRA7XX_CORE_IOPAD(0x363c, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* mdio_d.mdio_d */
+                       DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
                >;
        };
 
        davinci_mdio_sleep: davinci_mdio_sleep {
                pinctrl-single,pins = <
-                       0x23c (MUX_MODE15)
-                       0x240 (MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x363c, MUX_MODE15)
+                       DRA7XX_CORE_IOPAD(0x3640, MUX_MODE15)
                >;
        };
 };
index a4ba31b..a4a281f 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 /dts-v1/;
-/include/ "lpc32xx.dtsi"
+#include "lpc32xx.dtsi"
 
 / {
        model = "Embedded Artists LPC3250 board based on NXP LPC3250";
@@ -22,7 +22,7 @@
 
        memory {
                device_type = "memory";
-               reg = <0 0x4000000>;
+               reg = <0x80000000 0x4000000>;
        };
 
        ahb {
                        use-iram;
                };
 
-               /* Here, choose exactly one from: ohci, usbd */
-               ohci@31020000 {
-                       transceiver = <&isp1301>;
-                       status = "okay";
-               };
-
-/*
-               usbd@31020000 {
-                       transceiver = <&isp1301>;
-                       status = "okay";
-               };
-*/
-
                /* 128MB Flash via SLC NAND controller */
                slc: flash@20020000 {
                        status = "okay";
                                clock-frequency = <100000>;
                        };
 
-                       i2cusb: i2c@31020300 {
-                               clock-frequency = <100000>;
-
-                               isp1301: usb-transceiver@2d {
-                                       compatible = "nxp,isp1301";
-                                       reg = <0x2d>;
-                               };
-                       };
-
                        sd@20098000 {
                                wp-gpios = <&pca9532 5 0>;
                                cd-gpios = <&pca9532 4 0>;
                };
        };
 };
+
+/* Here, choose exactly one from: ohci, usbd */
+&ohci /* &usbd */ {
+       transceiver = <&isp1301>;
+       status = "okay";
+};
+
+&i2cusb {
+       clock-frequency = <100000>;
+
+       isp1301: usb-transceiver@2d {
+               compatible = "nxp,isp1301";
+               reg = <0x2d>;
+       };
+};
index edad0c4..57795da 100644 (file)
@@ -44,7 +44,7 @@
        };
 
        gic: interrupt-controller@e0020000 {
-               compatible = "arm,cortex-a9-gic";
+               compatible = "arm,pl390";
                interrupt-controller;
                #interrupt-cells = <3>;
                reg = <0xe0028000 0x1000>,
index 2f30d63..18e3def 100644 (file)
                        interrupt-parent = <&gic>;
                };
 
+               poweroff: syscon-poweroff {
+                       compatible = "syscon-poweroff";
+                       regmap = <&pmu_system_controller>;
+                       offset = <0x330C>; /* PS_HOLD_CONTROL */
+                       mask = <0x5200>; /* Reset value */
+               };
+
+               reboot: syscon-reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&pmu_system_controller>;
+                       offset = <0x0400>; /* SWRESET */
+                       mask = <0x1>;
+               };
+
                mipi_phy: video-phy@10020710 {
                        compatible = "samsung,s5pv210-mipi-video-phy";
                        #phy-cells = <1>;
index 3184e10..045785c 100644 (file)
                interrupt-parent = <&gic>;
        };
 
+       poweroff: syscon-poweroff {
+               compatible = "syscon-poweroff";
+               regmap = <&pmu_system_controller>;
+               offset = <0x330C>; /* PS_HOLD_CONTROL */
+               mask = <0x5200>; /* reset value */
+       };
+
+       reboot: syscon-reboot {
+               compatible = "syscon-reboot";
+               regmap = <&pmu_system_controller>;
+               offset = <0x0400>; /* SWRESET */
+               mask = <0x1>;
+       };
+
        dsi_0: dsi@11C80000 {
                compatible = "samsung,exynos4210-mipi-dsi";
                reg = <0x11C80000 0x10000>;
                iommus = <&sysmmu_jpeg>;
        };
 
+       rotator: rotator@12810000 {
+               compatible = "samsung,exynos4210-rotator";
+               reg = <0x12810000 0x64>;
+               interrupts = <0 83 0>;
+               clocks = <&clock CLK_ROTATOR>;
+               clock-names = "rotator";
+               iommus = <&sysmmu_rotator>;
+       };
+
        hdmi: hdmi@12D00000 {
                compatible = "samsung,exynos4210-hdmi";
                reg = <0x12D00000 0x70000>;
                interrupts = <5 0>;
                clock-names = "sysmmu", "master";
                clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
-               power-domains = <&pd_lcd0>;
                #iommu-cells = <0>;
        };
 
                power-domains = <&pd_lcd0>;
                #iommu-cells = <0>;
        };
+
+       prng: rng@10830400 {
+               compatible = "samsung,exynos4-rng";
+               reg = <0x10830400 0x200>;
+               clocks = <&clock CLK_SSS>;
+               clock-names = "secss";
+               status = "disabled";
+       };
 };
index b8f8669..5821ad8 100644 (file)
        status = "okay";
 };
 
-&g2d {
-       status = "okay";
-};
-
 &i2c_0 {
        status = "okay";
        samsung,i2c-sda-delay = <100>;
index bc1448b..104cbb3 100644 (file)
        };
 };
 
-&g2d {
-       status = "okay";
-};
-
 &i2c_0 {
        #address-cells = <1>;
        #size-cells = <0>;
index 81b7ec7..4f5d379 100644 (file)
 
 &serial_0 {
        status = "okay";
+       /delete-property/dmas;
+       /delete-property/dma-names;
 };
 
 &serial_1 {
        status = "okay";
+       /delete-property/dmas;
+       /delete-property/dma-names;
 };
 
 &serial_2 {
        status = "okay";
+       /delete-property/dmas;
+       /delete-property/dma-names;
 };
 
 &serial_3 {
        status = "okay";
+       /delete-property/dmas;
+       /delete-property/dma-names;
 };
index 3e5ba66..c1cb8df 100644 (file)
                interrupts = <0 89 0>;
                clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
                clock-names = "sclk_fimg2d", "fimg2d";
+               power-domains = <&pd_lcd0>;
                iommus = <&sysmmu_g2d>;
-               status = "disabled";
        };
 
        camera {
                     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
 };
 
+&mdma1 {
+       power-domains = <&pd_lcd0>;
+};
+
 &pmu_system_controller {
        clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
                        "clkout4", "clkout8", "clkout9";
                <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>, <&clock CLK_XUSBXTI>;
        #clock-cells = <1>;
 };
+
+&rotator {
+       power-domains = <&pd_lcd0>;
+};
+
+&sysmmu_rotator {
+       power-domains = <&pd_lcd0>;
+};
index edf0fc8..395c3ca 100644 (file)
        assigned-clock-rates = <0>, <176000000>;
 };
 
-&g2d {
-       status = "okay";
-};
-
 &hdmi {
        hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
index 646ff0b..dd89f7b 100644 (file)
@@ -13,7 +13,6 @@
 
 /dts-v1/;
 #include "exynos4412-odroid-common.dtsi"
-#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "Hardkernel ODROID-U3 board based on Exynos4412";
index c8d86af..9e2e24c 100644 (file)
        status = "okay";
 };
 
-&g2d {
-       status = "okay";
-};
-
 &i2c_0 {
        #address-cells = <1>;
        #size-cells = <0>;
index c2421df..a130ab3 100644 (file)
        };
 };
 
-&g2d {
-       status = "okay";
-};
-
 &keypad {
        samsung,keypad-num-rows = <3>;
        samsung,keypad-num-columns = <8>;
index 40a474c..a6f78c3 100644 (file)
        status = "okay";
 };
 
+&prng {
+       status = "okay";
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
index b77dac6..84a23f9 100644 (file)
                clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
                clock-names = "sclk_fimg2d", "fimg2d";
                iommus = <&sysmmu_g2d>;
-               status = "disabled";
        };
 
        camera {
        compatible = "samsung,exynos4212-jpeg";
 };
 
+&rotator {
+       compatible = "samsung,exynos4212-rotator";
+};
+
 &mixer {
        compatible = "samsung,exynos4212-mixer";
        clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
index 110dbd4..e2439e8 100644 (file)
                status = "disabled";
        };
 
+       poweroff: syscon-poweroff {
+               compatible = "syscon-poweroff";
+               regmap = <&pmu_system_controller>;
+               offset = <0x330C>; /* PS_HOLD_CONTROL */
+               mask = <0x5200>; /* reset value */
+       };
+
+       reboot: syscon-reboot {
+               compatible = "syscon-reboot";
+               regmap = <&pmu_system_controller>;
+               offset = <0x0400>; /* SWRESET */
+               mask = <0x1>;
+       };
+
        fimd: fimd@14400000 {
                compatible = "samsung,exynos5250-fimd";
                interrupt-parent = <&combiner>;
index 0a7f408..5cb33ba 100644 (file)
 &mmc_0 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
-       card-detect-delay = <200>;
+       non-removable;
        samsung,dw-mshc-ciu-div = <3>;
        samsung,dw-mshc-sdr-timing = <2 3>;
        samsung,dw-mshc-ddr-timing = <1 2>;
 &mmc_3 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
+       non-removable;
        cap-sdio-irq;
        keep-power-in-suspend;
-       card-detect-delay = <200>;
        samsung,dw-mshc-ciu-div = <3>;
        samsung,dw-mshc-sdr-timing = <2 3>;
        samsung,dw-mshc-ddr-timing = <1 2>;
index 88b9cf5..33e2d5f 100644 (file)
                iommu-names = "left", "right";
        };
 
+       rotator: rotator@11C00000 {
+               compatible = "samsung,exynos5250-rotator";
+               reg = <0x11C00000 0x64>;
+               interrupts = <0 84 0>;
+               clocks = <&clock CLK_ROTATOR>;
+               clock-names = "rotator";
+               iommus = <&sysmmu_rotator>;
+       };
+
        tmu: tmu@10060000 {
                compatible = "samsung,exynos5250-tmu";
                reg = <0x10060000 0x100>;
index 731eefd..fad0779 100644 (file)
                        reg = <0x10040000 0x5000>;
                };
 
+               poweroff: syscon-poweroff {
+                       compatible = "syscon-poweroff";
+                       regmap = <&pmu_system_controller>;
+                       offset = <0x330C>; /* PS_HOLD_CONTROL */
+                       mask = <0x5200>; /* reset value */
+               };
+
+               reboot: syscon-reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&pmu_system_controller>;
+                       offset = <0x0400>; /* SWRESET */
+                       mask = <0x1>;
+               };
+
                mct: mct@101C0000 {
                        compatible = "samsung,exynos4210-mct";
                        reg = <0x101C0000 0xB00>;
index 72ba6f0..35cfb07 100644 (file)
 &mmc_0 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
        mmc-hs200-1_8v;
        cap-mmc-highspeed;
        non-removable;
-       card-detect-delay = <200>;
        clock-frequency = <400000000>;
        samsung,dw-mshc-ciu-div = <3>;
        samsung,dw-mshc-sdr-timing = <0 4>;
 &mmc_1 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
+       non-removable;
        cap-sdio-irq;
        keep-power-in-suspend;
-       card-detect-delay = <200>;
        clock-frequency = <400000000>;
        samsung,dw-mshc-ciu-div = <1>;
        samsung,dw-mshc-sdr-timing = <0 1>;
index 1b3d6c7..48a0a55 100644 (file)
                iommus = <&sysmmu_tv>;
        };
 
+       rotator: rotator@11C00000 {
+               compatible = "samsung,exynos5250-rotator";
+               reg = <0x11C00000 0x64>;
+               interrupts = <0 84 0>;
+               clocks = <&clock CLK_ROTATOR>;
+               clock-names = "rotator";
+               iommus = <&sysmmu_rotator>;
+       };
+
        gsc_0: video-scaler@13e00000 {
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e00000 0x1000>;
                #iommu-cells = <0>;
        };
 
+       sysmmu_rotator: sysmmu@0x11D40000 {
+               compatible = "samsung,exynos-sysmmu";
+               reg = <0x11D40000 0x1000>;
+               interrupt-parent = <&combiner>;
+               interrupts = <4 0>;
+               clock-names = "sysmmu", "master";
+               clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+               #iommu-cells = <0>;
+       };
+
        sysmmu_jpeg0: sysmmu@0x11F10000 {
                compatible = "samsung,exynos-sysmmu";
                reg = <0x11F10000 0x1000>;
index 1af5bdc..9134217 100644 (file)
                        <19200000>;
 };
 
-&fimd {
-       status = "okay";
-};
-
-
 &hdmi {
        status = "okay";
        hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
index b1b3608..2ae1cf4 100644 (file)
@@ -67,5 +67,5 @@
 };
 
 &usbdrd_dwc3_1 {
-       dr_mode = "otg";
+       dr_mode = "peripheral";
 };
index 0c0bbdb..432406d 100644 (file)
@@ -98,5 +98,5 @@
 };
 
 &usbdrd_dwc3_1 {
-       dr_mode = "otg";
+       dr_mode = "peripheral";
 };
index 1cc2e95..064176f 100644 (file)
 &mmc_0 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
        mmc-hs200-1_8v;
        mmc-hs400-1_8v;
        cap-mmc-highspeed;
        non-removable;
-       card-detect-delay = <200>;
        clock-frequency = <800000000>;
        samsung,dw-mshc-ciu-div = <3>;
        samsung,dw-mshc-sdr-timing = <0 4>;
 &mmc_1 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
+       non-removable;
        cap-sdio-irq;
        keep-power-in-suspend;
-       card-detect-delay = <200>;
        clock-frequency = <400000000>;
        samsung,dw-mshc-ciu-div = <1>;
        samsung,dw-mshc-sdr-timing = <0 1>;
index 7c4b9f2..848ffa7 100644 (file)
 #define MX25_PAD_CONTRAST__CC4                 0x118 0x310 0x000 0x11 0x000
 #define MX25_PAD_CONTRAST__PWM4_PWMO           0x118 0x310 0x000 0x14 0x000
 #define MX25_PAD_CONTRAST__FEC_CRS             0x118 0x310 0x508 0x15 0x001
+#define MX25_PAD_CONTRAST__USBH2_PWR           0x118 0x310 0x000 0x16 0x000
 
 #define MX25_PAD_PWM__PWM                      0x11c 0x314 0x000 0x10 0x000
 #define MX25_PAD_PWM__GPIO_1_26                        0x11c 0x314 0x000 0x15 0x000
 #define MX25_PAD_SD1_DATA3__GPIO_2_28          0x1a4 0x39c 0x000 0x15 0x000
 
 #define MX25_PAD_KPP_ROW0__KPP_ROW0            0x1a8 0x3a0 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW0__UART1_DTR           0x1a8 0x3a0 0x000 0x14 0x000
 #define MX25_PAD_KPP_ROW0__GPIO_2_29           0x1a8 0x3a0 0x000 0x15 0x000
 
 #define MX25_PAD_KPP_ROW1__KPP_ROW1            0x1ac 0x3a4 0x000 0x10 0x000
 
 #define MX25_PAD_KPP_ROW2__KPP_ROW2            0x1b0 0x3a8 0x000 0x10 0x000
 #define MX25_PAD_KPP_ROW2__CSI_D0              0x1b0 0x3a8 0x488 0x13 0x002
+#define MX25_PAD_KPP_ROW2__UART1_DCD           0x1b0 0x3a8 0x000 0x14 0x000
 #define MX25_PAD_KPP_ROW2__GPIO_2_31           0x1b0 0x3a8 0x000 0x15 0x000
 
 #define MX25_PAD_KPP_ROW3__KPP_ROW3            0x1b4 0x3ac 0x000 0x10 0x000
index 677f81d..cde329e 100644 (file)
                i2c2 = &i2c3;
                mmc0 = &esdhc1;
                mmc1 = &esdhc2;
+               pwm0 = &pwm1;
+               pwm1 = &pwm2;
+               pwm2 = &pwm3;
+               pwm3 = &pwm4;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
index 5df0b24..7a80bd6 100644 (file)
 
                        pwm: pwm@80064000 {
                                pinctrl-names = "default";
-                               pinctrl-0 = <&pwm3_pins_b>;
+                               pinctrl-0 = <&pwm4_pins_a>;
                                status = "okay";
                        };
 
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm 3 5000000>;
+               pwms = <&pwm 4 5000000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
        };
index c5b57d4..fae7b90 100644 (file)
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
+                               auart4_2pins_b: auart4@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART0_CTS__AUART4_RX
+                                               MX28_PAD_AUART0_RTS__AUART4_TX
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
                                mac0_pins_a: mac0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
diff --git a/arch/arm/boot/dts/imx51-ts4800.dts b/arch/arm/boot/dts/imx51-ts4800.dts
new file mode 100644 (file)
index 0000000..0ff76a1
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2015 Savoir-faire Linux
+ *
+ * This device tree is based on imx51-babbage.dts
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+/dts-v1/;
+#include "imx51.dtsi"
+
+/ {
+       model = "Technologic Systems TS-4800";
+       compatible = "technologic,imx51-ts4800", "fsl,imx51";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       memory {
+               reg = <0x90000000 0x10000000>;
+       };
+
+       clocks {
+               ckih1 {
+                       clock-frequency = <22579200>;
+               };
+
+               ckih2 {
+                       clock-frequency = <24576000>;
+               };
+       };
+
+       backlight_reg: regulator-backlight {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_enable_lcd>;
+               regulator-name = "enable_lcd_reg";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio4 9 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 78770>;
+               brightness-levels = <0 150 200 255>;
+               default-brightness-level = <1>;
+               power-supply = <&backlight_reg>;
+       };
+
+       display0: display@di0 {
+               compatible = "fsl,imx-parallel-display";
+               interface-pix-fmt = "rgb24";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_lcd>;
+
+               display-timings {
+                       800x480p60 {
+                               native-mode;
+                               clock-frequency = <30066000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hfront-porch = <50>;
+                               hback-porch = <70>;
+                               hsync-len = <50>;
+                               vback-porch = <0>;
+                               vfront-porch = <0>;
+                               vsync-len = <50>;
+                       };
+               };
+
+               port@0 {
+                       display0_in: endpoint {
+                               remote-endpoint = <&ipu_di0_disp0>;
+                       };
+               };
+       };
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "mii";
+       phy-reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <1>;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       rtc: m41t00@68 {
+               compatible = "stm,m41t00";
+               reg = <0x68>;
+       };
+};
+
+&ipu_di0_disp0 {
+       remote-endpoint = <&display0_in>;
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm_backlight>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&weim {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_weim>;
+       status = "okay";
+
+       fpga@0 {
+               compatible = "simple-bus";
+               fsl,weim-cs-timing = <0x0061008F 0x00000002 0x1c022000
+                                     0x00000000 0x1c092480 0x00000000>;
+               reg = <0 0x0000000 0x1d000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0 0 0x1d000>;
+
+               syscon: syscon@b0010000 {
+                       compatible = "syscon", "simple-mfd";
+                       reg = <0x10000 0x3d>;
+                       reg-io-width = <2>;
+
+                       wdt@e {
+                               compatible = "technologic,ts4800-wdt";
+                               syscon = <&syscon 0xe>;
+                       };
+               };
+
+               touchscreen {
+                       compatible = "technologic,ts4800-ts";
+                       reg = <0x12000 0x1000>;
+                       syscon = <&syscon 0x10 6>;
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX51_PAD_CSPI1_MISO__ECSPI1_MISO        0x185
+                       MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI        0x185
+                       MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK        0x185
+                       MX51_PAD_CSPI1_SS0__GPIO4_24            0x85 /* CS0 */
+               >;
+       };
+
+       pinctrl_enable_lcd: enablelcdgrp {
+               fsl,pins = <
+                       MX51_PAD_CSI2_D12__GPIO4_9              0x1c5
+               >;
+       };
+
+       pinctrl_esdhc1: esdhc1grp {
+               fsl,pins = <
+                       MX51_PAD_SD1_CMD__SD1_CMD               0x400020d5
+                       MX51_PAD_SD1_CLK__SD1_CLK               0x20d5
+                       MX51_PAD_SD1_DATA0__SD1_DATA0           0x20d5
+                       MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
+                       MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
+                       MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       MX51_PAD_GPIO1_0__GPIO1_0               0x100
+                       MX51_PAD_GPIO1_1__GPIO1_1               0x100
+               >;
+       };
+
+       pinctrl_fec: fecgrp {
+               fsl,pins = <
+                       MX51_PAD_EIM_EB2__FEC_MDIO              0x000001f5
+                       MX51_PAD_EIM_EB3__FEC_RDATA1            0x00000085
+                       MX51_PAD_EIM_CS2__FEC_RDATA2            0x00000085
+                       MX51_PAD_EIM_CS3__FEC_RDATA3            0x00000085
+                       MX51_PAD_EIM_CS4__FEC_RX_ER             0x00000180
+                       MX51_PAD_EIM_CS5__FEC_CRS               0x00000180
+                       MX51_PAD_DISP2_DAT10__FEC_COL           0x00000180
+                       MX51_PAD_DISP2_DAT11__FEC_RX_CLK        0x00000180
+                       MX51_PAD_DISP2_DAT14__FEC_RDATA0        0x00002180
+                       MX51_PAD_DISP2_DAT15__FEC_TDATA0        0x00002004
+                       MX51_PAD_NANDF_CS2__FEC_TX_ER           0x00002004
+                       MX51_PAD_DI2_PIN2__FEC_MDC              0x00002004
+                       MX51_PAD_DISP2_DAT6__FEC_TDATA1         0x00002004
+                       MX51_PAD_DISP2_DAT7__FEC_TDATA2         0x00002004
+                       MX51_PAD_DISP2_DAT8__FEC_TDATA3         0x00002004
+                       MX51_PAD_DISP2_DAT9__FEC_TX_EN          0x00002004
+                       MX51_PAD_DISP2_DAT13__FEC_TX_CLK        0x00002180
+                       MX51_PAD_DISP2_DAT12__FEC_RX_DV         0x000020a4
+                       MX51_PAD_EIM_A20__GPIO2_14              0x00000085 /* Phy Reset */
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX51_PAD_KEY_COL4__I2C2_SCL             0x400001ed
+                       MX51_PAD_KEY_COL5__I2C2_SDA             0x400001ed
+               >;
+       };
+
+       pinctrl_lcd: lcdgrp {
+               fsl,pins = <
+                       MX51_PAD_DISP1_DAT0__DISP1_DAT0         0x5
+                       MX51_PAD_DISP1_DAT1__DISP1_DAT1         0x5
+                       MX51_PAD_DISP1_DAT2__DISP1_DAT2         0x5
+                       MX51_PAD_DISP1_DAT3__DISP1_DAT3         0x5
+                       MX51_PAD_DISP1_DAT4__DISP1_DAT4         0x5
+                       MX51_PAD_DISP1_DAT5__DISP1_DAT5         0x5
+                       MX51_PAD_DISP1_DAT6__DISP1_DAT6         0x5
+                       MX51_PAD_DISP1_DAT7__DISP1_DAT7         0x5
+                       MX51_PAD_DISP1_DAT8__DISP1_DAT8         0x5
+                       MX51_PAD_DISP1_DAT9__DISP1_DAT9         0x5
+                       MX51_PAD_DISP1_DAT10__DISP1_DAT10       0x5
+                       MX51_PAD_DISP1_DAT11__DISP1_DAT11       0x5
+                       MX51_PAD_DISP1_DAT12__DISP1_DAT12       0x5
+                       MX51_PAD_DISP1_DAT13__DISP1_DAT13       0x5
+                       MX51_PAD_DISP1_DAT14__DISP1_DAT14       0x5
+                       MX51_PAD_DISP1_DAT15__DISP1_DAT15       0x5
+                       MX51_PAD_DISP1_DAT16__DISP1_DAT16       0x5
+                       MX51_PAD_DISP1_DAT17__DISP1_DAT17       0x5
+                       MX51_PAD_DISP1_DAT18__DISP1_DAT18       0x5
+                       MX51_PAD_DISP1_DAT19__DISP1_DAT19       0x5
+                       MX51_PAD_DISP1_DAT20__DISP1_DAT20       0x5
+                       MX51_PAD_DISP1_DAT21__DISP1_DAT21       0x5
+                       MX51_PAD_DISP1_DAT22__DISP1_DAT22       0x5
+                       MX51_PAD_DISP1_DAT23__DISP1_DAT23       0x5
+                       MX51_PAD_DI1_PIN2__DI1_PIN2             0x5
+                       MX51_PAD_DI1_PIN3__DI1_PIN3             0x5
+                       MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK     0x5
+                       MX51_PAD_DI_GP4__DI2_PIN15              0x5
+               >;
+       };
+
+       pinctrl_pwm_backlight: backlightgrp {
+               fsl,pins = <
+                       MX51_PAD_GPIO1_2__PWM1_PWMO             0x80000000
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX51_PAD_UART1_RXD__UART1_RXD           0x1c5
+                       MX51_PAD_UART1_TXD__UART1_TXD           0x1c5
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX51_PAD_UART2_RXD__UART2_RXD           0x1c5
+                       MX51_PAD_UART2_TXD__UART2_TXD           0x1c5
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX51_PAD_EIM_D25__UART3_RXD             0x1c5
+                       MX51_PAD_EIM_D26__UART3_TXD             0x1c5
+               >;
+       };
+
+       pinctrl_weim: weimgrp {
+               fsl,pins = <
+                       MX51_PAD_EIM_DTACK__EIM_DTACK           0x85
+                       MX51_PAD_EIM_CS0__EIM_CS0               0x0
+                       MX51_PAD_EIM_CS1__EIM_CS1               0x0
+                       MX51_PAD_EIM_EB0__EIM_EB0               0x85
+                       MX51_PAD_EIM_EB1__EIM_EB1               0x85
+                       MX51_PAD_EIM_OE__EIM_OE                 0x85
+                       MX51_PAD_EIM_LBA__EIM_LBA               0x85
+               >;
+       };
+};
index 4b0ec07..c13a73a 100644 (file)
                compatible = "fsl,imx-display-subsystem";
                ports = <&ipu1_di0>, <&ipu1_di1>;
        };
+
+       gpu-subsystem {
+               compatible = "fsl,imx-gpu-subsystem";
+               cores = <&gpu_2d>, <&gpu_3d>;
+       };
 };
 
 &gpt {
-       compatible = "fsl,imx6dl-gpt", "fsl,imx6q-gpt";
+       compatible = "fsl,imx6dl-gpt";
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/imx6q-novena.dts b/arch/arm/boot/dts/imx6q-novena.dts
new file mode 100644 (file)
index 0000000..5acd0c6
--- /dev/null
@@ -0,0 +1,785 @@
+/*
+ * Copyright 2015 Sutajio Ko-Usagi PTE LTD
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this file; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Kosagi Novena Dual/Quad";
+       compatible = "kosagi,imx6q-novena", "fsl,imx6q";
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 10000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_backlight_novena>;
+               power-supply = <&reg_lvds_lcd>;
+               brightness-levels = <0 3 6 12 16 24 32 48 64 96 128 192 255>;
+               default-brightness-level = <12>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys_novena>;
+
+               user-button {
+                       label = "User Button";
+                       gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+               };
+
+               lid {
+                       label = "Lid";
+                       gpios = <&gpio4 12 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <5>; /* EV_SW */
+                       linux,code = <0>;       /* SW_LID */
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_leds_novena>;
+
+               heartbeat {
+                       label = "novena:white:panel";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "default-on";
+               };
+       };
+
+       panel: panel {
+               compatible = "innolux,n133hse-ea1", "simple-panel";
+               backlight = <&backlight>;
+       };
+
+       reg_2p5v: regulator-2p5v {
+               compatible = "regulator-fixed";
+               regulator-name = "2P5V";
+               regulator-min-microvolt = <2500000>;
+               regulator-max-microvolt = <2500000>;
+               regulator-always-on;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_audio_codec: regulator-audio-codec {
+               compatible = "regulator-fixed";
+               regulator-name = "es8328-power";
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               startup-delay-us = <400000>;
+               gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_display: regulator-display {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-display-power";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <200000>;
+               gpio = <&gpio5 28 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_lvds_lcd: regulator-lvds-lcd {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-lvds-power";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_pcie: regulator-pcie {
+               compatible = "regulator-fixed";
+               regulator-name = "pcie-bus-power";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+               gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
+       reg_sata: regulator-sata {
+               compatible = "regulator-fixed";
+               regulator-name = "sata-power";
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <10000>;
+               gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_usb_otg_vbus: regulator-usb-otg-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+       };
+
+       sound {
+               compatible = "fsl,imx-audio-es8328";
+               model = "imx-audio-es8328";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-amp-supply = <&reg_audio_codec>;
+               jack-gpio = <&gpio5 15 GPIO_ACTIVE_HIGH>;
+               audio-routing =
+                       "Speaker", "LOUT2",
+                       "Speaker", "ROUT2",
+                       "Speaker", "audio-amp",
+                       "Headphone", "ROUT1",
+                       "Headphone", "LOUT1",
+                       "LINPUT1", "Mic Jack",
+                       "RINPUT1", "Mic Jack",
+                       "Mic Jack", "Mic Bias";
+               mux-int-port = <0x1>;
+               mux-ext-port = <0x3>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux_novena>;
+       status = "okay";
+};
+
+&ecspi3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3_novena>;
+       fsl,spi-num-chipselects = <3>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet_novena>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+       rxc-skew-ps = <3000>;
+       rxdv-skew-ps = <0>;
+       txc-skew-ps = <3000>;
+       txen-skew-ps = <0>;
+       rxd0-skew-ps = <0>;
+       rxd1-skew-ps = <0>;
+       rxd2-skew-ps = <0>;
+       rxd3-skew-ps = <0>;
+       txd0-skew-ps = <3000>;
+       txd1-skew-ps = <3000>;
+       txd2-skew-ps = <3000>;
+       txd3-skew-ps = <3000>;
+       status = "okay";
+};
+
+&hdmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hdmi_novena>;
+       ddc-i2c-bus = <&i2c2>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1_novena>;
+       status = "okay";
+
+       accel: mma8452@1c {
+               compatible = "fsl,mma8452";
+               reg = <0x1c>;
+       };
+
+       rtc: pcf8523@68 {
+               compatible = "nxp,pcf8523";
+               reg = <0x68>;
+       };
+
+       sbs_battery: bq20z75@0b {
+               compatible = "sbs,sbs-battery";
+               reg = <0x0b>;
+               sbs,i2c-retry-count = <50>;
+       };
+
+       touch: stmpe811@44 {
+               compatible = "st,stmpe811";
+               reg = <0x44>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               irq-gpio = <&gpio5 13 GPIO_ACTIVE_HIGH>;
+               id = <0>;
+               blocks = <0x5>;
+               irq-trigger = <0x1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_stmpe_novena>;
+               vio-supply = <&reg_3p3v>;
+               vcc-supply = <&reg_3p3v>;
+
+               stmpe_touchscreen {
+                       compatible = "st,stmpe-ts";
+                       st,sample-time = <4>;
+                       st,mod-12b = <1>;
+                       st,ref-sel = <0>;
+                       st,adc-freq = <1>;
+                       st,ave-ctrl = <1>;
+                       st,touch-det-delay = <2>;
+                       st,settling = <2>;
+                       st,fraction-z = <7>;
+                       st,i-drive = <1>;
+               };
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2_novena>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       reg_sw1a: sw1a {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       reg_sw1c: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       reg_sw2: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       reg_sw3a: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       reg_sw3b: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       reg_sw4: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       reg_swbst: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                               regulator-boot-on;
+                       };
+
+                       reg_snvs: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       reg_vref: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       reg_vgen1: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       reg_vgen2: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       reg_vgen3: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       reg_vgen4: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       reg_vgen5: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       reg_vgen6: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3_novena>;
+       status = "okay";
+
+       codec: es8328@11 {
+               compatible = "everest,es8328";
+               reg = <0x11>;
+               DVDD-supply = <&reg_audio_codec>;
+               AVDD-supply = <&reg_audio_codec>;
+               PVDD-supply = <&reg_audio_codec>;
+               HPVDD-supply = <&reg_audio_codec>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_sound_novena>;
+               clocks = <&clks IMX6QDL_CLK_CKO1>;
+               assigned-clocks = <&clks IMX6QDL_CLK_CKO>,
+                                 <&clks IMX6QDL_CLK_CKO1_SEL>,
+                                 <&clks IMX6QDL_CLK_PLL4_AUDIO>,
+                                 <&clks IMX6QDL_CLK_CKO1>;
+               assigned-clock-parents = <&clks IMX6QDL_CLK_CKO1>,
+                                        <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>,
+                                        <&clks IMX6QDL_CLK_OSC>,
+                                        <&clks IMX6QDL_CLK_CKO1_PODF>;
+               assigned-clock-rates = <0 0 722534400 22579200>;
+       };
+};
+
+&kpp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_kpp_novena>;
+       linux,keymap = <
+               MATRIX_KEY(1, 1, KEY_CONFIG)
+       >;
+       status = "okay";
+};
+
+&ldb {
+       fsl,dual-channel;
+       status = "okay";
+
+       lvds-channel@0 {
+               fsl,data-mapping = "jeida";
+               fsl,data-width = <24>;
+               fsl,panel = <&panel>;
+               status = "okay";
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie_novena>;
+       reset-gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&sata {
+       target-supply = <&reg_sata>;
+       fsl,transmit-level-mV = <1025>;
+       fsl,transmit-boost-mdB = <0>;
+       fsl,transmit-atten-16ths = <8>;
+       status = "okay";
+};
+
+&ssi1 {
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_novena>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3_novena>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4_novena>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       dr_mode = "otg";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg_novena>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_swbst>;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2_novena>;
+       cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3_novena>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_audmux_novena: audmuxgrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
+                       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
+                       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
+                       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
+               >;
+       };
+
+       pinctrl_backlight_novena: backlightgrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT8__PWM1_OUT         0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT10__GPIO5_IO28       0x1b0b1
+                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x1b0b1
+               >;
+       };
+
+       pinctrl_ecspi3_novena: ecspi3grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                       MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                       MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+               >;
+       };
+
+       pinctrl_enet_novena: enetgrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b020
+                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b028
+                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b028
+                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b028
+                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b028
+                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b028
+                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       /* Ethernet reset */
+                       MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x1b0b1
+               >;
+       };
+
+       pinctrl_fpga_gpio: fpgagpiogrp-novena {
+               fsl,pins = <
+                       /* FPGA power */
+                       MX6QDL_PAD_SD1_DAT1__GPIO1_IO17         0x1b0b1
+                       /* Reset */
+                       MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07      0x1b0b1
+                       /* FPGA GPIOs */
+                       MX6QDL_PAD_EIM_DA0__GPIO3_IO00          0x1b0b1
+                       MX6QDL_PAD_EIM_DA1__GPIO3_IO01          0x1b0b1
+                       MX6QDL_PAD_EIM_DA2__GPIO3_IO02          0x1b0b1
+                       MX6QDL_PAD_EIM_DA3__GPIO3_IO03          0x1b0b1
+                       MX6QDL_PAD_EIM_DA4__GPIO3_IO04          0x1b0b1
+                       MX6QDL_PAD_EIM_DA5__GPIO3_IO05          0x1b0b1
+                       MX6QDL_PAD_EIM_DA6__GPIO3_IO06          0x1b0b1
+                       MX6QDL_PAD_EIM_DA7__GPIO3_IO07          0x1b0b1
+                       MX6QDL_PAD_EIM_DA8__GPIO3_IO08          0x1b0b1
+                       MX6QDL_PAD_EIM_DA9__GPIO3_IO09          0x1b0b1
+                       MX6QDL_PAD_EIM_DA10__GPIO3_IO10         0x1b0b1
+                       MX6QDL_PAD_EIM_DA11__GPIO3_IO11         0x1b0b1
+                       MX6QDL_PAD_EIM_DA12__GPIO3_IO12         0x1b0b1
+                       MX6QDL_PAD_EIM_DA13__GPIO3_IO13         0x1b0b1
+                       MX6QDL_PAD_EIM_DA14__GPIO3_IO14         0x1b0b1
+                       MX6QDL_PAD_EIM_DA15__GPIO3_IO15         0x1b0b1
+                       MX6QDL_PAD_EIM_A16__GPIO2_IO22          0x1b0b1
+                       MX6QDL_PAD_EIM_A17__GPIO2_IO21          0x1b0b1
+                       MX6QDL_PAD_EIM_A18__GPIO2_IO20          0x1b0b1
+                       MX6QDL_PAD_EIM_CS0__GPIO2_IO23          0x1b0b1
+                       MX6QDL_PAD_EIM_CS1__GPIO2_IO24          0x1b0b1
+                       MX6QDL_PAD_EIM_LBA__GPIO2_IO27          0x1b0b1
+                       MX6QDL_PAD_EIM_OE__GPIO2_IO25           0x1b0b1
+                       MX6QDL_PAD_EIM_RW__GPIO2_IO26           0x1b0b1
+                       MX6QDL_PAD_EIM_WAIT__GPIO5_IO00         0x1b0b1
+                       MX6QDL_PAD_EIM_BCLK__GPIO6_IO31         0x1b0b1
+               >;
+       };
+
+       pinctrl_fpga_eim: fpgaeimgrp-novena {
+               fsl,pins = <
+                       /* FPGA power */
+                       MX6QDL_PAD_SD1_DAT1__GPIO1_IO17         0x1b0b1
+                       /* Reset */
+                       MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07      0x1b0b1
+                       /* FPGA GPIOs */
+                       MX6QDL_PAD_EIM_DA0__EIM_AD00            0xb0f1
+                       MX6QDL_PAD_EIM_DA1__EIM_AD01            0xb0f1
+                       MX6QDL_PAD_EIM_DA2__EIM_AD02            0xb0f1
+                       MX6QDL_PAD_EIM_DA3__EIM_AD03            0xb0f1
+                       MX6QDL_PAD_EIM_DA4__EIM_AD04            0xb0f1
+                       MX6QDL_PAD_EIM_DA5__EIM_AD05            0xb0f1
+                       MX6QDL_PAD_EIM_DA6__EIM_AD06            0xb0f1
+                       MX6QDL_PAD_EIM_DA7__EIM_AD07            0xb0f1
+                       MX6QDL_PAD_EIM_DA8__EIM_AD08            0xb0f1
+                       MX6QDL_PAD_EIM_DA9__EIM_AD09            0xb0f1
+                       MX6QDL_PAD_EIM_DA10__EIM_AD10           0xb0f1
+                       MX6QDL_PAD_EIM_DA11__EIM_AD11           0xb0f1
+                       MX6QDL_PAD_EIM_DA12__EIM_AD12           0xb0f1
+                       MX6QDL_PAD_EIM_DA13__EIM_AD13           0xb0f1
+                       MX6QDL_PAD_EIM_DA14__EIM_AD14           0xb0f1
+                       MX6QDL_PAD_EIM_DA15__EIM_AD15           0xb0f1
+                       MX6QDL_PAD_EIM_A16__EIM_ADDR16          0xb0f1
+                       MX6QDL_PAD_EIM_A17__EIM_ADDR17          0xb0f1
+                       MX6QDL_PAD_EIM_A18__EIM_ADDR18          0xb0f1
+                       MX6QDL_PAD_EIM_CS0__EIM_CS0_B           0xb0f1
+                       MX6QDL_PAD_EIM_CS1__EIM_CS1_B           0xb0f1
+                       MX6QDL_PAD_EIM_LBA__EIM_LBA_B           0xb0f1
+                       MX6QDL_PAD_EIM_OE__EIM_OE_B             0xb0f1
+                       MX6QDL_PAD_EIM_RW__EIM_RW               0xb0f1
+                       MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B         0xb0f1
+                       MX6QDL_PAD_EIM_BCLK__EIM_BCLK           0xb0f1
+               >;
+       };
+
+       pinctrl_gpio_keys_novena: gpiokeysgrp-novena {
+               fsl,pins = <
+                       /* User button */
+                       MX6QDL_PAD_KEY_COL4__GPIO4_IO14         0x1b0b0
+                       /* PCIe Wakeup */
+                       MX6QDL_PAD_EIM_D22__GPIO3_IO22          0x1f0e0
+                       /* Lid switch */
+                       MX6QDL_PAD_KEY_COL3__GPIO4_IO12         0x1b0b0
+               >;
+       };
+
+       pinctrl_hdmi_novena: hdmigrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE   0x1f8b0
+                       MX6QDL_PAD_EIM_A24__GPIO5_IO04          0x1b0b1
+               >;
+       };
+
+       pinctrl_i2c1_novena: i2c1grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c2_novena: i2c2grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_EB2__I2C2_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D16__I2C2_SDA            0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3_novena: i2c3grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D17__I2C3_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D18__I2C3_SDA            0x4001b8b1
+               >;
+       };
+
+       pinctrl_kpp_novena: kppgrp-novena {
+               fsl,pins = <
+                       /* Front panel button */
+                       MX6QDL_PAD_KEY_ROW1__KEY_ROW1           0x1b0b1
+                       /* Fake column driver, not connected */
+                       MX6QDL_PAD_KEY_COL1__KEY_COL1           0x1b0b1
+               >;
+       };
+
+       pinctrl_leds_novena: ledsgrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT3__GPIO1_IO21         0x1b0b1
+               >;
+       };
+
+       pinctrl_pcie_novena: pciegrp-novena {
+               fsl,pins = <
+                       /* Reset */
+                       MX6QDL_PAD_EIM_D29__GPIO3_IO29          0x1b0b1
+                       /* Power On */
+                       MX6QDL_PAD_GPIO_17__GPIO7_IO12          0x1b0b1
+                       /* Wifi kill */
+                       MX6QDL_PAD_EIM_A22__GPIO2_IO16          0x1b0b1
+               >;
+       };
+
+       pinctrl_sata_novena: satagrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D30__GPIO3_IO30          0x1b0b1
+               >;
+       };
+
+       pinctrl_senoko_novena: senokogrp-novena {
+               fsl,pins = <
+                       /* Senoko IRQ line */
+                       MX6QDL_PAD_SD1_CLK__GPIO1_IO20          0x13048
+                       /* Senoko reset line */
+                       MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21       0x1b0b1
+               >;
+       };
+
+       pinctrl_sound_novena: soundgrp-novena {
+               fsl,pins = <
+                       /* Audio power regulator */
+                       MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17      0x1b0b1
+                       /* Headphone plug */
+                       MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15      0x1b0b1
+                       MX6QDL_PAD_GPIO_0__CCM_CLKO1            0x000b0
+               >;
+       };
+
+       pinctrl_stmpe_novena: stmpegrp-novena {
+               fsl,pins = <
+                       /* Touchscreen interrupt */
+                       MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2_novena: uart2grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D26__UART2_TX_DATA       0x1b0b1
+                       MX6QDL_PAD_EIM_D27__UART2_RX_DATA       0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3_novena: uart3grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                       MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+               >;
+       };
+
+       pinctrl_uart4_novena: uart4grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg_novena: usbotggrp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID       0x17059
+               >;
+       };
+
+       pinctrl_usdhc2_novena: usdhc2grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_SD2_CMD__SD2_CMD             0x170f9
+                       MX6QDL_PAD_SD2_CLK__SD2_CLK             0x100f9
+                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x170f9
+                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x170f9
+                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x170f9
+                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x170f9
+                       /* Write protect */
+                       MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x1b0b1
+                       /* Card detect */
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x1b0b1
+               >;
+       };
+
+       pinctrl_usdhc3_novena: usdhc3grp-novena {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170f9
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x100f9
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170f9
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170f9
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170f9
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170f9
+               >;
+       };
+};
index 399103b..0d93c0e 100644 (file)
@@ -14,6 +14,7 @@
 
 / {
        aliases {
+               ipu1 = &ipu2;
                spi4 = &ecspi5;
        };
 
 
                        iomuxc: iomuxc@020e0000 {
                                compatible = "fsl,imx6q-iomuxc";
-
-                               ipu2 {
-                                       pinctrl_ipu2_1: ipu2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK 0x10
-                                                       MX6QDL_PAD_DI0_PIN15__IPU2_DI0_PIN15       0x10
-                                                       MX6QDL_PAD_DI0_PIN2__IPU2_DI0_PIN02        0x10
-                                                       MX6QDL_PAD_DI0_PIN3__IPU2_DI0_PIN03        0x10
-                                                       MX6QDL_PAD_DI0_PIN4__IPU2_DI0_PIN04        0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT0__IPU2_DISP0_DATA00   0x10
-                                                       MX6QDL_PAD_DISP0_DAT1__IPU2_DISP0_DATA01   0x10
-                                                       MX6QDL_PAD_DISP0_DAT2__IPU2_DISP0_DATA02   0x10
-                                                       MX6QDL_PAD_DISP0_DAT3__IPU2_DISP0_DATA03   0x10
-                                                       MX6QDL_PAD_DISP0_DAT4__IPU2_DISP0_DATA04   0x10
-                                                       MX6QDL_PAD_DISP0_DAT5__IPU2_DISP0_DATA05   0x10
-                                                       MX6QDL_PAD_DISP0_DAT6__IPU2_DISP0_DATA06   0x10
-                                                       MX6QDL_PAD_DISP0_DAT7__IPU2_DISP0_DATA07   0x10
-                                                       MX6QDL_PAD_DISP0_DAT8__IPU2_DISP0_DATA08   0x10
-                                                       MX6QDL_PAD_DISP0_DAT9__IPU2_DISP0_DATA09   0x10
-                                                       MX6QDL_PAD_DISP0_DAT10__IPU2_DISP0_DATA10  0x10
-                                                       MX6QDL_PAD_DISP0_DAT11__IPU2_DISP0_DATA11  0x10
-                                                       MX6QDL_PAD_DISP0_DAT12__IPU2_DISP0_DATA12  0x10
-                                                       MX6QDL_PAD_DISP0_DAT13__IPU2_DISP0_DATA13  0x10
-                                                       MX6QDL_PAD_DISP0_DAT14__IPU2_DISP0_DATA14  0x10
-                                                       MX6QDL_PAD_DISP0_DAT15__IPU2_DISP0_DATA15  0x10
-                                                       MX6QDL_PAD_DISP0_DAT16__IPU2_DISP0_DATA16  0x10
-                                                       MX6QDL_PAD_DISP0_DAT17__IPU2_DISP0_DATA17  0x10
-                                                       MX6QDL_PAD_DISP0_DAT18__IPU2_DISP0_DATA18  0x10
-                                                       MX6QDL_PAD_DISP0_DAT19__IPU2_DISP0_DATA19  0x10
-                                                       MX6QDL_PAD_DISP0_DAT20__IPU2_DISP0_DATA20  0x10
-                                                       MX6QDL_PAD_DISP0_DAT21__IPU2_DISP0_DATA21  0x10
-                                                       MX6QDL_PAD_DISP0_DAT22__IPU2_DISP0_DATA22  0x10
-                                                       MX6QDL_PAD_DISP0_DAT23__IPU2_DISP0_DATA23  0x10
-                                               >;
-                                       };
-                               };
                        };
                };
 
                        status = "disabled";
                };
 
+               gpu_vg: gpu@02204000 {
+                       compatible = "vivante,gc";
+                       reg = <0x02204000 0x4000>;
+                       interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks IMX6QDL_CLK_OPENVG_AXI>,
+                                <&clks IMX6QDL_CLK_GPU2D_CORE>;
+                       clock-names = "bus", "core";
+                       power-domains = <&gpc 1>;
+               };
+
                ipu2: ipu@02800000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                compatible = "fsl,imx-display-subsystem";
                ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;
        };
+
+       gpu-subsystem {
+               compatible = "fsl,imx-gpu-subsystem";
+               cores = <&gpu_2d>, <&gpu_3d>, <&gpu_vg>;
+       };
 };
 
 &hdmi {
index dc0cebf..5cd16f2 100644 (file)
        status = "okay";
 };
 
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>; /* MX6_DIO3 */
+       status = "disabled";
+};
+
 &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1>;
                        >;
                };
 
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm4: pwm4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT2__PWM4_OUT           0x1b0b1
+                       >;
+               };
+
                pinctrl_uart1: uart1grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
index 18cd411..9fa8a10 100644 (file)
        status = "okay";
 };
 
+&clks {
+       assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+       assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+                         <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
+&ecspi3 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3>;
+       status = "okay";
+};
+
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
        status = "okay";
 };
 
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
 &pwm4 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
                        >;
                };
 
+               pinctrl_ecspi3: escpi3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+                               MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                               MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                               MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24       0x100b1
+                       >;
+               };
+
                pinctrl_enet: enetgrp {
                        fsl,pins = <
                                MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
                        >;
                };
 
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
                pinctrl_pwm4: pwm4grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD1_CMD__PWM4_OUT            0x1b0b1
index eea90f3..e8375e1 100644 (file)
        status = "okay";
 };
 
+&clks {
+       assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+       assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+                         <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
 &ldb {
        status = "okay";
 
-       lvds-channel@1 {
+       lvds-channel@0 {
                fsl,data-mapping = "spwg";
                fsl,data-width = <18>;
                status = "okay";
        };
 };
 
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
 &pwm4 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
                        >;
                };
 
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
                pinctrl_pwm4: pwm4grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD1_CMD__PWM4_OUT            0x1b0b1
index 6c11a2a..66983dc 100644 (file)
        status = "okay";
 };
 
+&clks {
+       assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+       assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+                         <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
                        swbst_reg: swbst {
                                regulator-min-microvolt = <5000000>;
                                regulator-max-microvolt = <5150000>;
+                               regulator-boot-on;
+                               regulator-always-on;
                        };
 
                        snvs_reg: vsnvs {
 &ldb {
        status = "okay";
 
-       lvds-channel@1 {
+       lvds-channel@0 {
                fsl,data-mapping = "spwg";
                fsl,data-width = <18>;
                status = "okay";
        };
 };
 
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>; /* MX6_DIO0 */
+       status = "disabled";
+};
+
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
 &pwm4 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
                        >;
                };
 
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_9__PWM1_OUT             0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
                pinctrl_pwm4: pwm4grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD1_CMD__PWM4_OUT            0x1b0b1
index 741f3d5..118bea5 100644 (file)
        status = "okay";
 };
 
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
 &ssi1 {
        status = "okay";
 };
                        >;
                };
 
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
                pinctrl_uart2: uart2grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
index d1e5048..cca39f1 100644 (file)
        status = "okay";
 };
 
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
 &uart2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart2>;
                        >;
                };
 
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
                pinctrl_uart2: uart2grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
index 2b6cc8b..4f6ae92 100644 (file)
@@ -30,6 +30,7 @@
                i2c0 = &i2c1;
                i2c1 = &i2c2;
                i2c2 = &i2c3;
+               ipu0 = &ipu1;
                mmc0 = &usdhc1;
                mmc1 = &usdhc2;
                mmc2 = &usdhc3;
                usbphy1 = &usbphy2;
        };
 
-       intc: interrupt-controller@00a01000 {
-               compatible = "arm,cortex-a9-gic";
-               #interrupt-cells = <3>;
-               interrupt-controller;
-               reg = <0x00a01000 0x1000>,
-                     <0x00a00100 0x100>;
-               interrupt-parent = <&intc>;
-       };
-
        clocks {
                #address-cells = <1>;
                #size-cells = <0>;
                        };
                };
 
+               gpu_3d: gpu@00130000 {
+                       compatible = "vivante,gc";
+                       reg = <0x00130000 0x4000>;
+                       interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks IMX6QDL_CLK_GPU3D_AXI>,
+                                <&clks IMX6QDL_CLK_GPU3D_CORE>,
+                                <&clks IMX6QDL_CLK_GPU3D_SHADER>;
+                       clock-names = "bus", "core", "shader";
+                       power-domains = <&gpc 1>;
+               };
+
+               gpu_2d: gpu@00134000 {
+                       compatible = "vivante,gc";
+                       reg = <0x00134000 0x4000>;
+                       interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks IMX6QDL_CLK_GPU2D_AXI>,
+                                <&clks IMX6QDL_CLK_GPU2D_CORE>;
+                       clock-names = "bus", "core";
+                       power-domains = <&gpc 1>;
+               };
+
                timer@00a00600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0x00a00600 0x20>;
                        clocks = <&clks IMX6QDL_CLK_TWD>;
                };
 
+               intc: interrupt-controller@00a01000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x00a01000 0x1000>,
+                             <0x00a00100 0x100>;
+                       interrupt-parent = <&intc>;
+               };
+
                L2: l2-cache@00a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
                        #address-cells = <3>;
                        #size-cells = <2>;
                        device_type = "pci";
-                       ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000 /* configuration space */
-                                 0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
+                       ranges = <0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
                                  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
                        num-lanes = <1>;
                        interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
                                                      "rxtx1", "rxtx2",
                                                      "rxtx3", "rxtx4",
                                                      "rxtx5", "rxtx6",
-                                                     "rxtx7", "dma";
+                                                     "rxtx7", "spba";
                                        status = "disabled";
                                };
 
                                                 <&clks IMX6QDL_CLK_ESAI_EXTAL>,
                                                 <&clks IMX6QDL_CLK_ESAI_IPG>,
                                                 <&clks IMX6QDL_CLK_SPBA>;
-                                       clock-names = "core", "mem", "extal", "fsys", "dma";
+                                       clock-names = "core", "mem", "extal", "fsys", "spba";
                                        dmas = <&sdma 23 21 0>, <&sdma 24 21 0>;
                                        dma-names = "rx", "tx";
                                        status = "disabled";
                                                "asrck_1", "asrck_2", "asrck_3", "asrck_4",
                                                "asrck_5", "asrck_6", "asrck_7", "asrck_8",
                                                "asrck_9", "asrck_a", "asrck_b", "asrck_c",
-                                               "asrck_d", "asrck_e", "asrck_f", "dma";
+                                               "asrck_d", "asrck_e", "asrck_f", "spba";
                                        dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
                                                <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
                                        dma-names = "rxa", "rxb", "rxc",
                                clocks = <&clks IMX6QDL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
                                dr_mode = "host";
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                clocks = <&clks IMX6QDL_CLK_USBOH3>;
                                fsl,usbmisc = <&usbmisc 2>;
                                dr_mode = "host";
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                clocks = <&clks IMX6QDL_CLK_USBOH3>;
                                fsl,usbmisc = <&usbmisc 3>;
                                dr_mode = "host";
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
index d8ba99f..d12b250 100644 (file)
                                                "rxtx1", "rxtx2",
                                                "rxtx3", "rxtx4",
                                                "rxtx5", "rxtx6",
-                                               "rxtx7", "dma";
+                                               "rxtx7", "spba";
                                        status = "disabled";
                                };
 
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbmisc = <&usbmisc 2>;
                                dr_mode = "host";
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
index 167f77b..a5f7602 100644 (file)
                                                      "rxtx1", "rxtx2",
                                                      "rxtx3", "rxtx4",
                                                      "rxtx5", "rxtx6",
-                                                     "rxtx7", "dma";
+                                                     "rxtx7", "spba";
                                        status = "disabled";
                                };
 
                                                 <&clks IMX6SX_CLK_ESAI_IPG>,
                                                 <&clks IMX6SX_CLK_SPBA>;
                                        clock-names = "core", "mem", "extal",
-                                                     "fsys", "dma";
+                                                     "fsys", "spba";
                                        status = "disabled";
                                };
 
                                                 <&clks IMX6SX_CLK_ASRC_IPG>,
                                                 <&clks IMX6SX_CLK_SPDIF>,
                                                 <&clks IMX6SX_CLK_SPBA>;
-                                       clock-names = "mem", "ipg", "asrck", "dma";
+                                       clock-names = "mem", "ipg", "asrck", "spba";
                                        dmas = <&sdma 17 20 1>, <&sdma 18 20 1>,
                                               <&sdma 19 20 1>, <&sdma 20 20 1>,
                                               <&sdma 21 20 1>, <&sdma 22 20 1>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
                                fsl,anatop = <&anatop>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                clocks = <&clks IMX6SX_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                phy_type = "hsic";
                                fsl,anatop = <&anatop>;
                                dr_mode = "host";
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SX_CLK_IPG>;
                                clock-names = "adc";
+                               fsl,adck-max-frequency = <30000000>, <40000000>,
+                                                        <20000000>;
                                status = "disabled";
                         };
 
                                interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SX_CLK_IPG>;
                                clock-names = "adc";
+                               fsl,adck-max-frequency = <30000000>, <40000000>,
+                                                        <20000000>;
                                status = "disabled";
                         };
 
index d00e994..99b6465 100644 (file)
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
                                fsl,anatop = <&anatop>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                clocks = <&clks IMX6UL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
                                status = "disabled";
                        };
 
                                status = "disabled";
                        };
 
+                       adc1: adc@02198000 {
+                               compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";
+                               reg = <0x02198000 0x4000>;
+                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_ADC1>;
+                               num-channels = <2>;
+                               clock-names = "adc";
+                               fsl,adck-max-frequency = <30000000>, <40000000>,
+                                                        <20000000>;
+                               status = "disabled";
+                       };
+
                        i2c1: i2c@021a0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
new file mode 100644 (file)
index 0000000..4863451
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Support for CompuLab CL-SOM-iMX7 System-on-Module
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Ilya Ledvich <ilya@compulab.co.il>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "imx7d.dtsi"
+
+/ {
+       model = "CompuLab CL-SOM-iMX7";
+       compatible = "compulab,cl-som-imx7", "fsl,imx7d";
+
+       memory {
+               reg = <0x80000000 0x10000000>; /* 256 MB - minimal configuration */
+       };
+
+       reg_usb_otg1_vbus: regulator-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg1_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&cpu0 {
+       arm-supply = <&sw1a_reg>;
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1>;
+       assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+                         <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+       assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+       assigned-clock-rates = <0>, <100000000>;
+       phy-mode = "rgmii";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       reg = <0>;
+               };
+
+               ethphy1: ethernet-phy@1 {
+                       reg = <1>;
+               };
+       };
+};
+
+&fec2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet2>;
+       assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+                         <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
+       assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+       assigned-clock-rates = <0>, <100000000>;
+       phy-mode = "rgmii";
+       phy-handle = <&ethphy1>;
+       fsl,magic-packet;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: pmic@8 {
+               compatible = "fsl,pfuze3000";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1a {
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1475000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       /* use sw1c_reg to align with pfuze100/pfuze200 */
+                       sw1c_reg: sw1b {
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1475000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3 {
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1650000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vldo1 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen2_reg: vldo2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vccsd {
+                               regulator-min-microvolt = <2850000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen4_reg: v33 {
+                               regulator-min-microvolt = <2850000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vldo3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vldo4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       pca9555: pca9555@20 {
+               compatible = "nxp,pca9555";
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0x20>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c08";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
+       assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
+       vbus-supply = <&reg_usb_otg1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+       assigned-clock-rates = <400000000>;
+       bus-width = <8>;
+       fsl,tuning-step = <2>;
+       non-removable;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       MX7D_PAD_SD2_CD_B__ENET1_MDIO                   0x3
+                       MX7D_PAD_SD2_WP__ENET1_MDC                      0x3
+                       MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC       0x1
+                       MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0       0x1
+                       MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1       0x1
+                       MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2       0x1
+                       MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3       0x1
+                       MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1
+                       MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC       0x1
+                       MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0       0x1
+                       MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1       0x1
+                       MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2       0x1
+                       MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3       0x1
+                       MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1
+               >;
+       };
+
+       pinctrl_enet2: enet2grp {
+               fsl,pins = <
+                       MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC             0x1
+                       MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0            0x1
+                       MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1            0x1
+                       MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2            0x1
+                       MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3             0x1
+                       MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL          0x1
+                       MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC            0x1
+                       MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0            0x1
+                       MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1             0x1
+                       MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2             0x1
+                       MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3            0x1
+                       MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL         0x1
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX7D_PAD_I2C2_SDA__I2C2_SDA             0x4000007f
+                       MX7D_PAD_I2C2_SCL__I2C2_SCL             0x4000007f
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX    0x79
+                       MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX    0x79
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1grp {
+               fsl,pins = <
+                       MX7D_PAD_GPIO1_IO05__GPIO1_IO5          0x14 /* OTG PWREN */
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX7D_PAD_SD3_CMD__SD3_CMD               0x59
+                       MX7D_PAD_SD3_CLK__SD3_CLK               0x19
+                       MX7D_PAD_SD3_DATA0__SD3_DATA0           0x59
+                       MX7D_PAD_SD3_DATA1__SD3_DATA1           0x59
+                       MX7D_PAD_SD3_DATA2__SD3_DATA2           0x59
+                       MX7D_PAD_SD3_DATA3__SD3_DATA3           0x59
+                       MX7D_PAD_SD3_DATA4__SD3_DATA4           0x59
+                       MX7D_PAD_SD3_DATA5__SD3_DATA5           0x59
+                       MX7D_PAD_SD3_DATA6__SD3_DATA6           0x59
+                       MX7D_PAD_SD3_DATA7__SD3_DATA7           0x59
+                       MX7D_PAD_SD3_STROBE__SD3_STROBE         0x19
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx7d-sbc-imx7.dts b/arch/arm/boot/dts/imx7d-sbc-imx7.dts
new file mode 100644 (file)
index 0000000..d63c597
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Support for CompuLab SBC-iMX7 Single Board Computer
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Ilya Ledvich <ilya@compulab.co.il>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ */
+
+#include "imx7d-cl-som-imx7.dts"
+
+/ {
+       model = "CompuLab SBC-iMX7";
+       compatible = "compulab,sbc-imx7", "compulab,cl-som-imx7", "fsl,imx7d";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+       enable-sdio-wakeup;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX7D_PAD_SD1_CMD__SD1_CMD               0x59
+                       MX7D_PAD_SD1_CLK__SD1_CLK               0x19
+                       MX7D_PAD_SD1_DATA0__SD1_DATA0           0x59
+                       MX7D_PAD_SD1_DATA1__SD1_DATA1           0x59
+                       MX7D_PAD_SD1_DATA2__SD1_DATA2           0x59
+                       MX7D_PAD_SD1_DATA3__SD1_DATA3           0x59
+                       MX7D_PAD_SD1_CD_B__GPIO5_IO0            0x59 /* CD */
+                       MX7D_PAD_SD1_WP__GPIO5_IO1              0x59 /* WP */
+               >;
+       };
+};
index 432aaf5..b2c4536 100644 (file)
        };
 };
 
+&adc1 {
+       vref-supply = <&reg_vref_1v8>;
+       status = "okay";
+};
+
+&adc2 {
+       vref-supply = <&reg_vref_1v8>;
+       status = "okay";
+};
+
 &cpu0 {
        arm-supply = <&sw1a_reg>;
 };
index ebc053a..25ad309 100644 (file)
@@ -85,9 +85,7 @@
                                792000  975000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
-                       clocks = <&clks IMX7D_ARM_A7_ROOT_CLK>, <&clks IMX7D_ARM_A7_ROOT_SRC>,
-                                <&clks IMX7D_PLL_ARM_MAIN_CLK>, <&clks IMX7D_PLL_SYS_MAIN_CLK>;
-                       clock-names = "arm", "arm_root_src", "pll_arm", "pll_sys_main";
+                       clocks = <&clks IMX7D_CLK_ARM>;
                };
 
                cpu1: cpu@1 {
                        reg = <0x30400000 0x400000>;
                        ranges;
 
+                       adc1: adc@30610000 {
+                               compatible = "fsl,imx7d-adc";
+                               reg = <0x30610000 0x10000>;
+                               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX7D_ADC_ROOT_CLK>;
+                               clock-names = "adc";
+                               status = "disabled";
+                       };
+
+                       adc2: adc@30620000 {
+                               compatible = "fsl,imx7d-adc";
+                               reg = <0x30620000 0x10000>;
+                               interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX7D_ADC_ROOT_CLK>;
+                               clock-names = "adc";
+                               status = "disabled";
+                       };
+
                        pwm1: pwm@30660000 {
                                compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
                                reg = <0x30660000 0x10000>;
diff --git a/arch/arm/boot/dts/kirkwood-nsa325.dts b/arch/arm/boot/dts/kirkwood-nsa325.dts
new file mode 100644 (file)
index 0000000..bc4ec93
--- /dev/null
@@ -0,0 +1,238 @@
+/* Device tree file for the Zyxel NSA 325 NAS box.
+ *
+ * Copyright (c) 2015, Hans Ulli Kroll <ulli.kroll@googlemail.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.
+ *
+ * Based upon the board setup file created by Peter Schildmann
+ */
+
+/dts-v1/;
+
+#include "kirkwood-nsa3x0-common.dtsi"
+
+/ {
+       model = "ZyXEL NSA325";
+       compatible = "zyxel,nsa325", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       pcie@1,0 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pin-controller@10000 {
+                       pinctrl-names = "default";
+
+                       pmx_led_hdd2_green: pmx-led-hdd2-green {
+                               marvell,pins = "mpp12";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_hdd2_red: pmx-led-hdd2-red {
+                               marvell,pins = "mpp13";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_mcu_data: pmx-mcu-data {
+                               marvell,pins = "mpp14";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_usb_green: pmx-led-usb-green {
+                               marvell,pins = "mpp15";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_mcu_clk: pmx-mcu-clk {
+                               marvell,pins = "mpp16";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_mcu_act: pmx-mcu-act {
+                               marvell,pins = "mpp17";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_sys_green: pmx-led-sys-green {
+                               marvell,pins = "mpp28";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_sys_orange: pmx-led-sys-orange {
+                               marvell,pins = "mpp29";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_hdd1_green: pmx-led-hdd1-green {
+                               marvell,pins = "mpp41";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led_hdd1_red: pmx-led-hdd1-red {
+                               marvell,pins = "mpp42";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_htp: pmx-htp {
+                               marvell,pins = "mpp43";
+                               marvell,function = "gpio";
+                       };
+
+                       /*
+                        * Buzzer needs to be switched at around 1kHz so is
+                        * not compatible with the gpio-beeper driver.
+                        */
+                       pmx_buzzer: pmx-buzzer {
+                               marvell,pins = "mpp44";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_vid_b1: pmx-vid-b1 {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_power_resume_data: pmx-power-resume-data {
+                               marvell,pins = "mpp47";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_power_resume_clk: pmx-power-resume-clk {
+                               marvell,pins = "mpp49";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_pwr_sata1: pmx-pwr-sata1 {
+                               marvell,pins = "mpp47";
+                               marvell,function = "gpio";
+                       };
+               };
+
+               /* This board uses the pcf8563 RTC instead of the SoC RTC */
+               rtc@10300 {
+                       status = "disabled";
+               };
+
+               i2c@11000 {
+                       status = "okay";
+
+                       pcf8563: pcf8563@51 {
+                               compatible = "nxp,pcf8563";
+                               reg = <0x51>;
+                       };
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_pwr_sata1>;
+               pinctrl-names = "default";
+
+               usb0_power: regulator@1 {
+                       enable-active-high;
+               };
+
+               sata1_power: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "SATA1 Power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       enable-active-high;
+                       gpio = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_led_hdd2_green &pmx_led_hdd2_red
+                            &pmx_led_usb_green
+                            &pmx_led_sys_green &pmx_led_sys_orange
+                            &pmx_led_copy_green &pmx_led_copy_red
+                            &pmx_led_hdd1_green &pmx_led_hdd1_red>;
+               pinctrl-names = "default";
+
+               green-sys {
+                       label = "nsa325:green:sys";
+                       gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+               };
+               orange-sys {
+                       label = "nsa325:orange:sys";
+                       gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+               };
+               green-hdd1 {
+                       label = "nsa325:green:hdd1";
+                       gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+               };
+               red-hdd1 {
+                       label = "nsa325:red:hdd1";
+                       gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+               };
+               green-hdd2 {
+                       label = "nsa325:green:hdd2";
+                       gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+               };
+               red-hdd2 {
+                       label = "nsa325:red:hdd2";
+                       gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+               };
+               green-usb {
+                       label = "nsa325:green:usb";
+                       gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+               };
+               green-copy {
+                       label = "nsa325:green:copy";
+                       gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+               };
+               red-copy {
+                       label = "nsa325:red:copy";
+                       gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+               };
+
+       /* The following pins are currently not assigned to a driver,
+          some of them should be configured as inputs.
+       pinctrl-0 = <&pmx_mcu_data &pmx_mcu_clk &pmx_mcu_act
+                    &pmx_htp &pmx_vid_b1
+                    &pmx_power_resume_data &pmx_power_resume_clk>; */
+       };
+
+
+};
+
+&mdio {
+       status = "okay";
+       ethphy0: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
+
diff --git a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
new file mode 100644 (file)
index 0000000..1db6f2c
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * kirkwood-pogoplug-series-4.dts - Device tree file for PogoPlug Series 4
+ * inspired by the board files made by Kevin Mihelich for ArchLinux,
+ * and their DTS file.
+ *
+ * Copyright (C) 2015 Linus Walleij <linus.walleij@linaro.org>
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+#include <dt-bindings/input/linux-event-codes.h>
+
+/ {
+       model = "Cloud Engines PogoPlug Series 4";
+       compatible = "cloudengines,pogoplugv4", "marvell,kirkwood-88f6192",
+                    "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x08000000>;
+       };
+
+       chosen {
+               stdout-path = "uart0:115200n8";
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_button_eject>;
+               pinctrl-names = "default";
+
+               button@1 {
+                       debounce_interval = <50>;
+                       wakeup-source;
+                       linux,code = <KEY_EJECTCD>;
+                       label = "Eject Button";
+                       gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_led_green &pmx_led_red>;
+               pinctrl-names = "default";
+
+               health {
+                       label = "pogoplugv4:green:health";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+                       default-state = "on";
+               };
+               fault {
+                       label = "pogoplugv4:red:fault";
+                       gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&pinctrl {
+       pmx_sata0: pmx-sata0 {
+               marvell,pins = "mpp21";
+               marvell,function = "sata0";
+       };
+
+       pmx_sata1: pmx-sata1 {
+               marvell,pins = "mpp20";
+               marvell,function = "sata1";
+       };
+
+       pmx_sdio_cd: pmx-sdio-cd {
+               marvell,pins = "mpp27";
+               marvell,function = "gpio";
+       };
+
+       pmx_sdio_wp: pmx-sdio-wp {
+               marvell,pins = "mpp28";
+               marvell,function = "gpio";
+       };
+
+       pmx_button_eject: pmx-button-eject {
+               marvell,pins = "mpp29";
+               marvell,function = "gpio";
+       };
+
+       pmx_led_green: pmx-led-green {
+               marvell,pins = "mpp22";
+               marvell,function = "gpio";
+       };
+
+       pmx_led_red: pmx-led-red {
+               marvell,pins = "mpp24";
+               marvell,function = "gpio";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+/*
+ * This PCIE controller has a USB 3.0 XHCI controller at 1,0
+ */
+&pciec {
+       status = "okay";
+};
+
+&pcie0 {
+       status = "okay";
+};
+
+&sata {
+       status = "okay";
+       pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+       pinctrl-names = "default";
+       nr-ports = <1>;
+};
+
+&sdio {
+       status = "okay";
+       pinctrl-0 = <&pmx_sdio &pmx_sdio_cd &pmx_sdio_wp>;
+       pinctrl-names = "default";
+       cd-gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+};
+
+&nand {
+       /* 128 MiB of NAND flash */
+       chip-delay = <40>;
+       status = "okay";
+       partitions {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       label = "u-boot";
+                       reg = <0x00000000 0x200000>;
+                       read-only;
+               };
+
+               partition@200000 {
+                       label = "uImage";
+                       reg = <0x00200000 0x300000>;
+               };
+
+               partition@500000 {
+                       label = "uImage2";
+                       reg = <0x00500000 0x300000>;
+               };
+
+               partition@800000 {
+                       label = "failsafe";
+                       reg = <0x00800000 0x800000>;
+               };
+
+               partition@1000000 {
+                       label = "root";
+                       reg = <0x01000000 0x7000000>;
+               };
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
index 5b04300..fb13f18 100644 (file)
                        label = "sysboot2";
                        gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;     /* gpio2 */
                        linux,code = <BTN_0>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                sysboot5 {
                        label = "sysboot5";
                        gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;     /* gpio7 */
                        linux,code = <BTN_1>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                gpio1 {
                        label = "gpio1";
                        gpios = <&gpio6 21 GPIO_ACTIVE_LOW>;    /* gpio181 */
                        linux,code = <BTN_2>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                gpio2 {
                        label = "gpio2";
                        gpios = <&gpio6 18 GPIO_ACTIVE_LOW>;    /* gpio178 */
                        linux,code = <BTN_3>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "omap3logic";
+               ti,mcbsp = <&mcbsp2>;
+       };
+
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
        };
 };
 
+&vaux1 {
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+};
+
+&vaux4 {
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+};
+
+&mcbsp2 {
+       status = "okay";
+};
+
 &charger {
        ti,bb-uvolt = <3200000>;
        ti,bb-uamp = <150>;
        };
 };
 
+&vpll2 {
+       regulator-always-on;
+};
+
+&dss {
+       status = "ok";
+       vdds_dsi-supply = <&vpll2>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&dss_dpi_pins1>;
+       port {
+               dpi_out: endpoint {
+                       remote-endpoint = <&lcd_in>;
+                       data-lines = <16>;
+               };
+       };
+};
+
+/ {
+       aliases {
+               display0 = &lcd0;
+       };
+
+       lcd0: display@0 {
+               compatible = "panel-dpi";
+               label = "15";
+               status = "okay";
+               /* default-on; */
+               pinctrl-names = "default";
+               enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;    /* gpio155, lcd INI */
+
+               port {
+                       lcd_in: endpoint {
+                               remote-endpoint = <&dpi_out>;
+                       };
+               };
+
+               panel-timing {
+                       clock-frequency = <9000000>;
+                       hactive = <480>;
+                       vactive = <272>;
+                       hfront-porch = <3>;
+                       hback-porch = <2>;
+                       hsync-len = <42>;
+                       vback-porch = <3>;
+                       vfront-porch = <4>;
+                       vsync-len = <11>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+       };
+
+       bl: backlight {
+               compatible = "gpio-backlight";
+               pinctrl-names = "default";
+               pinctrl-0 = <&backlight_pins>;
+
+               gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>, /* gpio_56 */
+                       <&gpio5 26 GPIO_ACTIVE_HIGH>; /* gpio_154 */
+               default-on;
+       };
+};
+
 &mmc1 {
        interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>;
        pinctrl-names = "default";
                        OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT | MUX_MODE0)        /* sdmmc1_dat3.sdmmc1_dat3 */
                >;
        };
+
+       tsc2004_pins: pinmux_tsc2004_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE4)        /* mcbsp4_dr.gpio_153 */
+               >;
+       };
+
+       backlight_pins: pinmux_backlight_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20B8, PIN_OUTPUT | MUX_MODE4)       /* gpmc_ncs5.gpio_56 */
+                       OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE4)       /* mcbsp4_dx.gpio_154 */
+               >;
+       };
+
+       dss_dpi_pins1: pinmux_dss_dpi_pins1 {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+                       OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+                       OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+                       OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+
+                       OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+
+                       OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE3)   /* dss_data18.dss_data0 */
+                       OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE3)   /* dss_data19.dss_data1 */
+                       OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE3)   /* dss_data20.dss_data2 */
+                       OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE3)   /* dss_data21.dss_data3 */
+                       OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE3)   /* dss_data22.dss_data4 */
+                       OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3)   /* dss_data23.dss_data5 */
+               >;
+       };
 };
 
 &omap3_pmx_wkup {
        };
 };
 
+&i2c3 {
+       touchscreen: tsc2004@48 {
+               compatible = "ti,tsc2004";
+               reg = <0x48>;
+               vio-supply = <&vaux1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tsc2004_pins>;
+               interrupts-extended = <&gpio5 25 IRQ_TYPE_EDGE_RISING>; /* gpio 153 */
+
+               touchscreen-fuzz-x = <4>;
+               touchscreen-fuzz-y = <7>;
+               touchscreen-fuzz-pressure = <2>;
+               touchscreen-size-x = <4096>;
+               touchscreen-size-y = <4096>;
+               touchscreen-max-pressure = <2048>;
+
+               ti,x-plate-ohms = <280>;
+               ti,esd-recovery-timeout-ms = <8000>;
+       };
+};
+
 &uart1 {
        interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>;
 };
index 36387b1..7fed0bd 100644 (file)
                reg = <0x48>;
                interrupts = <7>; /* SYS_NIRQ cascaded to intc */
                interrupt-parent = <&intc>;
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
+                       };
+               };
        };
 };
 
+&i2c2 {
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+};
+
 /*
  * Only found on the wireless SOM. For the SOM without wireless, the pins for
  * MMC3 can be routed with jumpers to the second MMC slot on the devkit and
                        OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4)       /* mcbsp1_fsr.gpio_157 */
                >;
        };
+       mcbsp2_pins: pinmux_mcbsp2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0)        /* mcbsp2_fsx */
+                       OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0)        /* mcbsp2_clkx */
+                       OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0)        /* mcbsp2_dr */
+                       OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0)       /* mcbsp2_dx */
+               >;
+       };
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0)        /* uart2_cts.uart2_cts */
+                       OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0)       /* uart2_rts .uart2_rts*/
+                       OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0)       /* uart2_tx.uart2_tx */
+                       OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0)        /* uart2_rx.uart2_rx */
+                       OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4)       /* GPIO_162,BT_EN */
+               >;
+       };
+};
+
+&uart2 {
+       interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
 };
 
 &omap3_pmx_core2 {
index 52591d8..053a1f5 100644 (file)
                        status = "disabled";
                };
 
+               eeprom: eeprom@4000e000 {
+                       compatible = "nxp,lpc1857-eeprom";
+                       reg = <0x4000e000 0x1000>, <0x20040000 0x4000>;
+                       reg-names = "reg", "mem";
+                       clocks = <&ccu1 CLK_CPU_EEPROM>;
+                       clock-names = "eeprom";
+                       resets = <&rgu 27>;
+                       interrupts = <4>;
+                       status = "disabled";
+               };
+
                mac: ethernet@40010000 {
                        compatible = "nxp,lpc1850-dwmac", "snps,dwmac-3.611", "snps,dwmac";
                        reg = <0x40010000 0x2000>;
index 3abebb7..c85cf97 100644 (file)
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
        compatible = "nxp,lpc3220";
        interrupt-parent = <&mic>;
 
        cpus {
-               #address-cells = <0>;
+               #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu {
+               cpu@0 {
                        compatible = "arm,arm926ej-s";
                        device_type = "cpu";
+                       reg = <0x0>;
                };
        };
 
@@ -31,7 +32,8 @@
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "simple-bus";
-               ranges = <0x20000000 0x20000000 0x30000000>;
+               ranges = <0x20000000 0x20000000 0x30000000>,
+                        <0xe0000000 0xe0000000 0x04000000>;
 
                /*
                 * Enable either SLC or MLC
                        status = "disabled";
                };
 
-               dma@31000000 {
+               dma: dma@31000000 {
                        compatible = "arm,pl080", "arm,primecell";
                        reg = <0x31000000 0x1000>;
                        interrupts = <0x1c 0>;
                };
 
-               /*
-                * Enable either ohci or usbd (gadget)!
-                */
-               ohci@31020000 {
-                       compatible = "nxp,ohci-nxp", "usb-ohci";
-                       reg = <0x31020000 0x300>;
-                       interrupts = <0x3b 0>;
-                       status = "disabled";
-               };
+               usb {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0x0 0x31020000 0x00001000>;
 
-               usbd@31020000 {
-                       compatible = "nxp,lpc3220-udc";
-                       reg = <0x31020000 0x300>;
-                       interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
-                       status = "disabled";
+                       /*
+                        * Enable either ohci or usbd (gadget)!
+                        */
+                       ohci: ohci@0 {
+                               compatible = "nxp,ohci-nxp", "usb-ohci";
+                               reg = <0x0 0x300>;
+                               interrupts = <0x3b 0>;
+                               status = "disabled";
+                       };
+
+                       usbd: usbd@0 {
+                               compatible = "nxp,lpc3220-udc";
+                               reg = <0x0 0x300>;
+                               interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+                               status = "disabled";
+                       };
+
+                       i2cusb: i2c@300 {
+                               compatible = "nxp,pnx-i2c";
+                               reg = <0x300 0x100>;
+                               interrupts = <0x3f 0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               pnx,timeout = <0x64>;
+                       };
                };
 
-               clcd@31040000 {
+               clcd: clcd@31040000 {
                        compatible = "arm,pl110", "arm,primecell";
                        reg = <0x31040000 0x1000>;
                        interrupts = <0x0e 0>;
                        interrupts = <0x1d 0>;
                };
 
+               emc: memory-controller@31080000 {
+                       compatible = "arm,pl175", "arm,primecell";
+                       reg = <0x31080000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ranges = <0 0xe0000000 0x01000000>,
+                                <1 0xe1000000 0x01000000>,
+                                <2 0xe2000000 0x01000000>,
+                                <3 0xe3000000 0x01000000>;
+                       status = "disabled";
+               };
+
                apb {
                        #address-cells = <1>;
                        #size-cells = <1>;
                                reg = <0x20094000 0x1000>;
                        };
 
-                       sd@20098000 {
+                       sd: sd@20098000 {
                                compatible = "arm,pl18x", "arm,primecell";
                                reg = <0x20098000 0x1000>;
                                interrupts = <0x0f 0>, <0x0d 0>;
                                status = "disabled";
                                #pwm-cells = <2>;
                        };
-
-                       i2cusb: i2c@31020300 {
-                               compatible = "nxp,pnx-i2c";
-                               reg = <0x31020300 0x100>;
-                               interrupts = <0x3f 0>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               pnx,timeout = <0x64>;
-                       };
                };
 
                fab {
                                status = "disabled";
                        };
 
-                       rtc@40024000 {
+                       rtc: rtc@40024000 {
                                compatible = "nxp,lpc3220-rtc";
                                reg = <0x40024000 0x1000>;
                                interrupts = <0x34 0>;
                                #gpio-cells = <3>; /* bank, pin, flags */
                        };
 
-                       watchdog@4003C000 {
+                       timer4: timer@4002C000 {
+                               compatible = "nxp,lpc3220-timer";
+                               reg = <0x4002C000 0x1000>;
+                               interrupts = <0x3 0>;
+                               status = "disabled";
+                       };
+
+                       timer5: timer@40030000 {
+                               compatible = "nxp,lpc3220-timer";
+                               reg = <0x40030000 0x1000>;
+                               interrupts = <0x4 0>;
+                               status = "disabled";
+                       };
+
+                       watchdog: watchdog@4003C000 {
                                compatible = "nxp,pnx4008-wdt";
                                reg = <0x4003C000 0x1000>;
                        };
 
+                       timer0: timer@40044000 {
+                               compatible = "nxp,lpc3220-timer";
+                               reg = <0x40044000 0x1000>;
+                               interrupts = <0x10 0>;
+                       };
+
                        /*
                         * TSC vs. ADC: Since those two share the same
                         * hardware, you need to choose from one of the
                         * them
                         */
 
-                       adc@40048000 {
+                       adc: adc@40048000 {
                                compatible = "nxp,lpc3220-adc";
                                reg = <0x40048000 0x1000>;
                                interrupts = <0x27 0>;
                                status = "disabled";
                        };
 
-                       tsc@40048000 {
+                       tsc: tsc@40048000 {
                                compatible = "nxp,lpc3220-tsc";
                                reg = <0x40048000 0x1000>;
                                interrupts = <0x27 0>;
                                status = "disabled";
                        };
 
-                       key@40050000 {
+                       timer1: timer@4004C000 {
+                               compatible = "nxp,lpc3220-timer";
+                               reg = <0x4004C000 0x1000>;
+                               interrupts = <0x11 0>;
+                       };
+
+                       key: key@40050000 {
                                compatible = "nxp,lpc3220-key";
                                reg = <0x40050000 0x1000>;
                                interrupts = <54 0>;
                                status = "disabled";
                        };
 
-                       pwm: pwm@4005C000 {
+                       timer2: timer@40058000 {
+                               compatible = "nxp,lpc3220-timer";
+                               reg = <0x40058000 0x1000>;
+                               interrupts = <0x12 0>;
+                               status = "disabled";
+                       };
+
+                       pwm1: pwm@4005C000 {
                                compatible = "nxp,lpc3220-pwm";
-                               reg = <0x4005C000 0x8>;
+                               reg = <0x4005C000 0x4>;
+                               status = "disabled";
+                       };
+
+                       pwm2: pwm@4005C004 {
+                               compatible = "nxp,lpc3220-pwm";
+                               reg = <0x4005C004 0x4>;
+                               status = "disabled";
+                       };
+
+                       timer3: timer@40060000 {
+                               compatible = "nxp,lpc3220-timer";
+                               reg = <0x40060000 0x1000>;
+                               interrupts = <0x13 0>;
                                status = "disabled";
                        };
                };
index 5f500c1..5cfadb0 100644 (file)
                };
        };
 
+       i2c0_pins: i2c0-pins {
+               i2c0_pins_cfg {
+                       pins = "i2c0_scl", "i2c0_sda";
+                       function = "i2c0";
+                       input-enable;
+               };
+       };
+
        ssp_pins: ssp-pins {
                ssp1_cs {
                        pins = "p6_7";
        clock-frequency = <50000000>;
 };
 
+&i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       clock-frequency = <400000>;
+
+       eeprom@50 {
+               compatible = "microchip,24c512";
+               reg = <0x50>;
+       };
+
+       eeprom@51 {
+               compatible = "microchip,24c02";
+               reg = <0x51>;
+       };
+
+       eeprom@54 {
+               compatible = "microchip,24c512";
+               reg = <0x54>;
+       };
+};
+
 &mac {
        status = "okay";
        phy-mode = "rmii";
        pinctrl-0 = <&enet_rmii_pins>;
 };
 
+&sct_pwm {
+       status = "okay";
+};
+
 &ssp1 {
        status = "okay";
        pinctrl-names = "default";
index 391121d..079d3cf 100644 (file)
        pinctrl-0 = <&i2c0_pins>;
        clock-frequency = <400000>;
 
+       mma7455@1d {
+               compatible = "fsl,mma7455";
+               reg = <0x1d>;
+       };
+
        lm75@48 {
                compatible = "nxp,lm75";
                reg = <0x48>;
index fb9ecc7..72f12db 100644 (file)
@@ -37,3 +37,7 @@
                };
        };
 };
+
+&eeprom {
+       status = "okay";
+};
index 0521e68..9408753 100644 (file)
        status = "okay";
 };
 
+&sata {
+       status = "okay";
+};
+
 &uart0 {
        status = "okay";
 };
index fbb89d1..75ecaed 100644 (file)
                        bitclock-master;
                };
        };
+
+       panel: panel {
+               compatible = "nec,nl4827hc19-05b";
+       };
+};
+
+&dcu {
+       fsl,panel = <&panel>;
+       status = "okay";
 };
 
 &dspi1 {
        status = "okay";
 };
 
+&sata {
+       status = "okay";
+};
+
 &uart0 {
        status = "okay";
 };
index 9430a99..2c84ca2 100644 (file)
                        status = "disabled";
                };
 
+               sata: sata@3200000 {
+                       compatible = "fsl,ls1021a-ahci";
+                       reg = <0x0 0x3200000 0x0 0x10000>,
+                             <0x0 0x20220520 0x0 0x4>;
+                       reg-names = "ahci", "sata-ecc";
+                       interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&platform_clk 1>;
+                       dma-coherent;
+                       status = "disabled";
+               };
+
                scfg: scfg@1570000 {
                        compatible = "fsl,ls1021a-scfg", "syscon";
                        reg = <0x0 0x1570000 0x0 0x10000>;
                                 <&platform_clk 1>;
                };
 
+               dcu: dcu@2ce0000 {
+                       compatible = "fsl,ls1021a-dcu";
+                       reg = <0x0 0x2ce0000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&platform_clk 0>;
+                       clock-names = "dcu";
+                       big-endian;
+                       status = "disabled";
+               };
+
                mdio0: mdio@2d24000 {
                        compatible = "gianfar";
                        device_type = "mdio";
index a8e2911..e50f1a1 100644 (file)
@@ -46,6 +46,7 @@
 
 /dts-v1/;
 #include "meson8b.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "Hardkernel ODROID-C1";
        memory {
                reg = <0x40000000 0x40000000>;
        };
+
+       leds {
+               compatible = "gpio-leds";
+               blue {
+                       label = "c1:blue:alive";
+                       gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
+               };
+       };
 };
 
 &uart_AO {
index ee352bf..8bad557 100644 (file)
                        #interrupt-cells = <3>;
                };
 
+               wdt: watchdog@c1109900 {
+                       compatible = "amlogic,meson8b-wdt";
+                       reg = <0xc1109900 0x8>;
+                       interrupts = <0 0 1>;
+               };
+
                timer@c1109940 {
                        compatible = "amlogic,meson6-timer";
                        reg = <0xc1109940 0x18>;
diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
new file mode 100644 (file)
index 0000000..082ca88
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Erin Lo <erin.lo@mediatek.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.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include "mt2701.dtsi"
+
+/ {
+       model = "MediaTek MT2701 evaluation board";
+       compatible = "mediatek,mt2701-evb", "mediatek,mt2701";
+
+       memory {
+               reg = <0 0x80000000 0 0x40000000>;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
new file mode 100644 (file)
index 0000000..3766904
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Erin.Lo <erin.lo@mediatek.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.
+ *
+ * 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 <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton64.dtsi"
+
+/ {
+       compatible = "mediatek,mt2701";
+       interrupt-parent = <&sysirq>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x0>;
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x1>;
+               };
+               cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x2>;
+               };
+               cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x3>;
+               };
+       };
+
+       system_clk: dummy13m {
+               compatible = "fixed-clock";
+               clock-frequency = <13000000>;
+               #clock-cells = <0>;
+       };
+
+       rtc_clk: dummy32k {
+               compatible = "fixed-clock";
+               clock-frequency = <32000>;
+               #clock-cells = <0>;
+       };
+
+       uart_clk: dummy26m {
+               compatible = "fixed-clock";
+               clock-frequency = <26000000>;
+               #clock-cells = <0>;
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       watchdog: watchdog@10007000 {
+               compatible = "mediatek,mt2701-wdt",
+                            "mediatek,mt6589-wdt";
+               reg = <0 0x10007000 0 0x100>;
+       };
+
+       timer: timer@10008000 {
+               compatible = "mediatek,mt2701-timer",
+                            "mediatek,mt6577-timer";
+               reg = <0 0x10008000 0 0x80>;
+               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&system_clk>, <&rtc_clk>;
+               clock-names = "system-clk", "rtc-clk";
+       };
+
+       sysirq: interrupt-controller@10200100 {
+               compatible = "mediatek,mt2701-sysirq",
+                            "mediatek,mt6577-sysirq";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               interrupt-parent = <&gic>;
+               reg = <0 0x10200100 0 0x1c>;
+       };
+
+       gic: interrupt-controller@10211000 {
+               compatible = "arm,cortex-a7-gic";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               interrupt-parent = <&gic>;
+               reg = <0 0x10211000 0 0x1000>,
+                     <0 0x10212000 0 0x1000>,
+                     <0 0x10214000 0 0x2000>,
+                     <0 0x10216000 0 0x2000>;
+       };
+
+       uart0: serial@11002000 {
+               compatible = "mediatek,mt2701-uart",
+                            "mediatek,mt6577-uart";
+               reg = <0 0x11002000 0 0x400>;
+               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&uart_clk>;
+               status = "disabled";
+       };
+
+       uart1: serial@11003000 {
+               compatible = "mediatek,mt2701-uart",
+                            "mediatek,mt6577-uart";
+               reg = <0 0x11003000 0 0x400>;
+               interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&uart_clk>;
+               status = "disabled";
+       };
+
+       uart2: serial@11004000 {
+               compatible = "mediatek,mt2701-uart",
+                            "mediatek,mt6577-uart";
+               reg = <0 0x11004000 0 0x400>;
+               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&uart_clk>;
+               status = "disabled";
+       };
+
+       uart3: serial@11005000 {
+               compatible = "mediatek,mt2701-uart",
+                            "mediatek,mt6577-uart";
+               reg = <0 0x11005000 0 0x400>;
+               interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&uart_clk>;
+               status = "disabled";
+       };
+};
index cb99b02..1d7f92b 100644 (file)
@@ -15,7 +15,7 @@
 #include <dt-bindings/clock/mt8135-clk.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/reset-controller/mt8135-resets.h>
+#include <dt-bindings/reset/mt8135-resets.h>
 #include "skeleton64.dtsi"
 #include "mt8135-pinfunc.h"
 
index 73f1e3a..01e1e2d 100644 (file)
@@ -69,7 +69,7 @@
                        label = "user";
                        gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x114>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
        };
 &omap3_pmx_wkup {
        gpio1_pins: pinmux_gpio1_pins {
                pinctrl-single,pins = <
-                       0x0e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot2.gpio_4 */
+                       OMAP3_WKUP_IOPAD(0x2a0e, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot2.gpio_4 */
                >;
        };
 
        dss_dpi_pins2: pinmux_dss_dpi_pins1 {
                pinctrl-single,pins = <
-                       0x0a (PIN_OUTPUT | MUX_MODE3)   /* sys_boot0.dss_data18 */
-                       0x0c (PIN_OUTPUT | MUX_MODE3)   /* sys_boot1.dss_data19 */
-                       0x10 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot3.dss_data20 */
-                       0x12 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot4.dss_data21 */
-                       0x14 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot5.dss_data22 */
-                       0x16 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot6.dss_data23 */
+                       OMAP3_WKUP_IOPAD(0x2a0a, PIN_OUTPUT | MUX_MODE3)   /* sys_boot0.dss_data18 */
+                       OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE3)   /* sys_boot1.dss_data19 */
+                       OMAP3_WKUP_IOPAD(0x2a10, PIN_OUTPUT | MUX_MODE3)   /* sys_boot3.dss_data20 */
+                       OMAP3_WKUP_IOPAD(0x2a12, PIN_OUTPUT | MUX_MODE3)   /* sys_boot4.dss_data21 */
+                       OMAP3_WKUP_IOPAD(0x2a14, PIN_OUTPUT | MUX_MODE3)   /* sys_boot5.dss_data22 */
+                       OMAP3_WKUP_IOPAD(0x2a16, PIN_OUTPUT | MUX_MODE3)   /* sys_boot6.dss_data23 */
                >;
        };
 };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x16e (PIN_INPUT | MUX_MODE0)   /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0)  /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
+                       OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0)        /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)       /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
                >;
        };
 
index 274c2c4..8ba465d 100644 (file)
@@ -80,7 +80,7 @@
                        label = "user";
                        gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
                        linux,code = <0x114>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
        };
 &omap3_pmx_wkup {
        gpio1_pins: pinmux_gpio1_pins {
                pinctrl-single,pins = <
-                       0x14 (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot5.gpio_7 */
+                       OMAP3_WKUP_IOPAD(0x2a14, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot5.gpio_7 */
                >;
        };
 };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+                       OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
                >;
        };
 
        tfp410_pins: pinmux_tfp410_pins {
                pinctrl-single,pins = <
-                       0x196 (PIN_OUTPUT | MUX_MODE4)  /* hdq_sio.gpio_170 */
+                       OMAP3_CORE1_IOPAD(0x21c6, PIN_OUTPUT | MUX_MODE4)       /* hdq_sio.gpio_170 */
                >;
        };
 
        dss_dpi_pins: pinmux_dss_dpi_pins {
                pinctrl-single,pins = <
-                       0x0a4 (PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
-                       0x0a6 (PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
-                       0x0a8 (PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
-                       0x0aa (PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
-                       0x0ac (PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
-                       0x0ae (PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
-                       0x0b0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
-                       0x0b2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
-                       0x0b4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
-                       0x0b6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
-                       0x0b8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
-                       0x0ba (PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
-                       0x0bc (PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
-                       0x0be (PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
-                       0x0c0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
-                       0x0c2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
-                       0x0c4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
-                       0x0c6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
-                       0x0c8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
-                       0x0ca (PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
-                       0x0cc (PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
-                       0x0ce (PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
-                       0x0d0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data18.dss_data18 */
-                       0x0d2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data19.dss_data19 */
-                       0x0d4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data20.dss_data20 */
-                       0x0d6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data21.dss_data21 */
-                       0x0d8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data22.dss_data22 */
-                       0x0da (PIN_OUTPUT | MUX_MODE0)   /* dss_data23.dss_data23 */
+                       OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+                       OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+                       OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+                       OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+                       OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
+                       OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
+                       OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
+                       OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
+                       OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
+                       OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
+                       OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+                       OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0)   /* dss_data18.dss_data18 */
+                       OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0)   /* dss_data19.dss_data19 */
+                       OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0)   /* dss_data20.dss_data20 */
+                       OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0)   /* dss_data21.dss_data21 */
+                       OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0)   /* dss_data22.dss_data22 */
+                       OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0)   /* dss_data23.dss_data23 */
                >;
        };
 };
index 8c813e7..e5f7f5c 100644 (file)
                ti,debounce-tol = /bits/ 16 <10>;
                ti,debounce-rep = /bits/ 16 <1>;
 
-               linux,wakeup;
+               wakeup-source;
        };
 };
 
index 9ca2865..86850bb 100644 (file)
@@ -64,7 +64,7 @@
                        label = "user";
                        gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
                        linux,code = <BTN_EXTRA>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 4813e96..738910d 100644 (file)
@@ -68,6 +68,6 @@
                ti,keep-vref-on = <1>;
                ti,settle-delay-usec = /bits/ 16 <150>;
 
-               linux,wakeup;
+               wakeup-source;
        };
 };
index bb339d1..ac18865 100644 (file)
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
-                       0x116 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_cmd.sdmmc1_cmd */
-                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0.sdmmc1_dat0 */
-                       0x11a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat1.sdmmc1_dat1 */
-                       0x11c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat2.sdmmc1_dat2 */
-                       0x11e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat3.sdmmc1_dat3 */
-                       0x120 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat4.sdmmc1_dat4 */
-                       0x122 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat5.sdmmc1_dat5 */
-                       0x124 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat6.sdmmc1_dat6 */
-                       0x126 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat7.sdmmc1_dat7 */
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* sdmmc1_clk.sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat0.sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat1.sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat2.sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat3.sdmmc1_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2150, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat4.sdmmc1_dat4 */
+                       OMAP3_CORE1_IOPAD(0x2152, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat5.sdmmc1_dat5 */
+                       OMAP3_CORE1_IOPAD(0x2154, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat6.sdmmc1_dat6 */
+                       OMAP3_CORE1_IOPAD(0x2156, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat7.sdmmc1_dat7 */
                >;
        };
 
        /* NOTE: Clocked externally, needs INPUT also for sdmmc2_clk.sdmmc2_clk */
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_clk.sdmmc2_clk */
-                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_cmd.sdmmc2_cmd */
-                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat0.sdmmc2_dat0 */
-                       0x12e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
-                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat2.sdmmc2_dat2 */
-                       0x132 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat3.sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
                >;
        };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx_irtx.uart3_tx_irtx */
+                       OMAP3_CORE1_IOPAD(0x219e, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)               /* uart3_tx_irtx.uart3_tx_irtx */
                >;
        };
 
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0x150 (PIN_OUTPUT | MUX_MODE4)          /* uart1_cts.gpio_150 */
-                       0x14e (PIN_INPUT | MUX_MODE4)           /* uart1_rts.gpio_149 */
+                       OMAP3_CORE1_IOPAD(0x2180, PIN_OUTPUT | MUX_MODE4)               /* uart1_cts.gpio_150 */
+                       OMAP3_CORE1_IOPAD(0x217e, PIN_INPUT | MUX_MODE4)                /* uart1_rts.gpio_149 */
                >;
        };
 
        smsc911x_pins: pinmux_smsc911x_pins {
                pinctrl-single,pins = <
-                       0x1a2 (PIN_INPUT | MUX_MODE4)           /* mcspi1_cs2.gpio_176 */
+                       OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT | MUX_MODE4)                /* mcspi1_cs2.gpio_176 */
                >;
        };
 };
 &omap3_pmx_wkup {
        dss_dpi_pins2: pinmux_dss_dpi_pins1 {
                pinctrl-single,pins = <
-                       0x0a (PIN_OUTPUT | MUX_MODE3)   /* sys_boot0.dss_data18 */
-                       0x0c (PIN_OUTPUT | MUX_MODE3)   /* sys_boot1.dss_data19 */
-                       0x10 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot3.dss_data20 */
-                       0x12 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot4.dss_data21 */
-                       0x14 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot5.dss_data22 */
-                       0x16 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot6.dss_data23 */
+                       OMAP3_WKUP_IOPAD(0x2a0a, PIN_OUTPUT | MUX_MODE3)   /* sys_boot0.dss_data18 */
+                       OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE3)   /* sys_boot1.dss_data19 */
+                       OMAP3_WKUP_IOPAD(0x2a10, PIN_OUTPUT | MUX_MODE3)   /* sys_boot3.dss_data20 */
+                       OMAP3_WKUP_IOPAD(0x2a12, PIN_OUTPUT | MUX_MODE3)   /* sys_boot4.dss_data21 */
+                       OMAP3_WKUP_IOPAD(0x2a14, PIN_OUTPUT | MUX_MODE3)   /* sys_boot5.dss_data22 */
+                       OMAP3_WKUP_IOPAD(0x2a16, PIN_OUTPUT | MUX_MODE3)   /* sys_boot6.dss_data23 */
                >;
        };
 };
index e14d15e..5e2d643 100644 (file)
@@ -37,7 +37,7 @@
                        label = "aux";
                        linux,code = <169>;
                        gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 3835e15..33d6b4e 100644 (file)
        model = "IGEPv2 Rev. C (TI OMAP AM/DM37x)";
        compatible = "isee,omap3-igep0020", "ti,omap36xx", "ti,omap3";
 
-       /* Regulator to trigger the WIFI_PDN signal of the Wifi module */
-       lbee1usjyc_pdn: lbee1usjyc_pdn {
+       vmmcsdio_fixed: fixedregulator-mmcsdio {
                compatible = "regulator-fixed";
-               regulator-name = "regulator-lbee1usjyc-pdn";
+               regulator-name = "vmmcsdio_fixed";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;    /* gpio_138 - WIFI_PDN */
-               startup-delay-us = <10000>;
-               enable-active-high;
        };
 
-       /* Regulator to trigger the RESET_N_W signal of the Wifi module */
-       lbee1usjyc_reset_n_w: lbee1usjyc_reset_n_w {
-               compatible = "regulator-fixed";
-               regulator-name = "regulator-lbee1usjyc-reset-n-w";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>;    /* gpio_139 - RESET_N_W */
-               enable-active-high;
+       mmc2_pwrseq: mmc2_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>,      /* gpio_139 - RESET_N_W */
+                             <&gpio5 10 GPIO_ACTIVE_LOW>;      /* gpio_138 - WIFI_PDN */
        };
 };
 
@@ -51,8 +43,8 @@
 &mmc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc2_pins &lbee1usjyc_pins>;
-       vmmc-supply = <&lbee1usjyc_pdn>;
-       vmmc_aux-supply = <&lbee1usjyc_reset_n_w>;
+       vmmc-supply = <&vmmcsdio_fixed>;
+       mmc-pwrseq = <&mmc2_pwrseq>;
        bus-width = <4>;
        non-removable;
 };
index 468608d..55b0cc4 100644 (file)
        model = "IGEP COM MODULE Rev. E (TI OMAP AM/DM37x)";
        compatible = "isee,omap3-igep0030", "ti,omap36xx", "ti,omap3";
 
-       /* Regulator to trigger the WIFI_PDN signal of the Wifi module */
-       lbee1usjyc_pdn: lbee1usjyc_pdn {
+       vmmcsdio_fixed: fixedregulator-mmcsdio {
                compatible = "regulator-fixed";
-               regulator-name = "regulator-lbee1usjyc-pdn";
+               regulator-name = "vmmcsdio_fixed";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;    /* gpio_138 - WIFI_PDN */
-               startup-delay-us = <10000>;
-               enable-active-high;
        };
 
-       /* Regulator to trigger the RESET_N_W signal of the Wifi module */
-       lbee1usjyc_reset_n_w: lbee1usjyc_reset_n_w {
-               compatible = "regulator-fixed";
-               regulator-name = "regulator-lbee1usjyc-reset-n-w";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>;    /* gpio_139 - RESET_N_W */
-               enable-active-high;
+       mmc2_pwrseq: mmc2_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>,      /* gpio_139 - RESET_N_W */
+                             <&gpio5 10 GPIO_ACTIVE_LOW>;      /* gpio_138 - WIFI_PDN */
        };
 };
 
@@ -62,8 +54,8 @@
 &mmc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc2_pins &lbee1usjyc_pins>;
-       vmmc-supply = <&lbee1usjyc_pdn>;
-       vmmc_aux-supply = <&lbee1usjyc_reset_n_w>;
+       vmmc-supply = <&vmmcsdio_fixed>;
+       mmc-pwrseq = <&mmc2_pwrseq>;
        bus-width = <4>;
        non-removable;
 };
index d2fab8c..5401630 100644 (file)
                        label = "enter";
                        gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* gpio101 */
                        linux,code = <KEY_ENTER>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_f1 {
                        label = "f1";
                        gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* gpio102 */
                        linux,code = <KEY_F1>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_f2 {
                        label = "f2";
                        gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; /* gpio103 */
                        linux,code = <KEY_F2>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_f3 {
                        label = "f3";
                        gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; /* gpio104 */
                        linux,code = <KEY_F3>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_f4 {
                        label = "f4";
                        gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; /* gpio105 */
                        linux,code = <KEY_F4>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_left {
                        label = "left";
                        gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* gpio106 */
                        linux,code = <KEY_LEFT>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_right {
                        label = "right";
                        gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; /* gpio107 */
                        linux,code = <KEY_RIGHT>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_up {
                        label = "up";
                        gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; /* gpio108 */
                        linux,code = <KEY_UP>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                key_down {
                        label = "down";
                        gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; /* gpio109 */
                        linux,code = <KEY_DOWN>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
 &omap3_pmx_core {
        gpio_key_pins: pinmux_gpio_key_pins {
                pinctrl-single,pins = <
-                       0xea (PIN_INPUT | MUX_MODE4)    /* cam_d2.gpio_101 */
-                       0xec (PIN_INPUT | MUX_MODE4)    /* cam_d3.gpio_102 */
-                       0xee (PIN_INPUT | MUX_MODE4)    /* cam_d4.gpio_103 */
-                       0xf0 (PIN_INPUT | MUX_MODE4)    /* cam_d5.gpio_104 */
-                       0xf2 (PIN_INPUT | MUX_MODE4)    /* cam_d6.gpio_105 */
-                       0xf4 (PIN_INPUT | MUX_MODE4)    /* cam_d7.gpio_106 */
-                       0xf6 (PIN_INPUT | MUX_MODE4)    /* cam_d8.gpio_107 */
-                       0xf8 (PIN_INPUT | MUX_MODE4)    /* cam_d9.gpio_108 */
-                       0xfa (PIN_INPUT | MUX_MODE4)    /* cam_d10.gpio_109 */
+                       OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE4)        /* cam_d2.gpio_101 */
+                       OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE4)        /* cam_d3.gpio_102 */
+                       OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE4)        /* cam_d4.gpio_103 */
+                       OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE4)        /* cam_d5.gpio_104 */
+                       OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE4)        /* cam_d6.gpio_105 */
+                       OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE4)        /* cam_d7.gpio_106 */
+                       OMAP3_CORE1_IOPAD(0x2126, PIN_INPUT | MUX_MODE4)        /* cam_d8.gpio_107 */
+                       OMAP3_CORE1_IOPAD(0x2128, PIN_INPUT | MUX_MODE4)        /* cam_d9.gpio_108 */
+                       OMAP3_CORE1_IOPAD(0x212a, PIN_INPUT | MUX_MODE4)        /* cam_d10.gpio_109 */
                >;
        };
 
        musb_pins: pinmux_musb_pins {
                pinctrl-single,pins = <
-                       0x172 (PIN_INPUT | MUX_MODE0)   /* hsusb0_clk.hsusb0_clk */
-                       0x17a (PIN_INPUT | MUX_MODE0)   /* hsusb0_data0.hsusb0_data0 */
-                       0x17c (PIN_INPUT | MUX_MODE0)   /* hsusb0_data1.hsusb0_data1 */
-                       0x17e (PIN_INPUT | MUX_MODE0)   /* hsusb0_data2.hsusb0_data2 */
-                       0x180 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data3.hsusb0_data3 */
-                       0x182 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data4.hsusb0_data4 */
-                       0x184 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data5.hsusb0_data5 */
-                       0x186 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data6.hsusb0_data6 */
-                       0x188 (PIN_INPUT | MUX_MODE0)   /* hsusb0_data7.hsusb0_data7 */
-                       0x176 (PIN_INPUT | MUX_MODE0)   /* hsusb0_dir.hsusb0_dir */
-                       0x178 (PIN_INPUT | MUX_MODE0)   /* hsusb0_nxt.hsusb0_nxt */
-                       0x174 (PIN_OUTPUT | MUX_MODE0)  /* hsusb0_stp.hsusb0_stp */
+                       OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0)        /* hsusb0_clk.hsusb0_clk */
+                       OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0)        /* hsusb0_data0.hsusb0_data0 */
+                       OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0)        /* hsusb0_data1.hsusb0_data1 */
+                       OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0)        /* hsusb0_data2.hsusb0_data2 */
+                       OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0)        /* hsusb0_data3.hsusb0_data3 */
+                       OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0)        /* hsusb0_data4.hsusb0_data4 */
+                       OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0)        /* hsusb0_data5.hsusb0_data5 */
+                       OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0)        /* hsusb0_data6.hsusb0_data6 */
+                       OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0)        /* hsusb0_data7.hsusb0_data7 */
+                       OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0)        /* hsusb0_dir.hsusb0_dir */
+                       OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0)        /* hsusb0_nxt.hsusb0_nxt */
+                       OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0)       /* hsusb0_stp.hsusb0_stp */
                >;
        };
 
index 57d7c93..93f8dfe 100644 (file)
                ti,pressure-max = /bits/ 16 <255>;
                ti,swap-xy;
 
-               linux,wakeup;
+               wakeup-source;
        };
 };
 
index 5f5e0f3..74d8f7e 100644 (file)
                        gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* 110 */
                        linux,input-type = <5>; /* EV_SW */
                        linux,code = <0x09>; /* SW_CAMERA_LENS_COVER */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                camera_focus {
                        label = "Camera Focus";
                        gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 68 */
                        linux,code = <0x210>; /* KEY_CAMERA_FOCUS */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                camera_capture {
                        label = "Camera Capture";
                        gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; /* 69 */
                        linux,code = <0xd4>; /* KEY_CAMERA */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                lock_button {
                        label = "Lock Button";
                        gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* 113 */
                        linux,code = <0x98>; /* KEY_SCREENLOCK */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                keypad_slide {
@@ -96,7 +96,7 @@
                        gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; /* 71 */
                        linux,input-type = <5>; /* EV_SW */
                        linux,code = <0x0a>; /* SW_KEYPAD_SLIDE */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                proximity_sensor {
 
        uart2_pins: pinmux_uart2_pins {
                pinctrl-single,pins = <
-                       0x14a (PIN_INPUT | MUX_MODE0)           /* uart2_rx */
-                       0x148 (PIN_OUTPUT | MUX_MODE0)          /* uart2_tx */
+                       OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0)                /* uart2_rx */
+                       OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0)               /* uart2_tx */
                >;
        };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x16e (PIN_INPUT | MUX_MODE0)           /* uart3_rx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx */
+                       OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0)                /* uart3_rx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)               /* uart3_tx */
                >;
        };
 
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0x18a (PIN_INPUT | MUX_MODE0)           /* i2c1_scl */
-                       0x18c (PIN_INPUT | MUX_MODE0)           /* i2c1_sda */
+                       OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0)                /* i2c1_scl */
+                       OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)                /* i2c1_sda */
                >;
        };
 
        i2c2_pins: pinmux_i2c2_pins {
                pinctrl-single,pins = <
-                       0x18e (PIN_INPUT | MUX_MODE0)           /* i2c2_scl */
-                       0x190 (PIN_INPUT | MUX_MODE0)           /* i2c2_sda */
+                       OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)                /* i2c2_scl */
+                       OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)                /* i2c2_sda */
                >;
        };
 
        i2c3_pins: pinmux_i2c3_pins {
                pinctrl-single,pins = <
-                       0x192 (PIN_INPUT | MUX_MODE0)           /* i2c3_scl */
-                       0x194 (PIN_INPUT | MUX_MODE0)           /* i2c3_sda */
+                       OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)                /* i2c3_scl */
+                       OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)                /* i2c3_sda */
                >;
        };
 
 
        mcspi4_pins: pinmux_mcspi4_pins {
                pinctrl-single,pins = <
-                       0x15c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */
-                       0x162 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */
-                       0x160 (PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */
-                       0x166 (PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */
+                       OMAP3_CORE1_IOPAD(0x218c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */
+                       OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */
+                       OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */
+                       OMAP3_CORE1_IOPAD(0x2196, PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */
                >;
        };
 
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x114 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_clk */
-                       0x116 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_cmd */
-                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0 */
-                       0x11a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat1 */
-                       0x11c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat2 */
-                       0x11e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3 */
                >;
        };
 
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_clk */
-                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_cmd */
-                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat0 */
-                       0x12e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat1 */
-                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat2 */
-                       0x132 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat3 */
-                       0x134 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat4 */
-                       0x136 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat5 */
-                       0x138 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat6 */
-                       0x13a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat7 */
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat4 */
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat5 */
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat6 */
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat7 */
                >;
        };
 
        acx565akm_pins: pinmux_acx565akm_pins {
                pinctrl-single,pins = <
-                       0x0d4 (PIN_OUTPUT | MUX_MODE4)          /* RX51_LCD_RESET_GPIO */
+                       OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE4)               /* RX51_LCD_RESET_GPIO */
                >;
        };
 
        dss_sdi_pins: pinmux_dss_sdi_pins {
                pinctrl-single,pins = <
-                       0x0c0 (PIN_OUTPUT | MUX_MODE1)   /* dss_data10.sdi_dat1n */
-                       0x0c2 (PIN_OUTPUT | MUX_MODE1)   /* dss_data11.sdi_dat1p */
-                       0x0c4 (PIN_OUTPUT | MUX_MODE1)   /* dss_data12.sdi_dat2n */
-                       0x0c6 (PIN_OUTPUT | MUX_MODE1)   /* dss_data13.sdi_dat2p */
+                       OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE1)   /* dss_data10.sdi_dat1n */
+                       OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE1)   /* dss_data11.sdi_dat1p */
+                       OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE1)   /* dss_data12.sdi_dat2n */
+                       OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE1)   /* dss_data13.sdi_dat2p */
 
-                       0x0d8 (PIN_OUTPUT | MUX_MODE1)   /* dss_data22.sdi_clkp */
-                       0x0da (PIN_OUTPUT | MUX_MODE1)   /* dss_data23.sdi_clkn */
+                       OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE1)   /* dss_data22.sdi_clkp */
+                       OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE1)   /* dss_data23.sdi_clkn */
                >;
        };
 
        wl1251_pins: pinmux_wl1251 {
                pinctrl-single,pins = <
-                       0x0ce (PIN_OUTPUT | MUX_MODE4)          /* gpio 87 => wl1251 enable */
-                       0x05a (PIN_INPUT | MUX_MODE4)           /* gpio 42 => wl1251 irq */
+                       OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE4)               /* gpio 87 => wl1251 enable */
+                       OMAP3_CORE1_IOPAD(0x208a, PIN_INPUT | MUX_MODE4)                /* gpio 42 => wl1251 irq */
                >;
        };
 
        ssi_pins: pinmux_ssi {
                pinctrl-single,pins = <
-                       0x150 (PIN_INPUT_PULLUP | MUX_MODE1)    /* ssi1_rdy_tx */
-                       0x14e (PIN_OUTPUT | MUX_MODE1)          /* ssi1_flag_tx */
-                       0x152 (PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* ssi1_wake_tx (cawake) */
-                       0x14c (PIN_OUTPUT | MUX_MODE1)          /* ssi1_dat_tx */
-                       0x154 (PIN_INPUT | MUX_MODE1)           /* ssi1_dat_rx */
-                       0x156 (PIN_INPUT | MUX_MODE1)           /* ssi1_flag_rx */
-                       0x158 (PIN_OUTPUT | MUX_MODE1)          /* ssi1_rdy_rx */
-                       0x15a (PIN_OUTPUT | MUX_MODE1)          /* ssi1_wake */
+                       OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT_PULLUP | MUX_MODE1) /* ssi1_rdy_tx */
+                       OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE1)               /* ssi1_flag_tx */
+                       OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* ssi1_wake_tx (cawake) */
+                       OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE1)               /* ssi1_dat_tx */
+                       OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT | MUX_MODE1)                /* ssi1_dat_rx */
+                       OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE1)                /* ssi1_flag_rx */
+                       OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE1)               /* ssi1_rdy_rx */
+                       OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | MUX_MODE1)               /* ssi1_wake */
                >;
        };
 
        modem_pins: pinmux_modem {
                pinctrl-single,pins = <
-                       0x0ac (PIN_OUTPUT | MUX_MODE4)          /* gpio 70 => cmt_apeslpx */
-                       0x0b0 (PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* gpio 72 => ape_rst_rq */
-                       0x0b2 (PIN_OUTPUT | MUX_MODE4)          /* gpio 73 => cmt_rst_rq */
-                       0x0b4 (PIN_OUTPUT | MUX_MODE4)          /* gpio 74 => cmt_en */
-                       0x0b6 (PIN_OUTPUT | MUX_MODE4)          /* gpio 75 => cmt_rst */
-                       0x15e (PIN_OUTPUT | MUX_MODE4)          /* gpio 157 => cmt_bsi */
+                       OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE4)               /* gpio 70 => cmt_apeslpx */
+                       OMAP3_CORE1_IOPAD(0x20e0, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* gpio 72 => ape_rst_rq */
+                       OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE4)               /* gpio 73 => cmt_rst_rq */
+                       OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE4)               /* gpio 74 => cmt_en */
+                       OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE4)               /* gpio 75 => cmt_rst */
+                       OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4)               /* gpio 157 => cmt_bsi */
                >;
        };
 };
index e9ee1df..a2c2b8d 100644 (file)
 &omap3_pmx_core {
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
-                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
-                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
-                       0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
-                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
-                       0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
                >;
        };
 };
index 7aae8fb..3b3a759 100644 (file)
@@ -48,7 +48,7 @@
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;            /* gpio_10 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index 17b82f8..7df2792 100644 (file)
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
                button1@14 {
                        label = "button1";
                        linux,code = <BTN_1>;
                        gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index b09cedf..6314da2 100644 (file)
                ti,x-plate-ohms = /bits/ 16 <180>;
                ti,pressure-max = /bits/ 16 <255>;
 
-               linux,wakeup;
+               wakeup-source;
        };
 };
index 5f97959..7e3fe85 100644 (file)
                ti,x-plate-ohms = /bits/ 16 <180>;
                ti,pressure-max = /bits/ 16 <255>;
 
-               linux,wakeup;
+               wakeup-source;
        };
 };
 
index 49d2254..250cc7f 100644 (file)
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
                button1@14 {
                        label = "button1";
                        linux,code = <BTN_1>;
                        gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index 680d726..8df7ec3 100644 (file)
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
                button1@14 {
                        label = "button1";
                        linux,code = <BTN_1>;
                        gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index 087aedf..0ea2c45 100644 (file)
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
                button1@14 {
                        label = "button1";
                        linux,code = <BTN_1>;
                        gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 };
index cfe140c..13e9d1f 100644 (file)
                        label = "up";
                        linux,code = <KEY_UP>;
                        gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;    /* GPIO_110 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                down-button {
                        label = "down";
                        linux,code = <KEY_DOWN>;
                        gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;     /* GPIO_103 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                left-button {
                        label = "left";
                        linux,code = <KEY_LEFT>;
                        gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;     /* GPIO_96 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                right-button {
                        label = "right";
                        linux,code = <KEY_RIGHT>;
                        gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;     /* GPIO_98 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                pageup-button {
                        label = "game 1";
                        linux,code = <KEY_PAGEUP>;
                        gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;    /* GPIO_109 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                pagedown-button {
                        label = "game 3";
                        linux,code = <KEY_PAGEDOWN>;
                        gpios = <&gpio4 10 GPIO_ACTIVE_LOW>;    /* GPIO_106 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                home-button {
                        label = "game 4";
                        linux,code = <KEY_HOME>;
                        gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;     /* GPIO_101 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                end-button {
                        label = "game 2";
                        linux,code = <KEY_END>;
                        gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;    /* GPIO_111 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                right-shift {
                        label = "l";
                        linux,code = <KEY_RIGHTSHIFT>;
                        gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;     /* GPIO_102 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                kp-plus {
                        label = "l2";
                        linux,code = <KEY_KPPLUS>;
                        gpios = <&gpio4 1 GPIO_ACTIVE_LOW>;     /* GPIO_97 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                right-ctrl {
                        label = "r";
                        linux,code = <KEY_RIGHTCTRL>;
                        gpios = <&gpio4 9 GPIO_ACTIVE_LOW>;     /* GPIO_105 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                kp-minus {
                        label = "r2";
                        linux,code = <KEY_KPMINUS>;
                        gpios = <&gpio4 11 GPIO_ACTIVE_LOW>;    /* GPIO_107 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                left-ctrl {
                        label = "ctrl";
                        linux,code = <KEY_LEFTCTRL>;
                        gpios = <&gpio4 8 GPIO_ACTIVE_LOW>;     /* GPIO_104 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                menu {
                        label = "menu";
                        linux,code = <KEY_MENU>;
                        gpios = <&gpio4 3 GPIO_ACTIVE_LOW>;     /* GPIO_99 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                hold {
                        label = "hold";
                        linux,code = <KEY_COFFEE>;
                        gpios = <&gpio6 16 GPIO_ACTIVE_LOW>;    /* GPIO_176 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                left-alt {
                        label = "alt";
                        linux,code = <KEY_LEFTALT>;
                        gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;    /* GPIO_100 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                lid {
                ti,x-plate-ohms = /bits/ 16 <40>;
                ti,pressure-max = /bits/ 16 <255>;
 
-               linux,wakeup;
+               wakeup-source;
        };
 
        lcd: lcd@1 {
index f4b1a61..157345b 100644 (file)
@@ -66,6 +66,6 @@
                ti,x-plate-ohms = /bits/ 16 <40>;
                ti,pressure-max = /bits/ 16 <255>;
                ti,swap-xy;
-               linux,wakeup;
+               wakeup-source;
        };
 };
index 7bc5fdd..f19170b 100644 (file)
        /* REVISIT: twl gpio0 is mmc0_cd */
        mmc1_pins: pinmux_mmc1_pins {
                pinctrl-single,pins = <
-                       0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
-                       0x116 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_cmd.sdmmc1_cmd */
-                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0.sdmmc1_dat0 */
-                       0x11a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat1.sdmmc1_dat1 */
-                       0x11c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat2.sdmmc1_dat2 */
-                       0x11e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat3.sdmmc1_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* sdmmc1_clk.sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* sdmmc1_cmd.sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
                >;
        };
 
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_clk.sdmmc2_clk */
-                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_cmd.sdmmc2_cmd */
-                       0x12c (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat0.sdmmc2_dat0 */
-                       0x12e (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat1.sdmmc2_dat1 */
-                       0x130 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat2.sdmmc2_dat2 */
-                       0x132 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat3.sdmmc2_dat3 */
-                       0x134 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat4.sdmmc2_dat4 */
-                       0x136 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat5.sdmmc2_dat5 */
-                       0x138 (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat6.sdmmc2_dat6 */
-                       0x13a (PIN_INPUT | MUX_MODE0)           /* sdmmc2_dat7.sdmmc2_dat7 */
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat3.sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat4.sdmmc2_dat4 */
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat5.sdmmc2_dat5 */
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat6.sdmmc2_dat6 */
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE0)                /* sdmmc2_dat7.sdmmc2_dat7 */
                >;
        };
 
 
        uart1_pins: pinmux_uart1_pins {
                pinctrl-single,pins = <
-                        0x150 (PIN_INPUT | MUX_MODE0)          /* uart1_cts.uart1_cts */
-                        0x14e (PIN_OUTPUT | MUX_MODE0)         /* uart1_rts.uart1_rts */
-                        0x152 (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
-                        0x14c (PIN_OUTPUT | MUX_MODE0)         /* uart1_tx.uart1_tx */
+                        OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0)               /* uart1_cts.uart1_cts */
+                        OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0)              /* uart1_rts.uart1_rts */
+                        OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+                        OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0)              /* uart1_tx.uart1_tx */
                >;
        };
 
        uart2_pins: pinmux_uart2_pins {
                pinctrl-single,pins = <
-                        0x144 (PIN_INPUT_PULLUP | MUX_MODE0)   /* uart2_cts.uart2_cts */
-                        0x146 (PIN_OUTPUT | MUX_MODE0)         /* uart2_rts.uart2_rts */
-                        0x14a (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
-                        0x148 (PIN_OUTPUT | MUX_MODE0)         /* uart2_tx.uart2_tx */
+                        OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0)        /* uart2_cts.uart2_cts */
+                        OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0)              /* uart2_rts.uart2_rts */
+                        OMAP3_CORE1_IOPAD(0x217a, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+                        OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0)              /* uart2_tx.uart2_tx */
                >;
        };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                        0x16a (PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */
-                        0x16c (PIN_OUTPUT | MUX_MODE0)         /* uart3_rts_sd.uart3_rts_sd */
-                        0x16e (WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
-                        0x170 (PIN_OUTPUT | MUX_MODE0)         /* uart3_tx_irtx.uart3_tx_irtx */
+                        OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* uart3_cts_rctx.uart3_cts_rctx */
+                        OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0)              /* uart3_rts_sd.uart3_rts_sd */
+                        OMAP3_CORE1_IOPAD(0x219e, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                        OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)              /* uart3_tx_irtx.uart3_tx_irtx */
                >;
        };
 
        /* wl12xx GPIO output for WLAN_EN */
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0xea (PIN_OUTPUT| MUX_MODE4)            /* cam_d2.gpio_101 */
+                       OMAP3_CORE1_IOPAD(0x211a, PIN_OUTPUT| MUX_MODE4)                /* cam_d2.gpio_101 */
                >;
        };
 };
 &omap3_pmx_wkup {
        wlan_host_wkup: pinmux_wlan_host_wkup_pins {
                pinctrl-single,pins = <
-                       0x1a (PIN_INPUT_PULLUP | MUX_MODE4)     /* sys_clkout1.gpio_10 WLAN_HOST_WKUP */
+                       OMAP3_WKUP_IOPAD(0x2a1a, PIN_INPUT_PULLUP | MUX_MODE4)  /* sys_clkout1.gpio_10 WLAN_HOST_WKUP */
                >;
        };
 };
index 8a2b253..d1ffabb 100644 (file)
                        ti,hwmods = "gpmc";
                        reg = <0x6e000000 0x02d0>;
                        interrupts = <20>;
+                       dmas = <&sdma 4>;
+                       dma-names = "rxtx";
                        gpmc,num-cs = <8>;
                        gpmc,num-waitpins = <4>;
                        #address-cells = <2>;
index b75f7b2..06c5482 100644 (file)
@@ -36,7 +36,7 @@
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio4 25 GPIO_ACTIVE_LOW>;    /* gpio_121 */
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 133f1b7..78d3631 100644 (file)
@@ -13,8 +13,8 @@
 /* Pandaboard Rev A4+ have external pullups on SCL & SDA */
 &dss_hdmi_pins {
        pinctrl-single,pins = <
-               0x5a (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_cec.hdmi_cec */
-               0x5c (PIN_INPUT | MUX_MODE0)            /* hdmi_scl.hdmi_scl */
-               0x5e (PIN_INPUT | MUX_MODE0)            /* hdmi_sda.hdmi_sda */
+               OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+               OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)               /* hdmi_scl.hdmi_scl */
+               OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)               /* hdmi_sda.hdmi_sda */
                >;
 };
index 18d0966..df2e356 100644 (file)
 
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
-                       0xe0 (PIN_OUTPUT | MUX_MODE3)   /* hdq_sio.gpio_127 */
-                       0x160 (PIN_INPUT | MUX_MODE0)   /* sys_nirq2.sys_nirq2 */
+                       OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3)      /* hdq_sio.gpio_127 */
+                       OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0)       /* sys_nirq2.sys_nirq2 */
                >;
        };
 
        mcpdm_pins: pinmux_mcpdm_pins {
                pinctrl-single,pins = <
-                       0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_ul_data.abe_pdm_ul_data */
-                       0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_dl_data.abe_pdm_dl_data */
-                       0xca (PIN_INPUT_PULLUP   | MUX_MODE0)   /* abe_pdm_frame.abe_pdm_frame */
-                       0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_lb_clk.abe_pdm_lb_clk */
-                       0xce (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_clks.abe_clks */
+                       OMAP4_IOPAD(0x106, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_pdm_ul_data.abe_pdm_ul_data */
+                       OMAP4_IOPAD(0x108, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_pdm_dl_data.abe_pdm_dl_data */
+                       OMAP4_IOPAD(0x10a, PIN_INPUT_PULLUP   | MUX_MODE0)      /* abe_pdm_frame.abe_pdm_frame */
+                       OMAP4_IOPAD(0x10c, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+                       OMAP4_IOPAD(0x10e, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_clks.abe_clks */
                >;
        };
 
        mcbsp1_pins: pinmux_mcbsp1_pins {
                pinctrl-single,pins = <
-                       0xbe (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
-                       0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_mcbsp1_dr.abe_mcbsp1_dr */
-                       0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)  /* abe_mcbsp1_dx.abe_mcbsp1_dx */
-                       0xc4 (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
+                       OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0)               /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+                       OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_mcbsp1_dr.abe_mcbsp1_dr */
+                       OMAP4_IOPAD(0x102, PIN_OUTPUT_PULLDOWN | MUX_MODE0)     /* abe_mcbsp1_dx.abe_mcbsp1_dx */
+                       OMAP4_IOPAD(0x104, PIN_INPUT | MUX_MODE0)               /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
                >;
        };
 
        dss_dpi_pins: pinmux_dss_dpi_pins {
                pinctrl-single,pins = <
-                       0x122 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data23 */
-                       0x124 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data22 */
-                       0x126 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data21 */
-                       0x128 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data20 */
-                       0x12a (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data19 */
-                       0x12c (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data18 */
-                       0x12e (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data15 */
-                       0x130 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data14 */
-                       0x132 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data13 */
-                       0x134 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data12 */
-                       0x136 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data11 */
-
-                       0x174 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data10 */
-                       0x176 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data9 */
-                       0x178 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data16 */
-                       0x17a (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data17 */
-                       0x17c (PIN_OUTPUT | MUX_MODE5)  /* dispc2_hsync */
-                       0x17e (PIN_OUTPUT | MUX_MODE5)  /* dispc2_pclk */
-                       0x180 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_vsync */
-                       0x182 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_de */
-                       0x184 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data8 */
-                       0x186 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data7 */
-                       0x188 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data6 */
-                       0x18a (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data5 */
-                       0x18c (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data4 */
-                       0x18e (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data3 */
-
-                       0x190 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data2 */
-                       0x192 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data1 */
-                       0x194 (PIN_OUTPUT | MUX_MODE5)  /* dispc2_data0 */
+                       OMAP4_IOPAD(0x162, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data23 */
+                       OMAP4_IOPAD(0x164, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data22 */
+                       OMAP4_IOPAD(0x166, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data21 */
+                       OMAP4_IOPAD(0x168, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data20 */
+                       OMAP4_IOPAD(0x16a, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data19 */
+                       OMAP4_IOPAD(0x16c, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data18 */
+                       OMAP4_IOPAD(0x16e, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data15 */
+                       OMAP4_IOPAD(0x170, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data14 */
+                       OMAP4_IOPAD(0x172, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data13 */
+                       OMAP4_IOPAD(0x174, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data12 */
+                       OMAP4_IOPAD(0x176, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data11 */
+
+                       OMAP4_IOPAD(0x1b4, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data10 */
+                       OMAP4_IOPAD(0x1b6, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data9 */
+                       OMAP4_IOPAD(0x1b8, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data16 */
+                       OMAP4_IOPAD(0x1ba, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data17 */
+                       OMAP4_IOPAD(0x1bc, PIN_OUTPUT | MUX_MODE5)      /* dispc2_hsync */
+                       OMAP4_IOPAD(0x1be, PIN_OUTPUT | MUX_MODE5)      /* dispc2_pclk */
+                       OMAP4_IOPAD(0x1c0, PIN_OUTPUT | MUX_MODE5)      /* dispc2_vsync */
+                       OMAP4_IOPAD(0x1c2, PIN_OUTPUT | MUX_MODE5)      /* dispc2_de */
+                       OMAP4_IOPAD(0x1c4, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data8 */
+                       OMAP4_IOPAD(0x1c6, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data7 */
+                       OMAP4_IOPAD(0x1c8, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data6 */
+                       OMAP4_IOPAD(0x1ca, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data5 */
+                       OMAP4_IOPAD(0x1cc, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data4 */
+                       OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data3 */
+
+                       OMAP4_IOPAD(0x1d0, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data2 */
+                       OMAP4_IOPAD(0x1d2, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data1 */
+                       OMAP4_IOPAD(0x1d4, PIN_OUTPUT | MUX_MODE5)      /* dispc2_data0 */
                >;
        };
 
        tfp410_pins: pinmux_tfp410_pins {
                pinctrl-single,pins = <
-                       0x144 (PIN_OUTPUT | MUX_MODE3)  /* gpio_0 */
+                       OMAP4_IOPAD(0x184, PIN_OUTPUT | MUX_MODE3)      /* gpio_0 */
                >;
        };
 
        dss_hdmi_pins: pinmux_dss_hdmi_pins {
                pinctrl-single,pins = <
-                       0x5a (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_cec.hdmi_cec */
-                       0x5c (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_scl.hdmi_scl */
-                       0x5e (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_sda.hdmi_sda */
+                       OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+                       OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_scl.hdmi_scl */
+                       OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_sda.hdmi_sda */
                >;
        };
 
        tpd12s015_pins: pinmux_tpd12s015_pins {
                pinctrl-single,pins = <
-                       0x22 (PIN_OUTPUT | MUX_MODE3)           /* gpmc_a17.gpio_41 */
-                       0x48 (PIN_OUTPUT | MUX_MODE3)           /* gpmc_nbe1.gpio_60 */
-                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE3)   /* hdmi_hpd.gpio_63 */
+                       OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3)              /* gpmc_a17.gpio_41 */
+                       OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3)              /* gpmc_nbe1.gpio_60 */
+                       OMAP4_IOPAD(0x098, PIN_INPUT_PULLDOWN | MUX_MODE3)      /* hdmi_hpd.gpio_63 */
                >;
        };
 
        hsusbb1_pins: pinmux_hsusbb1_pins {
                pinctrl-single,pins = <
-                       0x82 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
-                       0x84 (PIN_OUTPUT | MUX_MODE4)           /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
-                       0x86 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
-                       0x88 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
-                       0x8a (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
-                       0x8c (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
-                       0x8e (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
-                       0x90 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
-                       0x92 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
-                       0x94 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
-                       0x96 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
-                       0x98 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
+                       OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
+                       OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4)              /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
+                       OMAP4_IOPAD(0x0c6, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
+                       OMAP4_IOPAD(0x0c8, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
+                       OMAP4_IOPAD(0x0ca, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
+                       OMAP4_IOPAD(0x0cc, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
+                       OMAP4_IOPAD(0x0ce, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
+                       OMAP4_IOPAD(0x0d0, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
+                       OMAP4_IOPAD(0x0d2, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
+                       OMAP4_IOPAD(0x0d4, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
+                       OMAP4_IOPAD(0x0d6, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
+                       OMAP4_IOPAD(0x0d8, PIN_INPUT_PULLDOWN | MUX_MODE4)      /* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
                >;
        };
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0xe2 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c1_scl */
-                       0xe4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c1_sda */
+                       OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c1_scl */
+                       OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c1_sda */
                >;
        };
 
        i2c2_pins: pinmux_i2c2_pins {
                pinctrl-single,pins = <
-                       0xe6 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c2_scl */
-                       0xe8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c2_sda */
+                       OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c2_scl */
+                       OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c2_sda */
                >;
        };
 
        i2c3_pins: pinmux_i2c3_pins {
                pinctrl-single,pins = <
-                       0xea (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c3_scl */
-                       0xec (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c3_sda */
+                       OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c3_scl */
+                       OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c3_sda */
                >;
        };
 
        i2c4_pins: pinmux_i2c4_pins {
                pinctrl-single,pins = <
-                       0xee (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c4_scl */
-                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c4_sda */
+                       OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c4_scl */
+                       OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c4_sda */
                >;
        };
 
         */
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0x26 (PIN_OUTPUT | MUX_MODE3)           /* gpmc_a19.gpio_43 */
-                       0x2c (PIN_OUTPUT | MUX_MODE3)           /* gpmc_a22.gpio_46 */
-                       0x30 (PIN_OUTPUT_PULLUP | MUX_MODE3)    /* gpmc_a24.gpio_48 */
-                       0x32 (PIN_OUTPUT_PULLUP | MUX_MODE3)    /* gpmc_a25.gpio_49 */
+                       OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3)              /* gpmc_a19.gpio_43 */
+                       OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3)              /* gpmc_a22.gpio_46 */
+                       OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLUP | MUX_MODE3)       /* gpmc_a24.gpio_48 */
+                       OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3)       /* gpmc_a25.gpio_49 */
                >;
        };
 
        /* wl12xx GPIO inputs and SDIO pins */
        wl12xx_pins: pinmux_wl12xx_pins {
                pinctrl-single,pins = <
-                       0x38 (PIN_INPUT | MUX_MODE3)            /* gpmc_ncs2.gpio_52 */
-                       0x3a (PIN_INPUT | MUX_MODE3)            /* gpmc_ncs3.gpio_53 */
-                       0x108 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_clk.sdmmc5_clk */
-                       0x10a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_cmd.sdmmc5_cmd */
-                       0x10c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat0.sdmmc5_dat0 */
-                       0x10e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat1.sdmmc5_dat1 */
-                       0x110 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat2.sdmmc5_dat2 */
-                       0x112 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat3.sdmmc5_dat3 */
+                       OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3)               /* gpmc_ncs2.gpio_52 */
+                       OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3)               /* gpmc_ncs3.gpio_53 */
+                       OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_clk.sdmmc5_clk */
+                       OMAP4_IOPAD(0x14a, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_cmd.sdmmc5_cmd */
+                       OMAP4_IOPAD(0x14c, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat0.sdmmc5_dat0 */
+                       OMAP4_IOPAD(0x14e, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat1.sdmmc5_dat1 */
+                       OMAP4_IOPAD(0x150, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat2.sdmmc5_dat2 */
+                       OMAP4_IOPAD(0x152, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat3.sdmmc5_dat3 */
                >;
        };
 };
 &omap4_pmx_wkup {
        led_wkgpio_pins: pinmux_leds_wkpins {
                pinctrl-single,pins = <
-                       0x1a (PIN_OUTPUT | MUX_MODE3)   /* gpio_wk7 */
-                       0x1c (PIN_OUTPUT | MUX_MODE3)   /* gpio_wk8 */
+                       OMAP4_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE3)      /* gpio_wk7 */
+                       OMAP4_IOPAD(0x05c, PIN_OUTPUT | MUX_MODE3)      /* gpio_wk8 */
                >;
        };
 };
index 2f1dabc..119f8e6 100644 (file)
 /* PandaboardES has external pullups on SCL & SDA */
 &dss_hdmi_pins {
        pinctrl-single,pins = <
-               0x5a (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_cec.hdmi_cec */
-               0x5c (PIN_INPUT | MUX_MODE0)            /* hdmi_scl.hdmi_scl */
-               0x5e (PIN_INPUT | MUX_MODE0)            /* hdmi_sda.hdmi_sda */
+               OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+               OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)               /* hdmi_scl.hdmi_scl */
+               OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)               /* hdmi_sda.hdmi_sda */
                >;
 };
 
 &omap4_pmx_core {
        led_gpio_pins: gpio_led_pmx {
                pinctrl-single,pins = <
-                       0xb6 (PIN_OUTPUT | MUX_MODE3)   /* gpio_110 */
+                       OMAP4_IOPAD(0x0f6, PIN_OUTPUT | MUX_MODE3)      /* gpio_110 */
                >;
        };
 };
 
 &led_wkgpio_pins {
        pinctrl-single,pins = <
-               0x1c (PIN_OUTPUT | MUX_MODE3)   /* gpio_wk8 */
+               OMAP4_IOPAD(0x05c, PIN_OUTPUT | MUX_MODE3)      /* gpio_wk8 */
        >;
 };
 
index aad5dda..b4d19a7 100644 (file)
@@ -10,8 +10,8 @@
 /* SDP boards with 4430 ES2.3+ or 4460 have external pullups on SCL & SDA */
 &dss_hdmi_pins {
        pinctrl-single,pins = <
-               0x5a (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_cec.hdmi_cec */
-               0x5c (PIN_INPUT | MUX_MODE0)            /* hdmi_scl.hdmi_scl */
-               0x5e (PIN_INPUT | MUX_MODE0)            /* hdmi_sda.hdmi_sda */
+               OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+               OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)               /* hdmi_scl.hdmi_scl */
+               OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)               /* hdmi_sda.hdmi_sda */
                >;
 };
index f0bdc41..aae5132 100644 (file)
 
        uart2_pins: pinmux_uart2_pins {
                pinctrl-single,pins = <
-                       0xd8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* uart2_cts.uart2_cts */
-                       0xda (PIN_OUTPUT | MUX_MODE0)           /* uart2_rts.uart2_rts */
-                       0xdc (PIN_INPUT_PULLUP | MUX_MODE0)     /* uart2_rx.uart2_rx */
-                       0xde (PIN_OUTPUT | MUX_MODE0)           /* uart2_tx.uart2_tx */
+                       OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0)        /* uart2_cts.uart2_cts */
+                       OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0)              /* uart2_rts.uart2_rts */
+                       OMAP4_IOPAD(0x11c, PIN_INPUT_PULLUP | MUX_MODE0)        /* uart2_rx.uart2_rx */
+                       OMAP4_IOPAD(0x11e, PIN_OUTPUT | MUX_MODE0)              /* uart2_tx.uart2_tx */
                >;
        };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x100 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart3_cts_rctx.uart3_cts_rctx */
-                       0x102 (PIN_OUTPUT | MUX_MODE0)          /* uart3_rts_sd.uart3_rts_sd */
-                       0x104 (PIN_INPUT | MUX_MODE0)           /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x106 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx_irtx.uart3_tx_irtx */
+                       OMAP4_IOPAD(0x140, PIN_INPUT_PULLUP | MUX_MODE0)        /* uart3_cts_rctx.uart3_cts_rctx */
+                       OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE0)              /* uart3_rts_sd.uart3_rts_sd */
+                       OMAP4_IOPAD(0x144, PIN_INPUT | MUX_MODE0)               /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP4_IOPAD(0x146, PIN_OUTPUT | MUX_MODE0)              /* uart3_tx_irtx.uart3_tx_irtx */
                >;
        };
 
        uart4_pins: pinmux_uart4_pins {
                pinctrl-single,pins = <
-                       0x11c (PIN_INPUT | MUX_MODE0)           /* uart4_rx.uart4_rx */
-                       0x11e (PIN_OUTPUT | MUX_MODE0)          /* uart4_tx.uart4_tx */
+                       OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0)               /* uart4_rx.uart4_rx */
+                       OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0)              /* uart4_tx.uart4_tx */
                >;
        };
 
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
-                       0xe0 (PIN_OUTPUT | MUX_MODE3)           /* hdq_sio.gpio_127 */
-                       0x160 (PIN_INPUT | MUX_MODE0)           /* sys_nirq2.sys_nirq2 */
+                       OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3)              /* hdq_sio.gpio_127 */
+                       OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0)               /* sys_nirq2.sys_nirq2 */
                >;
        };
 
        mcpdm_pins: pinmux_mcpdm_pins {
                pinctrl-single,pins = <
-                       0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_ul_data.abe_pdm_ul_data */
-                       0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_dl_data.abe_pdm_dl_data */
-                       0xca (PIN_INPUT_PULLUP | MUX_MODE0)     /* abe_pdm_frame.abe_pdm_frame */
-                       0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_lb_clk.abe_pdm_lb_clk */
-                       0xce (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_clks.abe_clks */
+                       OMAP4_IOPAD(0x106, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_pdm_ul_data.abe_pdm_ul_data */
+                       OMAP4_IOPAD(0x108, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_pdm_dl_data.abe_pdm_dl_data */
+                       OMAP4_IOPAD(0x10a, PIN_INPUT_PULLUP | MUX_MODE0)        /* abe_pdm_frame.abe_pdm_frame */
+                       OMAP4_IOPAD(0x10c, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+                       OMAP4_IOPAD(0x10e, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_clks.abe_clks */
                >;
        };
 
        dmic_pins: pinmux_dmic_pins {
                pinctrl-single,pins = <
-                       0xd0 (PIN_OUTPUT | MUX_MODE0)           /* abe_dmic_clk1.abe_dmic_clk1 */
-                       0xd2 (PIN_INPUT | MUX_MODE0)            /* abe_dmic_din1.abe_dmic_din1 */
-                       0xd4 (PIN_INPUT | MUX_MODE0)            /* abe_dmic_din2.abe_dmic_din2 */
-                       0xd6 (PIN_INPUT | MUX_MODE0)            /* abe_dmic_din3.abe_dmic_din3 */
+                       OMAP4_IOPAD(0x110, PIN_OUTPUT | MUX_MODE0)              /* abe_dmic_clk1.abe_dmic_clk1 */
+                       OMAP4_IOPAD(0x112, PIN_INPUT | MUX_MODE0)               /* abe_dmic_din1.abe_dmic_din1 */
+                       OMAP4_IOPAD(0x114, PIN_INPUT | MUX_MODE0)               /* abe_dmic_din2.abe_dmic_din2 */
+                       OMAP4_IOPAD(0x116, PIN_INPUT | MUX_MODE0)               /* abe_dmic_din3.abe_dmic_din3 */
                >;
        };
 
        mcbsp1_pins: pinmux_mcbsp1_pins {
                pinctrl-single,pins = <
-                       0xbe (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
-                       0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_mcbsp1_dr.abe_mcbsp1_dr */
-                       0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)  /* abe_mcbsp1_dx.abe_mcbsp1_dx */
-                       0xc4 (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
+                       OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0)               /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+                       OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_mcbsp1_dr.abe_mcbsp1_dr */
+                       OMAP4_IOPAD(0x102, PIN_OUTPUT_PULLDOWN | MUX_MODE0)     /* abe_mcbsp1_dx.abe_mcbsp1_dx */
+                       OMAP4_IOPAD(0x104, PIN_INPUT | MUX_MODE0)               /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
                >;
        };
 
        mcbsp2_pins: pinmux_mcbsp2_pins {
                pinctrl-single,pins = <
-                       0xb6 (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp2_clkx.abe_mcbsp2_clkx */
-                       0xb8 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_mcbsp2_dr.abe_mcbsp2_dr */
-                       0xba (PIN_OUTPUT_PULLDOWN | MUX_MODE0)  /* abe_mcbsp2_dx.abe_mcbsp2_dx */
-                       0xbc (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp2_fsx.abe_mcbsp2_fsx */
+                       OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0)               /* abe_mcbsp2_clkx.abe_mcbsp2_clkx */
+                       OMAP4_IOPAD(0x0f8, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_mcbsp2_dr.abe_mcbsp2_dr */
+                       OMAP4_IOPAD(0x0fa, PIN_OUTPUT_PULLDOWN | MUX_MODE0)     /* abe_mcbsp2_dx.abe_mcbsp2_dx */
+                       OMAP4_IOPAD(0x0fc, PIN_INPUT | MUX_MODE0)               /* abe_mcbsp2_fsx.abe_mcbsp2_fsx */
                >;
        };
 
        mcspi1_pins: pinmux_mcspi1_pins {
                pinctrl-single,pins = <
-                       0xf2 (PIN_INPUT | MUX_MODE0)            /*  mcspi1_clk.mcspi1_clk */
-                       0xf4 (PIN_INPUT | MUX_MODE0)            /*  mcspi1_somi.mcspi1_somi */
-                       0xf6 (PIN_INPUT | MUX_MODE0)            /*  mcspi1_simo.mcspi1_simo */
-                       0xf8 (PIN_INPUT | MUX_MODE0)            /*  mcspi1_cs0.mcspi1_cs0 */
+                       OMAP4_IOPAD(0x132, PIN_INPUT | MUX_MODE0)               /*  mcspi1_clk.mcspi1_clk */
+                       OMAP4_IOPAD(0x134, PIN_INPUT | MUX_MODE0)               /*  mcspi1_somi.mcspi1_somi */
+                       OMAP4_IOPAD(0x136, PIN_INPUT | MUX_MODE0)               /*  mcspi1_simo.mcspi1_simo */
+                       OMAP4_IOPAD(0x138, PIN_INPUT | MUX_MODE0)               /*  mcspi1_cs0.mcspi1_cs0 */
                >;
        };
 
        dss_hdmi_pins: pinmux_dss_hdmi_pins {
                pinctrl-single,pins = <
-                       0x5a (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_cec.hdmi_cec */
-                       0x5c (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_scl.hdmi_scl */
-                       0x5e (PIN_INPUT_PULLUP | MUX_MODE0)     /* hdmi_sda.hdmi_sda */
+                       OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+                       OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_scl.hdmi_scl */
+                       OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_sda.hdmi_sda */
                >;
        };
 
        tpd12s015_pins: pinmux_tpd12s015_pins {
                pinctrl-single,pins = <
-                       0x22 (PIN_OUTPUT | MUX_MODE3)           /* gpmc_a17.gpio_41 */
-                       0x48 (PIN_OUTPUT | MUX_MODE3)           /* gpmc_nbe1.gpio_60 */
-                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE3)   /* hdmi_hpd.gpio_63 */
+                       OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3)              /* gpmc_a17.gpio_41 */
+                       OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3)              /* gpmc_nbe1.gpio_60 */
+                       OMAP4_IOPAD(0x098, PIN_INPUT_PULLDOWN | MUX_MODE3)      /* hdmi_hpd.gpio_63 */
                >;
        };
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0xe2 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c1_scl */
-                       0xe4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c1_sda */
+                       OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c1_scl */
+                       OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c1_sda */
                >;
        };
 
        i2c2_pins: pinmux_i2c2_pins {
                pinctrl-single,pins = <
-                       0xe6 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c2_scl */
-                       0xe8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c2_sda */
+                       OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c2_scl */
+                       OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c2_sda */
                >;
        };
 
        i2c3_pins: pinmux_i2c3_pins {
                pinctrl-single,pins = <
-                       0xea (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c3_scl */
-                       0xec (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c3_sda */
+                       OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c3_scl */
+                       OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c3_sda */
                >;
        };
 
        i2c4_pins: pinmux_i2c4_pins {
                pinctrl-single,pins = <
-                       0xee (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c4_scl */
-                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c4_sda */
+                       OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c4_scl */
+                       OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c4_sda */
                >;
        };
 
        /* wl12xx GPIO output for WLAN_EN */
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0x3c (PIN_OUTPUT | MUX_MODE3)           /* gpmc_nwp.gpio_54 */
+                       OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3)              /* gpmc_nwp.gpio_54 */
                >;
        };
 
        /* wl12xx GPIO inputs and SDIO pins */
        wl12xx_pins: pinmux_wl12xx_pins {
                pinctrl-single,pins = <
-                       0x3a (PIN_INPUT | MUX_MODE3)            /* gpmc_ncs3.gpio_53 */
-                       0x108 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_clk.sdmmc5_clk */
-                       0x10a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_cmd.sdmmc5_cmd */
-                       0x10c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat0.sdmmc5_dat0 */
-                       0x10e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat1.sdmmc5_dat1 */
-                       0x110 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat2.sdmmc5_dat2 */
-                       0x112 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat3.sdmmc5_dat3 */
+                       OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3)               /* gpmc_ncs3.gpio_53 */
+                       OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_clk.sdmmc5_clk */
+                       OMAP4_IOPAD(0x14a, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_cmd.sdmmc5_cmd */
+                       OMAP4_IOPAD(0x14c, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat0.sdmmc5_dat0 */
+                       OMAP4_IOPAD(0x14e, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat1.sdmmc5_dat1 */
+                       OMAP4_IOPAD(0x150, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat2.sdmmc5_dat2 */
+                       OMAP4_IOPAD(0x152, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat3.sdmmc5_dat3 */
                >;
        };
 };
index f2d2fdb..6e278d7 100644 (file)
@@ -41,7 +41,7 @@
                        label = "user";
                        gpios = <&gpio6 24 GPIO_ACTIVE_HIGH>; /* gpio 184 */
                        linux,code = <BTN_EXTRA>;
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index 5a206c1..2bd9c83 100644 (file)
                        #interrupt-cells = <2>;
                };
 
+               elm: elm@48078000 {
+                       compatible = "ti,am3352-elm";
+                       reg = <0x48078000 0x2000>;
+                       interrupts = <4>;
+                       ti,hwmods = "elm";
+                       status = "disabled";
+               };
+
                gpmc: gpmc@50000000 {
                        compatible = "ti,omap4430-gpmc";
                        reg = <0x50000000 0x1000>;
                        #address-cells = <2>;
                        #size-cells = <1>;
                        interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&sdma 4>;
+                       dma-names = "rxtx";
                        gpmc,num-cs = <8>;
                        gpmc,num-waitpins = <4>;
                        ti,hwmods = "gpmc";
index 5cf76a1..888412c 100644 (file)
 
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
-                       0x17e (PIN_OUTPUT | MUX_MODE6)  /* mcspi1_somi.gpio5_141 */
+                       OMAP5_IOPAD(0x1be, PIN_OUTPUT | MUX_MODE6)      /* mcspi1_somi.gpio5_141 */
                >;
        };
 
        mcpdm_pins: pinmux_mcpdm_pins {
                pinctrl-single,pins = <
-                       0x142 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* abe_clks.abe_clks */
-                       0x15c (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* abemcpdm_ul_data.abemcpdm_ul_data */
-                       0x15e (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* abemcpdm_dl_data.abemcpdm_dl_data */
-                       0x160 (PIN_INPUT_PULLUP | MUX_MODE0)    /* abemcpdm_frame.abemcpdm_frame */
-                       0x162 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* abemcpdm_lb_clk.abemcpdm_lb_clk */
+                       OMAP5_IOPAD(0x182, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abe_clks.abe_clks */
+                       OMAP5_IOPAD(0x19c, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abemcpdm_ul_data.abemcpdm_ul_data */
+                       OMAP5_IOPAD(0x19e, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abemcpdm_dl_data.abemcpdm_dl_data */
+                       OMAP5_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE0)        /* abemcpdm_frame.abemcpdm_frame */
+                       OMAP5_IOPAD(0x1a2, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abemcpdm_lb_clk.abemcpdm_lb_clk */
                >;
        };
 
        mcbsp1_pins: pinmux_mcbsp1_pins {
                pinctrl-single,pins = <
-                       0x14c (PIN_INPUT | MUX_MODE1)           /* abedmic_clk2.abemcbsp1_fsx */
-                       0x14e (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* abedmic_clk3.abemcbsp1_dx */
-                       0x150 (PIN_INPUT | MUX_MODE1)           /* abeslimbus1_clock.abemcbsp1_clkx */
-                       0x152 (PIN_INPUT_PULLDOWN | MUX_MODE1)  /* abeslimbus1_data.abemcbsp1_dr */
+                       OMAP5_IOPAD(0x18c, PIN_INPUT | MUX_MODE1)               /* abedmic_clk2.abemcbsp1_fsx */
+                       OMAP5_IOPAD(0x18e, PIN_OUTPUT_PULLDOWN | MUX_MODE1)     /* abedmic_clk3.abemcbsp1_dx */
+                       OMAP5_IOPAD(0x190, PIN_INPUT | MUX_MODE1)               /* abeslimbus1_clock.abemcbsp1_clkx */
+                       OMAP5_IOPAD(0x192, PIN_INPUT_PULLDOWN | MUX_MODE1)      /* abeslimbus1_data.abemcbsp1_dr */
                >;
        };
 
        mcbsp2_pins: pinmux_mcbsp2_pins {
                pinctrl-single,pins = <
-                       0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* abemcbsp2_dr.abemcbsp2_dr */
-                       0x156 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abemcbsp2_dx.abemcbsp2_dx */
-                       0x158 (PIN_INPUT | MUX_MODE0)           /* abemcbsp2_fsx.abemcbsp2_fsx */
-                       0x15a (PIN_INPUT | MUX_MODE0)           /* abemcbsp2_clkx.abemcbsp2_clkx */
+                       OMAP5_IOPAD(0x194, PIN_INPUT_PULLDOWN | MUX_MODE0)      /* abemcbsp2_dr.abemcbsp2_dr */
+                       OMAP5_IOPAD(0x196, PIN_OUTPUT_PULLDOWN | MUX_MODE0)     /* abemcbsp2_dx.abemcbsp2_dx */
+                       OMAP5_IOPAD(0x198, PIN_INPUT | MUX_MODE0)               /* abemcbsp2_fsx.abemcbsp2_fsx */
+                       OMAP5_IOPAD(0x19a, PIN_INPUT | MUX_MODE0)               /* abemcbsp2_clkx.abemcbsp2_clkx */
                >;
        };
 
        i2c1_pins: pinmux_i2c1_pins {
                pinctrl-single,pins = <
-                       0x1b2 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl */
-                       0x1b4 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda */
+                       OMAP5_IOPAD(0x1f2, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c1_scl */
+                       OMAP5_IOPAD(0x1f4, PIN_INPUT_PULLUP | MUX_MODE0)        /* i2c1_sda */
                >;
        };
 
        mcspi2_pins: pinmux_mcspi2_pins {
                pinctrl-single,pins = <
-                       0xbc (PIN_INPUT | MUX_MODE0)            /*  mcspi2_clk */
-                       0xbe (PIN_INPUT | MUX_MODE0)            /*  mcspi2_simo */
-                       0xc0 (PIN_INPUT_PULLUP | MUX_MODE0)     /*  mcspi2_somi */
-                       0xc2 (PIN_OUTPUT | MUX_MODE0)           /*  mcspi2_cs0 */
+                       OMAP5_IOPAD(0x0fc, PIN_INPUT | MUX_MODE0)               /*  mcspi2_clk */
+                       OMAP5_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0)               /*  mcspi2_simo */
+                       OMAP5_IOPAD(0x100, PIN_INPUT_PULLUP | MUX_MODE0)        /*  mcspi2_somi */
+                       OMAP5_IOPAD(0x102, PIN_OUTPUT | MUX_MODE0)              /*  mcspi2_cs0 */
                >;
        };
 
        mcspi3_pins: pinmux_mcspi3_pins {
                pinctrl-single,pins = <
-                       0x78 (PIN_INPUT | MUX_MODE1)            /*  mcspi3_somi */
-                       0x7a (PIN_INPUT | MUX_MODE1)            /*  mcspi3_cs0 */
-                       0x7c (PIN_INPUT | MUX_MODE1)            /*  mcspi3_simo */
-                       0x7e (PIN_INPUT | MUX_MODE1)            /*  mcspi3_clk */
+                       OMAP5_IOPAD(0x0b8, PIN_INPUT | MUX_MODE1)               /*  mcspi3_somi */
+                       OMAP5_IOPAD(0x0ba, PIN_INPUT | MUX_MODE1)               /*  mcspi3_cs0 */
+                       OMAP5_IOPAD(0x0bc, PIN_INPUT | MUX_MODE1)               /*  mcspi3_simo */
+                       OMAP5_IOPAD(0x0be, PIN_INPUT | MUX_MODE1)               /*  mcspi3_clk */
                >;
        };
 
 
        usbhost_pins: pinmux_usbhost_pins {
                pinctrl-single,pins = <
-                       0x84 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
-                       0x86 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_data */
+                       OMAP5_IOPAD(0x0c4, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
+                       OMAP5_IOPAD(0x0c6, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_data */
 
-                       0x19e (PIN_INPUT | MUX_MODE0) /* usbb3_hsic_strobe */
-                       0x1a0 (PIN_INPUT | MUX_MODE0) /* usbb3_hsic_data */
+                       OMAP5_IOPAD(0x1de, PIN_INPUT | MUX_MODE0) /* usbb3_hsic_strobe */
+                       OMAP5_IOPAD(0x1e0, PIN_INPUT | MUX_MODE0) /* usbb3_hsic_data */
 
-                       0x70 (PIN_OUTPUT | MUX_MODE6) /* gpio3_80 HUB_NRESET */
-                       0x6e (PIN_OUTPUT | MUX_MODE6) /* gpio3_79 ETH_NRESET */
+                       OMAP5_IOPAD(0x0b0, PIN_OUTPUT | MUX_MODE6) /* gpio3_80 HUB_NRESET */
+                       OMAP5_IOPAD(0x0ae, PIN_OUTPUT | MUX_MODE6) /* gpio3_79 ETH_NRESET */
                >;
        };
 
        led_gpio_pins: pinmux_led_gpio_pins {
                pinctrl-single,pins = <
-                       0x196 (PIN_OUTPUT | MUX_MODE6) /* uart3_cts_rctx.gpio5_153 */
+                       OMAP5_IOPAD(0x1d6, PIN_OUTPUT | MUX_MODE6) /* uart3_cts_rctx.gpio5_153 */
                >;
        };
 
        uart1_pins: pinmux_uart1_pins {
                pinctrl-single,pins = <
-                       0x60 (PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_cts */
-                       0x62 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_tx.uart1_cts */
-                       0x64 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rx.uart1_rts */
-                       0x66 (PIN_OUTPUT | MUX_MODE0) /* uart1_rx.uart1_rts */
+                       OMAP5_IOPAD(0x0a0, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_cts */
+                       OMAP5_IOPAD(0x0a2, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_tx.uart1_cts */
+                       OMAP5_IOPAD(0x0a4, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rx.uart1_rts */
+                       OMAP5_IOPAD(0x0a6, PIN_OUTPUT | MUX_MODE0) /* uart1_rx.uart1_rts */
                >;
        };
 
        uart3_pins: pinmux_uart3_pins {
                pinctrl-single,pins = <
-                       0x19a (PIN_OUTPUT | MUX_MODE0) /* uart3_rts_irsd.uart3_tx_irtx */
-                       0x19c (PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_rx_irrx.uart3_usbb3_hsic */
+                       OMAP5_IOPAD(0x1da, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_irsd.uart3_tx_irtx */
+                       OMAP5_IOPAD(0x1dc, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_rx_irrx.uart3_usbb3_hsic */
                >;
        };
 
        uart5_pins: pinmux_uart5_pins {
                pinctrl-single,pins = <
-                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_rx.uart5_rx */
-                       0x172 (PIN_OUTPUT | MUX_MODE0) /* uart5_tx.uart5_tx */
-                       0x174 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_cts.uart5_rts */
-                       0x176 (PIN_OUTPUT | MUX_MODE0) /* uart5_cts.uart5_rts */
+                       OMAP5_IOPAD(0x1b0, PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_rx.uart5_rx */
+                       OMAP5_IOPAD(0x1b2, PIN_OUTPUT | MUX_MODE0) /* uart5_tx.uart5_tx */
+                       OMAP5_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_cts.uart5_rts */
+                       OMAP5_IOPAD(0x1b6, PIN_OUTPUT | MUX_MODE0) /* uart5_cts.uart5_rts */
                >;
        };
 
        dss_hdmi_pins: pinmux_dss_hdmi_pins {
                pinctrl-single,pins = <
-                       0x0fc (PIN_INPUT_PULLUP | MUX_MODE0)    /* hdmi_cec.hdmi_cec */
-                       0x100 (PIN_INPUT | MUX_MODE0)   /* hdmi_ddc_scl.hdmi_ddc_scl */
-                       0x102 (PIN_INPUT | MUX_MODE0)   /* hdmi_ddc_sda.hdmi_ddc_sda */
+                       OMAP5_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+                       OMAP5_IOPAD(0x140, PIN_INPUT | MUX_MODE0)       /* hdmi_ddc_scl.hdmi_ddc_scl */
+                       OMAP5_IOPAD(0x142, PIN_INPUT | MUX_MODE0)       /* hdmi_ddc_sda.hdmi_ddc_sda */
                >;
        };
 
        tpd12s015_pins: pinmux_tpd12s015_pins {
                pinctrl-single,pins = <
-                       0x0fe (PIN_INPUT_PULLDOWN | MUX_MODE6)  /* hdmi_hpd.gpio7_193 */
+                       OMAP5_IOPAD(0x13e, PIN_INPUT_PULLDOWN | MUX_MODE6)      /* hdmi_hpd.gpio7_193 */
                >;
        };
 };
 
        usbhost_wkup_pins: pinmux_usbhost_wkup_pins {
                pinctrl-single,pins = <
-                       0x1A (PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
+                       OMAP5_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
                >;
        };
 
        wlcore_irq_pin: pinmux_wlcore_irq_pin {
                pinctrl-single,pins = <
-                       OMAP5_IOPAD(0x040, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE6)    /* llia_wakereqin.gpio1_wk14 */
+                       OMAP5_IOPAD(0x40, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE6)     /* llia_wakereqin.gpio1_wk14 */
                >;
        };
 };
index 3774b37..ecc591d 100644 (file)
 
        ads7846_pins: pinmux_ads7846_pins {
                pinctrl-single,pins = <
-                       0x02 (PIN_INPUT_PULLDOWN | MUX_MODE6)  /* llib_wakereqin.gpio1_wk15 */
+                       OMAP5_IOPAD(0x0042, PIN_INPUT_PULLDOWN | MUX_MODE6)  /* llib_wakereqin.gpio1_wk15 */
                >;
        };
 };
                ti,debounce-tol = /bits/ 16 <10>;
                ti,debounce-rep = /bits/ 16 <1>;
 
-               linux,wakeup;
+               wakeup-source;
        };
 };
 
index 05b1c1e..60b3fbb 100644 (file)
@@ -40,8 +40,8 @@
 &omap5_pmx_core {
        i2c5_pins: pinmux_i2c5_pins {
                pinctrl-single,pins = <
-                       0x186 (PIN_INPUT | MUX_MODE0)           /* i2c5_scl */
-                       0x188 (PIN_INPUT | MUX_MODE0)           /* i2c5_sda */
+                       OMAP5_IOPAD(0x1c6, PIN_INPUT | MUX_MODE0)               /* i2c5_scl */
+                       OMAP5_IOPAD(0x1c8, PIN_INPUT | MUX_MODE0)               /* i2c5_sda */
                >;
        };
 };
index 4c04389..ca3c17f 100644 (file)
                        #address-cells = <2>;
                        #size-cells = <1>;
                        interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&sdma 4>;
+                       dma-names = "rxtx";
                        gpmc,num-cs = <8>;
                        gpmc,num-waitpins = <4>;
                        ti,hwmods = "gpmc";
index 90fdbd7..7d253bb 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 /dts-v1/;
-/include/ "lpc32xx.dtsi"
+#include "lpc32xx.dtsi"
 
 / {
        model = "PHYTEC phyCORE-LPC3250 board based on NXP LPC3250";
@@ -22,7 +22,7 @@
 
        memory {
                device_type = "memory";
-               reg = <0 0x4000000>;
+               reg = <0x80000000 0x4000000>;
        };
 
        ahb {
                        use-iram;
                };
 
-               /* Here, choose exactly one from: ohci, usbd */
-               ohci@31020000 {
-                       transceiver = <&isp1301>;
-                       status = "okay";
-               };
-
-/*
-               usbd@31020000 {
-                       transceiver = <&isp1301>;
-                       status = "okay";
-               };
-*/
-
                clcd@31040000 {
                        status = "okay";
                };
                                clock-frequency = <100000>;
                        };
 
-                       i2cusb: i2c@31020300 {
-                               clock-frequency = <100000>;
-
-                               isp1301: usb-transceiver@2c {
-                                       compatible = "nxp,isp1301";
-                                       reg = <0x2c>;
-                               };
-                       };
-
                        ssp0: ssp@20084000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                };
        };
 };
+
+/* Here, choose exactly one from: ohci, usbd */
+&ohci /* &usbd */ {
+       transceiver = <&isp1301>;
+       status = "okay";
+};
+
+&i2cusb {
+       clock-frequency = <100000>;
+
+       isp1301: usb-transceiver@2c {
+               compatible = "nxp,isp1301";
+               reg = <0x2c>;
+       };
+};
index 03784f1..21095da 100644 (file)
@@ -54,7 +54,7 @@
 
 
                                /* Buck SMPS */
-                               pm8921_s1: s1 {
+                               s1 {
                                        regulator-always-on;
                                        regulator-min-microvolt = <1225000>;
                                        regulator-max-microvolt = <1225000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_s3: s3 {
+                               s3 {
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1400000>;
                                        qcom,switch-mode-frequency = <4800000>;
                                };
 
-                               pm8921_s4: s4 {
+                               s4 {
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        qcom,switch-mode-frequency = <3200000>;
                                };
 
-                               pm8921_s7: s7 {
+                               s7 {
                                        regulator-min-microvolt = <1300000>;
                                        regulator-max-microvolt = <1300000>;
                                        qcom,switch-mode-frequency = <3200000>;
                                };
 
-                               pm8921_l3: l3 {
+                               l3 {
                                        regulator-min-microvolt = <3050000>;
                                        regulator-max-microvolt = <3300000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l4: l4 {
+                               l4 {
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1800000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l5: l5 {
+                               l5 {
                                        regulator-min-microvolt = <2750000>;
                                        regulator-max-microvolt = <3000000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l23: l23 {
+                               l23 {
                                        regulator-min-microvolt = <1700000>;
                                        regulator-max-microvolt = <1900000>;
                                        bias-pull-down;
index 11ac608..fd4d49e 100644 (file)
                                        bias-disable;
                                };
                        };
+
+                       pcie_pins: pcie_pinmux {
+                               mux {
+                                       pins = "gpio27";
+                                       function = "gpio";
+                               };
+                               conf {
+                                       pins = "gpio27";
+                                       drive-strength = <12>;
+                                       bias-disable;
+                               };
+                       };
                };
 
                rpm@108000 {
@@ -64,7 +76,7 @@
 
 
                                /* Buck SMPS */
-                               pm8921_s1: s1 {
+                               s1 {
                                        regulator-always-on;
                                        regulator-min-microvolt = <1225000>;
                                        regulator-max-microvolt = <1225000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_s3: s3 {
+                               s3 {
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1400000>;
                                        qcom,switch-mode-frequency = <4800000>;
                                };
 
-                               pm8921_s4: s4 {
+                               s4 {
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        qcom,switch-mode-frequency = <3200000>;
                                };
 
-                               pm8921_s7: s7 {
+                               s7 {
                                        regulator-min-microvolt = <1300000>;
                                        regulator-max-microvolt = <1300000>;
                                        qcom,switch-mode-frequency = <3200000>;
                                };
 
-                               pm8921_l3: l3 {
+                               l3 {
                                        regulator-min-microvolt = <3050000>;
                                        regulator-max-microvolt = <3300000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l4: l4 {
+                               l4 {
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1800000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l5: l5 {
+                               l5 {
                                        regulator-min-microvolt = <2750000>;
                                        regulator-max-microvolt = <3000000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l6: l6 {
+                               l6 {
                                        regulator-min-microvolt = <2950000>;
                                        regulator-max-microvolt = <2950000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_l23: l23 {
+                               l23 {
                                        regulator-min-microvolt = <1700000>;
                                        regulator-max-microvolt = <1900000>;
                                        bias-pull-down;
                                };
 
-                               pm8921_lvs1: lvs1 {
+                               lvs1 {
+                                       bias-pull-down;
+                               };
+
+                               lvs6 {
                                        bias-pull-down;
                                };
                        };
 
                gsbi@16500000 {
                        status = "ok";
-                       qcom,mode = <GSBI_PROT_I2C_UART>;
+                       qcom,mode = <GSBI_PROT_UART_W_FC>;
 
                        serial@16540000 {
                                status = "ok";
                        status = "okay";
                };
 
+               pci@1b500000 {
+                       status = "ok";
+                       vdda-supply = <&pm8921_s3>;
+                       vdda_phy-supply = <&pm8921_lvs6>;
+                       vdda_refclk-supply = <&ext_3p3v>;
+                       pinctrl-0 = <&pcie_pins>;
+                       pinctrl-names = "default";
+                       perst-gpio = <&tlmm_pinmux 27 GPIO_ACTIVE_LOW>;
+               };
+
                qcom,ssbi@500000 {
                        pmic@0 {
                                gpio@150 {
diff --git a/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts
new file mode 100644 (file)
index 0000000..06b3c76
--- /dev/null
@@ -0,0 +1,436 @@
+#include "qcom-apq8064-v2.0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mfd/qcom-rpm.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+       model = "Sony Xperia Z";
+       compatible = "sony,xperia-yuga", "qcom,apq8064";
+
+       aliases {
+               serial0 = &gsbi5_serial;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               input-name = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_pin_a>;
+
+               camera-focus {
+                       label = "camera_focus";
+                       gpios = <&pm8921_gpio 3 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_CAMERA_FOCUS>;
+               };
+
+               camera-snapshot {
+                       label = "camera_snapshot";
+                       gpios = <&pm8921_gpio 4 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_CAMERA>;
+               };
+
+               volume-down {
+                       label = "volume_down";
+                       gpios = <&pm8921_gpio 29 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+
+               volume-up {
+                       label = "volume_up";
+                       gpios = <&pm8921_gpio 35 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+       };
+
+       soc {
+               pinctrl@800000 {
+                       gsbi5_uart_pin_a: gsbi5-uart-pin-active {
+                               rx {
+                                       pins = "gpio52";
+                                       function = "gsbi5";
+                                       drive-strength = <2>;
+                                       bias-pull-up;
+                               };
+
+                               tx {
+                                       pins = "gpio51";
+                                       function = "gsbi5";
+                                       drive-strength = <4>;
+                                       bias-disable;
+                               };
+                       };
+
+                       sdcc1_pin_a: sdcc1-pin-active {
+                               clk {
+                                       pins = "sdc1_clk";
+                                       drive-strengh = <16>;
+                                       bias-disable;
+                               };
+
+                               cmd {
+                                       pins = "sdc1_cmd";
+                                       drive-strengh = <10>;
+                                       bias-pull-up;
+                               };
+
+                               data {
+                                       pins = "sdc1_data";
+                                       drive-strengh = <10>;
+                                       bias-pull-up;
+                               };
+                       };
+
+                       sdcc3_pin_a: sdcc3-pin-active {
+                               clk {
+                                       pins = "sdc3_clk";
+                                       drive-strengh = <8>;
+                                       bias-disable;
+                               };
+
+                               cmd {
+                                       pins = "sdc3_cmd";
+                                       drive-strengh = <8>;
+                                       bias-pull-up;
+                               };
+
+                               data {
+                                       pins = "sdc3_data";
+                                       drive-strengh = <8>;
+                                       bias-pull-up;
+                               };
+                       };
+
+                       sdcc3_cd_pin_a: sdcc3-cd-pin-active {
+                               pins = "gpio26";
+                               function = "gpio";
+
+                               drive-strength = <2>;
+                               bias-disable;
+                       };
+               };
+
+
+               rpm@108000 {
+                       regulators {
+                               vin_l1_l2_l12_l18-supply = <&pm8921_s4>;
+                               vin_lvs_1_3_6-supply = <&pm8921_s4>;
+                               vin_lvs_4_5_7-supply = <&pm8921_s4>;
+                               vin_ncp-supply = <&pm8921_l6>;
+                               vin_lvs2-supply = <&pm8921_s4>;
+                               vin_l24-supply = <&pm8921_s1>;
+                               vin_l25-supply = <&pm8921_s1>;
+                               vin_l27-supply = <&pm8921_s7>;
+                               vin_l28-supply = <&pm8921_s7>;
+
+                               /* Buck SMPS */
+                               s1 {
+                                       regulator-always-on;
+                                       regulator-min-microvolt = <1225000>;
+                                       regulator-max-microvolt = <1225000>;
+                                       qcom,switch-mode-frequency = <3200000>;
+                                       bias-pull-down;
+                               };
+
+                               s2 {
+                                       regulator-min-microvolt = <1300000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       qcom,switch-mode-frequency = <1600000>;
+                                       bias-pull-down;
+                               };
+
+                               s3 {
+                                       regulator-min-microvolt = <500000>;
+                                       regulator-max-microvolt = <1150000>;
+                                       qcom,switch-mode-frequency = <4800000>;
+                                       bias-pull-down;
+                               };
+
+                               s4 {
+                                       regulator-always-on;
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       qcom,switch-mode-frequency = <1600000>;
+                                       bias-pull-down;
+                                       qcom,force-mode = <QCOM_RPM_FORCE_MODE_AUTO>;
+                               };
+
+                               s7 {
+                                       regulator-min-microvolt = <1300000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       qcom,switch-mode-frequency = <3200000>;
+                               };
+
+                               s8 {
+                                       regulator-min-microvolt = <2200000>;
+                                       regulator-max-microvolt = <2200000>;
+                                       qcom,switch-mode-frequency = <1600000>;
+                               };
+
+                               /* PMOS LDO */
+                               l1 {
+                                       regulator-always-on;
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       bias-pull-down;
+                               };
+
+                               l2 {
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       bias-pull-down;
+                               };
+
+                               l3 {
+                                       regulator-min-microvolt = <3075000>;
+                                       regulator-max-microvolt = <3075000>;
+                                       bias-pull-down;
+                               };
+
+                               l4 {
+                                       regulator-always-on;
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       bias-pull-down;
+                               };
+
+                               l5 {
+                                       regulator-min-microvolt = <2950000>;
+                                       regulator-max-microvolt = <2950000>;
+                                       bias-pull-down;
+                               };
+
+                               l6 {
+                                       regulator-min-microvolt = <2950000>;
+                                       regulator-max-microvolt = <2950000>;
+                                       bias-pull-down;
+                               };
+
+                               l7 {
+                                       regulator-min-microvolt = <1850000>;
+                                       regulator-max-microvolt = <2950000>;
+                                       bias-pull-down;
+                               };
+
+                               l8 {
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       bias-pull-down;
+                               };
+
+                               l9 {
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       bias-pull-down;
+                               };
+
+                               l10 {
+                                       regulator-min-microvolt = <2900000>;
+                                       regulator-max-microvolt = <2900000>;
+                                       bias-pull-down;
+                               };
+
+                               l11 {
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       bias-pull-down;
+                               };
+
+                               l12 {
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       bias-pull-down;
+                               };
+
+                               l14 {
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       bias-pull-down;
+                               };
+
+                               l15 {
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <2950000>;
+                                       bias-pull-down;
+                               };
+
+                               l16 {
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       bias-pull-down;
+                               };
+
+                               l17 {
+                                       regulator-min-microvolt = <2000000>;
+                                       regulator-max-microvolt = <2000000>;
+                                       bias-pull-down;
+                               };
+
+                               l18 {
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       bias-pull-down;
+                               };
+
+                               l21 {
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                                       bias-pull-down;
+                               };
+
+                               l22 {
+                                       regulator-min-microvolt = <2600000>;
+                                       regulator-max-microvolt = <2600000>;
+                                       bias-pull-down;
+                               };
+
+                               l23 {
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       bias-pull-down;
+                               };
+
+                               l24 {
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1150000>;
+                                       bias-pull-down;
+                               };
+
+                               l25 {
+                                       regulator-always-on;
+                                       regulator-min-microvolt = <1250000>;
+                                       regulator-max-microvolt = <1250000>;
+                                       bias-pull-down;
+                               };
+
+                               l27 {
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                               };
+
+                               l28 {
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                                       bias-pull-down;
+                               };
+
+                               l29 {
+                                       regulator-min-microvolt = <2000000>;
+                                       regulator-max-microvolt = <2000000>;
+                                       bias-pull-down;
+                               };
+
+                               /* Low Voltage Switch */
+                               lvs1 {
+                                       bias-pull-down;
+                               };
+
+                               lvs2 {
+                                       bias-pull-down;
+                               };
+
+                               lvs3 {
+                                       bias-pull-down;
+                               };
+
+                               lvs4 {
+                                       bias-pull-down;
+                               };
+
+                               lvs5 {
+                                       bias-pull-down;
+                               };
+
+                               lvs6 {
+                                       bias-pull-down;
+                               };
+
+                               lvs7 {
+                                       bias-pull-down;
+                               };
+
+                               usb-switch {};
+
+                               hdmi-switch {};
+
+                               ncp {
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       qcom,switch-mode-frequency = <1600000>;
+                               };
+                       };
+               };
+
+               qcom,ssbi@500000 {
+                       pmic@0 {
+                               gpio@150 {
+                                       gpio_keys_pin_a: gpio-keys-pin-active {
+                                               pins = "gpio3", "gpio4", "gpio29", "gpio35";
+                                               function = "normal";
+
+                                               bias-pull-up;
+                                               drive-push-pull;
+                                               input-enable;
+                                               power-source = <2>;
+                                               qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+                                               qcom,pull-up-strength = <0>;
+                                       };
+                               };
+                       };
+               };
+
+               phy@12500000 {
+                       status          = "okay";
+                       vddcx-supply    = <&pm8921_s3>;
+                       v3p3-supply     = <&pm8921_l3>;
+                       v1p8-supply     = <&pm8921_l4>;
+               };
+
+               gadget@12500000 {
+                       status = "okay";
+               };
+
+               gsbi@1a200000 {
+                       status = "ok";
+                       qcom,mode = <GSBI_PROT_I2C_UART>;
+
+                       serial@1a240000 {
+                               status = "ok";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&gsbi5_uart_pin_a>;
+                       };
+               };
+
+               amba {
+                       sdcc1: sdcc@12400000 {
+                               status = "okay";
+
+                               vmmc-supply = <&pm8921_l5>;
+                               vqmmc-supply = <&pm8921_s4>;
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&sdcc1_pin_a>;
+                       };
+
+                       sdcc3: sdcc@12180000 {
+                               status = "okay";
+
+                               vmmc-supply = <&pm8921_l6>;
+                               cd-gpios = <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>;
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&sdcc3_pin_a>, <&sdcc3_cd_pin_a>;
+                       };
+               };
+       };
+};
index a4c1762..ed521e8 100644 (file)
        compatible = "qcom,apq8064";
        interrupt-parent = <&intc>;
 
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               smem_region: smem@80000000 {
+                       reg = <0x80000000 0x200000>;
+                       no-map;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                interrupts = <1 10 0x304>;
        };
 
+       clocks {
+               cxo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <19200000>;
+               };
+
+               pxo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <27000000>;
+               };
+
+               sleep_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       sfpb_mutex: hwmutex {
+               compatible = "qcom,sfpb-mutex";
+               syscon = <&sfpb_wrapper_mutex 0x604 0x4>;
+               #hwlock-cells = <1>;
+       };
+
+       smem {
+               compatible = "qcom,smem";
+               memory-region = <&smem_region>;
+
+               hwlocks = <&sfpb_mutex 3>;
+       };
+
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
                        };
                };
 
+               sfpb_wrapper_mutex: syscon@1200000 {
+                       compatible = "syscon";
+                       reg = <0x01200000 0x8000>;
+               };
+
                intc: interrupt-controller@2000000 {
                        compatible = "qcom,msm-qgic2";
                        interrupt-controller;
                        };
                };
 
+               gsbi5: gsbi@1a200000 {
+                       status = "disabled";
+                       compatible = "qcom,gsbi-v1.0.0";
+                       cell-index = <5>;
+                       reg = <0x1a200000 0x03>;
+                       clocks = <&gcc GSBI5_H_CLK>;
+                       clock-names = "iface";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       gsbi5_serial: serial@1a240000 {
+                               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+                               reg = <0x1a240000 0x100>,
+                                     <0x1a200000 0x03>;
+                               interrupts = <0 154 0x0>;
+                               clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
+                               clock-names = "core", "iface";
+                               status = "disabled";
+                       };
+               };
+
                gsbi6: gsbi@16500000 {
                        status = "disabled";
                        compatible = "qcom,gsbi-v1.0.0";
                        };
                };
 
+               rng@1a500000 {
+                       compatible = "qcom,prng";
+                       reg = <0x1a500000 0x200>;
+                       clocks = <&gcc PRNG_CLK>;
+                       clock-names = "core";
+               };
+
                qcom,ssbi@500000 {
                        compatible = "qcom,ssbi";
                        reg = <0x00500000 0x1000>;
 
                                pm8921_gpio: gpio@150 {
 
-                                       compatible = "qcom,pm8921-gpio";
+                                       compatible = "qcom,pm8921-gpio",
+                                                    "qcom,ssbi-gpio";
                                        reg = <0x150>;
                                        interrupts = <192 1>, <193 1>, <194 1>,
                                                     <195 1>, <196 1>, <197 1>,
                                };
 
                                pm8921_mpps: mpps@50 {
-                                       compatible = "qcom,pm8921-mpp";
+                                       compatible = "qcom,pm8921-mpp",
+                                                    "qcom,ssbi-mpp";
                                        reg = <0x50>;
                                        gpio-controller;
                                        #gpio-cells = <2>;
                        regulators {
                                compatible = "qcom,rpm-pm8921-regulators";
 
+                               pm8921_s1: s1 {};
+                               pm8921_s2: s2 {};
+                               pm8921_s3: s3 {};
+                               pm8921_s4: s4 {};
+                               pm8921_s7: s7 {};
+                               pm8921_s8: s8 {};
+
+                               pm8921_l1: l1 {};
+                               pm8921_l2: l2 {};
+                               pm8921_l3: l3 {};
+                               pm8921_l4: l4 {};
+                               pm8921_l5: l5 {};
+                               pm8921_l6: l6 {};
+                               pm8921_l7: l7 {};
+                               pm8921_l8: l8 {};
+                               pm8921_l9: l9 {};
+                               pm8921_l10: l10 {};
+                               pm8921_l11: l11 {};
+                               pm8921_l12: l12 {};
+                               pm8921_l14: l14 {};
+                               pm8921_l15: l15 {};
+                               pm8921_l16: l16 {};
+                               pm8921_l17: l17 {};
+                               pm8921_l18: l18 {};
+                               pm8921_l21: l21 {};
+                               pm8921_l22: l22 {};
+                               pm8921_l23: l23 {};
+                               pm8921_l24: l24 {};
+                               pm8921_l25: l25 {};
+                               pm8921_l26: l26 {};
+                               pm8921_l27: l27 {};
+                               pm8921_l28: l28 {};
+                               pm8921_l29: l29 {};
+
+                               pm8921_lvs1: lvs1 {};
+                               pm8921_lvs2: lvs2 {};
+                               pm8921_lvs3: lvs3 {};
+                               pm8921_lvs4: lvs4 {};
+                               pm8921_lvs5: lvs5 {};
+                               pm8921_lvs6: lvs6 {};
+                               pm8921_lvs7: lvs7 {};
+
+                               pm8921_usb_switch: usb-switch {};
+
                                pm8921_hdmi_switch: hdmi-switch {
                                        bias-pull-down;
                                };
+
+                               pm8921_ncp: ncp {};
                        };
                };
 
                        compatible = "qcom,tcsr-apq8064", "syscon";
                        reg = <0x1a400000 0x100>;
                };
+
+               pcie: pci@1b500000 {
+                       compatible = "qcom,pcie-apq8064", "snps,dw-pcie";
+                       reg = <0x1b500000 0x1000
+                              0x1b502000 0x80
+                              0x1b600000 0x100
+                              0x0ff00000 0x100000>;
+                       reg-names = "dbi", "elbi", "parf", "config";
+                       device_type = "pci";
+                       linux,pci-domain = <0>;
+                       bus-range = <0x00 0xff>;
+                       num-lanes = <1>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000   /* I/O */
+                                 0x82000000 0 0 0x08000000 0 0x07e00000>; /* memory */
+                       interrupts = <GIC_SPI 238 IRQ_TYPE_NONE>;
+                       interrupt-names = "msi";
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0x7>;
+                       interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                       <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                       <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                       <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+                       clocks = <&gcc PCIE_A_CLK>,
+                                <&gcc PCIE_H_CLK>,
+                                <&gcc PCIE_PHY_REF_CLK>;
+                       clock-names = "core", "iface", "phy";
+                       resets = <&gcc PCIE_ACLK_RESET>,
+                                <&gcc PCIE_HCLK_RESET>,
+                                <&gcc PCIE_POR_RESET>,
+                                <&gcc PCIE_PCI_RESET>,
+                                <&gcc PCIE_PHY_RESET>;
+                       reset-names = "axi", "ahb", "por", "pci", "phy";
+                       status = "disabled";
+               };
        };
 };
index 835bdc7..c0e2053 100644 (file)
@@ -8,6 +8,8 @@
 
        aliases {
                serial0 = &blsp1_uart2;
+               usid0 = &pm8941_0;
+               usid4 = &pm8841_0;
        };
 
        chosen {
index c9c2b76..2052b84 100644 (file)
@@ -3,10 +3,11 @@
 
 / {
        model = "Qualcomm APQ8084/IFC6540";
-       compatible = "qcom,apq8084-ifc6540", "qcom,apq8084";
+       compatible = "qcom,apq8084-sbc", "qcom,apq8084";
 
        aliases {
                serial0 = &blsp2_uart2;
+               usid0 = &pma8084_0;
        };
 
        chosen {
index 3016c70..d174d15 100644 (file)
@@ -7,6 +7,7 @@
 
        aliases {
                serial0 = &blsp2_uart2;
+               usid0 = &pma8084_0;
        };
 
        chosen {
index fcffeca..08214cb 100644 (file)
        compatible = "qcom,apq8084";
        interrupt-parent = <&intc>;
 
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               smem_mem: smem_region@fa00000 {
+                       reg = <0xfa00000 0x200000>;
+                       no-map;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                clock-frequency = <19200000>;
        };
 
+       smem {
+               compatible = "qcom,smem";
+
+               qcom,rpm-msg-ram = <&rpm_msg_ram>;
+               memory-region = <&smem_mem>;
+
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
                              <0xf9002000 0x1000>;
                };
 
+               apcs: syscon@f9011000 {
+                       compatible = "syscon";
+                       reg = <0xf9011000 0x1000>;
+               };
+
                timer@f9020000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
                        reg = <0xfc400000 0x4000>;
                };
 
+               tcsr_mutex_regs: syscon@fd484000 {
+                       compatible = "syscon";
+                       reg = <0xfd484000 0x2000>;
+               };
+
+               tcsr_mutex: hwlock {
+                       compatible = "qcom,tcsr-mutex";
+                       syscon = <&tcsr_mutex_regs 0 0x80>;
+                       #hwlock-cells = <1>;
+               };
+
+               rpm_msg_ram: memory@fc428000 {
+                       compatible = "qcom,rpm-msg-ram";
+                       reg = <0xfc428000 0x4000>;
+               };
+
                tlmm: pinctrl@fd510000 {
                        compatible = "qcom,apq8084-pinctrl";
                        reg = <0xfd510000 0x4000>;
                        #interrupt-cells = <4>;
                };
        };
+
+       smd {
+               compatible = "qcom,smd";
+
+               rpm {
+                       interrupts = <0 168 1>;
+                       qcom,ipc = <&apcs 8 0>;
+                       qcom,smd-edge = <15>;
+
+                       rpm_requests {
+                               compatible = "qcom,rpm-apq8084";
+                               qcom,smd-channels = "rpm_requests";
+
+                               pma8084-regulators {
+                                       compatible = "qcom,rpm-pma8084-regulators";
+
+                                       pma8084_s1: s1 {};
+                                       pma8084_s2: s2 {};
+                                       pma8084_s3: s3 {};
+                                       pma8084_s4: s4 {};
+                                       pma8084_s5: s5 {};
+                                       pma8084_s6: s6 {};
+                                       pma8084_s7: s7 {};
+                                       pma8084_s8: s8 {};
+                                       pma8084_s9: s9 {};
+                                       pma8084_s10: s10 {};
+                                       pma8084_s11: s11 {};
+                                       pma8084_s12: s12 {};
+
+                                       pma8084_l1: l1 {};
+                                       pma8084_l2: l2 {};
+                                       pma8084_l3: l3 {};
+                                       pma8084_l4: l4 {};
+                                       pma8084_l5: l5 {};
+                                       pma8084_l6: l6 {};
+                                       pma8084_l7: l7 {};
+                                       pma8084_l8: l8 {};
+                                       pma8084_l9: l9 {};
+                                       pma8084_l10: l10 {};
+                                       pma8084_l11: l11 {};
+                                       pma8084_l12: l12 {};
+                                       pma8084_l13: l13 {};
+                                       pma8084_l14: l14 {};
+                                       pma8084_l15: l15 {};
+                                       pma8084_l16: l16 {};
+                                       pma8084_l17: l17 {};
+                                       pma8084_l18: l18 {};
+                                       pma8084_l19: l19 {};
+                                       pma8084_l20: l20 {};
+                                       pma8084_l21: l21 {};
+                                       pma8084_l22: l22 {};
+                                       pma8084_l23: l23 {};
+                                       pma8084_l24: l24 {};
+                                       pma8084_l25: l25 {};
+                                       pma8084_l26: l26 {};
+                                       pma8084_l27: l27 {};
+
+                                       pma8084_lvs1: lvs1 {};
+                                       pma8084_lvs2: lvs2 {};
+                                       pma8084_lvs3: lvs3 {};
+                                       pma8084_lvs4: lvs4 {};
+
+                                       pma8084_5vs1: 5vs1 {};
+                               };
+                       };
+               };
+       };
 };
index 134cd91..51a40d8 100644 (file)
                qcom,no-pc-write;
        };
 
+       clocks {
+               cxo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <19200000>;
+                       clock-output-names = "cxo_board";
+               };
+
+               pxo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <27000000>;
+                       clock-output-names = "pxo_board";
+               };
+
+               sleep_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+                       clock-output-names = "sleep_clk";
+               };
+       };
+
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
index 016f9ad..a0398b6 100644 (file)
@@ -1,6 +1,9 @@
 #include "qcom-msm8974.dtsi"
 #include "qcom-pm8841.dtsi"
 #include "qcom-pm8941.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 
 / {
        model = "Sony Xperia Z1";
                stdout-path = "serial0:115200n8";
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+               input-name = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_pin_a>;
+
+               volume-down {
+                       label = "volume_down";
+                       gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+
+               camera-snapshot {
+                       label = "camera_snapshot";
+                       gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_CAMERA>;
+               };
+
+               camera-focus {
+                       label = "camera_focus";
+                       gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_CAMERA_FOCUS>;
+               };
+
+               volume-up {
+                       label = "volume_up";
+                       gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+       };
+
        memory@0 {
                reg = <0 0x40000000>, <0x40000000 0x40000000>;
                device_type = "memory";
        };
+
+       smd {
+               rpm {
+                       rpm_requests {
+                               pm8841-regulators {
+                                       s1 {
+                                               regulator-min-microvolt = <675000>;
+                                               regulator-max-microvolt = <1050000>;
+                                       };
+
+                                       s2 {
+                                               regulator-min-microvolt = <500000>;
+                                               regulator-max-microvolt = <1050000>;
+                                       };
+
+                                       s3 {
+                                               regulator-min-microvolt = <500000>;
+                                               regulator-max-microvolt = <1050000>;
+                                       };
+
+                                       s4 {
+                                               regulator-min-microvolt = <500000>;
+                                               regulator-max-microvolt = <1050000>;
+                                       };
+                               };
+
+                               pm8941-regulators {
+                                       vdd_l1_l3-supply = <&pm8941_s1>;
+                                       vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+                                       vdd_l4_l11-supply = <&pm8941_s1>;
+                                       vdd_l5_l7-supply = <&pm8941_s2>;
+                                       vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+                                       vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+                                       vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+                                       vdd_l21-supply = <&vreg_boost>;
+                                       vin_5vs-supply = <&pm8941_5v>;
+
+                                       s1 {
+                                               regulator-min-microvolt = <1300000>;
+                                               regulator-max-microvolt = <1300000>;
+                                               regulator-always-on;
+                                               regulator-boot-on;
+                                       };
+
+                                       s2 {
+                                               regulator-min-microvolt = <2150000>;
+                                               regulator-max-microvolt = <2150000>;
+                                               regulator-boot-on;
+                                       };
+
+                                       s3 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+                                               regulator-always-on;
+                                               regulator-boot-on;
+                                       };
+
+                                       s4 {
+                                               regulator-min-microvolt = <5000000>;
+                                               regulator-max-microvolt = <5000000>;
+                                       };
+
+                                       l1 {
+                                               regulator-min-microvolt = <1225000>;
+                                               regulator-max-microvolt = <1225000>;
+
+                                               regulator-always-on;
+                                               regulator-boot-on;
+                                       };
+
+                                       l2 {
+                                               regulator-min-microvolt = <1200000>;
+                                               regulator-max-microvolt = <1200000>;
+                                       };
+
+                                       l3 {
+                                               regulator-min-microvolt = <1200000>;
+                                               regulator-max-microvolt = <1200000>;
+                                       };
+
+                                       l4 {
+                                               regulator-min-microvolt = <1225000>;
+                                               regulator-max-microvolt = <1225000>;
+                                       };
+
+                                       l5 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+                                       };
+
+                                       l6 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+
+                                               regulator-boot-on;
+                                       };
+
+                                       l7 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+
+                                               regulator-boot-on;
+                                       };
+
+                                       l8 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+                                       };
+
+                                       l9 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <2950000>;
+                                       };
+
+                                       l11 {
+                                               regulator-min-microvolt = <1300000>;
+                                               regulator-max-microvolt = <1350000>;
+                                       };
+
+                                       l12 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+
+                                               regulator-always-on;
+                                               regulator-boot-on;
+                                       };
+
+                                       l13 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <2950000>;
+
+                                               regulator-boot-on;
+                                       };
+
+                                       l14 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+                                       };
+
+                                       l15 {
+                                               regulator-min-microvolt = <2050000>;
+                                               regulator-max-microvolt = <2050000>;
+                                       };
+
+                                       l16 {
+                                               regulator-min-microvolt = <2700000>;
+                                               regulator-max-microvolt = <2700000>;
+                                       };
+
+                                       l17 {
+                                               regulator-min-microvolt = <2700000>;
+                                               regulator-max-microvolt = <2700000>;
+                                       };
+
+                                       l18 {
+                                               regulator-min-microvolt = <2850000>;
+                                               regulator-max-microvolt = <2850000>;
+                                       };
+
+                                       l19 {
+                                               regulator-min-microvolt = <3300000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       l20 {
+                                               regulator-min-microvolt = <2950000>;
+                                               regulator-max-microvolt = <2950000>;
+
+                                               regulator-allow-set-load;
+                                               regulator-boot-on;
+                                               regulator-system-load = <200000>;
+                                       };
+
+                                       l21 {
+                                               regulator-min-microvolt = <2950000>;
+                                               regulator-max-microvolt = <2950000>;
+
+                                               regulator-boot-on;
+                                       };
+
+                                       l22 {
+                                               regulator-min-microvolt = <3000000>;
+                                               regulator-max-microvolt = <3000000>;
+                                       };
+
+                                       l23 {
+                                               regulator-min-microvolt = <2800000>;
+                                               regulator-max-microvolt = <2800000>;
+                                       };
+
+                                       l24 {
+                                               regulator-min-microvolt = <3075000>;
+                                               regulator-max-microvolt = <3075000>;
+
+                                               regulator-boot-on;
+                                       };
+                               };
+                       };
+               };
+       };
+
+       vreg_boost: vreg-boost {
+               compatible = "regulator-fixed";
+
+               regulator-name = "vreg-boost";
+               regulator-min-microvolt = <3150000>;
+               regulator-max-microvolt = <3150000>;
+
+               regulator-always-on;
+               regulator-boot-on;
+
+               gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&boost_bypass_n_pin>;
+     };
 };
 
 &soc {
+       sdhci@f9824900 {
+               status = "ok";
+
+               vmmc-supply = <&pm8941_l20>;
+               vqmmc-supply = <&pm8941_s3>;
+
+               bus-width = <8>;
+               non-removable;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdhc1_pin_a>;
+       };
+
+       sdhci@f98a4900 {
+               status = "ok";
+
+               bus-width = <4>;
+
+               vmmc-supply = <&pm8941_l21>;
+               vqmmc-supply = <&pm8941_l13>;
+
+               cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+       };
+
        serial@f991e000 {
                status = "ok";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&blsp1_uart2_pin_a>;
+       };
+
+       pinctrl@fd510000 {
+               blsp1_uart2_pin_a: blsp1-uart2-pin-active {
+                       rx {
+                               pins = "gpio5";
+                               function = "blsp_uart2";
+
+                               drive-strength = <2>;
+                               bias-pull-up;
+                       };
+
+                       tx {
+                               pins = "gpio4";
+                               function = "blsp_uart2";
+
+                               drive-strength = <4>;
+                               bias-disable;
+                       };
+               };
+
+               sdhc1_pin_a: sdhc1-pin-active {
+                       clk {
+                               pins = "sdc1_clk";
+                               drive-strength = <16>;
+                               bias-disable;
+                       };
+
+                       cmd-data {
+                               pins = "sdc1_cmd", "sdc1_data";
+                               drive-strength = <10>;
+                               bias-pull-up;
+                       };
+               };
+
+               sdhc2_cd_pin_a: sdhc2-cd-pin-active {
+                       pins = "gpio62";
+                       function = "gpio";
+
+                       drive-strength = <2>;
+                       bias-disable;
+                };
+
+               sdhc2_pin_a: sdhc2-pin-active {
+                       clk {
+                               pins = "sdc2_clk";
+                               drive-strength = <10>;
+                               bias-disable;
+                       };
+
+                       cmd-data {
+                               pins = "sdc2_cmd", "sdc2_data";
+                               drive-strength = <6>;
+                               bias-pull-up;
+                       };
+               };
+
        };
 };
 
 &spmi_bus {
        pm8941@0 {
+               charger@1000 {
+                       qcom,fast-charge-safe-current = <1500000>;
+                       qcom,fast-charge-current-limit = <1500000>;
+                       qcom,dc-current-limit = <1800000>;
+                       qcom,fast-charge-safe-voltage = <4400000>;
+                       qcom,fast-charge-high-threshold-voltage = <4350000>;
+                       qcom,fast-charge-low-threshold-voltage = <3400000>;
+                       qcom,auto-recharge-threshold-voltage = <4200000>;
+                       qcom,minimum-input-voltage = <4300000>;
+               };
+
+               gpios@c000 {
+                       boost_bypass_n_pin: boost-bypass {
+                               pins = "gpio21";
+                               function = "normal";
+                       };
+
+                       gpio_keys_pin_a: gpio-keys-active {
+                               pins = "gpio2", "gpio3", "gpio4", "gpio5";
+                               function = "normal";
+
+                               bias-pull-up;
+                               power-source = <PM8941_GPIO_S3>;
+                       };
+               };
+
                coincell@2800 {
                        status = "ok";
                        qcom,rset-ohms = <2100>;
                        qcom,vset-millivolts = <3000>;
                };
        };
+
+       pm8941@1 {
+               wled@d800 {
+                       status = "ok";
+
+                       qcom,cs-out;
+                       qcom,current-limit = <20>;
+                       qcom,current-boost-limit = <805>;
+                       qcom,switching-freq = <1600>;
+                       qcom,ovp = <29>;
+                       qcom,num-strings = <2>;
+               };
+       };
 };
index 753bdfd..dfdafdc 100644 (file)
                        interrupts = <0 208 0>;
                };
 
+               blsp_i2c8: i2c@f9964000 {
+                       status = "disabled";
+                       compatible = "qcom,i2c-qup-v2.1.1";
+                       reg = <0xf9964000 0x1000>;
+                       interrupts = <0 102 IRQ_TYPE_NONE>;
+                       clocks = <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                blsp_i2c11: i2c@f9967000 {
                        status = "disabled";
                        compatible = "qcom,i2c-qup-v2.1.1";
index 8f1a0b1..9f357f6 100644 (file)
@@ -3,14 +3,14 @@
 
 &spmi_bus {
 
-       usid4: pm8841@4 {
-               compatible = "qcom,spmi-pmic";
+       pm8841_0: pm8841@4 {
+               compatible = "qcom,pm8841", "qcom,spmi-pmic";
                reg = <0x4 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
 
                pm8841_mpps: mpps@a000 {
-                       compatible = "qcom,pm8841-mpp";
+                       compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
                        reg = <0xa000 0x400>;
                        gpio-controller;
                        #gpio-cells = <2>;
@@ -27,8 +27,8 @@
                };
        };
 
-       usid5: pm8841@5 {
-               compatible = "qcom,spmi-pmic";
+       pm8841_1: pm8841@5 {
+               compatible = "qcom,pm8841", "qcom,spmi-pmic";
                reg = <0x5 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
index b0d4439..ca53a59 100644 (file)
@@ -4,8 +4,8 @@
 
 &spmi_bus {
 
-       usid0: pm8941@0 {
-               compatible ="qcom,spmi-pmic";
+       pm8941_0: pm8941@0 {
+               compatible = "qcom,pm8941", "qcom,spmi-pmic";
                reg = <0x0 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
@@ -48,7 +48,7 @@
                };
 
                pm8941_gpios: gpios@c000 {
-                       compatible = "qcom,pm8941-gpio";
+                       compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio";
                        reg = <0xc000 0x2400>;
                        gpio-controller;
                        #gpio-cells = <2>;
@@ -91,7 +91,7 @@
                };
 
                pm8941_mpps: mpps@a000 {
-                       compatible = "qcom,pm8941-mpp";
+                       compatible = "qcom,pm8941-mpp", "qcom,spmi-mpp";
                        reg = <0xa000 0x800>;
                        gpio-controller;
                        #gpio-cells = <2>;
                };
        };
 
-       usid1: pm8941@1 {
-               compatible = "qcom,spmi-pmic";
+       pm8941_1: pm8941@1 {
+               compatible = "qcom,pm8941", "qcom,spmi-pmic";
                reg = <0x1 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
 
-               wled@d800 {
+               pm8941_wled: wled@d800 {
                        compatible = "qcom,pm8941-wled";
                        reg = <0xd800 0x100>;
                        label = "backlight";
 
-                       qcom,cs-out;
-                       qcom,current-limit = <20>;
-                       qcom,current-boost-limit = <805>;
-                       qcom,switching-freq = <1600>;
-                       qcom,ovp = <29>;
-                       qcom,num-strings = <2>;
+                       status = "disabled";
                };
        };
 };
index 5e240cc..4e9bd3f 100644 (file)
@@ -4,8 +4,8 @@
 
 &spmi_bus {
 
-       usid0: pma8084@0 {
-               compatible = "qcom,spmi-pmic";
+       pma8084_0: pma8084@0 {
+               compatible = "qcom,pma8084", "qcom,spmi-pmic";
                reg = <0x0 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
@@ -19,7 +19,7 @@
                };
 
                pma8084_gpios: gpios@c000 {
-                       compatible = "qcom,pma8084-gpio";
+                       compatible = "qcom,pma8084-gpio", "qcom,spmi-gpio";
                        reg = <0xc000 0x1600>;
                        gpio-controller;
                        #gpio-cells = <2>;
@@ -48,7 +48,7 @@
                };
 
                pma8084_mpps: mpps@a000 {
-                       compatible = "qcom,pma8084-mpp";
+                       compatible = "qcom,pma8084-mpp", "qcom,spmi-mpp";
                        reg = <0xa000 0x800>;
                        gpio-controller;
                        #gpio-cells = <2>;
                };
        };
 
-       usid1: pma8084@1 {
-               compatible = "qcom,spmi-pmic";
+       pma8084_1: pma8084@1 {
+               compatible = "qcom,pma8084", "qcom,spmi-pmic";
                reg = <0x1 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
index 060c32c..4657d7f 100644 (file)
        };
 
        gic: interrupt-controller@e8201000 {
-               compatible = "arm,cortex-a9-gic";
+               compatible = "arm,pl390";
                #interrupt-cells = <3>;
                #address-cells = <0>;
                interrupt-controller;
index a4c4259..5902570 100644 (file)
@@ -23,7 +23,7 @@
 
        chosen {
                bootargs = "ignore_loglevel root=/dev/nfs ip=dhcp rw";
-               stdout-path = &scifa0;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
                        gpios = <&pfc 324 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_0>;
                        label = "S16";
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                menu-key {
index 105d9c9..c548cab 100644 (file)
@@ -85,7 +85,7 @@
                        gpios = <&pfc 99 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_POWER>;
                        label = "SW3";
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
 
                back-key {
 };
 
 &extal1_clk {
-       clock-frequency = <25000000>;
+       clock-frequency = <24000000>;
 };
 &extal2_clk {
        clock-frequency = <48000000>;
index e14cb14..6ef9547 100644 (file)
                        reg = <0x0>;
                        clock-frequency = <800000000>;
                        power-domains = <&pd_a3sm>;
+                       next-level-cache = <&L2>;
                };
        };
 
        gic: interrupt-controller@c2800000 {
-               compatible = "arm,cortex-a9-gic";
+               compatible = "arm,pl390";
                #interrupt-cells = <3>;
                interrupt-controller;
                reg = <0xc2800000 0x1000>,
                      <0xc2000000 0x1000>;
        };
 
+       L2: cache-controller {
+               compatible = "arm,pl310-cache";
+               reg = <0xf0100000 0x1000>;
+               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&pd_a3sm>;
+               arm,data-latency = <3 3 3>;
+               arm,tag-latency = <2 2 2>;
+               arm,shared-override;
+               cache-unified;
+               cache-level = <2>;
+       };
+
        dbsc3: memory-controller@fe400000 {
                compatible = "renesas,dbsc3-r8a7740";
                reg = <0xfe400000 0x400>;
index 90543b1..a52b359 100644 (file)
@@ -28,8 +28,8 @@
        };
 
        chosen {
-               bootargs = "console=ttySC0,115200 ignore_loglevel ip=dhcp root=/dev/nfs rw";
-               stdout-path = &scif0;
+               bootargs = "ignore_loglevel ip=dhcp root=/dev/nfs rw";
+               stdout-path = "serial0:115200n8";
        };
 
        memory {
        };
 
        sdhi0_pins: sd0 {
-               renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
-                                 "sdhi0_cd";
+               renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
                renesas,function = "sdhi0";
        };
+       sdhi0_pup_pins: sd0_pup {
+               renesas,groups = "sdhi0_cd", "sdhi0_wp";
+               renesas,function = "sdhi0";
+               bias-pull-up;
+       };
 
        hspi0_pins: hspi0 {
                renesas,groups = "hspi0_a";
        };
 };
 
+&rcar_sound {
+       /* Single DAI */
+       #sound-dai-cells = <0>;
+};
+
 &sdhi0 {
-       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-0 = <&sdhi0_pins>, <&sdhi0_pup_pins>;
        pinctrl-names = "default";
 
        vmmc-supply = <&fixedregulator3v3>;
        status = "okay";
 
        flash: flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
                compatible = "spansion,s25fl008k", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <104000000>;
                m25p,fast-read;
 
-               partition@0 {
-                       label = "data(spi)";
-                       reg = <0x00000000 0x00100000>;
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "data(spi)";
+                               reg = <0x00000000 0x00100000>;
+                       };
                };
        };
 };
index 4f8e078..791aafd 100644 (file)
@@ -61,7 +61,7 @@
        };
 
        gic: interrupt-controller@fe438000 {
-               compatible = "arm,cortex-a9-gic";
+               compatible = "arm,pl390";
                #interrupt-cells = <3>;
                interrupt-controller;
                reg = <0xfe438000 0x1000>,
        };
 
        rcar_sound: sound@ffd90000 {
-               #sound-dai-cells = <1>;
+               /*
+                * #sound-dai-cells is required
+                *
+                * Single DAI : #sound-dai-cells = <0>;         <&rcar_sound>;
+                * Multi  DAI : #sound-dai-cells = <1>;         <&rcar_sound N>;
+                */
                compatible = "renesas,rcar_sound-r8a7778", "renesas,rcar_sound-gen1";
                reg =   <0xffd90000 0x1000>,    /* SRU */
                        <0xffd91000 0x240>,     /* SSI */
index c553abd..052dcee 100644 (file)
        compatible = "renesas,lager", "renesas,r8a7790";
 
        aliases {
-               serial0 = &scifa0;
+               serial0 = &scif0;
                serial1 = &scifa1;
        };
 
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scifa0;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
                button@1 {
                        linux,code = <KEY_1>;
                        label = "SW2-1";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                        gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
                };
                button@2 {
                        linux,code = <KEY_2>;
                        label = "SW2-2";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                        gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
                };
                button@3 {
                        linux,code = <KEY_3>;
                        label = "SW2-3";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                        gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
                };
                button@4 {
                        linux,code = <KEY_4>;
                        label = "SW2-4";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                        gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
                };
                renesas,function = "du";
        };
 
-       scifa0_pins: serial0 {
-               renesas,groups = "scifa0_data";
-               renesas,function = "scifa0";
+       scif0_pins: serial0 {
+               renesas,groups = "scif0_data";
+               renesas,function = "scif0";
        };
 
        ether_pins: ether {
        status = "okay";
 
        flash: flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
                compatible = "spansion,s25fl512s", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <30000000>;
                spi-cpol;
                m25p,fast-read;
 
-               partition@0 {
-                       label = "loader";
-                       reg = <0x00000000 0x00040000>;
-                       read-only;
-               };
-               partition@40000 {
-                       label = "user";
-                       reg = <0x00040000 0x00400000>;
-                       read-only;
-               };
-               partition@440000 {
-                       label = "flash";
-                       reg = <0x00440000 0x03bc0000>;
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "loader";
+                               reg = <0x00000000 0x00040000>;
+                               read-only;
+                       };
+                       partition@40000 {
+                               label = "user";
+                               reg = <0x00040000 0x00400000>;
+                               read-only;
+                       };
+                       partition@440000 {
+                               label = "flash";
+                               reg = <0x00440000 0x03bc0000>;
+                       };
                };
        };
 };
 
-&scifa0 {
-       pinctrl-0 = <&scifa0_pins>;
+&scif0 {
+       pinctrl-0 = <&scif0_pins>;
        pinctrl-names = "default";
 
        status = "okay";
index e07ae5d..7dfd393 100644 (file)
                interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
-               gpio-ranges = <&pfc 0 32 32>;
+               gpio-ranges = <&pfc 0 32 30>;
                #interrupt-cells = <2>;
                interrupt-controller;
                clocks = <&mstp9_clks R8A7790_CLK_GPIO1>;
                interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
-               gpio-ranges = <&pfc 0 64 32>;
+               gpio-ranges = <&pfc 0 64 30>;
                #interrupt-cells = <2>;
                interrupt-controller;
                clocks = <&mstp9_clks R8A7790_CLK_GPIO2>;
        };
 
        dmac0: dma-controller@e6700000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
                reg = <0 0xe6700000 0 0x20000>;
                interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
                              0 200 IRQ_TYPE_LEVEL_HIGH
        };
 
        dmac1: dma-controller@e6720000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
                reg = <0 0xe6720000 0 0x20000>;
                interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
                              0 216 IRQ_TYPE_LEVEL_HIGH
        };
 
        audma0: dma-controller@ec700000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
                reg = <0 0xec700000 0 0x10000>;
                interrupts =    <0 346 IRQ_TYPE_LEVEL_HIGH
                                 0 320 IRQ_TYPE_LEVEL_HIGH
        };
 
        audma1: dma-controller@ec720000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
                reg = <0 0xec720000 0 0x10000>;
                interrupts =    <0 347 IRQ_TYPE_LEVEL_HIGH
                                 0 333 IRQ_TYPE_LEVEL_HIGH
        };
 
        usb_dmac0: dma-controller@e65a0000 {
-               compatible = "renesas,usb-dmac";
+               compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac";
                reg = <0 0xe65a0000 0 0x100>;
                interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH
                              0 109 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        usb_dmac1: dma-controller@e65b0000 {
-               compatible = "renesas,usb-dmac";
+               compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac";
                reg = <0 0xe65b0000 0 0x100>;
                interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH
                              0 110 IRQ_TYPE_LEVEL_HIGH>;
                interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <110>;
                status = "disabled";
        };
 
                interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <110>;
                status = "disabled";
        };
 
        };
 
        ipmmu_sy0: mmu@e6280000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
                reg = <0 0xe6280000 0 0x1000>;
                interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
                             <0 224 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_sy1: mmu@e6290000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
                reg = <0 0xe6290000 0 0x1000>;
                interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_ds: mmu@e6740000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
                reg = <0 0xe6740000 0 0x1000>;
                interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
                             <0 199 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_mp: mmu@ec680000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
                reg = <0 0xec680000 0 0x1000>;
                interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_mx: mmu@fe951000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
                reg = <0 0xfe951000 0 0x1000>;
                interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
                             <0 221 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_rt: mmu@ffc80000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
                reg = <0 0xffc80000 0 0x1000>;
                interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
diff --git a/arch/arm/boot/dts/r8a7791-henninger.dts b/arch/arm/boot/dts/r8a7791-henninger.dts
deleted file mode 100644 (file)
index 655d180..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Device Tree Source for the Henninger board
- *
- * Copyright (C) 2014 Renesas Solutions Corp.
- * Copyright (C) 2014 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-/dts-v1/;
-#include "r8a7791.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
-       model = "Henninger";
-       compatible = "renesas,henninger", "renesas,r8a7791";
-
-       aliases {
-               serial0 = &scif0;
-       };
-
-       chosen {
-               bootargs = "console=ttySC0,38400 ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scif0;
-       };
-
-       memory@40000000 {
-               device_type = "memory";
-               reg = <0 0x40000000 0 0x40000000>;
-       };
-
-       memory@200000000 {
-               device_type = "memory";
-               reg = <2 0x00000000 0 0x40000000>;
-       };
-
-       vcc_sdhi0: regulator@0 {
-               compatible = "regulator-fixed";
-
-               regulator-name = "SDHI0 Vcc";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-       };
-
-       vccq_sdhi0: regulator@1 {
-               compatible = "regulator-gpio";
-
-               regulator-name = "SDHI0 VccQ";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <3300000>;
-
-               gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
-               gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
-       };
-
-       vcc_sdhi2: regulator@2 {
-               compatible = "regulator-fixed";
-
-               regulator-name = "SDHI2 Vcc";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-       };
-
-       vccq_sdhi2: regulator@3 {
-               compatible = "regulator-gpio";
-
-               regulator-name = "SDHI2 VccQ";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <3300000>;
-
-               gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
-               gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
-       };
-};
-
-&extal_clk {
-       clock-frequency = <20000000>;
-};
-
-&pfc {
-       scif0_pins: serial0 {
-               renesas,groups = "scif0_data_d";
-               renesas,function = "scif0";
-       };
-
-       ether_pins: ether {
-               renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
-               renesas,function = "eth";
-       };
-
-       phy1_pins: phy1 {
-               renesas,groups = "intc_irq0";
-               renesas,function = "intc";
-       };
-
-       sdhi0_pins: sd0 {
-               renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
-               renesas,function = "sdhi0";
-       };
-
-       sdhi2_pins: sd2 {
-               renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
-               renesas,function = "sdhi2";
-       };
-
-       i2c2_pins: i2c2 {
-               renesas,groups = "i2c2";
-               renesas,function = "i2c2";
-       };
-
-       qspi_pins: spi0 {
-               renesas,groups = "qspi_ctrl", "qspi_data4";
-               renesas,function = "qspi";
-       };
-
-       msiof0_pins: spi1 {
-               renesas,groups = "msiof0_clk", "msiof0_sync", "msiof0_rx",
-                                "msiof0_tx";
-               renesas,function = "msiof0";
-       };
-
-       usb0_pins: usb0 {
-               renesas,groups = "usb0";
-               renesas,function = "usb0";
-       };
-
-       usb1_pins: usb1 {
-               renesas,groups = "usb1";
-               renesas,function = "usb1";
-       };
-
-       vin0_pins: vin0 {
-               renesas,groups = "vin0_data8", "vin0_clk";
-               renesas,function = "vin0";
-       };
-
-       can0_pins: can0 {
-               renesas,groups = "can0_data";
-               renesas,function = "can0";
-       };
-};
-
-&scif0 {
-       pinctrl-0 = <&scif0_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
-
-&ether {
-       pinctrl-0 = <&ether_pins &phy1_pins>;
-       pinctrl-names = "default";
-
-       phy-handle = <&phy1>;
-       renesas,ether-link-active-low;
-       status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-               interrupt-parent = <&irqc0>;
-               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-               micrel,led-mode = <1>;
-       };
-};
-
-&sata0 {
-       status = "okay";
-};
-
-&sdhi0 {
-       pinctrl-0 = <&sdhi0_pins>;
-       pinctrl-names = "default";
-
-       vmmc-supply = <&vcc_sdhi0>;
-       vqmmc-supply = <&vccq_sdhi0>;
-       cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
-       wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
-       status = "okay";
-};
-
-&sdhi2 {
-       pinctrl-0 = <&sdhi2_pins>;
-       pinctrl-names = "default";
-
-       vmmc-supply = <&vcc_sdhi2>;
-       vqmmc-supply = <&vccq_sdhi2>;
-       cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>;
-       status = "okay";
-};
-
-&i2c2 {
-       pinctrl-0 = <&i2c2_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-       clock-frequency = <400000>;
-
-       composite-in@20 {
-               compatible = "adi,adv7180";
-               reg = <0x20>;
-               remote = <&vin0>;
-
-               port {
-                       adv7180: endpoint {
-                               bus-width = <8>;
-                               remote-endpoint = <&vin0ep>;
-                       };
-               };
-       };
-};
-
-&qspi {
-       pinctrl-0 = <&qspi_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-
-       flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               compatible = "spansion,s25fl512s", "jedec,spi-nor";
-               reg = <0>;
-               spi-max-frequency = <30000000>;
-               spi-tx-bus-width = <4>;
-               spi-rx-bus-width = <4>;
-               m25p,fast-read;
-
-               partition@0 {
-                       label = "loader_prg";
-                       reg = <0x00000000 0x00040000>;
-                       read-only;
-               };
-               partition@40000 {
-                       label = "user_prg";
-                       reg = <0x00040000 0x00400000>;
-                       read-only;
-               };
-               partition@440000 {
-                       label = "flash_fs";
-                       reg = <0x00440000 0x03bc0000>;
-               };
-       };
-};
-
-&msiof0 {
-       pinctrl-0 = <&msiof0_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-
-       pmic@0 {
-               compatible = "renesas,r2a11302ft";
-               reg = <0>;
-               spi-max-frequency = <6000000>;
-               spi-cpol;
-               spi-cpha;
-       };
-};
-
-&pci0 {
-       status = "okay";
-       pinctrl-0 = <&usb0_pins>;
-       pinctrl-names = "default";
-};
-
-&pci1 {
-       status = "okay";
-       pinctrl-0 = <&usb1_pins>;
-       pinctrl-names = "default";
-};
-
-&hsusb {
-       status = "okay";
-       pinctrl-0 = <&usb0_pins>;
-       pinctrl-names = "default";
-       renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
-};
-
-&usbphy {
-       status = "okay";
-};
-
-&pcie_bus_clk {
-       status = "okay";
-};
-
-&pciec {
-       status = "okay";
-};
-
-/* composite video input */
-&vin0 {
-       status = "okay";
-       pinctrl-0 = <&vin0_pins>;
-       pinctrl-names = "default";
-
-       port {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               vin0ep: endpoint {
-                       remote-endpoint = <&adv7180>;
-                       bus-width = <8>;
-               };
-       };
-};
-
-&can0 {
-       pinctrl-0 = <&can0_pins>;
-       pinctrl-names = "default";
-       status = "okay";
-};
index fc44ea3..45256f3 100644 (file)
@@ -54,7 +54,7 @@
 
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scif0;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
                        gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_1>;
                        label = "SW2-1";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-2 {
                        gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_2>;
                        label = "SW2-2";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-3 {
                        gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_3>;
                        label = "SW2-3";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-4 {
                        gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_4>;
                        label = "SW2-4";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-a {
                        gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_A>;
                        label = "SW30";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-b {
                        gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_B>;
                        label = "SW31";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-c {
                        gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_C>;
                        label = "SW32";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-d {
                        gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_D>;
                        label = "SW33";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-e {
                        gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_E>;
                        label = "SW34";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-f {
                        gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_F>;
                        label = "SW35";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
                key-g {
                        gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_G>;
                        label = "SW36";
-                       gpio-key,wakeup;
+                       wakeup-source;
                        debounce-interval = <20>;
                };
        };
        };
 
        du_pins: du {
-               renesas,groups = "du_rgb666", "du_sync", "du_disp", "du_clk_out_0";
+               renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
                renesas,function = "du";
        };
 
        status = "okay";
 
        flash: flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
                compatible = "spansion,s25fl512s", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <30000000>;
                spi-cpol;
                m25p,fast-read;
 
-               partition@0 {
-                       label = "loader";
-                       reg = <0x00000000 0x00080000>;
-                       read-only;
-               };
-               partition@80000 {
-                       label = "user";
-                       reg = <0x00080000 0x00580000>;
-                       read-only;
-               };
-               partition@600000 {
-                       label = "flash";
-                       reg = <0x00600000 0x03a00000>;
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "loader";
+                               reg = <0x00000000 0x00080000>;
+                               read-only;
+                       };
+                       partition@80000 {
+                               label = "user";
+                               reg = <0x00080000 0x00580000>;
+                               read-only;
+                       };
+                       partition@600000 {
+                               label = "flash";
+                               reg = <0x00600000 0x03a00000>;
+                       };
                };
        };
 };
index fe0f12f..6713b1e 100644 (file)
@@ -22,7 +22,7 @@
 
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scif0;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
                renesas,groups = "vin0_data8", "vin0_clk";
                renesas,function = "vin0";
        };
+
+       can0_pins: can0 {
+               renesas,groups = "can0_data";
+               renesas,function = "can0";
+       };
 };
 
 &scif0 {
        status = "okay";
 
        flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
                compatible = "spansion,s25fl512s", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <30000000>;
                spi-rx-bus-width = <4>;
                m25p,fast-read;
 
-               partition@0 {
-                       label = "loader_prg";
-                       reg = <0x00000000 0x00040000>;
-                       read-only;
-               };
-               partition@40000 {
-                       label = "user_prg";
-                       reg = <0x00040000 0x00400000>;
-                       read-only;
-               };
-               partition@440000 {
-                       label = "flash_fs";
-                       reg = <0x00440000 0x03bc0000>;
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "loader_prg";
+                               reg = <0x00000000 0x00040000>;
+                               read-only;
+                       };
+                       partition@40000 {
+                               label = "user_prg";
+                               reg = <0x00040000 0x00400000>;
+                               read-only;
+                       };
+                       partition@440000 {
+                               label = "flash_fs";
+                               reg = <0x00440000 0x03bc0000>;
+                       };
                };
        };
 };
        status = "okay";
 };
 
+&hsusb {
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+       renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
+};
+
 &usbphy {
        status = "okay";
 };
 &pciec {
        status = "okay";
 };
+
+&can0 {
+       pinctrl-0 = <&can0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
index 328f48b..2a369dd 100644 (file)
                interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
-               gpio-ranges = <&pfc 0 32 32>;
+               gpio-ranges = <&pfc 0 32 26>;
                #interrupt-cells = <2>;
                interrupt-controller;
                clocks = <&mstp9_clks R8A7791_CLK_GPIO1>;
        };
 
        dmac0: dma-controller@e6700000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
                reg = <0 0xe6700000 0 0x20000>;
                interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
                              0 200 IRQ_TYPE_LEVEL_HIGH
        };
 
        dmac1: dma-controller@e6720000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
                reg = <0 0xe6720000 0 0x20000>;
                interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
                              0 216 IRQ_TYPE_LEVEL_HIGH
        };
 
        audma0: dma-controller@ec700000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
                reg = <0 0xec700000 0 0x10000>;
                interrupts =    <0 346 IRQ_TYPE_LEVEL_HIGH
                                 0 320 IRQ_TYPE_LEVEL_HIGH
        };
 
        audma1: dma-controller@ec720000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
                reg = <0 0xec720000 0 0x10000>;
                interrupts =    <0 347 IRQ_TYPE_LEVEL_HIGH
                                 0 333 IRQ_TYPE_LEVEL_HIGH
        };
 
        usb_dmac0: dma-controller@e65a0000 {
-               compatible = "renesas,usb-dmac";
+               compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac";
                reg = <0 0xe65a0000 0 0x100>;
                interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH
                              0 109 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        usb_dmac1: dma-controller@e65b0000 {
-               compatible = "renesas,usb-dmac";
+               compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac";
                reg = <0 0xe65b0000 0 0x100>;
                interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH
                              0 110 IRQ_TYPE_LEVEL_HIGH>;
                interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
                power-domains = <&cpg_clocks>;
+               i2c-scl-internal-delay-ns = <110>;
                status = "disabled";
        };
 
        pfc: pfc@e6060000 {
                compatible = "renesas,pfc-r8a7791";
                reg = <0 0xe6060000 0 0x250>;
-               #gpio-range-cells = <3>;
        };
 
        mmcif0: mmc@ee200000 {
                status = "disabled";
        };
 
+       avb: ethernet@e6800000 {
+               compatible = "renesas,etheravb-r8a7791",
+                            "renesas,etheravb-rcar-gen2";
+               reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+               interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7791_CLK_ETHERAVB>;
+               power-domains = <&cpg_clocks>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
        sata0: sata@ee300000 {
                compatible = "renesas,sata-r8a7791";
                reg = <0 0xee300000 0 0x2000>;
                        clock-mult = <1>;
                        clock-output-names = "m2";
                };
-               imp_clk: imp_clk {
-                       compatible = "fixed-factor-clock";
-                       clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
-                       #clock-cells = <0>;
-                       clock-div = <4>;
-                       clock-mult = <1>;
-                       clock-output-names = "imp";
-               };
                rclk_clk: rclk_clk {
                        compatible = "fixed-factor-clock";
                        clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
                        clocks = <&zx_clk>, <&hp_clk>, <&zg_clk>, <&zg_clk>,
-                                <&zg_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>;
+                                <&zg_clk>, <&hp_clk>, <&p_clk>, <&zs_clk>,
+                                <&zs_clk>;
                        #clock-cells = <1>;
                        clock-indices = <
                                R8A7791_CLK_IPMMU_SGX R8A7791_CLK_MLB
                                R8A7791_CLK_VIN2 R8A7791_CLK_VIN1 R8A7791_CLK_VIN0
-                               R8A7791_CLK_ETHER R8A7791_CLK_SATA1 R8A7791_CLK_SATA0
+                               R8A7791_CLK_ETHERAVB R8A7791_CLK_ETHER
+                               R8A7791_CLK_SATA1 R8A7791_CLK_SATA0
                        >;
                        clock-output-names =
-                               "ipmmu_sgx", "mlb", "vin2", "vin1", "vin0", "ether",
-                               "sata1", "sata0";
+                               "ipmmu_sgx", "mlb", "vin2", "vin1", "vin0",
+                               "etheravb", "ether", "sata1", "sata0";
                };
                mstp9_clks: mstp9_clks@e6150994 {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
        };
 
        ipmmu_sy0: mmu@e6280000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xe6280000 0 0x1000>;
                interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
                             <0 224 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_sy1: mmu@e6290000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xe6290000 0 0x1000>;
                interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_ds: mmu@e6740000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xe6740000 0 0x1000>;
                interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
                             <0 199 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_mp: mmu@ec680000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xec680000 0 0x1000>;
                interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_mx: mmu@fe951000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xfe951000 0 0x1000>;
                interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
                             <0 221 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_rt: mmu@ffc80000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xffc80000 0 0x1000>;
                interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_gp: mmu@e62a0000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
                reg = <0 0xe62a0000 0 0x1000>;
                interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
                             <0 261 IRQ_TYPE_LEVEL_HIGH>;
index 96443ec..baa59fe 100644 (file)
@@ -24,7 +24,7 @@
 
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scif0;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
        clock-frequency = <20000000>;
 };
 
+&pfc {
+       scif0_pins: serial0 {
+               renesas,groups = "scif0_data_d";
+               renesas,function = "scif0";
+       };
+
+       scif1_pins: serial1 {
+               renesas,groups = "scif1_data_d";
+               renesas,function = "scif1";
+       };
+
+       ether_pins: ether {
+               renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+               renesas,function = "eth";
+       };
+
+       phy1_pins: phy1 {
+               renesas,groups = "intc_irq0";
+               renesas,function = "intc";
+       };
+
+       qspi_pins: spi0 {
+               renesas,groups = "qspi_ctrl", "qspi_data4";
+               renesas,function = "qspi";
+       };
+};
+
 &ether {
+       pinctrl-0 = <&ether_pins &phy1_pins>;
+       pinctrl-names = "default";
+
        phy-handle = <&phy1>;
        renesas,ether-link-active-low;
        status = "okay";
 };
 
 &scif0 {
+       pinctrl-0 = <&scif0_pins>;
+       pinctrl-names = "default";
+
        status = "okay";
 };
 
 &scif1 {
+       pinctrl-0 = <&scif1_pins>;
+       pinctrl-names = "default";
+
        status = "okay";
 };
+
+&qspi {
+       pinctrl-0 = <&qspi_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       flash@0 {
+               compatible = "spansion,s25fl512s", "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <30000000>;
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+               spi-cpol;
+               spi-cpha;
+               m25p,fast-read;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "loader";
+                               reg = <0x00000000 0x00040000>;
+                               read-only;
+                       };
+                       partition@40000 {
+                               label = "user";
+                               reg = <0x00040000 0x00400000>;
+                               read-only;
+                       };
+                       partition@440000 {
+                               label = "flash";
+                               reg = <0x00440000 0x03bc0000>;
+                       };
+               };
+       };
+};
index c465404..aef9e69 100644 (file)
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               spi0 = &qspi;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
        };
 
+       gpio0: gpio@e6050000 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6050000 0 0x50>;
+               interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 0 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO0>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio1: gpio@e6051000 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6051000 0 0x50>;
+               interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 32 26>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO1>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio2: gpio@e6052000 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6052000 0 0x50>;
+               interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 64 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO2>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio3: gpio@e6053000 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6053000 0 0x50>;
+               interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 96 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO3>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio4: gpio@e6054000 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6054000 0 0x50>;
+               interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 128 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO4>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio5: gpio@e6055000 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6055000 0 0x50>;
+               interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 160 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO5>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio6: gpio@e6055400 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6055400 0 0x50>;
+               interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 192 32>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO6>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       gpio7: gpio@e6055800 {
+               compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar";
+               reg = <0 0xe6055800 0 0x50>;
+               interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               gpio-ranges = <&pfc 0 224 26>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               clocks = <&mstp9_clks R8A7793_CLK_GPIO7>;
+               power-domains = <&cpg_clocks>;
+       };
+
+       thermal@e61f0000 {
+               compatible = "renesas,thermal-r8a7793", "renesas,rcar-thermal";
+               reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+               interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp5_clks R8A7793_CLK_THERMAL>;
+               power-domains = <&cpg_clocks>;
+       };
+
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
                power-domains = <&cpg_clocks>;
        };
 
+       pfc: pfc@e6060000 {
+               compatible = "renesas,pfc-r8a7793";
+               reg = <0 0xe6060000 0 0x250>;
+       };
+
+       dmac0: dma-controller@e6700000 {
+               compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac";
+               reg = <0 0xe6700000 0 0x20000>;
+               interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
+                             0 200 IRQ_TYPE_LEVEL_HIGH
+                             0 201 IRQ_TYPE_LEVEL_HIGH
+                             0 202 IRQ_TYPE_LEVEL_HIGH
+                             0 203 IRQ_TYPE_LEVEL_HIGH
+                             0 204 IRQ_TYPE_LEVEL_HIGH
+                             0 205 IRQ_TYPE_LEVEL_HIGH
+                             0 206 IRQ_TYPE_LEVEL_HIGH
+                             0 207 IRQ_TYPE_LEVEL_HIGH
+                             0 208 IRQ_TYPE_LEVEL_HIGH
+                             0 209 IRQ_TYPE_LEVEL_HIGH
+                             0 210 IRQ_TYPE_LEVEL_HIGH
+                             0 211 IRQ_TYPE_LEVEL_HIGH
+                             0 212 IRQ_TYPE_LEVEL_HIGH
+                             0 213 IRQ_TYPE_LEVEL_HIGH
+                             0 214 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12", "ch13", "ch14";
+               clocks = <&mstp2_clks R8A7793_CLK_SYS_DMAC0>;
+               clock-names = "fck";
+               power-domains = <&cpg_clocks>;
+               #dma-cells = <1>;
+               dma-channels = <15>;
+       };
+
+       dmac1: dma-controller@e6720000 {
+               compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac";
+               reg = <0 0xe6720000 0 0x20000>;
+               interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+                             0 216 IRQ_TYPE_LEVEL_HIGH
+                             0 217 IRQ_TYPE_LEVEL_HIGH
+                             0 218 IRQ_TYPE_LEVEL_HIGH
+                             0 219 IRQ_TYPE_LEVEL_HIGH
+                             0 308 IRQ_TYPE_LEVEL_HIGH
+                             0 309 IRQ_TYPE_LEVEL_HIGH
+                             0 310 IRQ_TYPE_LEVEL_HIGH
+                             0 311 IRQ_TYPE_LEVEL_HIGH
+                             0 312 IRQ_TYPE_LEVEL_HIGH
+                             0 313 IRQ_TYPE_LEVEL_HIGH
+                             0 314 IRQ_TYPE_LEVEL_HIGH
+                             0 315 IRQ_TYPE_LEVEL_HIGH
+                             0 316 IRQ_TYPE_LEVEL_HIGH
+                             0 317 IRQ_TYPE_LEVEL_HIGH
+                             0 318 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12", "ch13", "ch14";
+               clocks = <&mstp2_clks R8A7793_CLK_SYS_DMAC1>;
+               clock-names = "fck";
+               power-domains = <&cpg_clocks>;
+               #dma-cells = <1>;
+               dma-channels = <15>;
+       };
+
+       scifa0: serial@e6c40000 {
+               compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+               reg = <0 0xe6c40000 0 64>;
+               interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x21>, <&dmac0 0x22>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifa1: serial@e6c50000 {
+               compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+               reg = <0 0xe6c50000 0 64>;
+               interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x25>, <&dmac0 0x26>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifa2: serial@e6c60000 {
+               compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+               reg = <0 0xe6c60000 0 64>;
+               interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x27>, <&dmac0 0x28>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifa3: serial@e6c70000 {
+               compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+               reg = <0 0xe6c70000 0 64>;
+               interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifa4: serial@e6c78000 {
+               compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+               reg = <0 0xe6c78000 0 64>;
+               interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifa5: serial@e6c80000 {
+               compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+               reg = <0 0xe6c80000 0 64>;
+               interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x23>, <&dmac0 0x24>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifb0: serial@e6c20000 {
+               compatible = "renesas,scifb-r8a7793", "renesas,scifb";
+               reg = <0 0xe6c20000 0 64>;
+               interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifb1: serial@e6c30000 {
+               compatible = "renesas,scifb-r8a7793", "renesas,scifb";
+               reg = <0 0xe6c30000 0 64>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scifb2: serial@e6ce0000 {
+               compatible = "renesas,scifb-r8a7793", "renesas,scifb";
+               reg = <0 0xe6ce0000 0 64>;
+               interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
        scif0: serial@e6e60000 {
                compatible = "renesas,scif-r8a7793", "renesas,scif";
                reg = <0 0xe6e60000 0 64>;
                interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp7_clks R8A7793_CLK_SCIF0>;
                clock-names = "sci_ick";
+               dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
+               dma-names = "tx", "rx";
                power-domains = <&cpg_clocks>;
                status = "disabled";
        };
                interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp7_clks R8A7793_CLK_SCIF1>;
                clock-names = "sci_ick";
+               dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scif2: serial@e6e58000 {
+               compatible = "renesas,scif-r8a7793", "renesas,scif";
+               reg = <0 0xe6e58000 0 64>;
+               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_SCIF2>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scif3: serial@e6ea8000 {
+               compatible = "renesas,scif-r8a7793", "renesas,scif";
+               reg = <0 0xe6ea8000 0 64>;
+               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_SCIF3>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scif4: serial@e6ee0000 {
+               compatible = "renesas,scif-r8a7793", "renesas,scif";
+               reg = <0 0xe6ee0000 0 64>;
+               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_SCIF4>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       scif5: serial@e6ee8000 {
+               compatible = "renesas,scif-r8a7793", "renesas,scif";
+               reg = <0 0xe6ee8000 0 64>;
+               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_SCIF5>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       hscif0: serial@e62c0000 {
+               compatible = "renesas,hscif-r8a7793", "renesas,hscif";
+               reg = <0 0xe62c0000 0 96>;
+               interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       hscif1: serial@e62c8000 {
+               compatible = "renesas,hscif-r8a7793", "renesas,hscif";
+               reg = <0 0xe62c8000 0 96>;
+               interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               status = "disabled";
+       };
+
+       hscif2: serial@e62d0000 {
+               compatible = "renesas,hscif-r8a7793", "renesas,hscif";
+               reg = <0 0xe62d0000 0 96>;
+               interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>;
+               clock-names = "sci_ick";
+               dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
+               dma-names = "tx", "rx";
                power-domains = <&cpg_clocks>;
                status = "disabled";
        };
                status = "disabled";
        };
 
+       qspi: spi@e6b10000 {
+               compatible = "renesas,qspi-r8a7793", "renesas,qspi";
+               reg = <0 0xe6b10000 0 0x2c>;
+               interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7793_CLK_QSPI_MOD>;
+               dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg_clocks>;
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       du: display@feb00000 {
+               compatible = "renesas,du-r8a7793";
+               reg = <0 0xfeb00000 0 0x40000>,
+                     <0 0xfeb90000 0 0x1c>;
+               reg-names = "du", "lvds.0";
+               interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 268 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7793_CLK_DU0>,
+                        <&mstp7_clks R8A7793_CLK_DU1>,
+                        <&mstp7_clks R8A7793_CLK_LVDS0>;
+               clock-names = "du.0", "du.1", "lvds.0";
+               status = "disabled";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               du_out_rgb: endpoint {
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               du_out_lvds0: endpoint {
+                               };
+                       };
+               };
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                                "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
                                "vsp1-du0", "vsps";
                };
+               mstp2_clks: mstp2_clks@e6150138 {
+                       compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+                       clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+                                <&mp_clk>, <&mp_clk>, <&zs_clk>, <&zs_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               R8A7793_CLK_SCIFA2 R8A7793_CLK_SCIFA1 R8A7793_CLK_SCIFA0
+                               R8A7793_CLK_SCIFB0 R8A7793_CLK_SCIFB1 R8A7793_CLK_SCIFB2
+                               R8A7793_CLK_SYS_DMAC1 R8A7793_CLK_SYS_DMAC0
+                       >;
+                       clock-output-names =
+                               "scifa2", "scifa1", "scifa0", "scifb0",
+                               "scifb1", "scifb2", "sys-dmac1", "sys-dmac0";
+               };
                mstp3_clks: mstp3_clks@e615013c {
                        compatible = "renesas,r8a7793-mstp-clocks",
                                     "renesas,cpg-mstp-clocks";
                        clock-indices = <R8A7793_CLK_IRQC>;
                        clock-output-names = "irqc";
                };
+               mstp5_clks: mstp5_clks@e6150144 {
+                       compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+                       clocks = <&extal_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <R8A7793_CLK_THERMAL>;
+                       clock-output-names = "thermal";
+               };
                mstp7_clks: mstp7_clks@e615014c {
                        compatible = "renesas,r8a7793-mstp-clocks",
                                     "renesas,cpg-mstp-clocks";
                                "ipmmu_sgx", "vin2", "vin1", "vin0", "ether",
                                "sata1", "sata0";
                };
+               mstp9_clks: mstp9_clks@e6150994 {
+                       compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+                       clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+                                <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+                                <&cpg_clocks R8A7793_CLK_QSPI>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               R8A7793_CLK_GPIO7 R8A7793_CLK_GPIO6
+                               R8A7793_CLK_GPIO5 R8A7793_CLK_GPIO4
+                               R8A7793_CLK_GPIO3 R8A7793_CLK_GPIO2
+                               R8A7793_CLK_GPIO1 R8A7793_CLK_GPIO0
+                               R8A7793_CLK_QSPI_MOD
+                       >;
+                       clock-output-names =
+                               "gpio7", "gpio6", "gpio5", "gpio4",
+                               "gpio3", "gpio2", "gpio1", "gpio0",
+                               "qspi_mod";
+               };
+               mstp11_clks: mstp11_clks@e615099c {
+                       compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+                       clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               R8A7793_CLK_SCIFA3 R8A7793_CLK_SCIFA4 R8A7793_CLK_SCIFA5
+                       >;
+                       clock-output-names = "scifa3", "scifa4", "scifa5";
+               };
+       };
+
+       ipmmu_sy0: mmu@e6280000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xe6280000 0 0x1000>;
+               interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 224 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
+       ipmmu_sy1: mmu@e6290000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xe6290000 0 0x1000>;
+               interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
+       ipmmu_ds: mmu@e6740000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xe6740000 0 0x1000>;
+               interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 199 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
+       ipmmu_mp: mmu@ec680000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xec680000 0 0x1000>;
+               interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
+       ipmmu_mx: mmu@fe951000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xfe951000 0 0x1000>;
+               interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 221 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
+       ipmmu_rt: mmu@ffc80000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xffc80000 0 0x1000>;
+               interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
        };
 
+       ipmmu_gp: mmu@e62a0000 {
+               compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa";
+               reg = <0 0xe62a0000 0 0x1000>;
+               interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 261 IRQ_TYPE_LEVEL_HIGH>;
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
 };
index 928cfa6..2394e48 100644 (file)
@@ -21,7 +21,7 @@
 
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scif2;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
                #address-cells = <1>;
                #size-cells = <1>;
        };
+
+       vga-encoder {
+               compatible = "adi,adv7123";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7123_in: endpoint {
+                                       remote-endpoint = <&du_out_rgb1>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               adv7123_out: endpoint {
+                                       remote-endpoint = <&vga_in>;
+                               };
+                       };
+               };
+       };
+
+       vga {
+               compatible = "vga-connector";
+
+               port {
+                       vga_in: endpoint {
+                               remote-endpoint = <&adv7123_out>;
+                       };
+               };
+       };
+
+       x2_clk: x2-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <74250000>;
+       };
+
+       x13_clk: x13-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <148500000>;
+       };
+};
+
+&du {
+       pinctrl-0 = <&du_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       clocks = <&mstp7_clks R8A7794_CLK_DU0>,
+                <&mstp7_clks R8A7794_CLK_DU0>,
+                <&x13_clk>, <&x2_clk>;
+       clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1";
+
+       ports {
+               port@1 {
+                       endpoint {
+                               remote-endpoint = <&adv7123_in>;
+                       };
+               };
+       };
 };
 
 &extal_clk {
        clock-frequency = <20000000>;
 };
 
+&pfc {
+       du_pins: du {
+               renesas,groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0";
+               renesas,function = "du";
+       };
+
+       scif2_pins: serial2 {
+               renesas,groups = "scif2_data";
+               renesas,function = "scif2";
+       };
+
+       ether_pins: ether {
+               renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+               renesas,function = "eth";
+       };
+
+       phy1_pins: phy1 {
+               renesas,groups = "intc_irq8";
+               renesas,function = "intc";
+       };
+
+       i2c1_pins: i2c1 {
+               renesas,groups = "i2c1";
+               renesas,function = "i2c1";
+       };
+
+       vin0_pins: vin0 {
+               renesas,groups = "vin0_data8", "vin0_clk";
+               renesas,function = "vin0";
+       };
+};
+
 &cmt0 {
        status = "okay";
 };
 
 &ether {
+       pinctrl-0 = <&ether_pins &phy1_pins>;
+       pinctrl-names = "default";
+
        phy-handle = <&phy1>;
        renesas,ether-link-active-low;
        status = "okay";
        };
 };
 
+&i2c1 {
+       pinctrl-0 = <&i2c1_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       composite-in@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+               remote = <&vin0>;
+
+               port {
+                       adv7180: endpoint {
+                               bus-width = <8>;
+                               remote-endpoint = <&vin0ep>;
+                       };
+               };
+       };
+};
+
+&vin0 {
+       status = "okay";
+       pinctrl-0 = <&vin0_pins>;
+       pinctrl-names = "default";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vin0ep: endpoint {
+                       remote-endpoint = <&adv7180>;
+                       bus-width = <8>;
+               };
+       };
+};
+
 &scif2 {
+       pinctrl-0 = <&scif2_pins>;
+       pinctrl-names = "default";
+
        status = "okay";
 };
index 48ff3e2..5153e3a 100644 (file)
@@ -12,6 +12,7 @@
 
 /dts-v1/;
 #include "r8a7794.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "SILK";
@@ -23,7 +24,7 @@
 
        chosen {
                bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
-               stdout-path = &scif2;
+               stdout-path = "serial0:115200n8";
        };
 
        memory@40000000 {
                regulator-boot-on;
                regulator-always-on;
        };
+
+       vcc_sdhi1: regulator@3 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI1 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi1: regulator@4 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI1 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
 };
 
 &extal_clk {
                renesas,function = "mmc";
        };
 
+       sdhi1_pins: sd1 {
+               renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+               renesas,function = "sdhi1";
+       };
+
        qspi_pins: spi0 {
                renesas,groups = "qspi_ctrl", "qspi_data4";
                renesas,function = "qspi";
        status = "okay";
 };
 
+&sdhi1 {
+       pinctrl-0 = <&sdhi1_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi1>;
+       vqmmc-supply = <&vccq_sdhi1>;
+       cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
 &qspi {
        pinctrl-0 = <&qspi_pins>;
        pinctrl-names = "default";
        status = "okay";
 
        flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
                compatible = "spansion,s25fl512s", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <30000000>;
                spi-cpha;
                m25p,fast-read;
 
-               partition@0 {
-                       label = "loader";
-                       reg = <0x00000000 0x00040000>;
-                       read-only;
-               };
-               partition@40000 {
-                       label = "user";
-                       reg = <0x00040000 0x00400000>;
-                       read-only;
-               };
-               partition@440000 {
-                       label = "flash";
-                       reg = <0x00440000 0x03bc0000>;
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "loader";
+                               reg = <0x00000000 0x00040000>;
+                               read-only;
+                       };
+                       partition@40000 {
+                               label = "user";
+                               reg = <0x00040000 0x00400000>;
+                               read-only;
+                       };
+                       partition@440000 {
+                               label = "flash";
+                               reg = <0x00440000 0x03bc0000>;
+                       };
                };
        };
 };
index a9977d6..6c78f1f 100644 (file)
        pfc: pin-controller@e6060000 {
                compatible = "renesas,pfc-r8a7794";
                reg = <0 0xe6060000 0 0x11c>;
-               #gpio-range-cells = <3>;
        };
 
        dmac0: dma-controller@e6700000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
                reg = <0 0xe6700000 0 0x20000>;
                interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
                              0 200 IRQ_TYPE_LEVEL_HIGH
        };
 
        dmac1: dma-controller@e6720000 {
-               compatible = "renesas,rcar-dmac";
+               compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
                reg = <0 0xe6720000 0 0x20000>;
                interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
                              0 216 IRQ_TYPE_LEVEL_HIGH
                power-domains = <&cpg_clocks>;
                #address-cells = <1>;
                #size-cells = <0>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                power-domains = <&cpg_clocks>;
                #address-cells = <1>;
                #size-cells = <0>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                power-domains = <&cpg_clocks>;
                #address-cells = <1>;
                #size-cells = <0>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                power-domains = <&cpg_clocks>;
                #address-cells = <1>;
                #size-cells = <0>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                power-domains = <&cpg_clocks>;
                #address-cells = <1>;
                #size-cells = <0>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                power-domains = <&cpg_clocks>;
                #address-cells = <1>;
                #size-cells = <0>;
+               i2c-scl-internal-delay-ns = <6>;
                status = "disabled";
        };
 
                };
        };
 
+       du: display@feb00000 {
+               compatible = "renesas,du-r8a7794";
+               reg = <0 0xfeb00000 0 0x40000>;
+               reg-names = "du";
+               interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 268 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_DU0>,
+                        <&mstp7_clks R8A7794_CLK_DU0>;
+               clock-names = "du.0", "du.1";
+               status = "disabled";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               du_out_rgb0: endpoint {
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               du_out_rgb1: endpoint {
+                               };
+                       };
+               };
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                        clock-mult = <1>;
                        clock-output-names = "m2";
                };
-               imp_clk: imp_clk {
-                       compatible = "fixed-factor-clock";
-                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
-                       #clock-cells = <0>;
-                       clock-div = <4>;
-                       clock-mult = <1>;
-                       clock-output-names = "imp";
-               };
                rclk_clk: rclk_clk {
                        compatible = "fixed-factor-clock";
                        clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
                        reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
                        clocks = <&mp_clk>, <&mp_clk>,
                                 <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
-                                <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
+                                <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+                                <&zx_clk>;
                        #clock-cells = <1>;
                        clock-indices = <
                                R8A7794_CLK_EHCI R8A7794_CLK_HSUSB
                                R8A7794_CLK_HSCIF2 R8A7794_CLK_SCIF5
                                R8A7794_CLK_SCIF4 R8A7794_CLK_HSCIF1 R8A7794_CLK_HSCIF0
                                R8A7794_CLK_SCIF3 R8A7794_CLK_SCIF2 R8A7794_CLK_SCIF1
-                               R8A7794_CLK_SCIF0
+                               R8A7794_CLK_SCIF0 R8A7794_CLK_DU0
                        >;
                        clock-output-names =
                                "ehci", "hsusb",
                                "hscif2", "scif5", "scif4", "hscif1", "hscif0",
-                               "scif3", "scif2", "scif1", "scif0";
+                               "scif3", "scif2", "scif1", "scif0", "du0";
                };
                mstp8_clks: mstp8_clks@e6150990 {
                        compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
        };
 
        ipmmu_sy0: mmu@e6280000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
                reg = <0 0xe6280000 0 0x1000>;
                interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
                             <0 224 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        ipmmu_sy1: mmu@e6290000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
                reg = <0 0xe6290000 0 0x1000>;
                interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_ds: mmu@e6740000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
                reg = <0 0xe6740000 0 0x1000>;
                interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
                             <0 199 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
+               status = "disabled";
        };
 
        ipmmu_mp: mmu@ec680000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
                reg = <0 0xec680000 0 0x1000>;
                interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
        };
 
        ipmmu_mx: mmu@fe951000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
                reg = <0 0xfe951000 0 0x1000>;
                interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
                             <0 221 IRQ_TYPE_LEVEL_HIGH>;
                #iommu-cells = <1>;
+               status = "disabled";
        };
 
        ipmmu_gp: mmu@e62a0000 {
-               compatible = "renesas,ipmmu-vmsa";
+               compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
                reg = <0 0xe62a0000 0 0x1000>;
                interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
                             <0 261 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
new file mode 100644 (file)
index 0000000..28a0336
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3036.dtsi"
+
+/ {
+       model = "Rockchip RK3036 Evaluation board";
+       compatible = "rockchip,rk3036-evb", "rockchip,rk3036";
+};
+
+&i2c1 {
+       status = "okay";
+
+       hym8563: hym8563@51 {
+               compatible = "haoyu,hym8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "xin32k";
+       };
+};
+
+&uart2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts
new file mode 100644 (file)
index 0000000..992f9ca
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3036.dtsi"
+
+/ {
+       model = "Rockchip RK3036 KylinBoard";
+       compatible = "rockchip,rk3036-kylin", "rockchip,rk3036";
+
+       vcc_sys: vsys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&acodec {
+       status = "okay";
+};
+
+&emmc {
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+
+       status = "okay";
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int &global_pwroff>;
+               rockchip,system-power-controller;
+               wakeup-source;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+
+               vcc1-supply = <&vcc_sys>;
+               vcc2-supply = <&vcc_sys>;
+               vcc3-supply = <&vcc_sys>;
+               vcc4-supply = <&vcc_sys>;
+               vcc6-supply = <&vcc_sys>;
+               vcc7-supply = <&vcc_sys>;
+               vcc8-supply = <&vcc_18>;
+               vcc9-supply = <&vcc_io>;
+               vcc10-supply = <&vcc_io>;
+               vcc11-supply = <&vcc_sys>;
+               vcc12-supply = <&vcc_io>;
+               vddio-supply = <&vccio_pmu>;
+
+               regulators {
+                       vdd_cpu: DCDC_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-name = "vdd_arm";
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_gpu: DCDC_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <1250000>;
+                               regulator-name = "vdd_gpu";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc_ddr";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_io: DCDC_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc_io";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vccio_pmu: LDO_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vccio_pmu";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_tp: LDO_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc_tp";
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_10: LDO_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-name = "vdd_10";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc18_lcd: LDO_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc18_lcd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vccio_sd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vout5: LDO_REG6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-name = "vout5";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc_18: LDO_REG7 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_18";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca_codec: LDO_REG8 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcca_codec";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc_wl: SWITCH_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc_wl";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_lcd: SWITCH_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc_lcd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&sdio {
+       status = "okay";
+
+       broken-cd;
+       bus-width = <4>;
+       cap-sdio-irq;
+       default-sample-phase = <90>;
+       keep-power-in-suspend;
+       non-removable;
+       num-slots = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>;
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host {
+       status = "okay";
+};
+
+&usb_otg {
+       status = "okay";
+};
+
+&pinctrl {
+       pmic {
+               pmic_int: pmic-int {
+                       rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_default>;
+               };
+       };
+
+       sleep {
+               global_pwroff: global-pwroff {
+                       rockchip,pins = <2 7 RK_FUNC_1 &pcfg_pull_none>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
new file mode 100644 (file)
index 0000000..b9567c1
--- /dev/null
@@ -0,0 +1,622 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3036-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "rockchip,rk3036";
+
+       interrupt-parent = <&gic>;
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               mshc0 = &emmc;
+               mshc1 = &sdmmc;
+               mshc2 = &sdio;
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x60000000 0x40000000>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "rockchip,rk3036-smp";
+
+               cpu0: cpu@f00 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf00>;
+                       resets = <&cru SRST_CORE0>;
+                       operating-points = <
+                               /* KHz    uV */
+                                816000 1000000
+                       >;
+                       clock-latency = <40000>;
+                       clocks = <&cru ARMCLK>;
+               };
+
+               cpu1: cpu@f01 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf01>;
+                       resets = <&cru SRST_CORE1>;
+               };
+       };
+
+       amba {
+               compatible = "arm,amba-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               pdma: pdma@20078000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x20078000 0x4000>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       clocks = <&cru ACLK_DMAC2>;
+                       clock-names = "apb_pclk";
+               };
+       };
+
+       arm-pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>;
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               arm,cpu-registers-not-fw-configured;
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+               clock-frequency = <24000000>;
+       };
+
+       xin24m: oscillator {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xin24m";
+               #clock-cells = <0>;
+       };
+
+       bus_intmem@10080000 {
+               compatible = "mmio-sram";
+               reg = <0x10080000 0x2000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x10080000 0x2000>;
+
+               smp-sram@0 {
+                       compatible = "rockchip,rk3066-smp-sram";
+                       reg = <0x00 0x10>;
+               };
+       };
+
+       gic: interrupt-controller@10139000 {
+               compatible = "arm,gic-400";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+
+               reg = <0x10139000 0x1000>,
+                     <0x1013a000 0x1000>,
+                     <0x1013c000 0x2000>,
+                     <0x1013e000 0x2000>;
+               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       usb_otg: usb@10180000 {
+               compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+                               "snps,dwc2";
+               reg = <0x10180000 0x40000>;
+               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_OTG0>;
+               clock-names = "otg";
+               dr_mode = "otg";
+               g-np-tx-fifo-size = <16>;
+               g-rx-fifo-size = <275>;
+               g-tx-fifo-size = <256 128 128 64 64 32>;
+               g-use-dma;
+               status = "disabled";
+       };
+
+       usb_host: usb@101c0000 {
+               compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+                               "snps,dwc2";
+               reg = <0x101c0000 0x40000>;
+               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_OTG1>;
+               clock-names = "otg";
+               dr_mode = "host";
+               status = "disabled";
+       };
+
+       sdmmc: dwmmc@10214000 {
+               compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x10214000 0x4000>;
+               clock-frequency = <37500000>;
+               clock-freq-min-max = <400000 37500000>;
+               clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+               clock-names = "biu", "ciu";
+               fifo-depth = <0x100>;
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       sdio: dwmmc@10218000 {
+               compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x10218000 0x4000>;
+               clock-freq-min-max = <400000 37500000>;
+               clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+                        <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               fifo-depth = <0x100>;
+               interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       emmc: dwmmc@1021c000 {
+               compatible = "rockchip,rk3288-dw-mshc";
+               reg = <0x1021c000 0x4000>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               broken-cd;
+               bus-width = <8>;
+               cap-mmc-highspeed;
+               clock-frequency = <37500000>;
+               clock-freq-min-max = <400000 37500000>;
+               clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+                        <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               default-sample-phase = <158>;
+               disable-wp;
+               dmas = <&pdma 12>;
+               dma-names = "rx-tx";
+               fifo-depth = <0x100>;
+               mmc-ddr-1_8v;
+               non-removable;
+               num-slots = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+               status = "disabled";
+       };
+
+       i2s: i2s@10220000 {
+               compatible = "rockchip,rk3036-i2s", "rockchip,rk3066-i2s";
+               reg = <0x10220000 0x4000>;
+               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "i2s_hclk", "i2s_clk";
+               clocks = <&cru HCLK_I2S>, <&cru SCLK_I2S>;
+               dmas = <&pdma 0>, <&pdma 1>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s_bus>;
+               status = "disabled";
+       };
+
+       cru: clock-controller@20000000 {
+               compatible = "rockchip,rk3036-cru";
+               reg = <0x20000000 0x1000>;
+               rockchip,grf = <&grf>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               assigned-clocks = <&cru PLL_GPLL>;
+               assigned-clock-rates = <594000000>;
+       };
+
+       grf: syscon@20008000 {
+               compatible = "rockchip,rk3036-grf", "syscon";
+               reg = <0x20008000 0x1000>;
+       };
+
+       acodec: acodec-ana@20030000 {
+               compatible = "rk3036-codec";
+               reg = <0x20030000 0x4000>;
+               rockchip,grf = <&grf>;
+               clock-names = "acodec_pclk";
+               clocks = <&cru PCLK_ACODEC>;
+               status = "disabled";
+       };
+
+       timer: timer@20044000 {
+               compatible = "rockchip,rk3036-timer", "rockchip,rk3288-timer";
+               reg = <0x20044000 0x20>;
+               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&xin24m>, <&cru PCLK_TIMER>;
+               clock-names = "timer", "pclk";
+       };
+
+       pwm0: pwm@20050000 {
+               compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+               reg = <0x20050000 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_pin>;
+               status = "disabled";
+       };
+
+       pwm1: pwm@20050010 {
+               compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+               reg = <0x20050010 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm1_pin>;
+               status = "disabled";
+       };
+
+       pwm2: pwm@20050020 {
+               compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+               reg = <0x20050020 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm2_pin>;
+               status = "disabled";
+       };
+
+       pwm3: pwm@20050030 {
+               compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+               reg = <0x20050030 0x10>;
+               #pwm-cells = <2>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm3_pin>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@20056000 {
+               compatible = "rockchip,rk3288-i2c";
+               reg = <0x20056000 0x1000>;
+               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "i2c";
+               clocks = <&cru PCLK_I2C1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c1_xfer>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@2005a000 {
+               compatible = "rockchip,rk3288-i2c";
+               reg = <0x2005a000 0x1000>;
+               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "i2c";
+               clocks = <&cru PCLK_I2C2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_xfer>;
+               status = "disabled";
+       };
+
+       uart0: serial@20060000 {
+               compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+               reg = <0x20060000 0x100>;
+               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+               clock-names = "baudclk", "apb_pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+               status = "disabled";
+       };
+
+       uart1: serial@20064000 {
+               compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+               reg = <0x20064000 0x100>;
+               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+               clock-names = "baudclk", "apb_pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart1_xfer>;
+               status = "disabled";
+       };
+
+       uart2: serial@20068000 {
+               compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+               reg = <0x20068000 0x100>;
+               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+               clock-names = "baudclk", "apb_pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart2_xfer>;
+               status = "disabled";
+       };
+
+       i2c0: i2c@20072000 {
+               compatible = "rockchip,rk3288-i2c";
+               reg = <0x20072000 0x1000>;
+               interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "i2c";
+               clocks = <&cru PCLK_I2C0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c0_xfer>;
+               status = "disabled";
+       };
+
+       pinctrl: pinctrl {
+               compatible = "rockchip,rk3036-pinctrl";
+               rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               gpio0: gpio0@2007c000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x2007c000 0x100>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO0>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio1: gpio1@20080000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x20080000 0x100>;
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO1>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio2: gpio2@20084000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x20084000 0x100>;
+                       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO2>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               pcfg_pull_default: pcfg_pull_default {
+                       bias-pull-pin-default;
+               };
+
+               pcfg_pull_none: pcfg-pull-none {
+                       bias-disable;
+               };
+
+               pwm0 {
+                       pwm0_pin: pwm0-pin {
+                               rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm1 {
+                       pwm1_pin: pwm1-pin {
+                               rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm2 {
+                       pwm2_pin: pwm2-pin {
+                               rockchip,pins = <0 1 2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm3 {
+                       pwm3_pin: pwm3-pin {
+                               rockchip,pins = <0 27 1 &pcfg_pull_none>;
+                       };
+               };
+
+               sdmmc {
+                       sdmmc_clk: sdmmc-clk {
+                               rockchip,pins = <1 16 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       sdmmc_cmd: sdmmc-cmd {
+                               rockchip,pins = <1 15 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       sdmmc_cd: sdmcc-cd {
+                               rockchip,pins = <1 17 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       sdmmc_bus1: sdmmc-bus1 {
+                               rockchip,pins = <1 18 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       sdmmc_bus4: sdmmc-bus4 {
+                               rockchip,pins = <1 18 RK_FUNC_1 &pcfg_pull_default>,
+                                               <1 19 RK_FUNC_1 &pcfg_pull_default>,
+                                               <1 20 RK_FUNC_1 &pcfg_pull_default>,
+                                               <1 21 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+               };
+
+               sdio {
+                       sdio_bus1: sdio-bus1 {
+                               rockchip,pins = <0 11 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       sdio_bus4: sdio-bus4 {
+                               rockchip,pins = <0 11 RK_FUNC_1 &pcfg_pull_default>,
+                                               <0 12 RK_FUNC_1 &pcfg_pull_default>,
+                                               <0 13 RK_FUNC_1 &pcfg_pull_default>,
+                                               <0 14 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       sdio_cmd: sdio-cmd {
+                               rockchip,pins = <0 8 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       sdio_clk: sdio-clk {
+                               rockchip,pins = <0 9 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               emmc {
+                       /*
+                        * We run eMMC at max speed; bump up drive strength.
+                        * We also have external pulls, so disable the internal ones.
+                        */
+                       emmc_clk: emmc-clk {
+                               rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       emmc_cmd: emmc-cmd {
+                               rockchip,pins = <2 1 RK_FUNC_2 &pcfg_pull_default>;
+                       };
+
+                       emmc_bus8: emmc-bus8 {
+                               rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 25 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 26 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 27 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 28 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 29 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 30 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 31 RK_FUNC_2 &pcfg_pull_default>;
+                       };
+               };
+
+               i2c0 {
+                       i2c0_xfer: i2c0-xfer {
+                               rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>,
+                                               <0 1 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c1 {
+                       i2c1_xfer: i2c1-xfer {
+                               rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_none>,
+                                               <0 3 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c2 {
+                       i2c2_xfer: i2c2-xfer {
+                               rockchip,pins = <2 20 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 21 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s {
+                       i2s_bus: i2s-bus {
+                               rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_none>,
+                                               <1 1 RK_FUNC_1 &pcfg_pull_none>,
+                                               <1 2 RK_FUNC_1 &pcfg_pull_none>,
+                                               <1 3 RK_FUNC_1 &pcfg_pull_none>,
+                                               <1 4 RK_FUNC_1 &pcfg_pull_none>,
+                                               <1 5 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart0 {
+                       uart0_xfer: uart0-xfer {
+                               rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_default>,
+                                               <0 17 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart0_cts: uart0-cts {
+                               rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_default>;
+                       };
+
+                       uart0_rts: uart0-rts {
+                               rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart1 {
+                       uart1_xfer: uart1-xfer {
+                               rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_default>,
+                                               <2 23 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+                       /* no rts / cts for uart1 */
+               };
+
+               uart2 {
+                       uart2_xfer: uart2-xfer {
+                               rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_default>,
+                                               <1 19 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+                       /* no rts / cts for uart2 */
+               };
+       };
+};
index 946f187..58bac50 100644 (file)
                dma-names = "tx", "rx";
                clock-names = "i2s_hclk", "i2s_clk";
                clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+               rockchip,playback-channels = <8>;
+               rockchip,capture-channels = <2>;
                status = "disabled";
        };
 
                dma-names = "tx", "rx";
                clock-names = "i2s_hclk", "i2s_clk";
                clocks = <&cru HCLK_I2S1>, <&cru SCLK_I2S1>;
+               rockchip,playback-channels = <2>;
+               rockchip,capture-channels = <2>;
                status = "disabled";
        };
 
                dma-names = "tx", "rx";
                clock-names = "i2s_hclk", "i2s_clk";
                clocks = <&cru HCLK_I2S2>, <&cru SCLK_I2S2>;
+               rockchip,playback-channels = <2>;
+               rockchip,capture-channels = <2>;
                status = "disabled";
        };
 
                clock-names = "timer", "pclk";
        };
 
+       efuse: efuse@20010000 {
+               compatible = "rockchip,rockchip-efuse";
+               reg = <0x20010000 0x4000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               clocks = <&cru PCLK_EFUSE>;
+               clock-names = "pclk_efuse";
+
+               cpu_leakage: cpu_leakage {
+                       reg = <0x17 0x1>;
+               };
+       };
+
        timer@20038000 {
                compatible = "snps,dw-apb-timer-osc";
                reg = <0x20038000 0x100>;
index 6399942..348d46b 100644 (file)
                dma-names = "tx", "rx";
                clock-names = "i2s_hclk", "i2s_clk";
                clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+               rockchip,playback-channels = <2>;
+               rockchip,capture-channels = <2>;
                status = "disabled";
        };
 
                #reset-cells = <1>;
        };
 
+       efuse: efuse@20010000 {
+               compatible = "rockchip,rockchip-efuse";
+               reg = <0x20010000 0x4000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               clocks = <&cru PCLK_EFUSE>;
+               clock-names = "pclk_efuse";
+
+               cpu_leakage: cpu_leakage {
+                       reg = <0x17 0x1>;
+               };
+       };
+
        usbphy: phy {
                compatible = "rockchip,rk3188-usb-phy", "rockchip,rk3288-usb-phy";
                rockchip,grf = <&grf>;
diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
new file mode 100644 (file)
index 0000000..e3898b8
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3228.dtsi"
+
+/ {
+       model = "Rockchip RK3228 Evaluation board";
+       compatible = "rockchip,rk3228-evb", "rockchip,rk3228";
+
+       memory {
+               device_type = "memory";
+               reg = <0x60000000 0x40000000>;
+       };
+};
+
+&emmc {
+       broken-cd;
+       cap-mmc-highspeed;
+       mmc-ddr-1_8v;
+       disable-wp;
+       non-removable;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3228.dtsi b/arch/arm/boot/dts/rk3228.dtsi
new file mode 100644 (file)
index 0000000..119ff12
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3228-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "rockchip,rk3228";
+
+       interrupt-parent = <&gic>;
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@f00 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf00>;
+                       resets = <&cru SRST_CORE0>;
+                       operating-points = <
+                               /* KHz    uV */
+                                816000 1000000
+                       >;
+                       clock-latency = <40000>;
+                       clocks = <&cru ARMCLK>;
+               };
+
+               cpu1: cpu@f01 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf01>;
+                       resets = <&cru SRST_CORE1>;
+               };
+
+               cpu2: cpu@f02 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf02>;
+                       resets = <&cru SRST_CORE2>;
+               };
+
+               cpu3: cpu@f03 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0xf03>;
+                       resets = <&cru SRST_CORE3>;
+               };
+       };
+
+       amba {
+               compatible = "arm,amba-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               pdma: pdma@110f0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x110f0000 0x4000>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       clocks = <&cru ACLK_DMAC>;
+                       clock-names = "apb_pclk";
+               };
+       };
+
+       arm-pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               arm,cpu-registers-not-fw-configured;
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               clock-frequency = <24000000>;
+       };
+
+       xin24m: oscillator {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xin24m";
+               #clock-cells = <0>;
+       };
+
+       grf: syscon@11000000 {
+               compatible = "syscon";
+               reg = <0x11000000 0x1000>;
+       };
+
+       uart0: serial@11010000 {
+               compatible = "snps,dw-apb-uart";
+               reg = <0x11010000 0x100>;
+               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+               clock-names = "baudclk", "apb_pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               status = "disabled";
+       };
+
+       uart1: serial@11020000 {
+               compatible = "snps,dw-apb-uart";
+               reg = <0x11020000 0x100>;
+               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+               clock-names = "baudclk", "apb_pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart1_xfer>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               status = "disabled";
+       };
+
+       uart2: serial@11030000 {
+               compatible = "snps,dw-apb-uart";
+               reg = <0x11030000 0x100>;
+               interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+               clock-names = "baudclk", "apb_pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart2_xfer>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               status = "disabled";
+       };
+
+       pwm0: pwm@110b0000 {
+               compatible = "rockchip,rk3288-pwm";
+               reg = <0x110b0000 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_pin>;
+               status = "disabled";
+       };
+
+       pwm1: pwm@110b0010 {
+               compatible = "rockchip,rk3288-pwm";
+               reg = <0x110b0010 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm1_pin>;
+               status = "disabled";
+       };
+
+       pwm2: pwm@110b0020 {
+               compatible = "rockchip,rk3288-pwm";
+               reg = <0x110b0020 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm2_pin>;
+               status = "disabled";
+       };
+
+       pwm3: pwm@110b0030 {
+               compatible = "rockchip,rk3288-pwm";
+               reg = <0x110b0030 0x10>;
+               #pwm-cells = <2>;
+               clocks = <&cru PCLK_PWM>;
+               clock-names = "pwm";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm3_pin>;
+               status = "disabled";
+       };
+
+       timer: timer@110c0000 {
+               compatible = "rockchip,rk3288-timer";
+               reg = <0x110c0000 0x20>;
+               interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&xin24m>, <&cru PCLK_TIMER>;
+               clock-names = "timer", "pclk";
+       };
+
+       cru: clock-controller@110e0000 {
+               compatible = "rockchip,rk3228-cru";
+               reg = <0x110e0000 0x1000>;
+               rockchip,grf = <&grf>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               assigned-clocks = <&cru PLL_GPLL>;
+               assigned-clock-rates = <594000000>;
+       };
+
+       emmc: dwmmc@30020000 {
+               compatible = "rockchip,rk3288-dw-mshc";
+               reg = <0x30020000 0x4000>;
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <37500000>;
+               clock-freq-min-max = <400000 37500000>;
+               clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+                        <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               bus-width = <8>;
+               default-sample-phase = <158>;
+               num-slots = <1>;
+               fifo-depth = <0x100>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+               status = "disabled";
+       };
+
+       gic: interrupt-controller@32010000 {
+               compatible = "arm,gic-400";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+
+               reg = <0x32011000 0x1000>,
+                     <0x32012000 0x1000>,
+                     <0x32014000 0x2000>,
+                     <0x32016000 0x2000>;
+               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       pinctrl: pinctrl {
+               compatible = "rockchip,rk3228-pinctrl";
+               rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               gpio0: gpio0@11110000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x11110000 0x100>;
+                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO0>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio1: gpio1@11120000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x11120000 0x100>;
+                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO1>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio2: gpio2@11130000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x11130000 0x100>;
+                       interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO2>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio3: gpio3@11140000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x11140000 0x100>;
+                       interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO3>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               pcfg_pull_up: pcfg-pull-up {
+                       bias-pull-up;
+               };
+
+               pcfg_pull_down: pcfg-pull-down {
+                       bias-pull-down;
+               };
+
+               pcfg_pull_none: pcfg-pull-none {
+                       bias-disable;
+               };
+
+               emmc {
+                       emmc_clk: emmc-clk {
+                               rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       emmc_cmd: emmc-cmd {
+                               rockchip,pins = <1 22 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       emmc_bus8: emmc-bus8 {
+                               rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 25 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 26 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 27 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 28 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 29 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 30 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 31 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm0 {
+                       pwm0_pin: pwm0-pin {
+                               rockchip,pins = <3 21 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm1 {
+                       pwm1_pin: pwm1-pin {
+                               rockchip,pins = <0 30 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm2 {
+                       pwm2_pin: pwm2-pin {
+                               rockchip,pins = <1 12 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm3 {
+                       pwm3_pin: pwm3-pin {
+                               rockchip,pins = <1 11 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               uart0 {
+                       uart0_xfer: uart0-xfer {
+                               rockchip,pins = <2 26 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 27 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart0_cts: uart0-cts {
+                               rockchip,pins = <2 29 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart0_rts: uart0-rts {
+                               rockchip,pins = <0 17 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart1 {
+                       uart1_xfer: uart1-xfer {
+                               rockchip,pins = <1 9 RK_FUNC_1 &pcfg_pull_none>,
+                                               <1 10 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart1_cts: uart1-cts {
+                               rockchip,pins = <1 8 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart1_rts: uart1-rts {
+                               rockchip,pins = <1 11 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart2 {
+                       uart2_xfer: uart2-xfer {
+                               rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>,
+                                               <1 19 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       uart2_cts: uart2-cts {
+                               rockchip,pins = <0 25 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart2_rts: uart2-rts {
+                               rockchip,pins = <0 24 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+       };
+};
index 43949a6..452ca24 100644 (file)
 
 / {
        compatible = "rockchip,rk3288-evb-act8846", "rockchip,rk3288";
-};
 
-&cpu0 {
-       cpu0-supply = <&vdd_cpu>;
+       vcc_lcd: vcc-lcd {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio7 3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&lcd_en>;
+               regulator-name = "vcc_lcd";
+               vin-supply = <&vcc_io>;
+       };
+
+       vcc_wl: vcc-wl {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio7 9 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_pwr>;
+               regulator-name = "vcc_wl";
+               vin-supply = <&vcc_18>;
+       };
 };
 
 &i2c0 {
 
                        vdd_log: REG3 {
                                regulator-name = "VDD_LOG";
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <1000000>;
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1500000>;
                                regulator-always-on;
                        };
 
 
                        vccio_sd: REG5 {
                                regulator-name = "VCCIO_SD";
-                               regulator-min-microvolt = <3300000>;
+                               regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-always-on;
                        };
                                regulator-always-on;
                        };
 
-                       vcca_tp: REG8 {
+                       vcc_tp: REG8 {
                                regulator-name = "VCCA_TP";
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
                };
        };
 };
+
+&pinctrl {
+       lcd {
+               lcd_en: lcd-en  {
+                       rockchip,pins = <7 3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       wifi {
+               wifi_pwr: wifi-pwr {
+                       rockchip,pins = <7 9 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
index 18eb6cb..736b08b 100644 (file)
 
 / {
        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 {
-       cpu0-supply = <&vdd_cpu>;
 };
 
 &i2c0 {
                };
        };
 };
-
-&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";
-};
index f6d2e78..4faabdb 100644 (file)
                pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>;
        };
 
+       ext_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "ext_gmac";
+               #clock-cells = <0>;
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
                #address-cells = <1>;
        };
 };
 
+&cpu0 {
+       cpu0-supply = <&vdd_cpu>;
+};
+
 &emmc {
        broken-cd;
        bus-width = <8>;
        status = "okay";
 };
 
-&hdmi {
-       ddc-i2c-bus = <&i2c5>;
-       status = "okay";
-};
-
 &sdmmc {
        bus-width = <4>;
        cap-mmc-highspeed;
        vqmmc-supply = <&vccio_sd>;
 };
 
+&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";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c5>;
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
 };
index 14b9fc7..17f13c7 100644 (file)
                };
        };
 
+       ir: ir-receiver {
+               compatible = "gpio-ir-receiver";
+               gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&ir_int>;
+       };
+
        vcc_host: vcc-host-regulator {
                compatible = "regulator-fixed";
                enable-active-high;
                };
        };
 
+       ir {
+               ir_int: ir-int {
+                       rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
        pmic {
                pmic_int: pmic-int {
                        rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
index 1813b7c..1ece66f 100644 (file)
        act8846: act8846@5a {
                compatible = "active-semi,act8846";
                reg = <0x5a>;
+               system-power-controller;
                inl1-supply = <&vcc_io>;
                inl2-supply = <&vcc_sys>;
                inl3-supply = <&vcc_20>;
index 8af35c8..c5453a0 100644 (file)
                stdout-path = "serial2:115200n8";
        };
 
+       ir: ir-receiver {
+               compatible = "gpio-ir-receiver";
+               gpios = <&gpio8 1 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&ir_int>;
+       };
+
        sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "SPDIF";
 };
 
 &pinctrl {
+       ir {
+               ir_int: ir-int {
+                       rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
        pmic {
                pmic_int: pmic-int {
                        rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_up>;
index 3404066..651b962 100644 (file)
@@ -52,7 +52,7 @@ reserve_thermal: reserve_thermal {
 };
 
 cpu_thermal: cpu_thermal {
-       polling-delay-passive = <1000>; /* milliseconds */
+       polling-delay-passive = <100>; /* milliseconds */
        polling-delay = <5000>; /* milliseconds */
 
        thermal-sensors = <&tsadc 1>;
@@ -63,6 +63,11 @@ cpu_thermal: cpu_thermal {
                        hysteresis = <2000>; /* millicelsius */
                        type = "passive";
                };
+               cpu_alert1: cpu_alert1 {
+                       temperature = <75000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
                cpu_crit: cpu_crit {
                        temperature = <90000>; /* millicelsius */
                        hysteresis = <2000>; /* millicelsius */
@@ -73,6 +78,11 @@ cpu_thermal: cpu_thermal {
        cooling-maps {
                map0 {
                        trip = <&cpu_alert0>;
+                       cooling-device =
+                               <&cpu0 THERMAL_NO_LIMIT 6>;
+               };
+               map1 {
+                       trip = <&cpu_alert1>;
                        cooling-device =
                                <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
                };
@@ -80,7 +90,7 @@ cpu_thermal: cpu_thermal {
 };
 
 gpu_thermal: gpu_thermal {
-       polling-delay-passive = <1000>; /* milliseconds */
+       polling-delay-passive = <100>; /* milliseconds */
        polling-delay = <5000>; /* milliseconds */
 
        thermal-sensors = <&tsadc 2>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-brain.dts b/arch/arm/boot/dts/rk3288-veyron-brain.dts
new file mode 100644 (file)
index 0000000..cf5311d
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Google Veyron Brain Rev 0 board device tree source
+ *
+ * Copyright 2014 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-veyron.dtsi"
+
+/ {
+       model = "Google Brain";
+       compatible = "google,veyron-brain-rev0", "google,veyron-brain",
+                    "google,veyron", "rockchip,rk3288";
+
+       vcc33_sys: vcc33-sys {
+               vin-supply = <&vcc_5v>;
+       };
+
+       vcc33_io: vcc33_io {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc33_io";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc33_sys>;
+               /* This is gated by vcc_18 too */
+       };
+
+       /* This turns on vbus for host2 and otg (dwc2) */
+       vcc5_host2: vcc5-host2-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb2_pwr_en>;
+               regulator-name = "vcc5_host2";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&pinctrl {
+       hdmi {
+               vcc50_hdmi_en: vcc50-hdmi-en {
+                       rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               dvs_1: dvs-1 {
+                       rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               dvs_2: dvs-2 {
+                       rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       usb-host {
+               usb2_pwr_en: usb2-pwr-en {
+                       rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&rk808 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+       dvs-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>,
+                   <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+       /delete-property/ vcc6-supply;
+
+       regulators {
+               /* vcc33_io is sourced directly from vcc33_sys */
+               /delete-node/ LDO_REG1;
+
+               /* This is not a pwren anymore, but the real power supply */
+               vdd10_lcd: LDO_REG7 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-name = "vdd10_lcd";
+                       regulator-suspend-mem-disabled;
+               };
+
+               vcc18_hdmi: SWITCH_REG2 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-name = "vcc18_hdmi";
+                       regulator-suspend-mem-disabled;
+               };
+       };
+};
+
+&vcc50_hdmi {
+       enable-active-high;
+       gpio = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&vcc50_hdmi_en>;
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-mickey.dts b/arch/arm/boot/dts/rk3288-veyron-mickey.dts
new file mode 100644 (file)
index 0000000..f36f6f4
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Google Veyron Mickey Rev 0 board device tree source
+ *
+ * Copyright 2015 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-veyron.dtsi"
+
+/ {
+       model = "Google Mickey";
+       compatible = "google,veyron-mickey-rev8", "google,veyron-mickey-rev7",
+                    "google,veyron-mickey-rev6", "google,veyron-mickey-rev5",
+                    "google,veyron-mickey-rev4", "google,veyron-mickey-rev3",
+                    "google,veyron-mickey-rev2", "google,veyron-mickey-rev1",
+                    "google,veyron-mickey-rev0", "google,veyron-mickey",
+                    "google,veyron", "rockchip,rk3288";
+
+       vcc_5v: vcc-5v {
+               vin-supply = <&vcc33_sys>;
+       };
+
+       vcc33_io: vcc33_io {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc33_io";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc33_sys>;
+       };
+};
+
+&cpu_thermal {
+       /delete-node/ trips;
+       /delete-node/ cooling-maps;
+
+       trips {
+               cpu_alert_almost_warm: cpu_alert_almost_warm {
+                       temperature = <63000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_alert_warm: cpu_alert_warm {
+                       temperature = <65000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_alert_almost_hot: cpu_alert_almost_hot {
+                       temperature = <80000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_alert_hot: cpu_alert_hot {
+                       temperature = <82000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_alert_hotter: cpu_alert_hotter {
+                       temperature = <84000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_alert_very_hot: cpu_alert_very_hot {
+                       temperature = <85000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_crit: cpu_crit {
+                       temperature = <90000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "critical";
+               };
+       };
+
+       cooling-maps {
+               /*
+                * After 1st level, throttle the CPU down to as low as 1.4 GHz
+                * and don't let the GPU go faster than 400 MHz.  Note that we
+                * won't throttle the GPU lower than 400 MHz due to CPU
+                * heat--we'll let the GPU do the rest itself.
+                */
+               cpu_warm_limit_cpu {
+                       trip = <&cpu_alert_warm>;
+                       cooling-device =
+                               <&cpu0 THERMAL_NO_LIMIT 4>;
+               };
+
+               /*
+                * Add some discrete steps to help throttling system deal
+                * with the fact that there are two passive cooling devices:
+                * the CPU and the GPU.
+                *
+                * - 1.2 GHz - 1.0 GHz (almost hot)
+                * - 800 MHz           (hot)
+                * - 800 MHz - 696 MHz (hotter)
+                * - 696 MHz - min     (very hot)
+                *
+                * Note:
+                * - 800 MHz appears to be a "sweet spot" for me.  I can run
+                *   some pretty serious workload here and be happy.
+                * - After 696 MHz we stop lowering voltage, so throttling
+                *   past there is less effective.
+                */
+               cpu_almost_hot_limit_cpu {
+                       trip = <&cpu_alert_almost_hot>;
+                       cooling-device =
+                               <&cpu0 5 6>;
+               };
+               cpu_hot_limit_cpu {
+                       trip = <&cpu_alert_hot>;
+                       cooling-device =
+                               <&cpu0 7 7>;
+               };
+               cpu_hotter_limit_cpu {
+                       trip = <&cpu_alert_hotter>;
+                       cooling-device =
+                               <&cpu0 7 8>;
+               };
+               cpu_very_hot_limit_cpu {
+                       trip = <&cpu_alert_very_hot>;
+                       cooling-device =
+                               <&cpu0 8 THERMAL_NO_LIMIT>;
+               };
+       };
+};
+
+&emmc {
+       /delete-property/mmc-hs200-1_8v;
+};
+
+&i2c2 {
+       status = "disabled";
+};
+
+&i2c4 {
+       status = "disabled";
+};
+
+&i2s {
+       status = "okay";
+       clock-names = "i2s_hclk", "i2s_clk", "i2s_clk_out";
+       clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>, <&cru SCLK_I2S0_OUT>;
+};
+
+&rk808 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+       dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+                   <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+       /delete-property/ vcc6-supply;
+       /delete-property/ vcc12-supply;
+
+       vcc11-supply = <&vcc33_sys>;
+
+       regulators {
+               /* vcc33_io is sourced directly from vcc33_sys */
+               /delete-node/ LDO_REG1;
+               /delete-node/ LDO_REG7;
+
+               /* This is not a pwren anymore, but the real power supply */
+               vdd10_lcd: LDO_REG7 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-name = "vdd10_lcd";
+                       regulator-suspend-mem-disabled;
+               };
+
+               vcc18_lcd: LDO_REG8 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-name = "vcc18_lcd";
+                       regulator-suspend-mem-disabled;
+               };
+       };
+};
+
+&pinctrl {
+       hdmi {
+               power_hdmi_on: power-hdmi-on {
+                       rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               dvs_1: dvs-1 {
+                       rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               dvs_2: dvs-2 {
+                       rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+};
+
+&usb_host0_ehci {
+       status = "disabled";
+};
+
+&usb_host1 {
+       status = "disabled";
+};
+
+&vcc50_hdmi {
+       enable-active-high;
+       gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&power_hdmi_on>;
+};
index 85f0373..699beb0 100644 (file)
        clock-frequency = <400000>;
        i2c-scl-falling-time-ns = <50>;
        i2c-scl-rising-time-ns = <300>;
+
+       touchscreen@10 {
+               compatible = "elan,ekth3500";
+               reg = <0x10>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&touch_int &touch_rst>;
+               reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+               vcc33-supply = <&vcc33_touch>;
+               vccio-supply = <&vcc33_touch>;
+       };
 };
 
 &rk808 {
index a7ea7d0..b34a7b5 100644 (file)
        };
 };
 
+&cpu_alert0 {
+       temperature = <65000>;
+};
+
+&cpu_alert1 {
+       temperature = <70000>;
+};
+
 &rk808 {
        pinctrl-names = "default";
        pinctrl-0 = <&pmic_int_l>;
index 5e61f07..9fce91f 100644 (file)
        i2c-scl-rising-time-ns = <1000>;
 };
 
+&power {
+       assigned-clocks = <&cru SCLK_EDP_24M>;
+       assigned-clock-parents = <&xin24m>;
+};
+
 &pwm1 {
        status = "okay";
 };
index 04ea209..8ac49f3 100644 (file)
@@ -53,6 +53,7 @@
        interrupt-parent = <&gic>;
 
        aliases {
+               ethernet0 = &gmac;
                i2c0 = &i2c0;
                i2c1 = &i2c1;
                i2c2 = &i2c2;
                clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2s0_bus>;
+               rockchip,playback-channels = <8>;
+               rockchip,capture-channels = <2>;
                status = "disabled";
        };
 
+       crypto: cypto-controller@ff8a0000 {
+               compatible = "rockchip,rk3288-crypto";
+               reg = <0xff8a0000 0x4000>;
+               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>,
+                        <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>;
+               clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+               resets = <&cru SRST_CRYPTO>;
+               reset-names = "crypto-rst";
+               status = "okay";
+       };
+
        vopb: vop@ff930000 {
                compatible = "rockchip,rk3288-vop";
                reg = <0xff930000 0x19c>;
                interrupts = <GIC_PPI 9 0xf04>;
        };
 
+       efuse: efuse@ffb40000 {
+               compatible = "rockchip,rockchip-efuse";
+               reg = <0xffb40000 0x20>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               clocks = <&cru PCLK_EFUSE256>;
+               clock-names = "pclk_efuse";
+
+               cpu_leakage: cpu_leakage@17 {
+                       reg = <0x17 0x1>;
+               };
+       };
+
        usbphy: phy {
                compatible = "rockchip,rk3288-usb-phy";
                rockchip,grf = <&grf>;
                                rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up>;
                        };
 
-                       sdmmc_cd: sdmcc-cd {
+                       sdmmc_cd: sdmmc-cd {
                                rockchip,pins = <6 22 RK_FUNC_1 &pcfg_pull_up>;
                        };
 
index 4497d28..99eeea7 100644 (file)
@@ -49,6 +49,7 @@
        interrupt-parent = <&gic>;
 
        aliases {
+               ethernet0 = &emac;
                i2c0 = &i2c0;
                i2c1 = &i2c1;
                i2c2 = &i2c2;
index 4dfca8f..3f750f6 100644 (file)
                                                atmel,clk-output-range = <0 83000000>;
                                        };
 
+                                       pdmic_clk: pdmic_clk {
+                                               #clock-cells = <0>;
+                                               reg = <48>;
+                                               atmel,clk-output-range = <0 83000000>;
+                                       };
+
                                        i2s0_clk: i2s0_clk {
                                                #clock-cells = <0>;
                                                reg = <54>;
                                                atmel,clk-output-range = <0 83000000>;
                                        };
 
+                                       pdmic_gclk: pdmic_gclk {
+                                               #clock-cells = <0>;
+                                               reg = <48>;
+                                       };
+
                                        i2s0_gclk: i2s0_gclk {
                                                #clock-cells = <0>;
                                                reg = <54>;
                                clock-names = "t0_clk", "slow_clk";
                        };
 
+                       pdmic: pdmic@f8018000 {
+                               compatible = "atmel,sama5d2-pdmic";
+                               reg = <0xf8018000 0x124>;
+                               interrupts = <48 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+                                       | AT91_XDMAC_DT_PERID(50))>;
+                               dma-names = "rx";
+                               clocks = <&pdmic_clk>, <&pdmic_gclk>;
+                               clock-names = "pclk", "gclk";
+                               status = "disabled";
+                       };
+
                        uart0: serial@f801c000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xf801c000 0x100>;
                                clocks = <&h32ck>;
                        };
 
+                       watchdog@f8048040 {
+                               compatible = "atmel,sama5d4-wdt";
+                               reg = <0xf8048040 0x10>;
+                               interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
+                               status = "disabled";
+                       };
+
                        sckc@f8048050 {
                                compatible = "atmel,at91sam9x5-sckc";
                                reg = <0xf8048050 0x4>;
index 2193637..b8032bc 100644 (file)
                                        interrupt-parent = <&pmc>;
                                        interrupts = <AT91_PMC_MCKRDY>;
                                        clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
-                                       atmel,clk-output-range = <125000000 177000000>;
+                                       atmel,clk-output-range = <125000000 200000000>;
                                        atmel,clk-divisors = <1 2 4 3>;
                                };
 
                        };
 
                        i2c0: i2c@f8014000 {
-                               compatible = "atmel,at91sam9x5-i2c";
+                               compatible = "atmel,sama5d4-i2c";
                                reg = <0xf8014000 0x4000>;
                                interrupts = <32 IRQ_TYPE_LEVEL_HIGH 6>;
                                dmas = <&dma1
                        };
 
                        i2c1: i2c@f8018000 {
-                               compatible = "atmel,at91sam9x5-i2c";
+                               compatible = "atmel,sama5d4-i2c";
                                reg = <0xf8018000 0x4000>;
                                interrupts = <33 IRQ_TYPE_LEVEL_HIGH 6>;
                                dmas = <&dma1
                        };
 
                        i2c2: i2c@f8024000 {
-                               compatible = "atmel,at91sam9x5-i2c";
+                               compatible = "atmel,sama5d4-i2c";
                                reg = <0xf8024000 0x4000>;
                                interrupts = <34 IRQ_TYPE_LEVEL_HIGH 6>;
                                dmas = <&dma1
                                        pinctrl_mmc0_clk_cmd_dat0: mmc0_clk_cmd_dat0 {
                                                atmel,pins =
                                                        <AT91_PIOC 4 AT91_PERIPH_B AT91_PINCTRL_NONE    /* MCI0_CK, conflict with PCK1(ISI_MCK) */
-                                                        AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_CDB, conflict with NAND_D0 */
-                                                        AT91_PIOC 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB0, conflict with NAND_D1 */
+                                                        AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_CDA, conflict with NAND_D0 */
+                                                        AT91_PIOC 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA0, conflict with NAND_D1 */
                                                        >;
                                        };
                                        pinctrl_mmc0_dat1_3: mmc0_dat1_3 {
                                                atmel,pins =
-                                                       <AT91_PIOC 7 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB1, conflict with NAND_D2 */
-                                                        AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB2, conflict with NAND_D3 */
-                                                        AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DB3, conflict with NAND_D4 */
+                                                       <AT91_PIOC 7 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA1, conflict with NAND_D2 */
+                                                        AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA2, conflict with NAND_D3 */
+                                                        AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA3, conflict with NAND_D4 */
+                                                       >;
+                                       };
+                                       pinctrl_mmc0_dat4_7: mmc0_dat4_7 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_PULL_UP        /* MCI0_DA4, conflict with NAND_D5 */
+                                                        AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP        /* MCI0_DA5, conflict with NAND_D6 */
+                                                        AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP        /* MCI0_DA6, conflict with NAND_D7 */
+                                                        AT91_PIOC 13 AT91_PERIPH_B AT91_PINCTRL_PULL_UP        /* MCI0_DA7, conflict with NAND_OE */
                                                        >;
                                        };
                                };
index 7fc5602..aa8bae3 100644 (file)
                        gpios = <&pcf8575 14 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_HOME>;
                        label = "SW1";
-                       gpio-key,wakeup;
+                       wakeup-source;
                };
        };
 
index ff7c8f2..3a6056f 100644 (file)
@@ -28,6 +28,7 @@
                        reg = <0>;
                        clock-frequency = <1196000000>;
                        power-domains = <&pd_a2sl>;
+                       next-level-cache = <&L2>;
                };
                cpu@1 {
                        device_type = "cpu";
@@ -35,6 +36,7 @@
                        reg = <1>;
                        clock-frequency = <1196000000>;
                        power-domains = <&pd_a2sl>;
+                       next-level-cache = <&L2>;
                };
        };
 
                      <0xf0000100 0x100>;
        };
 
+       L2: cache-controller {
+               compatible = "arm,pl310-cache";
+               reg = <0xf0100000 0x1000>;
+               interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&pd_a3sm>;
+               arm,data-latency = <3 3 3>;
+               arm,tag-latency = <2 2 2>;
+               arm,shared-override;
+               cache-unified;
+               cache-level = <2>;
+       };
+
        sbsc2: memory-controller@fb400000 {
                compatible = "renesas,sbsc-sh73a0";
                reg = <0xfb400000 0x400>;
                status = "disabled";
        };
 
+       msiof0: spi@e6e20000 {
+               compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+               reg = <0xe6e20000 0x0064>;
+               interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp0_clks SH73A0_CLK_MSIOF0>;
+               power-domains = <&pd_a3sp>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       msiof1: spi@e6e10000 {
+               compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+               reg = <0xe6e10000 0x0064>;
+               interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_MSIOF1>;
+               power-domains = <&pd_a3sp>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       msiof2: spi@e6e00000 {
+               compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+               reg = <0xe6e00000 0x0064>;
+               interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_MSIOF2>;
+               power-domains = <&pd_a3sp>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       msiof3: spi@e6c90000 {
+               compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+               reg = <0xe6c90000 0x0064>;
+               interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_MSIOF3>;
+               power-domains = <&pd_a3sp>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
        sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee100000 0x100>;
                mstp0_clks: mstp0_clks@e6150130 {
                        compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0xe6150130 4>, <0xe6150030 4>;
-                       clocks = <&cpg_clocks SH73A0_CLK_HP>;
+                       clocks = <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>;
                        #clock-cells = <1>;
                        clock-indices = <
-                               SH73A0_CLK_IIC2
+                               SH73A0_CLK_IIC2 SH73A0_CLK_MSIOF0
                        >;
                        clock-output-names =
-                               "iic2";
+                               "iic2", "msiof0";
                };
                mstp1_clks: mstp1_clks@e6150134 {
                        compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0xe6150138 4>, <0xe6150040 4>;
                        clocks = <&sub_clk>, <&cpg_clocks SH73A0_CLK_HP>,
                                 <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
-                                <&sub_clk>, <&sub_clk>, <&sub_clk>, <&sub_clk>,
-                                <&sub_clk>, <&sub_clk>;
+                                <&sub_clk>, <&sub_clk>, <&sub_clk>,
+                                <&sub_clk>, <&sub_clk>, <&sub_clk>,
+                                <&sub_clk>, <&sub_clk>, <&sub_clk>;
                        #clock-cells = <1>;
                        clock-indices = <
                                SH73A0_CLK_SCIFA7 SH73A0_CLK_SY_DMAC
-                               SH73A0_CLK_MP_DMAC SH73A0_CLK_SCIFA5
-                               SH73A0_CLK_SCIFB SH73A0_CLK_SCIFA0
-                               SH73A0_CLK_SCIFA1 SH73A0_CLK_SCIFA2
-                               SH73A0_CLK_SCIFA3 SH73A0_CLK_SCIFA4
+                               SH73A0_CLK_MP_DMAC SH73A0_CLK_MSIOF3
+                               SH73A0_CLK_MSIOF1 SH73A0_CLK_SCIFA5
+                               SH73A0_CLK_SCIFB SH73A0_CLK_MSIOF2
+                               SH73A0_CLK_SCIFA0 SH73A0_CLK_SCIFA1
+                               SH73A0_CLK_SCIFA2 SH73A0_CLK_SCIFA3
+                               SH73A0_CLK_SCIFA4
                        >;
                        clock-output-names =
-                               "scifa7", "sy_dmac", "mp_dmac", "scifa5",
-                               "scifb", "scifa0", "scifa1", "scifa2",
-                               "scifa3", "scifa4";
+                               "scifa7", "sy_dmac", "mp_dmac", "msiof3",
+                               "msiof1", "scifa5", "scifb", "msiof2",
+                               "scifa0", "scifa1", "scifa2", "scifa3",
+                               "scifa4";
                };
                mstp3_clks: mstp3_clks@e615013c {
                        compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
index 39c470e..3ed4abd 100644 (file)
                        #size-cells = <0>;
                        clocks = <&l4_mp_clk>, <&sdmmc_clk_divided>;
                        clock-names = "biu", "ciu";
+                       status = "disabled";
                };
 
                ocram: sram@ffff0000 {
index a75a666..3c88678 100644 (file)
@@ -79,6 +79,7 @@
 &mmc0 {
        vmmc-supply = <&regulator_3_3v>;
        vqmmc-supply = <&regulator_3_3v>;
+       status = "okay";
 };
 
 &usb1 {
index 555e9ca..afea364 100644 (file)
 &mmc0 {
        vmmc-supply = <&regulator_3_3v>;
        vqmmc-supply = <&regulator_3_3v>;
+       status = "okay";
 };
 
 &uart0 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
new file mode 100644 (file)
index 0000000..f86f9c0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5.dtsi"
+
+/ {
+       model = "DENX MCV";
+       compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+       memory {
+               name = "memory";
+               device_type = "memory";
+               reg = <0x0 0x40000000>; /* 1 GiB */
+       };
+};
+
+&mmc0 {        /* On-SoM eMMC */
+       bus-width = <8>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
new file mode 100644 (file)
index 0000000..7186a29
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5_mcv.dtsi"
+
+/ {
+       model = "DENX MCV EVK";
+       compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+       aliases {
+               ethernet0 = &gmac0;
+               stmpe-i2c0 = &stmpe1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&can0 {
+       status = "okay";
+};
+
+&can1 {
+       status = "okay";
+};
+
+&gmac0 {
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&gpio0 {       /* GPIO  0 ... 28 */
+       status = "okay";
+};
+
+&gpio1 {       /* GPIO 29 ... 57 */
+       status = "okay";
+};
+
+&gpio2 {       /* GPIO 58..66 (HLGPI 0..13 at offset 13) */
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+       speed-mode = <0>;
+
+       stmpe1: stmpe811@41 {
+               compatible = "st,stmpe811";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x41>;
+               id = <0>;
+               blocks = <0x5>;
+               irq-gpio = <&portb 28 0x4>;     /* GPIO 57, trig. level HI */
+
+               stmpe_touchscreen {
+                       compatible = "st,stmpe-ts";
+                       reg = <0>;
+                       ts,sample-time = <4>;
+                       ts,mod-12b = <1>;
+                       ts,ref-sel = <0>;
+                       ts,adc-freq = <1>;
+                       ts,ave-ctrl = <1>;
+                       ts,touch-det-delay = <3>;
+                       ts,settling = <4>;
+                       ts,fraction-z = <7>;
+                       ts,i-drive = <1>;
+               };
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
index d4d0a28..15e43f4 100644 (file)
@@ -84,6 +84,7 @@
        cd-gpios = <&portb 18 0>;
        vmmc-supply = <&regulator_3_3v>;
        vqmmc-supply = <&regulator_3_3v>;
+       status = "okay";
 };
 
 &usb1 {
index 48bf651..b61f22f 100644 (file)
@@ -80,6 +80,7 @@
 &mmc0 {
        vmmc-supply = <&regulator_3_3v>;
        vqmmc-supply = <&regulator_3_3v>;
+       status = "okay";
 };
 
 &usb1 {
index 50f5e9d..341f5b7 100644 (file)
 
                                // DB8500_REGULATOR_VAPE
                                db8500_vape_reg: db8500_vape {
-                                       regulator-compatible = "db8500_vape";
                                        regulator-always-on;
                                };
 
                                // DB8500_REGULATOR_VARM
                                db8500_varm_reg: db8500_varm {
-                                       regulator-compatible = "db8500_varm";
                                };
 
                                // DB8500_REGULATOR_VMODEM
                                db8500_vmodem_reg: db8500_vmodem {
-                                       regulator-compatible = "db8500_vmodem";
                                };
 
                                // DB8500_REGULATOR_VPLL
                                db8500_vpll_reg: db8500_vpll {
-                                       regulator-compatible = "db8500_vpll";
                                };
 
                                // DB8500_REGULATOR_VSMPS1
                                db8500_vsmps1_reg: db8500_vsmps1 {
-                                       regulator-compatible = "db8500_vsmps1";
                                };
 
                                // DB8500_REGULATOR_VSMPS2
                                db8500_vsmps2_reg: db8500_vsmps2 {
-                                       regulator-compatible = "db8500_vsmps2";
                                };
 
                                // DB8500_REGULATOR_VSMPS3
                                db8500_vsmps3_reg: db8500_vsmps3 {
-                                       regulator-compatible = "db8500_vsmps3";
                                };
 
                                // DB8500_REGULATOR_VRF1
                                db8500_vrf1_reg: db8500_vrf1 {
-                                       regulator-compatible = "db8500_vrf1";
                                };
 
                                // DB8500_REGULATOR_SWITCH_SVAMMDSP
                                db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
-                                       regulator-compatible = "db8500_sva_mmdsp";
                                };
 
                                // DB8500_REGULATOR_SWITCH_SVAMMDSPRET
                                db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
-                                       regulator-compatible = "db8500_sva_mmdsp_ret";
                                };
 
                                // DB8500_REGULATOR_SWITCH_SVAPIPE
                                db8500_sva_pipe_reg: db8500_sva_pipe {
-                                       regulator-compatible = "db8500_sva_pipe";
                                };
 
                                // DB8500_REGULATOR_SWITCH_SIAMMDSP
                                db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
-                                       regulator-compatible = "db8500_sia_mmdsp";
                                };
 
                                // DB8500_REGULATOR_SWITCH_SIAMMDSPRET
 
                                // DB8500_REGULATOR_SWITCH_SIAPIPE
                                db8500_sia_pipe_reg: db8500_sia_pipe {
-                                       regulator-compatible = "db8500_sia_pipe";
                                };
 
                                // DB8500_REGULATOR_SWITCH_SGA
                                db8500_sga_reg: db8500_sga {
-                                       regulator-compatible = "db8500_sga";
                                        vin-supply = <&db8500_vape_reg>;
                                };
 
                                // DB8500_REGULATOR_SWITCH_B2R2_MCDE
                                db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
-                                       regulator-compatible = "db8500_b2r2_mcde";
                                        vin-supply = <&db8500_vape_reg>;
                                };
 
                                // DB8500_REGULATOR_SWITCH_ESRAM12
                                db8500_esram12_reg: db8500_esram12 {
-                                       regulator-compatible = "db8500_esram12";
                                };
 
                                // DB8500_REGULATOR_SWITCH_ESRAM12RET
                                db8500_esram12_ret_reg: db8500_esram12_ret {
-                                       regulator-compatible = "db8500_esram12_ret";
                                };
 
                                // DB8500_REGULATOR_SWITCH_ESRAM34
                                db8500_esram34_reg: db8500_esram34 {
-                                       regulator-compatible = "db8500_esram34";
                                };
 
                                // DB8500_REGULATOR_SWITCH_ESRAM34RET
                                db8500_esram34_ret_reg: db8500_esram34_ret {
-                                       regulator-compatible = "db8500_esram34_ret";
                                };
                        };
 
                                        compatible = "stericsson,ab8500-ext-regulator";
 
                                        ab8500_ext1_reg: ab8500_ext1 {
-                                               regulator-compatible = "ab8500_ext1";
                                                regulator-min-microvolt = <1800000>;
                                                regulator-max-microvolt = <1800000>;
                                                regulator-boot-on;
                                        };
 
                                        ab8500_ext2_reg: ab8500_ext2 {
-                                               regulator-compatible = "ab8500_ext2";
                                                regulator-min-microvolt = <1360000>;
                                                regulator-max-microvolt = <1360000>;
                                                regulator-boot-on;
                                        };
 
                                        ab8500_ext3_reg: ab8500_ext3 {
-                                               regulator-compatible = "ab8500_ext3";
                                                regulator-min-microvolt = <3400000>;
                                                regulator-max-microvolt = <3400000>;
                                                regulator-boot-on;
 
                                        // supplies to the display/camera
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
-                                               regulator-compatible = "ab8500_ldo_aux1";
                                                regulator-min-microvolt = <2500000>;
                                                regulator-max-microvolt = <2900000>;
                                                regulator-boot-on;
 
                                        // supplies to the on-board eMMC
                                        ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
-                                               regulator-compatible = "ab8500_ldo_aux2";
                                                regulator-min-microvolt = <1100000>;
                                                regulator-max-microvolt = <3300000>;
                                        };
 
                                        // supply for VAUX3; SDcard slots
                                        ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
-                                               regulator-compatible = "ab8500_ldo_aux3";
                                                regulator-min-microvolt = <1100000>;
                                                regulator-max-microvolt = <3300000>;
                                        };
 
                                        // supply for v-intcore12; VINTCORE12 LDO
                                        ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
-                                               regulator-compatible = "ab8500_ldo_intcore";
                                        };
 
                                        // supply for tvout; gpadc; TVOUT LDO
                                        ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
-                                               regulator-compatible = "ab8500_ldo_tvout";
                                        };
 
                                        // supply for ab8500-usb; USB LDO
                                        ab8500_ldo_usb_reg: ab8500_ldo_usb {
-                                               regulator-compatible = "ab8500_ldo_usb";
                                        };
 
                                        // supply for ab8500-vaudio; VAUDIO LDO
                                        ab8500_ldo_audio_reg: ab8500_ldo_audio {
-                                               regulator-compatible = "ab8500_ldo_audio";
                                        };
 
                                        // supply for v-anamic1 VAMIC1 LDO
                                        ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
-                                               regulator-compatible = "ab8500_ldo_anamic1";
                                        };
 
                                        // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
                                        ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
-                                               regulator-compatible = "ab8500_ldo_anamic2";
                                        };
 
                                        // supply for v-dmic; VDMIC LDO
                                        ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
-                                               regulator-compatible = "ab8500_ldo_dmic";
                                        };
 
                                        // supply for U8500 CSI/DSI; VANA LDO
                                        ab8500_ldo_ana_reg: ab8500_ldo_ana {
-                                               regulator-compatible = "ab8500_ldo_ana";
                                        };
                                };
                        };
index 78b7525..c3987ad 100644 (file)
                                rohm,touch-max-x = <384>;
                                rohm,touch-max-y = <704>;
                                rohm,flip-y;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&touch_rohm_mode>;
                        };
 
                        bu21013_tp@5d {
                                rohm,touch-max-x = <384>;
                                rohm,touch-max-y = <704>;
                                rohm,flip-y;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&touch_rohm_mode>;
                        };
                };
 
                                        };
                                };
                        };
+                       touch {
+                               touch_rohm_mode: touch_rohm {
+                                       /*
+                                        * ROHM touch screen uses GPIO 143 for
+                                        * RST1, GPIO 146 for RST2 and
+                                        * GPIO 67 for interrupts. Pull-up
+                                        * the IRQ line and drive both
+                                        * reset signals low.
+                                        */
+                                       stuib_cfg1 {
+                                               pins = "GPIO143_D12", "GPIO146_D13";
+                                               ste,config = <&gpio_out_lo>;
+                                       };
+                                       stuib_cfg2 {
+                                               pins = "GPIO67_G2";
+                                               ste,config = <&gpio_in_pu>;
+                                       };
+                               };
+                       };
                };
        };
 };
index 0e1c969..b7b4211 100644 (file)
@@ -66,7 +66,7 @@
                                        keypad,num-columns = <8>;
                                        keypad,num-rows = <8>;
                                        linux,no-autorepeat;
-                                       linux,wakeup;
+                                       wakeup-source;
                                        linux,keymap = <0x0301006b
                                                        0x04010066
                                                        0x06040072
                                             <19 IRQ_TYPE_EDGE_RISING>;
                        };
                        lsm303dlh@1e {
-                               /* Magnetometer */
+                               /*
+                                * This magnetometer is packaged with
+                                * the accelerometer, and has a DRDY line,
+                                * however it is not connected on this
+                                * board so it can not generate interrupts.
+                                */
                                compatible = "st,lsm303dlh-magn";
                                reg = <0x1e>;
                                vdd-supply = <&ab8500_ldo_aux1_reg>;
                                vddio-supply = <&db8500_vsmps2_reg>;
+                       };
+                       lis331dl@1c {
+                               /* Accelerometer */
+                               compatible = "st,lis331dl-accel";
+                               st,drdy-int-pin = <1>;
+                               reg = <0x1c>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&accel_tvk_mode>;
+                               interrupt-parent = <&gpio2>;
+                               interrupts = <18 IRQ_TYPE_EDGE_RISING>,
+                                            <19 IRQ_TYPE_EDGE_RISING>;
+                       };
+                       ak8974@0f {
+                               /* Magnetometer */
+                               compatible = "asahi-kasei,ak8974";
+                               reg = <0x0f>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
                                pinctrl-names = "default";
-                               pinctrl-0 = <&magneto_tvk_mode>;
+                               pinctrl-0 = <&gyro_magn_tvk_mode>;
+                               interrupt-parent = <&gpio1>;
+                               interrupts = <0 IRQ_TYPE_EDGE_RISING>;
                        };
                        l3g4200d@68 {
                                /* Gyroscope */
                                reg = <0x68>;
                                vdd-supply = <&ab8500_ldo_aux1_reg>;
                                vddio-supply = <&db8500_vsmps2_reg>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&gyro_magn_tvk_mode>;
+                               interrupt-parent = <&gpio1>;
+                               interrupts = <0 IRQ_TYPE_EDGE_RISING>;
                        };
                        lsp001wm@5c {
                                /* Barometer/pressure sensor */
                                        /* Accelerometer interrupt lines 1 & 2 */
                                        tvk_cfg {
                                                pins = "GPIO82_C1", "GPIO83_D3";
-                                               ste,config = <&gpio_in_pu>;
+                                               ste,config = <&gpio_in_pd>;
                                        };
                                };
                        };
-                       magnetometer {
-                               magneto_tvk_mode: magneto_tvk {
-                                       /* Magnetometer uses GPIO 31 and 32, pull these up/down respectively */
+                       gyroscope {
+                               /*
+                                * These lines are shared between Gyroscope l3g400dh
+                                * and AK8974 magnetometer.
+                                */
+                               gyro_magn_tvk_mode: gyro_magn_tvk {
+                                        /* GPIO 31 used for INT pull down the line */
                                        tvk_cfg1 {
                                                pins = "GPIO31_V3";
-                                               ste,config = <&gpio_in_pu>;
+                                               ste,config = <&gpio_in_pd>;
                                        };
+                                       /* GPIO 32 used for DRDY, pull this down */
                                        tvk_cfg2 {
                                                pins = "GPIO32_V2";
                                                ste,config = <&gpio_in_pd>;
index 9c2387b..149a72e 100644 (file)
@@ -43,7 +43,6 @@
                                  <&vaudio_hf_hrefv60_mode>,
                                  <&gbf_hrefv60_mode>,
                                  <&hdtv_hrefv60_mode>,
-                                 <&touch_hrefv60_mode>,
                                  <&gpios_hrefv60_mode>;
 
                        sdi0 {
                                        };
                                 };
                        };
-                       touch {
-                               touch_hrefv60_mode: touch_hrefv60 {
-                                       /*
-                                        * Touch screen uses GPIO 143 for RST1, GPIO 146 for RST2 and
-                                        * GPIO 67 for interrupts. Pull-up the IRQ line and drive both
-                                        * reset signals low.
-                                        */
-                                       hrefv60_cfg1 {
-                                               pins = "GPIO143_D12", "GPIO146_D13";
-                                               ste,config = <&gpio_out_lo>;
-                                       };
-                                       hrefv60_cfg2 {
-                                               pins = "GPIO67_G2";
-                                               ste,config = <&gpio_in_pu>;
-                                       };
-                               };
-                       };
                        mcde {
                                lcd_hrefv60_mode: lcd_hrefv60 {
                                        /*
index 35282c0..7893290 100644 (file)
                        label = "user_button";
                        gpios = <&gpio0 3 0x1>;
                        linux,code = <1>; /* KEY_ESC */
-                       gpio-key,wakeup;
+                       wakeup-source;
                        pinctrl-names = "default";
                        pinctrl-0 = <&user_button_default_mode>;
                };
index e80e421..08f8207 100644 (file)
                                vddio-supply = <&db8500_vsmps2_reg>;
                                pinctrl-names = "default";
                                pinctrl-0 = <&magneto_snowball_mode>;
-                               gpios = <&gpio5 5 0x4>; /* DRDY line */
+                               interrupt-parent = <&gpio5>;
+                               interrupts = <5 IRQ_TYPE_EDGE_RISING>; /* DRDY line */
                        };
                        l3g4200d@68 {
                                /* Gyroscope */
                                vddio-supply = <&db8500_vsmps2_reg>;
                                pinctrl-names = "default";
                                pinctrl-0 = <&gyro_snowball_mode>;
-                               gpios = <&gpio5 6 0x4>; /* DRDY line */
                                interrupt-parent = <&gpio5>;
-                               interrupts = <9 IRQ_TYPE_EDGE_RISING>; /* INT1 */
+                               interrupts = <6 IRQ_TYPE_EDGE_RISING>, /* DRDY line */
+                                            <9 IRQ_TYPE_EDGE_RISING>; /* INT1 */
                        };
                        lsp001wm@5c {
                                /* Barometer/pressure sensor */
index 82a6616..9c73ac2 100644 (file)
                        ab3100-regulators {
                                compatible = "stericsson,ab3100-regulators";
                                ab3100_ldo_a_reg: ab3100_ldo_a {
-                                       regulator-compatible = "ab3100_ldo_a";
                                        startup-delay-us = <200>;
                                        regulator-always-on;
                                        regulator-boot-on;
                                };
                                ab3100_ldo_c_reg: ab3100_ldo_c {
-                                       regulator-compatible = "ab3100_ldo_c";
                                        startup-delay-us = <200>;
                                };
                                ab3100_ldo_d_reg: ab3100_ldo_d {
-                                       regulator-compatible = "ab3100_ldo_d";
                                        startup-delay-us = <200>;
                                };
                                ab3100_ldo_e_reg: ab3100_ldo_e {
-                                       regulator-compatible = "ab3100_ldo_e";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        startup-delay-us = <200>;
                                        regulator-boot-on;
                                };
                                ab3100_ldo_f_reg: ab3100_ldo_f {
-                                       regulator-compatible = "ab3100_ldo_f";
                                        regulator-min-microvolt = <2500000>;
                                        regulator-max-microvolt = <2500000>;
                                        startup-delay-us = <600>;
                                        regulator-boot-on;
                                };
                                ab3100_ldo_g_reg: ab3100_ldo_g {
-                                       regulator-compatible = "ab3100_ldo_g";
                                        regulator-min-microvolt = <1500000>;
                                        regulator-max-microvolt = <2850000>;
                                        startup-delay-us = <400>;
                                };
                                ab3100_ldo_h_reg: ab3100_ldo_h {
-                                       regulator-compatible = "ab3100_ldo_h";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <2750000>;
                                        startup-delay-us = <200>;
                                };
                                ab3100_ldo_k_reg: ab3100_ldo_k {
-                                       regulator-compatible = "ab3100_ldo_k";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <2750000>;
                                        startup-delay-us = <200>;
                                };
                                ab3100_ext_reg: ab3100_ext {
-                                       regulator-compatible = "ab3100_ext";
                                };
                                ab3100_buck_reg: ab3100_buck {
-                                       regulator-compatible = "ab3100_buck";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1800000>;
                                        startup-delay-us = <1000>;
index 3f0aeb8..ac64781 100644 (file)
 /*
  * TODO:
  *   2x cameras via CSI
- *   audio
  *   AXP battery management
  *   NAND
  *   OTG
  *   Touchscreen - gt801_2plus1 @ i2c adapter 2 @ 0x48
  */
+&codec {
+       /* PH15 controls power to external amplifier (ft2012q) */
+       pinctrl-names = "default";
+       pinctrl-0 = <&codec_pa_pin>;
+       allwinner,pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
 
 &ehci0 {
        status = "okay";
        status = "okay";
 
        axp209: pmic@34 {
-               compatible = "x-powers,axp209";
                reg = <0x34>;
                interrupts = <0>;
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
        };
 };
 
+#include "axp209.dtsi"
+
 &i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins_a>;
 };
 
 &lradc {
-       vref-supply = <&reg_vcc3v0>;
+       vref-supply = <&reg_ldo2>;
 
        status = "okay";
 
        status = "okay";
 };
 
+&pio {
+       codec_pa_pin: codec_pa_pin@0 {
+               allwinner,pins = "PH15";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+};
+
+&reg_dcdc2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1400000>;
+       regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+       regulator-always-on;
+       regulator-min-microvolt = <1250000>;
+       regulator-max-microvolt = <1250000>;
+       regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+       regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "avcc";
+};
+
 &reg_usb1_vbus {
        status = "okay";
 };
index 487ce63..e09053b 100644 (file)
@@ -47,6 +47,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "iNet-1";
                serial0 = &uart0;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_en_pin_inet>;
+               pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+               default-brightness-level = <8>;
+               enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
+       };
+
        chosen {
                stdout-path = "serial0:115200n8";
        };
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins_a>;
        status = "okay";
+
+       ft5x: touchscreen@38 {
+               compatible = "edt,edt-ft5406";
+               reg = <0x38>;
+               interrupt-parent = <&pio>;
+               interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&touchscreen_wake_pin>;
+               wake-gpios = <&pio 1 13 GPIO_ACTIVE_HIGH>; /* PB13 */
+               touchscreen-size-x = <600>;
+               touchscreen-size-y = <1024>;
+               touchscreen-swapped-x-y;
+       };
 };
 
 &lradc {
 };
 
 &pio {
+       bl_en_pin_inet: bl_en_pin@0 {
+               allwinner,pins = "PH7";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       touchscreen_wake_pin: touchscreen_wake_pin@0 {
+               allwinner,pins = "PB13";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
        usb0_id_detect_pin: usb0_id_detect_pin@0 {
                allwinner,pins = "PH4";
                allwinner,function = "gpio_in";
        };
 };
 
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins_a>;
+       status = "okay";
+};
+
 &reg_dcdc2 {
        regulator-always-on;
        regulator-min-microvolt = <1000000>;
index 2fffc04..ca49b0d 100644 (file)
        chosen {
                stdout-path = "serial0:115200n8";
        };
+
+       gpio_keys {
+               compatible = "gpio-keys-polled";
+               pinctrl-names = "default";
+               pinctrl-0 = <&key_pins_inet9f>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               poll-interval = <20>;
+
+               button@0 {
+                       label = "Left Joystick Left";
+                       linux,code = <ABS_X>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <0xffffffff>; /* -1 */
+                       gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
+               };
+
+               button@1 {
+                       label = "Left Joystick Right";
+                       linux,code = <ABS_X>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <1>;
+                       gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
+               };
+
+               button@2 {
+                       label = "Left Joystick Up";
+                       linux,code = <ABS_Y>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <0xffffffff>; /* -1 */
+                       gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
+               };
+
+               button@3 {
+                       label = "Left Joystick Down";
+                       linux,code = <ABS_Y>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <1>;
+                       gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
+               };
+
+               button@4 {
+                       label = "Right Joystick Left";
+                       linux,code = <ABS_Z>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <0xffffffff>; /* -1 */
+                       gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
+               };
+
+               button@5 {
+                       label = "Right Joystick Right";
+                       linux,code = <ABS_Z>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <1>;
+                       gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
+               };
+
+               button@6 {
+                       label = "Right Joystick Up";
+                       linux,code = <ABS_RZ>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <0xffffffff>; /* -1 */
+                       gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
+               };
+
+               button@7 {
+                       label = "Right Joystick Down";
+                       linux,code = <ABS_RZ>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <1>;
+                       gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
+               };
+
+               button@8 {
+                       label = "DPad Left";
+                       linux,code = <ABS_HAT0X>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <0xffffffff>; /* -1 */
+                       gpios = <&pio 7 23 GPIO_ACTIVE_LOW>; /* PH23 */
+               };
+
+               button@9 {
+                       label = "DPad Right";
+                       linux,code = <ABS_HAT0X>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <1>;
+                       gpios = <&pio 7 24 GPIO_ACTIVE_LOW>; /* PH24 */
+               };
+
+               button@10 {
+                       label = "DPad Up";
+                       linux,code = <ABS_HAT0Y>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <0xffffffff>; /* -1 */
+                       gpios = <&pio 7 25 GPIO_ACTIVE_LOW>; /* PH25 */
+               };
+
+               button@11 {
+                       label = "DPad Down";
+                       linux,code = <ABS_HAT0Y>;
+                       linux,input-type = <EV_ABS>;
+                       linux,input-value = <1>;
+                       gpios = <&pio 7 26 GPIO_ACTIVE_LOW>; /* PH26 */
+               };
+
+               button@12 {
+                       label = "Button X";
+                       linux,code = <BTN_X>;
+                       gpios = <&pio 0 16 GPIO_ACTIVE_LOW>; /* PA16 */
+               };
+
+               button@13 {
+                       label = "Button Y";
+                       linux,code = <BTN_Y>;
+                       gpios = <&pio 0 14 GPIO_ACTIVE_LOW>; /* PA14 */
+               };
+
+               button@14 {
+                       label = "Button A";
+                       linux,code = <BTN_A>;
+                       gpios = <&pio 0 17 GPIO_ACTIVE_LOW>; /* PA17 */
+               };
+
+               button@15 {
+                       label = "Button B";
+                       linux,code = <BTN_B>;
+                       gpios = <&pio 0 15 GPIO_ACTIVE_LOW>; /* PA15 */
+               };
+
+               button@16 {
+                       label = "Select Button";
+                       linux,code = <BTN_SELECT>;
+                       gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
+               };
+
+               button@17 {
+                       label = "Start Button";
+                       linux,code = <BTN_START>;
+                       gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
+               };
+
+               button@18 {
+                       label = "Top Left Button";
+                       linux,code = <BTN_TL>;
+                       gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 */
+               };
+
+               button@19 {
+                       label = "Top Right Button";
+                       linux,code = <BTN_TR>;
+                       gpios = <&pio 0 13 GPIO_ACTIVE_LOW>; /* PA13 */
+               };
+       };
 };
 
 &cpu0 {
 };
 
 &pio {
+       key_pins_inet9f: key_pins@0 {
+               allwinner,pins = "PA0", "PA1", "PA3", "PA4",
+                                "PA5", "PA6", "PA8", "PA9",
+                                "PA11", "PA12", "PA13",
+                                "PA14", "PA15", "PA16", "PA17",
+                                "PH22", "PH23", "PH24", "PH25", "PH26";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+       };
+
        usb0_id_detect_pin: usb0_id_detect_pin@0 {
                allwinner,pins = "PH4";
                allwinner,function = "gpio_in";
index 3c7eebe..ddf0683 100644 (file)
        };
 };
 
+&codec {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
index 82e69c3..918f972 100644 (file)
@@ -47,6 +47,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "Point of View Protab2-IPS9";
                serial0 = &uart0;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_en_pin_protab>;
+               pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+               default-brightness-level = <8>;
+               enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
+       };
+
        chosen {
                stdout-path = "serial0:115200n8";
        };
 };
 
+&codec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&codec_pa_pin>;
+       allwinner,pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins_a>;
        status = "okay";
+
+       pixcir_ts@5c {
+               pinctrl-names = "default";
+               pinctrl-0 = <&touchscreen_pins>;
+               compatible = "pixcir,pixcir_tangoc";
+               reg = <0x5c>;
+               interrupt-parent = <&pio>;
+               interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; /* EINT21 (PH21) */
+               attb-gpio = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* PH21 */
+               enable-gpios = <&pio 0 5 GPIO_ACTIVE_LOW>;
+               wake-gpios = <&pio 1 13 GPIO_ACTIVE_LOW>;
+               touchscreen-size-x = <1024>;
+               touchscreen-size-y = <768>;
+               touchscreen-inverted-x;
+               touchscreen-inverted-y;
+       };
 };
 
 &lradc {
 };
 
 &pio {
+       bl_en_pin_protab: bl_en_pin@0 {
+               allwinner,pins = "PH7";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       codec_pa_pin: codec_pa_pin@0 {
+               allwinner,pins = "PH15";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       touchscreen_pins: touchscreen_pins@0 {
+               allwinner,pins = "PA5", "PB13";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
        usb0_id_detect_pin: usb0_id_detect_pin@0 {
                allwinner,pins = "PH4";
                allwinner,function = "gpio_in";
        };
 };
 
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins_a>;
+       status = "okay";
+};
+
 &reg_dcdc2 {
        regulator-always-on;
        regulator-min-microvolt = <1000000>;
index aa90f31..2c8f5e6 100644 (file)
@@ -66,7 +66,7 @@
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_be0-lcd0-hdmi";
                        clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
-                                <&ahb_gates 44>;
+                                <&ahb_gates 44>, <&dram_gates 26>;
                        status = "disabled";
                };
 
@@ -75,7 +75,8 @@
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_fe0-de_be0-lcd0-hdmi";
                        clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
-                                <&ahb_gates 44>, <&ahb_gates 46>;
+                                <&ahb_gates 44>, <&ahb_gates 46>,
+                                <&dram_gates 25>, <&dram_gates 26>;
                        status = "disabled";
                };
 
@@ -84,7 +85,8 @@
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_fe0-de_be0-lcd0";
                        clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
-                                <&ahb_gates 46>;
+                                <&ahb_gates 46>, <&dram_gates 25>,
+                                <&dram_gates 26>;
                        status = "disabled";
                };
 
@@ -93,7 +95,8 @@
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0";
                        clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
-                                <&ahb_gates 44>, <&ahb_gates 46>;
+                                <&ahb_gates 44>, <&ahb_gates 46>,
+                                <&dram_gates 25>, <&dram_gates 26>;
                        status = "disabled";
                };
        };
                        clock-output-names = "spi3";
                };
 
+               dram_gates: clk@01c20100 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-dram-gates-clk";
+                       reg = <0x01c20100 0x4>;
+                       clocks = <&pll5 0>;
+                       clock-indices = <0>,
+                                       <1>, <2>,
+                                       <3>,
+                                       <4>,
+                                       <5>, <6>,
+                                       <15>,
+                                       <24>, <25>,
+                                       <26>, <27>,
+                                       <28>, <29>;
+                       clock-output-names = "dram_ve",
+                                            "dram_csi0", "dram_csi1",
+                                            "dram_ts",
+                                            "dram_tvd",
+                                            "dram_tve0", "dram_tve1",
+                                            "dram_output",
+                                            "dram_de_fe1", "dram_de_fe0",
+                                            "dram_de_be0", "dram_de_be1",
+                                            "dram_de_mp", "dram_ace";
+               };
+
+               ve_clk: clk@01c2013c {
+                       #clock-cells = <0>;
+                       #reset-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-ve-clk";
+                       reg = <0x01c2013c 0x4>;
+                       clocks = <&pll4>;
+                       clock-output-names = "ve";
+               };
+
                codec_clk: clk@01c20140 {
                        #clock-cells = <0>;
                        compatible = "allwinner,sun4i-a10-codec-clk";
index 2b3511e..a790ec8 100644 (file)
        status = "okay";
 };
 
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       status = "okay";
+
+       axp152: pmic@30 {
+               compatible = "x-powers,axp152";
+               reg = <0x30>;
+               interrupts = <0>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_t004>;
diff --git a/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts
new file mode 100644 (file)
index 0000000..7fbb0b0
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       model = "Empire Electronix D709 tablet";
+       compatible = "empire-electronix,d709", "allwinner,sun5i-a13";
+
+       aliases {
+               serial0 = &uart1;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+               default-brightness-level = <8>;
+               /* TODO: backlight uses axp gpio1 as enable pin */
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       status = "okay";
+
+       axp209: pmic@34 {
+               reg = <0x34>;
+               interrupts = <0>;
+       };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins_a>;
+       status = "okay";
+
+       pcf8563: rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&lradc {
+       vref-supply = <&reg_ldo2>;
+       status = "okay";
+
+       button@200 {
+               label = "Volume Up";
+               linux,code = <KEY_VOLUMEUP>;
+               channel = <0>;
+               voltage = <200000>;
+       };
+
+       button@400 {
+               label = "Volume Down";
+               linux,code = <KEY_VOLUMEDOWN>;
+               channel = <0>;
+               voltage = <400000>;
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+       cd-inverted;
+       status = "okay";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins_a>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+
+       mmccard: mmccard@0 {
+               reg = <0>;
+               compatible = "mmc-card";
+               broken-hpi;
+       };
+};
+
+&otg_sram {
+       status = "okay";
+};
+
+&pio {
+       mmc0_cd_pin_inet98fv2: mmc0_cd_pin@0 {
+               allwinner,pins = "PG0";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+       };
+
+       usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+               allwinner,pins = "PG1";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+       };
+
+       usb0_id_detect_pin: usb0_id_detect_pin@0 {
+               allwinner,pins = "PG2";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+       };
+};
+
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins>;
+       status = "okay";
+};
+
+&reg_dcdc2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1400000>;
+       regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+       regulator-always-on;
+       regulator-min-microvolt = <1250000>;
+       regulator-max-microvolt = <1250000>;
+       regulator-name = "vdd-int-pll";
+};
+
+&reg_ldo1 {
+       regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "avcc";
+};
+
+&reg_ldo3 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-wifi";
+};
+
+&reg_usb0_vbus {
+       gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins_b>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usb0_vbus_pin_a {
+       allwinner,pins = "PG12";
+};
+
+&usbphy {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+       usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+       usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+       usb0_vbus-supply = <&reg_usb0_vbus>;
+       usb1_vbus-supply = <&reg_ldo3>;
+       status = "okay";
+};
index eb793d5..fa9ddfd 100644 (file)
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "Utoo P66";
        compatible = "utoo,p66", "allwinner,sun5i-a13";
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+               /* Note levels of 10 / 20% result in backlight off */
+               brightness-levels = <0 30 40 50 60 70 80 90 100>;
+               default-brightness-level = <6>;
+               /* TODO: backlight uses axp gpio1 as enable pin */
+       };
+
        i2c_lcd: i2c@0 {
                /* The lcd panel i2c interface is hooked up via gpios */
                compatible = "i2c-gpio";
        };
 };
 
+&codec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&codec_pa_pin>;
+       allwinner,pa-gpios = <&pio 6 3 GPIO_ACTIVE_HIGH>; /* PG3 */
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
 };
 
 &pio {
+       codec_pa_pin: codec_pa_pin@0 {
+               allwinner,pins = "PG3";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
        mmc0_cd_pin_p66: mmc0_cd_pin@0 {
                allwinner,pins = "PG0";
                allwinner,function = "gpio_in";
        };
 };
 
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins>;
+       status = "okay";
+};
+
 &reg_dcdc2 {
        regulator-always-on;
        regulator-min-microvolt = <1000000>;
index b199020..360adfb 100644 (file)
        allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
 };
 
-&reg_usb1_vbus {
-       gpio = <&pio 7 27 GPIO_ACTIVE_HIGH>;
+&p2wi {
        status = "okay";
+
+       axp22x: pmic@68 {
+               compatible = "x-powers,axp221";
+               reg = <0x68>;
+               interrupt-parent = <&nmi_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+       };
 };
 
-&usb1_vbus_pin_a {
-       allwinner,pins = "PH27";
+#include "axp22x.dtsi"
+
+&reg_aldo3 {
+       regulator-always-on;
+       regulator-min-microvolt = <2700000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "avcc";
 };
 
-&usbphy {
-       usb1_vbus-supply = <&reg_usb1_vbus>;
-       status = "okay";
+&reg_dc1sw {
+       regulator-name = "vcc-lcd-usb2";
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+};
+
+&reg_dc5ldo {
+       regulator-min-microvolt = <700000>;
+       regulator-max-microvolt = <1320000>;
+       regulator-name = "vdd-cpus";
+};
+
+&reg_dcdc1 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+       regulator-min-microvolt = <700000>;
+       regulator-max-microvolt = <1320000>;
+       regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc3 {
+       regulator-always-on;
+       regulator-min-microvolt = <700000>;
+       regulator-max-microvolt = <1320000>;
+       regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc4 {
+       regulator-always-on;
+       regulator-min-microvolt = <700000>;
+       regulator-max-microvolt = <1320000>;
+       regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+       regulator-always-on;
+       regulator-min-microvolt = <1500000>;
+       regulator-max-microvolt = <1500000>;
+       regulator-name = "vcc-dram";
+};
+
+&reg_dldo1 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-wifi";
+};
+
+/* Voltage source for I2C pullup resistors for I2C Bus 0 */
+&reg_dldo3 {
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+       regulator-name = "vddio-csi";
 };
 
 &uart0 {
        pinctrl-0 = <&uart0_pins_a>;
        status = "okay";
 };
+
+&usbphy {
+       usb1_vbus-supply = <&reg_dldo1>;
+       usb2_vbus-supply = <&reg_dc1sw>;
+       status = "okay";
+};
index fd7594f..67c8a76 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
        operating-points = <
diff --git a/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
new file mode 100644 (file)
index 0000000..f5b5325
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2015 Stefan Roese <sr@denx.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+       model = "ICnova-A20 SWAC";
+       compatible = "swac,icnova-a20-swac", "incircuit,icnova-a20", "allwinner,sun7i-a20";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&gmac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac_pins_mii_a>;
+       phy = <&phy1>;
+       phy-mode = "mii";
+       status = "okay";
+
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       status = "okay";
+
+       axp209: pmic@34 {
+               reg = <0x34>;
+               interrupt-parent = <&nmi_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins_a>;
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; /* PI5 */
+       cd-inverted;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1400000>;
+       regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1400000>;
+       regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+       regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "avcc";
+};
+
+&reg_usb1_vbus {
+       status = "okay";
+};
+
+&reg_usb2_vbus {
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
+
+&usbphy {
+       usb1_vbus-supply = <&reg_usb1_vbus>;
+       usb2_vbus-supply = <&reg_usb2_vbus>;
+       status = "okay";
+};
index 4f432f8..c9e648d 100644 (file)
        };
 };
 
+&codec {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
index b7fe102..c3c626b 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2015 - Marcus Cooper <codekipper@gmail.com>
+ * Copyright 2015 - Karsten Merker <merker@debian.org>
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
@@ -45,6 +46,7 @@
 #include "sunxi-common-regulators.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
 
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_pins_rgmii_a>;
        };
 };
 
+&lradc {
+       vref-supply = <&reg_vcc3v0>;
+       status = "okay";
+
+       button@190 {
+               label = "Volume Up";
+               linux,code = <KEY_VOLUMEUP>;
+               channel = <0>;
+               voltage = <190000>;
+       };
+
+       button@390 {
+               label = "Volume Down";
+               linux,code = <KEY_VOLUMEDOWN>;
+               channel = <0>;
+               voltage = <390000>;
+       };
+
+       button@600 {
+               label = "Menu";
+               linux,code = <KEY_MENU>;
+               channel = <0>;
+               voltage = <600000>;
+       };
+
+       button@800 {
+               label = "Search";
+               linux,code = <KEY_SEARCH>;
+               channel = <0>;
+               voltage = <800000>;
+       };
+
+       button@980 {
+               label = "Home";
+               linux,code = <KEY_HOMEPAGE>;
+               channel = <0>;
+               voltage = <980000>;
+       };
+
+       button@1180 {
+               label = "Esc";
+               linux,code = <KEY_ESC>;
+               channel = <0>;
+               voltage = <1180000>;
+       };
+
+       button@1400 {
+               label = "Enter";
+               linux,code = <KEY_ENTER>;
+               channel = <0>;
+               voltage = <1400000>;
+       };
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
        status = "okay";
 };
 
+&mmc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olimex_som_evb>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 7 0 GPIO_ACTIVE_HIGH>; /* PH0 */
+       cd-inverted;
+       status = "okay";
+};
+
 &ohci0 {
        status = "okay";
 };
                allwinner,drive = <SUN4I_PINCTRL_20_MA>;
                allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
        };
+
+       mmc3_cd_pin_olimex_som_evb: mmc3_cd_pin@0 {
+               allwinner,pins = "PH0";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+       };
 };
 
 &reg_ahci_5v {
index 4f65664..2be04c4 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
index 1757a6a..ddac732 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
index 861a4a6..1a8b39b 100644 (file)
        allwinner,pins = "PH2";
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
index 78239ad..2f6b21a 100644 (file)
@@ -48,6 +48,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "Wexler TAB7200";
                serial0 = &uart0;
        };
 
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+               default-brightness-level = <8>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_enable_pin>;
+               enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
+       };
+
        chosen {
                stdout-path = "serial0:115200n8";
        };
 };
 
+&codec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&codec_pa_pin>;
+       allwinner,pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins_a>;
        status = "okay";
+
+       gt911: touchscreen@5d {
+               compatible = "goodix,gt911";
+               reg = <0x5d>;
+               interrupt-parent = <&pio>;
+               interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; /* EINT21 (PH21) */
+               pinctrl-names = "default";
+               pinctrl-0 = <&ts_reset_pin>;
+               irq-gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* INT (PH21) */
+               reset-gpios = <&pio 1 13 GPIO_ACTIVE_HIGH>; /* RST (PB13) */
+               touchscreen-swapped-x-y;
+       };
 };
 
 &lradc {
 };
 
 &pio {
+       bl_enable_pin: bl_enable_pin@0 {
+               allwinner,pins = "PH7";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       codec_pa_pin: codec_pa_pin@0 {
+               allwinner,pins = "PH15";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       ts_reset_pin: ts_reset_pin@0 {
+               allwinner,pins = "PB13";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
        usb0_id_detect_pin: usb0_id_detect_pin@0 {
                allwinner,pins = "PH4";
                allwinner,function = "gpio_in";
        };
 };
 
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins_a>;
+       status = "okay";
+};
+
 &reg_dcdc2 {
        regulator-always-on;
        regulator-min-microvolt = <1000000>;
index 85b500d..dc31d47 100644 (file)
        status = "okay";
 };
 
+&gmac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac_pins_rgmii_a>;
+       phy = <&phy1>;
+       phy-mode = "rgmii";
+       status = "okay";
+
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &i2c0 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0_pins_a>;
index e02eb72..0940a78 100644 (file)
@@ -68,7 +68,7 @@
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_be0-lcd0-hdmi";
                        clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
-                                <&ahb_gates 44>;
+                                <&ahb_gates 44>, <&dram_gates 26>;
                        status = "disabled";
                };
 
@@ -76,7 +76,8 @@
                        compatible = "allwinner,simple-framebuffer",
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_be0-lcd0";
-                       clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+                       clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
+                                <&dram_gates 26>;
                        status = "disabled";
                };
 
@@ -85,7 +86,7 @@
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_be0-lcd0-tve0";
                        clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
-                                <&ahb_gates 44>;
+                                <&ahb_gates 44>, <&dram_gates 26>;
                        status = "disabled";
                };
        };
                        clock-output-names = "spi3";
                };
 
+               dram_gates: clk@01c20100 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-dram-gates-clk";
+                       reg = <0x01c20100 0x4>;
+                       clocks = <&pll5 0>;
+                       clock-indices = <0>,
+                                       <1>, <2>,
+                                       <3>,
+                                       <4>,
+                                       <5>, <6>,
+                                       <15>,
+                                       <24>, <25>,
+                                       <26>, <27>,
+                                       <28>, <29>;
+                       clock-output-names = "dram_ve",
+                                            "dram_csi0", "dram_csi1",
+                                            "dram_ts",
+                                            "dram_tvd",
+                                            "dram_tve0", "dram_tve1",
+                                            "dram_output",
+                                            "dram_de_fe1", "dram_de_fe0",
+                                            "dram_de_be0", "dram_de_be1",
+                                            "dram_de_mp", "dram_ace";
+               };
+
+               ve_clk: clk@01c2013c {
+                       #clock-cells = <0>;
+                       #reset-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-ve-clk";
+                       reg = <0x01c2013c 0x4>;
+                       clocks = <&pll4>;
+                       clock-output-names = "ve";
+               };
+
                codec_clk: clk@01c20140 {
                        #clock-cells = <0>;
                        compatible = "allwinner,sun4i-a10-codec-clk";
index 0c0964d..6f88fb0 100644 (file)
@@ -56,7 +56,7 @@
                #size-cells = <1>;
                ranges;
 
-               framebuffer@0 {
+               simplefb_lcd: framebuffer@0 {
                        compatible = "allwinner,simple-framebuffer",
                                     "simple-framebuffer";
                        allwinner,pipeline = "de_be0-lcd0";
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
new file mode 100644 (file)
index 0000000..e67df59
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 Jens Kuske <jenskuske@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+       model = "Xunlong Orange Pi Plus";
+       compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+       cd-inverted;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
new file mode 100644 (file)
index 0000000..1524130
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2015 Jens Kuske <jenskuske@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+       interrupt-parent = <&gic>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "arm,cortex-a7";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a7";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+
+               cpu@2 {
+                       compatible = "arm,cortex-a7";
+                       device_type = "cpu";
+                       reg = <2>;
+               };
+
+               cpu@3 {
+                       compatible = "arm,cortex-a7";
+                       device_type = "cpu";
+                       reg = <3>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               osc24M: osc24M_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <24000000>;
+                       clock-output-names = "osc24M";
+               };
+
+               osc32k: osc32k_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <32768>;
+                       clock-output-names = "osc32k";
+               };
+
+               pll1: clk@01c20000 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a23-pll1-clk";
+                       reg = <0x01c20000 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll1";
+               };
+
+               /* dummy clock until actually implemented */
+               pll5: pll5_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <0>;
+                       clock-output-names = "pll5";
+               };
+
+               pll6: clk@01c20028 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun6i-a31-pll6-clk";
+                       reg = <0x01c20028 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll6", "pll6x2";
+               };
+
+               pll6d2: pll6d2_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clocks = <&pll6 0>;
+                       clock-output-names = "pll6d2";
+               };
+
+               /* dummy clock until pll6 can be reused */
+               pll8: pll8_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <1>;
+                       clock-output-names = "pll8";
+               };
+
+               cpu: cpu_clk@01c20050 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
+                       reg = <0x01c20050 0x4>;
+                       clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+                       clock-output-names = "cpu";
+               };
+
+               axi: axi_clk@01c20050 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-axi-clk";
+                       reg = <0x01c20050 0x4>;
+                       clocks = <&cpu>;
+                       clock-output-names = "axi";
+               };
+
+               ahb1: ahb1_clk@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun6i-a31-ahb1-clk";
+                       reg = <0x01c20054 0x4>;
+                       clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
+                       clock-output-names = "ahb1";
+               };
+
+               ahb2: ahb2_clk@01c2005c {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-h3-ahb2-clk";
+                       reg = <0x01c2005c 0x4>;
+                       clocks = <&ahb1>, <&pll6d2>;
+                       clock-output-names = "ahb2";
+               };
+
+               apb1: apb1_clk@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
+                       reg = <0x01c20054 0x4>;
+                       clocks = <&ahb1>;
+                       clock-output-names = "apb1";
+               };
+
+               apb2: apb2_clk@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-apb1-clk";
+                       reg = <0x01c20058 0x4>;
+                       clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
+                       clock-output-names = "apb2";
+               };
+
+               bus_gates: clk@01c20060 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun8i-h3-bus-gates-clk";
+                       reg = <0x01c20060 0x14>;
+                       clocks = <&ahb1>, <&ahb2>, <&apb1>, <&apb2>;
+                       clock-names = "ahb1", "ahb2", "apb1", "apb2";
+                       clock-indices = <5>, <6>, <8>,
+                                       <9>, <10>, <13>,
+                                       <14>, <17>, <18>,
+                                       <19>, <20>,
+                                       <21>, <23>,
+                                       <24>, <25>,
+                                       <26>, <27>,
+                                       <28>, <29>,
+                                       <30>, <31>, <32>,
+                                       <35>, <36>, <37>,
+                                       <40>, <41>, <43>,
+                                       <44>, <52>, <53>,
+                                       <54>, <64>,
+                                       <65>, <69>, <72>,
+                                       <76>, <77>, <78>,
+                                       <96>, <97>, <98>,
+                                       <112>, <113>,
+                                       <114>, <115>,
+                                       <116>, <128>, <135>;
+                       clock-output-names = "bus_ce", "bus_dma", "bus_mmc0",
+                                            "bus_mmc1", "bus_mmc2", "bus_nand",
+                                            "bus_sdram", "bus_gmac", "bus_ts",
+                                            "bus_hstimer", "bus_spi0",
+                                            "bus_spi1", "bus_otg",
+                                            "bus_otg_ehci0", "bus_ehci1",
+                                            "bus_ehci2", "bus_ehci3",
+                                            "bus_otg_ohci0", "bus_ohci1",
+                                            "bus_ohci2", "bus_ohci3", "bus_ve",
+                                            "bus_lcd0", "bus_lcd1", "bus_deint",
+                                            "bus_csi", "bus_tve", "bus_hdmi",
+                                            "bus_de", "bus_gpu", "bus_msgbox",
+                                            "bus_spinlock", "bus_codec",
+                                            "bus_spdif", "bus_pio", "bus_ths",
+                                            "bus_i2s0", "bus_i2s1", "bus_i2s2",
+                                            "bus_i2c0", "bus_i2c1", "bus_i2c2",
+                                            "bus_uart0", "bus_uart1",
+                                            "bus_uart2", "bus_uart3",
+                                            "bus_scr", "bus_ephy", "bus_dbg";
+               };
+
+               mmc0_clk: clk@01c20088 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
+                       reg = <0x01c20088 0x4>;
+                       clocks = <&osc24M>, <&pll6 0>, <&pll8>;
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
+               };
+
+               mmc1_clk: clk@01c2008c {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
+                       reg = <0x01c2008c 0x4>;
+                       clocks = <&osc24M>, <&pll6 0>, <&pll8>;
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
+               };
+
+               mmc2_clk: clk@01c20090 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
+                       reg = <0x01c20090 0x4>;
+                       clocks = <&osc24M>, <&pll6 0>, <&pll8>;
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
+               };
+
+               mbus_clk: clk@01c2015c {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun8i-a23-mbus-clk";
+                       reg = <0x01c2015c 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5>;
+                       clock-output-names = "mbus";
+               };
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               dma: dma-controller@01c02000 {
+                       compatible = "allwinner,sun8i-h3-dma";
+                       reg = <0x01c02000 0x1000>;
+                       interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bus_gates 6>;
+                       resets = <&ahb_rst 6>;
+                       #dma-cells = <1>;
+               };
+
+               mmc0: mmc@01c0f000 {
+                       compatible = "allwinner,sun5i-a13-mmc";
+                       reg = <0x01c0f000 0x1000>;
+                       clocks = <&bus_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
+                       resets = <&ahb_rst 8>;
+                       reset-names = "ahb";
+                       interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mmc1: mmc@01c10000 {
+                       compatible = "allwinner,sun5i-a13-mmc";
+                       reg = <0x01c10000 0x1000>;
+                       clocks = <&bus_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
+                       resets = <&ahb_rst 9>;
+                       reset-names = "ahb";
+                       interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mmc2: mmc@01c11000 {
+                       compatible = "allwinner,sun5i-a13-mmc";
+                       reg = <0x01c11000 0x1000>;
+                       clocks = <&bus_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
+                       resets = <&ahb_rst 10>;
+                       reset-names = "ahb";
+                       interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               pio: pinctrl@01c20800 {
+                       compatible = "allwinner,sun8i-h3-pinctrl";
+                       reg = <0x01c20800 0x400>;
+                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bus_gates 69>;
+                       gpio-controller;
+                       #gpio-cells = <3>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+
+                       uart0_pins_a: uart0@0 {
+                               allwinner,pins = "PA4", "PA5";
+                               allwinner,function = "uart0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       mmc0_pins_a: mmc0@0 {
+                               allwinner,pins = "PF0", "PF1", "PF2", "PF3",
+                                                "PF4", "PF5";
+                               allwinner,function = "mmc0";
+                               allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       mmc0_cd_pin: mmc0_cd_pin@0 {
+                               allwinner,pins = "PF6";
+                               allwinner,function = "gpio_in";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+                       };
+
+                       mmc1_pins_a: mmc1@0 {
+                               allwinner,pins = "PG0", "PG1", "PG2", "PG3",
+                                                "PG4", "PG5";
+                               allwinner,function = "mmc1";
+                               allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+               };
+
+               ahb_rst: reset@01c202c0 {
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun6i-a31-ahb1-reset";
+                       reg = <0x01c202c0 0xc>;
+               };
+
+               apb1_rst: reset@01c202d0 {
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun6i-a31-clock-reset";
+                       reg = <0x01c202d0 0x4>;
+               };
+
+               apb2_rst: reset@01c202d8 {
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun6i-a31-clock-reset";
+                       reg = <0x01c202d8 0x4>;
+               };
+
+               timer@01c20c00 {
+                       compatible = "allwinner,sun4i-a10-timer";
+                       reg = <0x01c20c00 0xa0>;
+                       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
+               };
+
+               wdt0: watchdog@01c20ca0 {
+                       compatible = "allwinner,sun6i-a31-wdt";
+                       reg = <0x01c20ca0 0x20>;
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               uart0: serial@01c28000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x01c28000 0x400>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&bus_gates 112>;
+                       resets = <&apb2_rst 16>;
+                       dmas = <&dma 6>, <&dma 6>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               uart1: serial@01c28400 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x01c28400 0x400>;
+                       interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&bus_gates 113>;
+                       resets = <&apb2_rst 17>;
+                       dmas = <&dma 7>, <&dma 7>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               uart2: serial@01c28800 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x01c28800 0x400>;
+                       interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&bus_gates 114>;
+                       resets = <&apb2_rst 18>;
+                       dmas = <&dma 8>, <&dma 8>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               uart3: serial@01c28c00 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x01c28c00 0x400>;
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&bus_gates 115>;
+                       resets = <&apb2_rst 19>;
+                       dmas = <&dma 9>, <&dma 9>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               gic: interrupt-controller@01c81000 {
+                       compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+                       reg = <0x01c81000 0x1000>,
+                             <0x01c82000 0x1000>,
+                             <0x01c84000 0x2000>,
+                             <0x01c86000 0x2000>;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               };
+
+               rtc: rtc@01f00000 {
+                       compatible = "allwinner,sun6i-a31-rtc";
+                       reg = <0x01f00000 0x54>;
+                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+               };
+       };
+};
index 6484dcf..382bd9f 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_cubieboard4>;
+
+               green {
+                       label = "cubieboard4:green:usr";
+                       gpios = <&pio 7 17 GPIO_ACTIVE_HIGH>; /* PH17 */
+               };
+
+               red {
+                       label = "cubieboard4:red:usr";
+                       gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+               };
+       };
 };
 
 &pio {
+       led_pins_cubieboard4: led-pins@0 {
+               allwinner,pins = "PH6", "PH17";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
        mmc0_cd_pin_cubieboard4: mmc0_cd_pin@0 {
                allwinner,pins = "PH18";
                allwinner,function = "gpio_in";
        status = "okay";
 };
 
+&r_ir {
+       status = "okay";
+};
+
+&r_rsb {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index 6ce4b5e..c0060e4 100644 (file)
@@ -65,7 +65,7 @@
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
-               pinctrl-0 = <&led_pins_optimus>;
+               pinctrl-0 = <&led_pins_optimus>, <&led_r_pins_optimus>;
 
                /* The LED names match those found on the board */
 
                        gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>;
                };
 
-               /* led3 is on PM15, in R_PIO */
+               led3 {
+                       label = "optimus:led3:usr";
+                       gpios = <&r_pio 1 15 GPIO_ACTIVE_HIGH>; /* PM15 */
+               };
 
                led4 {
                        label = "optimus:led4:usr";
        status = "okay";
 };
 
+&r_ir {
+       status = "okay";
+};
+
+&r_pio {
+       led_r_pins_optimus: led-pins@1 {
+               allwinner,pins = "PM15";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+};
+
+&r_rsb {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index 1118bf5..e838f20 100644 (file)
                 */
                ranges = <0 0 0 0x20000000>;
 
+               /*
+                * This clock is actually configurable from the PRCM address
+                * space. The external 24M oscillator can be turned off, and
+                * the clock switched to an internal 16M RC oscillator. Under
+                * normal operation there's no reason to do this, and the
+                * default is to use the external good one, so just model this
+                * as a fixed clock. Also it is not entirely clear if the
+                * osc24M mux in the PRCM affects the entire clock tree, which
+                * would also throw all the PLL clock rates off, or just the
+                * downstream clocks in the PRCM.
+                */
                osc24M: osc24M_clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-output-names = "osc24M";
                };
 
+               /*
+                * The 32k clock is from an external source, normally the
+                * AC100 codec/RTC chip. This clock is by default enabled
+                * and clocked at 32768 Hz, from the oscillator connected
+                * to the AC100. It is configurable, but no such driver or
+                * bindings exist yet.
+                */
                osc32k: osc32k_clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                                             "usb_phy2", "usb_hsic_12M";
                };
 
+               pll3: clk@06000008 {
+                       /* placeholder until implemented */
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-rate = <0>;
+                       clock-output-names = "pll3";
+               };
+
                pll4: clk@0600000c {
                        #clock-cells = <0>;
                        compatible = "allwinner,sun9i-a80-pll4-clk";
                                        "apb1_uart2", "apb1_uart3",
                                        "apb1_uart4", "apb1_uart5";
                };
+
+               cpus_clk: clk@08001410 {
+                       compatible = "allwinner,sun9i-a80-cpus-clk";
+                       reg = <0x08001410 0x4>;
+                       #clock-cells = <0>;
+                       clocks = <&osc32k>, <&osc24M>, <&pll4>, <&pll3>;
+                       clock-output-names = "cpus";
+               };
+
+               ahbs: ahbs_clk {
+                       compatible = "fixed-factor-clock";
+                       #clock-cells = <0>;
+                       clock-div = <1>;
+                       clock-mult = <1>;
+                       clocks = <&cpus_clk>;
+                       clock-output-names = "ahbs";
+               };
+
+               apbs: clk@0800141c {
+                       compatible = "allwinner,sun8i-a23-apb0-clk";
+                       reg = <0x0800141c 0x4>;
+                       #clock-cells = <0>;
+                       clocks = <&ahbs>;
+                       clock-output-names = "apbs";
+               };
+
+               apbs_gates: clk@08001428 {
+                       compatible = "allwinner,sun9i-a80-apbs-gates-clk";
+                       reg = <0x08001428 0x4>;
+                       #clock-cells = <1>;
+                       clocks = <&apbs>;
+                       clock-indices = <0>, <1>,
+                                       <2>, <3>,
+                                       <4>, <5>,
+                                       <6>, <7>,
+                                       <12>, <13>,
+                                       <16>, <17>,
+                                       <18>, <20>;
+                       clock-output-names = "apbs_pio", "apbs_ir",
+                                       "apbs_timer", "apbs_rsb",
+                                       "apbs_uart", "apbs_1wire",
+                                       "apbs_i2c0", "apbs_i2c1",
+                                       "apbs_ps2_0", "apbs_ps2_1",
+                                       "apbs_dma", "apbs_i2s0",
+                                       "apbs_i2s1", "apbs_twd";
+               };
+
+               r_1wire_clk: clk@08001450 {
+                       reg = <0x08001450 0x4>;
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       clocks = <&osc32k>, <&osc24M>;
+                       clock-output-names = "r_1wire";
+               };
+
+               r_ir_clk: clk@08001454 {
+                       reg = <0x08001454 0x4>;
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       clocks = <&osc32k>, <&osc24M>;
+                       clock-output-names = "r_ir";
+               };
        };
 
        soc {
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               apbs_rst: reset@080014b0 {
+                       reg = <0x080014b0 0x4>;
+                       compatible = "allwinner,sun6i-a31-clock-reset";
+                       #reset-cells = <1>;
+               };
+
+               nmi_intc: interrupt-controller@080015a0 {
+                       compatible = "allwinner,sun9i-a80-nmi";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       reg = <0x080015a0 0xc>;
+                       interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               r_ir: ir@08002000 {
+                       compatible = "allwinner,sun5i-a13-ir";
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&r_ir_pins>;
+                       clocks = <&apbs_gates 1>, <&r_ir_clk>;
+                       clock-names = "apb", "ir";
+                       resets = <&apbs_rst 1>;
+                       reg = <0x08002000 0x40>;
+                       status = "disabled";
+               };
+
                r_uart: serial@08002800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x08002800 0x400>;
                        interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
-                       clocks = <&osc24M>;
+                       clocks = <&apbs_gates 4>;
+                       resets = <&apbs_rst 4>;
+                       status = "disabled";
+               };
+
+               r_pio: pinctrl@08002c00 {
+                       compatible = "allwinner,sun9i-a80-r-pinctrl";
+                       reg = <0x08002c00 0x400>;
+                       interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&apbs_gates 0>;
+                       resets = <&apbs_rst 0>;
+                       gpio-controller;
+                       interrupt-controller;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #gpio-cells = <3>;
+
+                       r_ir_pins: r_ir {
+                               allwinner,pins = "PL6";
+                               allwinner,function = "s_cir_rx";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       r_rsb_pins: r_rsb {
+                               allwinner,pins = "PN0", "PN1";
+                               allwinner,function = "s_rsb";
+                               allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+                       };
+               };
+
+               r_rsb: i2c@08003400 {
+                       compatible = "allwinner,sun8i-a23-rsb";
+                       reg = <0x08003400 0x400>;
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&apbs_gates 3>;
+                       clock-frequency = <3000000>;
+                       resets = <&apbs_rst 3>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&r_rsb_pins>;
                        status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
                };
        };
 };
diff --git a/arch/arm/boot/dts/tango4-common.dtsi b/arch/arm/boot/dts/tango4-common.dtsi
new file mode 100644 (file)
index 0000000..ef665d2
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Based on Mans Rullgard's Tango3 DT
+ * https://github.com/mansr/linux-tangox
+ */
+
+#define CPU_CLK 0
+#define SYS_CLK 1
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       interrupt-parent = <&gic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       periph_clk: periph_clk {
+               compatible = "fixed-factor-clock";
+               clocks = <&clkgen CPU_CLK>;
+               clock-mult = <1>;
+               clock-div  = <2>;
+               #clock-cells = <0>;
+       };
+
+       mpcore {
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x20000000 0x2000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               scu@0 {
+                       compatible = "arm,cortex-a9-scu";
+                       reg = <0x0 0x100>;
+               };
+
+               twd@600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x600 0x10>;
+                       interrupts = <GIC_PPI 13 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&periph_clk>;
+                       always-on;
+               };
+
+               gic: interrupt-controller@1000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x1000 0x1000>, <0x100 0x100>;
+               };
+       };
+
+       l2cc: l2-cache-controller@20100000 {
+               compatible = "arm,pl310-cache";
+               reg = <0x20100000 0x1000>;
+               cache-level = <2>;
+               cache-unified;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               interrupt-parent = <&irq0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               xtal: xtal {
+                       compatible = "fixed-clock";
+                       clock-frequency = <27000000>;
+                       #clock-cells = <0>;
+               };
+
+               clkgen: clkgen@10000 {
+                       compatible = "sigma,tango4-clkgen";
+                       reg = <0x10000 0x40>;
+                       clocks = <&xtal>;
+                       #clock-cells = <1>;
+               };
+
+               tick-counter@10048 {
+                       compatible = "sigma,tick-counter";
+                       reg = <0x10048 0x4>;
+                       clocks = <&xtal>;
+               };
+
+               uart: serial@10700 {
+                       compatible = "ralink,rt2880-uart";
+                       reg = <0x10700 0x30>;
+                       interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <7372800>;
+                       reg-shift = <2>;
+               };
+
+               eth0: ethernet@26000 {
+                       compatible = "sigma,smp8734-ethernet";
+                       reg = <0x26000 0x800>;
+                       interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clkgen SYS_CLK>;
+               };
+
+               intc: interrupt-controller@6e000 {
+                       compatible = "sigma,smp8642-intc";
+                       reg = <0x6e000 0x400>;
+                       ranges = <0 0x6e000 0x400>;
+                       interrupt-parent = <&gic>;
+                       interrupt-controller;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       irq0: irq0@000 {
+                               reg = <0x000 0x100>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       irq1: irq1@100 {
+                               reg = <0x100 0x100>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       irq2: irq2@300 {
+                               reg = <0x300 0x100>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/tango4-smp8758.dtsi b/arch/arm/boot/dts/tango4-smp8758.dtsi
new file mode 100644 (file)
index 0000000..7ed88ee
--- /dev/null
@@ -0,0 +1,31 @@
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "sigma,tango4-smp";
+
+               cpu0: cpu@0 {
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&l2cc>;
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu1: cpu@1 {
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&l2cc>;
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupt-affinity = <&cpu0>, <&cpu1>;
+               interrupts =
+                       <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                       <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+       };
+};
diff --git a/arch/arm/boot/dts/tango4-vantage-1172.dts b/arch/arm/boot/dts/tango4-vantage-1172.dts
new file mode 100644 (file)
index 0000000..3e5b9c8
--- /dev/null
@@ -0,0 +1,37 @@
+/dts-v1/;
+
+#include "tango4-smp8758.dtsi"
+#include "tango4-common.dtsi"
+
+/ {
+       model = "Sigma Designs SMP8758 Vantage-1172 Rev E1";
+       compatible = "sigma,vantage-1172", "sigma,smp8758", "sigma,tango4";
+
+       aliases {
+               serial = &uart;
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x80000000>; /* 2 GB */
+       };
+
+       chosen {
+               stdout-path = "serial:115200n8";
+       };
+};
+
+&eth0 {
+       phy-connection-type = "rgmii";
+       phy-handle = <&eth0_phy>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       /* Atheros AR8035 */
+       eth0_phy: ethernet-phy@4 {
+               compatible = "ethernet-phy-id004d.d072",
+                            "ethernet-phy-ieee802.3-c22";
+               interrupts = <37 IRQ_TYPE_EDGE_RISING>;
+               reg = <4>;
+       };
+};
diff --git a/arch/arm/boot/dts/tps65217.dtsi b/arch/arm/boot/dts/tps65217.dtsi
deleted file mode 100644 (file)
index a632724..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-/*
- * Integrated Power Management Chip
- * http://www.ti.com/lit/ds/symlink/tps65217.pdf
- */
-
-&tps {
-       compatible = "ti,tps65217";
-
-       regulators {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               dcdc1_reg: regulator@0 {
-                       reg = <0>;
-                       regulator-compatible = "dcdc1";
-               };
-
-               dcdc2_reg: regulator@1 {
-                       reg = <1>;
-                       regulator-compatible = "dcdc2";
-               };
-
-               dcdc3_reg: regulator@2 {
-                       reg = <2>;
-                       regulator-compatible = "dcdc3";
-               };
-
-               ldo1_reg: regulator@3 {
-                       reg = <3>;
-                       regulator-compatible = "ldo1";
-               };
-
-               ldo2_reg: regulator@4 {
-                       reg = <4>;
-                       regulator-compatible = "ldo2";
-               };
-
-               ldo3_reg: regulator@5 {
-                       reg = <5>;
-                       regulator-compatible = "ldo3";
-               };
-
-               ldo4_reg: regulator@6 {
-                       reg = <6>;
-                       regulator-compatible = "ldo4";
-               };
-       };
-};
index 3537ae5..5288e6d 100644 (file)
@@ -19,7 +19,7 @@
         */
        twl4030_pins: pinmux_twl4030_pins {
                pinctrl-single,pins = <
-                       0x1b0 (PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
+                       OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
                >;
        };
 };
index a4fa570..e373f59 100644 (file)
@@ -24,7 +24,7 @@
 &omap4_pmx_wkup {
        twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
                pinctrl-single,pins = <
-                       0x14 (PIN_OUTPUT | MUX_MODE2)           /* fref_clk0_out.sys_drm_msecure */
+                       OMAP4_IOPAD(0x054, PIN_OUTPUT | MUX_MODE2)              /* fref_clk0_out.sys_drm_msecure */
                >;
        };
 };
@@ -32,7 +32,7 @@
 &omap4_pmx_core {
        twl6030_pins: pinmux_twl6030_pins {
                pinctrl-single,pins = <
-                       0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)        /* sys_nirq1.sys_nirq1 */
+                       OMAP4_IOPAD(0x19e, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)    /* sys_nirq1.sys_nirq1 */
                >;
        };
 };
diff --git a/arch/arm/boot/dts/uniphier-common32.dtsi b/arch/arm/boot/dts/uniphier-common32.dtsi
new file mode 100644 (file)
index 0000000..ea9301a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Device Tree Source commonly used by UniPhier ARM SoCs
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       soc: soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               interrupt-parent = <&intc>;
+
+               extbus: extbus {
+                       compatible = "simple-bus";
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+               };
+
+               serial0: serial@54006800 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006800 0x40>;
+                       interrupts = <0 33 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart0>;
+                       clocks = <&uart_clk>;
+               };
+
+               serial1: serial@54006900 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006900 0x40>;
+                       interrupts = <0 35 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart1>;
+                       clocks = <&uart_clk>;
+               };
+
+               serial2: serial@54006a00 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006a00 0x40>;
+                       interrupts = <0 37 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart2>;
+                       clocks = <&uart_clk>;
+               };
+
+               serial3: serial@54006b00 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006b00 0x40>;
+                       interrupts = <0 177 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart3>;
+                       clocks = <&uart_clk>;
+               };
+
+               system-bus-controller@58c00000 {
+                       compatible = "socionext,uniphier-system-bus-controller";
+                       reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
+               };
+
+               timer@60000200 {
+                       compatible = "arm,cortex-a9-global-timer";
+                       reg = <0x60000200 0x20>;
+                       interrupts = <1 11 0x104>;
+                       clocks = <&arm_timer_clk>;
+               };
+
+               timer@60000600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x60000600 0x20>;
+                       interrupts = <1 13 0x104>;
+                       clocks = <&arm_timer_clk>;
+               };
+
+               intc: interrupt-controller@60001000 {
+                       compatible = "arm,cortex-a9-gic";
+                       reg = <0x60001000 0x1000>,
+                             <0x60000100 0x100>;
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+               };
+
+               pinctrl: pinctrl@5f801000 {
+                       /* specify compatible in each SoC DTSI */
+                       reg = <0x5f801000 0xe00>;
+               };
+       };
+};
+
+/include/ "uniphier-pinctrl.dtsi"
index af49381..34f0d8d 100644 (file)
@@ -42,7 +42,7 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
 
 / {
        compatible = "socionext,ph1-ld4";
                        clock-frequency = <100000000>;
                };
        };
+};
 
-       soc {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-               interrupt-parent = <&intc>;
-
-               extbus: extbus {
-                       compatible = "simple-bus";
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-               };
-
-               l2: l2-cache@500c0000 {
-                       compatible = "socionext,uniphier-system-cache";
-                       reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
-                             <0x506c0000 0x400>;
-                       interrupts = <0 174 4>, <0 175 4>;
-                       cache-unified;
-                       cache-size = <(512 * 1024)>;
-                       cache-sets = <256>;
-                       cache-line-size = <128>;
-                       cache-level = <2>;
-               };
-
-               serial0: serial@54006800 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006800 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart0>;
-                       interrupts = <0 33 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial1: serial@54006900 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006900 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart1>;
-                       interrupts = <0 35 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial2: serial@54006a00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006a00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart2>;
-                       interrupts = <0 37 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial3: serial@54006b00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006b00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart3>;
-                       interrupts = <0 29 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               i2c0: i2c@58400000 {
-                       compatible = "socionext,uniphier-i2c";
-                       status = "disabled";
-                       reg = <0x58400000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c0>;
-                       interrupts = <0 41 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c1: i2c@58480000 {
-                       compatible = "socionext,uniphier-i2c";
-                       status = "disabled";
-                       reg = <0x58480000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c1>;
-                       interrupts = <0 42 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               /* chip-internal connection for DMD */
-               i2c2: i2c@58500000 {
-                       compatible = "socionext,uniphier-i2c";
-                       reg = <0x58500000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c2>;
-                       interrupts = <0 43 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <400000>;
-               };
+&soc {
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+               interrupts = <0 174 4>, <0 175 4>;
+               cache-unified;
+               cache-size = <(512 * 1024)>;
+               cache-sets = <256>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+       };
 
-               i2c3: i2c@58580000 {
-                       compatible = "socionext,uniphier-i2c";
-                       status = "disabled";
-                       reg = <0x58580000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c3>;
-                       interrupts = <0 44 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <100000>;
-               };
+       i2c0: i2c@58400000 {
+               compatible = "socionext,uniphier-i2c";
+               status = "disabled";
+               reg = <0x58400000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 41 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c0>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <100000>;
+       };
 
-               system-bus-controller@58c00000 {
-                       compatible = "socionext,uniphier-system-bus-controller";
-                       reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
-               };
+       i2c1: i2c@58480000 {
+               compatible = "socionext,uniphier-i2c";
+               status = "disabled";
+               reg = <0x58480000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 42 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <100000>;
+       };
 
-               usb0: usb@5a800100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a800100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb0>;
-                       interrupts = <0 80 4>;
-               };
+       /* chip-internal connection for DMD */
+       i2c2: i2c@58500000 {
+               compatible = "socionext,uniphier-i2c";
+               reg = <0x58500000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 43 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c2>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <400000>;
+       };
 
-               usb1: usb@5a810100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a810100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb1>;
-                       interrupts = <0 81 4>;
-               };
+       i2c3: i2c@58580000 {
+               compatible = "socionext,uniphier-i2c";
+               status = "disabled";
+               reg = <0x58580000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 44 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c3>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <100000>;
+       };
 
-               usb2: usb@5a820100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a820100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb2>;
-                       interrupts = <0 82 4>;
-               };
+       usb0: usb@5a800100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a800100 0x100>;
+               interrupts = <0 80 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb0>;
+       };
 
-               pinctrl: pinctrl@5f801000 {
-                       compatible = "socionext,ph1-ld4-pinctrl",
-                                    "syscon";
-                       reg = <0x5f801000 0xe00>;
-               };
+       usb1: usb@5a810100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a810100 0x100>;
+               interrupts = <0 81 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb1>;
+       };
 
-               timer@60000200 {
-                       compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x60000200 0x20>;
-                       interrupts = <1 11 0x104>;
-                       clocks = <&arm_timer_clk>;
-               };
+       usb2: usb@5a820100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a820100 0x100>;
+               interrupts = <0 82 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb2>;
+       };
 
-               timer@60000600 {
-                       compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x60000600 0x20>;
-                       interrupts = <1 13 0x104>;
-                       clocks = <&arm_timer_clk>;
-               };
+};
 
-               intc: interrupt-controller@60001000 {
-                       compatible = "arm,cortex-a9-gic";
-                       #interrupt-cells = <3>;
-                       interrupt-controller;
-                       reg = <0x60001000 0x1000>,
-                             <0x60000100 0x100>;
-               };
-       };
+&serial3 {
+       interrupts = <0 29 4>;
 };
 
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+       compatible = "socionext,ph1-ld4-pinctrl", "syscon";
+};
index c6499ee..5321152 100644 (file)
@@ -53,7 +53,7 @@
        compatible = "socionext,ph1-ld6b";
 };
 
-/* UART3 unavilable: the pads are not wired to the package balls */
+/* UART3 unavailable: the pads are not wired to the package balls */
 &serial3 {
        status = "disabled";
 };
index 254642f..d78142f 100644 (file)
@@ -42,7 +42,7 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
 
 / {
        compatible = "socionext,ph1-pro4";
                        clock-frequency = <50000000>;
                };
        };
+};
 
-       soc {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-               interrupt-parent = <&intc>;
-
-               extbus: extbus {
-                       compatible = "simple-bus";
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-               };
-
-               l2: l2-cache@500c0000 {
-                       compatible = "socionext,uniphier-system-cache";
-                       reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
-                             <0x506c0000 0x400>;
-                       interrupts = <0 174 4>, <0 175 4>;
-                       cache-unified;
-                       cache-size = <(768 * 1024)>;
-                       cache-sets = <256>;
-                       cache-line-size = <128>;
-                       cache-level = <2>;
-               };
-
-               serial0: serial@54006800 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006800 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart0>;
-                       interrupts = <0 33 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial1: serial@54006900 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006900 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart1>;
-                       interrupts = <0 35 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial2: serial@54006a00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006a00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart2>;
-                       interrupts = <0 37 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial3: serial@54006b00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006b00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart3>;
-                       interrupts = <0 29 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               i2c0: i2c@58780000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58780000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c0>;
-                       interrupts = <0 41 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c1: i2c@58781000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58781000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c1>;
-                       interrupts = <0 42 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c2: i2c@58782000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58782000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c2>;
-                       interrupts = <0 43 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c3: i2c@58783000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58783000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c3>;
-                       interrupts = <0 44 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               /* i2c4 does not exist */
+&soc {
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+               interrupts = <0 174 4>, <0 175 4>;
+               cache-unified;
+               cache-size = <(768 * 1024)>;
+               cache-sets = <256>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+       };
 
-               /* chip-internal connection for DMD */
-               i2c5: i2c@58785000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58785000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 25 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+       i2c0: i2c@58780000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58780000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 41 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c0>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               /* chip-internal connection for HDMI */
-               i2c6: i2c@58786000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58786000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 26 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+       i2c1: i2c@58781000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58781000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 42 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               system-bus-controller@58c00000 {
-                       compatible = "socionext,uniphier-system-bus-controller";
-                       reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
-               };
+       i2c2: i2c@58782000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58782000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 43 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c2>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               usb2: usb@5a800100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a800100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb2>;
-                       interrupts = <0 80 4>;
-               };
+       i2c3: i2c@58783000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58783000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 44 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c3>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               usb3: usb@5a810100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a810100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb3>;
-                       interrupts = <0 81 4>;
-               };
+       /* i2c4 does not exist */
 
-               pinctrl: pinctrl@5f801000 {
-                       compatible = "socionext,ph1-pro4-pinctrl",
-                                    "syscon";
-                       reg = <0x5f801000 0xe00>;
-               };
+       /* chip-internal connection for DMD */
+       i2c5: i2c@58785000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58785000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 25 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
+       };
 
-               timer@60000200 {
-                       compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x60000200 0x20>;
-                       interrupts = <1 11 0x304>;
-                       clocks = <&arm_timer_clk>;
-               };
+       /* chip-internal connection for HDMI */
+       i2c6: i2c@58786000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58786000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 26 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
+       };
 
-               timer@60000600 {
-                       compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x60000600 0x20>;
-                       interrupts = <1 13 0x304>;
-                       clocks = <&arm_timer_clk>;
-               };
+       usb2: usb@5a800100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a800100 0x100>;
+               interrupts = <0 80 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb2>;
+       };
 
-               intc: interrupt-controller@60001000 {
-                       compatible = "arm,cortex-a9-gic";
-                       #interrupt-cells = <3>;
-                       interrupt-controller;
-                       reg = <0x60001000 0x1000>,
-                             <0x60000100 0x100>;
-               };
+       usb3: usb@5a810100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a810100 0x100>;
+               interrupts = <0 81 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb3>;
        };
 };
 
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+       compatible = "socionext,ph1-pro4-pinctrl", "syscon";
+};
index 11eb762..2f389ea 100644 (file)
@@ -42,7 +42,7 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
 
 / {
        compatible = "socionext,ph1-pro5";
                        clock-frequency = <50000000>;
                };
        };
+};
 
-       soc {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-               interrupt-parent = <&intc>;
-
-               extbus: extbus {
-                       compatible = "simple-bus";
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-               };
-
-               l2: l2-cache@500c0000 {
-                       compatible = "socionext,uniphier-system-cache";
-                       reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
-                             <0x506c0000 0x400>;
-                       interrupts = <0 190 4>, <0 191 4>;
-                       cache-unified;
-                       cache-size = <(2 * 1024 * 1024)>;
-                       cache-sets = <512>;
-                       cache-line-size = <128>;
-                       cache-level = <2>;
-                       next-level-cache = <&l3>;
-               };
-
-               l3: l3-cache@500c8000 {
-                       compatible = "socionext,uniphier-system-cache";
-                       reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
-                             <0x506c8000 0x400>;
-                       interrupts = <0 174 4>, <0 175 4>;
-                       cache-unified;
-                       cache-size = <(2 * 1024 * 1024)>;
-                       cache-sets = <512>;
-                       cache-line-size = <256>;
-                       cache-level = <3>;
-               };
-
-               serial0: serial@54006800 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006800 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart0>;
-                       interrupts = <0 33 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               serial1: serial@54006900 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006900 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart1>;
-                       interrupts = <0 35 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               serial2: serial@54006a00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006a00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart2>;
-                       interrupts = <0 37 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               serial3: serial@54006b00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006b00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart3>;
-                       interrupts = <0 177 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               i2c0: i2c@58780000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58780000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c0>;
-                       interrupts = <0 41 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c1: i2c@58781000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58781000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c1>;
-                       interrupts = <0 42 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c2: i2c@58782000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58782000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c2>;
-                       interrupts = <0 43 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c3: i2c@58783000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58783000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c3>;
-                       interrupts = <0 44 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
+&soc {
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x8>, <0x506c0000 0x400>;
+               interrupts = <0 190 4>, <0 191 4>;
+               cache-unified;
+               cache-size = <(2 * 1024 * 1024)>;
+               cache-sets = <512>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+               next-level-cache = <&l3>;
+       };
 
-               /* i2c4 does not exist */
+       l3: l3-cache@500c8000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c8000 0x2000>, <0x503c8100 0x8>, <0x506c8000 0x400>;
+               interrupts = <0 174 4>, <0 175 4>;
+               cache-unified;
+               cache-size = <(2 * 1024 * 1024)>;
+               cache-sets = <512>;
+               cache-line-size = <256>;
+               cache-level = <3>;
+       };
 
-               /* chip-internal connection for DMD */
-               i2c5: i2c@58785000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58785000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 25 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+       i2c0: i2c@58780000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58780000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 41 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c0>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               /* chip-internal connection for HDMI */
-               i2c6: i2c@58786000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58786000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 26 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+       i2c1: i2c@58781000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58781000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 42 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               system-bus-controller@58c00000 {
-                       compatible = "socionext,uniphier-system-bus-controller";
-                       reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
-               };
+       i2c2: i2c@58782000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58782000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 43 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c2>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               pinctrl: pinctrl@5f801000 {
-                       compatible = "socionext,ph1-pro5-pinctrl", "syscon";
-                       reg = <0x5f801000 0xe00>;
-               };
+       i2c3: i2c@58783000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58783000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 44 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c3>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               timer@60000200 {
-                       compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x60000200 0x20>;
-                       interrupts = <1 11 0x304>;
-                       clocks = <&arm_timer_clk>;
-               };
+       /* i2c4 does not exist */
 
-               timer@60000600 {
-                       compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x60000600 0x20>;
-                       interrupts = <1 13 0x304>;
-                       clocks = <&arm_timer_clk>;
-               };
+       /* chip-internal connection for DMD */
+       i2c5: i2c@58785000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58785000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 25 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
+       };
 
-               intc: interrupt-controller@60001000 {
-                       compatible = "arm,cortex-a9-gic";
-                       #interrupt-cells = <3>;
-                       interrupt-controller;
-                       reg = <0x60001000 0x1000>,
-                             <0x60000100 0x100>;
-               };
+       /* chip-internal connection for HDMI */
+       i2c6: i2c@58786000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58786000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 26 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
        };
 };
 
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+       compatible = "socionext,ph1-pro5-pinctrl", "syscon";
+};
index e88559b..7d06a1c 100644 (file)
@@ -42,7 +42,7 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
 
 / {
        compatible = "socionext,ph1-sld8";
                        clock-frequency = <100000000>;
                };
        };
+};
 
-       soc {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-               interrupt-parent = <&intc>;
-
-               extbus: extbus {
-                       compatible = "simple-bus";
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-               };
-
-               l2: l2-cache@500c0000 {
-                       compatible = "socionext,uniphier-system-cache";
-                       reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
-                             <0x506c0000 0x400>;
-                       interrupts = <0 174 4>, <0 175 4>;
-                       cache-unified;
-                       cache-size = <(256 * 1024)>;
-                       cache-sets = <256>;
-                       cache-line-size = <128>;
-                       cache-level = <2>;
-               };
-
-               serial0: serial@54006800 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006800 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart0>;
-                       interrupts = <0 33 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial1: serial@54006900 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006900 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart1>;
-                       interrupts = <0 35 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial2: serial@54006a00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006a00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart2>;
-                       interrupts = <0 37 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               serial3: serial@54006b00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006b00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart3>;
-                       interrupts = <0 29 4>;
-                       clocks = <&uart_clk>;
-                       fifo-size = <64>;
-               };
-
-               i2c0: i2c@58400000 {
-                       compatible = "socionext,uniphier-i2c";
-                       status = "disabled";
-                       reg = <0x58400000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c0>;
-                       interrupts = <0 41 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c1: i2c@58480000 {
-                       compatible = "socionext,uniphier-i2c";
-                       status = "disabled";
-                       reg = <0x58480000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c1>;
-                       interrupts = <0 42 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               /* chip-internal connection for DMD */
-               i2c2: i2c@58500000 {
-                       compatible = "socionext,uniphier-i2c";
-                       reg = <0x58500000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c2>;
-                       interrupts = <0 43 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <400000>;
-               };
-
-               i2c3: i2c@58580000 {
-                       compatible = "socionext,uniphier-i2c";
-                       status = "disabled";
-                       reg = <0x58580000 0x40>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c3>;
-                       interrupts = <0 44 1>;
-                       clocks = <&iobus_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               system-bus-controller@58c00000 {
-                       compatible = "socionext,uniphier-system-bus-controller";
-                       reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
-               };
+&soc {
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+               interrupts = <0 174 4>, <0 175 4>;
+               cache-unified;
+               cache-size = <(256 * 1024)>;
+               cache-sets = <256>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+       };
 
-               usb0: usb@5a800100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a800100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb0>;
-                       interrupts = <0 80 4>;
-               };
+       i2c0: i2c@58400000 {
+               compatible = "socionext,uniphier-i2c";
+               status = "disabled";
+               reg = <0x58400000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 41 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c0>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <100000>;
+       };
 
-               usb1: usb@5a810100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a810100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb1>;
-                       interrupts = <0 81 4>;
-               };
+       i2c1: i2c@58480000 {
+               compatible = "socionext,uniphier-i2c";
+               status = "disabled";
+               reg = <0x58480000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 42 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <100000>;
+       };
 
-               usb2: usb@5a820100 {
-                       compatible = "socionext,uniphier-ehci", "generic-ehci";
-                       status = "disabled";
-                       reg = <0x5a820100 0x100>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usb2>;
-                       interrupts = <0 82 4>;
-               };
+       /* chip-internal connection for DMD */
+       i2c2: i2c@58500000 {
+               compatible = "socionext,uniphier-i2c";
+               reg = <0x58500000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 43 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c2>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <400000>;
+       };
 
-               pinctrl: pinctrl@5f801000 {
-                       compatible = "socionext,ph1-sld8-pinctrl",
-                                    "syscon";
-                       reg = <0x5f801000 0xe00>;
-               };
+       i2c3: i2c@58580000 {
+               compatible = "socionext,uniphier-i2c";
+               status = "disabled";
+               reg = <0x58580000 0x40>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 44 1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c3>;
+               clocks = <&iobus_clk>;
+               clock-frequency = <100000>;
+       };
 
-               timer@60000200 {
-                       compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x60000200 0x20>;
-                       interrupts = <1 11 0x104>;
-                       clocks = <&arm_timer_clk>;
-               };
+       usb0: usb@5a800100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a800100 0x100>;
+               interrupts = <0 80 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb0>;
+       };
 
-               timer@60000600 {
-                       compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x60000600 0x20>;
-                       interrupts = <1 13 0x104>;
-                       clocks = <&arm_timer_clk>;
-               };
+       usb1: usb@5a810100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a810100 0x100>;
+               interrupts = <0 81 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb1>;
+       };
 
-               intc: interrupt-controller@60001000 {
-                       compatible = "arm,cortex-a9-gic";
-                       #interrupt-cells = <3>;
-                       interrupt-controller;
-                       reg = <0x60001000 0x1000>,
-                             <0x60000100 0x100>;
-               };
+       usb2: usb@5a820100 {
+               compatible = "socionext,uniphier-ehci", "generic-ehci";
+               status = "disabled";
+               reg = <0x5a820100 0x100>;
+               interrupts = <0 82 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb2>;
        };
 };
 
-/include/ "uniphier-pinctrl.dtsi"
+&serial3 {
+       interrupts = <0 29 4>;
+};
+
+&pinctrl {
+       compatible = "socionext,ph1-sld8-pinctrl", "syscon";
+};
index 259f1a9..6bd353f 100644 (file)
@@ -42,7 +42,7 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
 
 / {
        compatible = "socionext,proxstream2";
                        clock-frequency = <50000000>;
                };
        };
+};
 
-       soc {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-               interrupt-parent = <&intc>;
-
-               extbus: extbus {
-                       compatible = "simple-bus";
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-               };
-
-               l2: l2-cache@500c0000 {
-                       compatible = "socionext,uniphier-system-cache";
-                       reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
-                             <0x506c0000 0x400>;
-                       interrupts = <0 174 4>, <0 175 4>, <0 190 4>, <0 191 4>;
-                       cache-unified;
-                       cache-size = <(1280 * 1024)>;
-                       cache-sets = <512>;
-                       cache-line-size = <128>;
-                       cache-level = <2>;
-               };
-
-               serial0: serial@54006800 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006800 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart0>;
-                       interrupts = <0 33 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               serial1: serial@54006900 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006900 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart1>;
-                       interrupts = <0 35 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               serial2: serial@54006a00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006a00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart2>;
-                       interrupts = <0 37 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               serial3: serial@54006b00 {
-                       compatible = "socionext,uniphier-uart";
-                       status = "disabled";
-                       reg = <0x54006b00 0x40>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_uart3>;
-                       interrupts = <0 177 4>;
-                       clocks = <&uart_clk>;
-               };
-
-               i2c0: i2c@58780000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58780000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c0>;
-                       interrupts = <0 41 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c1: i2c@58781000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58781000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c1>;
-                       interrupts = <0 42 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c2: i2c@58782000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58782000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c2>;
-                       interrupts = <0 43 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               i2c3: i2c@58783000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       status = "disabled";
-                       reg = <0x58783000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_i2c3>;
-                       interrupts = <0 44 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <100000>;
-               };
-
-               /* chip-internal connection for DMD */
-               i2c4: i2c@58784000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58784000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 45 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+&soc {
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+               interrupts = <0 174 4>, <0 175 4>, <0 190 4>, <0 191 4>;
+               cache-unified;
+               cache-size = <(1280 * 1024)>;
+               cache-sets = <512>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+       };
 
-               /* chip-internal connection for STM */
-               i2c5: i2c@58785000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58785000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 25 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+       i2c0: i2c@58780000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58780000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 41 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c0>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               /* chip-internal connection for HDMI */
-               i2c6: i2c@58786000 {
-                       compatible = "socionext,uniphier-fi2c";
-                       reg = <0x58786000 0x80>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <0 26 4>;
-                       clocks = <&i2c_clk>;
-                       clock-frequency = <400000>;
-               };
+       i2c1: i2c@58781000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58781000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 42 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               system-bus-controller@58c00000 {
-                       compatible = "socionext,uniphier-system-bus-controller";
-                       reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
-               };
+       i2c2: i2c@58782000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58782000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c2>;
+               interrupts = <0 43 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               pinctrl: pinctrl@5f801000 {
-                       compatible = "socionext,proxstream2-pinctrl", "syscon";
-                       reg = <0x5f801000 0xe00>;
-               };
+       i2c3: i2c@58783000 {
+               compatible = "socionext,uniphier-fi2c";
+               status = "disabled";
+               reg = <0x58783000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 44 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c3>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <100000>;
+       };
 
-               timer@60000200 {
-                       compatible = "arm,cortex-a9-global-timer";
-                       reg = <0x60000200 0x20>;
-                       interrupts = <1 11 0xf04>;
-                       clocks = <&arm_timer_clk>;
-               };
+       /* chip-internal connection for DMD */
+       i2c4: i2c@58784000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58784000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 45 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
+       };
 
-               timer@60000600 {
-                       compatible = "arm,cortex-a9-twd-timer";
-                       reg = <0x60000600 0x20>;
-                       interrupts = <1 13 0xf04>;
-                       clocks = <&arm_timer_clk>;
-               };
+       /* chip-internal connection for STM */
+       i2c5: i2c@58785000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58785000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 25 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
+       };
 
-               intc: interrupt-controller@60001000 {
-                       compatible = "arm,cortex-a9-gic";
-                       #interrupt-cells = <3>;
-                       interrupt-controller;
-                       reg = <0x60001000 0x1000>,
-                             <0x60000100 0x100>;
-               };
+       /* chip-internal connection for HDMI */
+       i2c6: i2c@58786000 {
+               compatible = "socionext,uniphier-fi2c";
+               reg = <0x58786000 0x80>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <0 26 4>;
+               clocks = <&i2c_clk>;
+               clock-frequency = <400000>;
        };
 };
 
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+       compatible = "socionext,proxstream2-pinctrl", "syscon";
+};
index 3279bf1..6fd7efb 100644 (file)
        };
 
        core-module@10000000 {
-               compatible = "arm,core-module-versatile", "syscon";
+               compatible = "arm,core-module-versatile", "syscon", "simple-mfd";
                reg = <0x10000000 0x200>;
 
+               led@08.0 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x01>;
+                       label = "versatile:0";
+                       linux,default-trigger = "heartbeat";
+                       default-state = "on";
+               };
+               led@08.1 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x02>;
+                       label = "versatile:1";
+                       linux,default-trigger = "mmc0";
+                       default-state = "off";
+               };
+               led@08.2 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x04>;
+                       label = "versatile:2";
+                       linux,default-trigger = "cpu0";
+                       default-state = "off";
+               };
+               led@08.3 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x08>;
+                       label = "versatile:3";
+                       default-state = "off";
+               };
+               led@08.4 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x10>;
+                       label = "versatile:4";
+                       default-state = "off";
+               };
+               led@08.5 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x20>;
+                       label = "versatile:5";
+                       default-state = "off";
+               };
+               led@08.6 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x40>;
+                       label = "versatile:6";
+                       default-state = "off";
+               };
+               led@08.7 {
+                       compatible = "register-bit-led";
+                       offset = <0x08>;
+                       mask = <0x80>;
+                       label = "versatile:7";
+                       default-state = "off";
+               };
+
                /* OSC1 on AB, OSC4 on PB */
                osc1: cm_aux_osc@24M {
                        #clock-cells = <0>;
index e5949b9..6e556be 100644 (file)
        status = "okay";
 };
 
+&can0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan0>;
+       status = "disabled";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "disabled";
+};
+
 &dspi1 {
        bus-num = <1>;
        pinctrl-names = "default";
 
 &iomuxc {
        vf610-colibri {
+               pinctrl_flexcan0: can0grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB14__CAN0_RX        0x31F1
+                               VF610_PAD_PTB15__CAN0_TX        0x31F2
+                       >;
+               };
+
+               pinctrl_flexcan1: can1grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB16__CAN1_RX        0x31F1
+                               VF610_PAD_PTB17__CAN1_TX        0x31F2
+                       >;
+               };
+
                pinctrl_gpio_ext: gpio_ext {
                        fsl,pins = <
                                VF610_PAD_PTD10__GPIO_89        0x22ed /* EXT_IO_0 */
diff --git a/arch/arm/boot/dts/vf610m4-cosmic.dts b/arch/arm/boot/dts/vf610m4-cosmic.dts
new file mode 100644 (file)
index 0000000..8944a2d
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Device tree for Cosmic+ VF6xx Cortex-M4 support
+ *
+ * Copyright (C) 2015
+ *
+ * Based on vf610m4 Colibri
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "vf610m4.dtsi"
+
+/ {
+       model = "VF610 Cortex-M4";
+       compatible = "fsl,vf610m4";
+};
+
+&gpio0 {
+       status = "disabled";
+};
+
+&gpio1 {
+       status = "disabled";
+};
+
+&gpio2 {
+       status = "disabled";
+};
+
+&gpio3 {
+       status = "disabled";
+};
+
+&gpio4 {
+       status = "disabled";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&iomuxc {
+       vf610-cosmic {
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               VF610_PAD_PTA20__UART3_TX               0x21a2
+                               VF610_PAD_PTA21__UART3_RX               0x21a1
+                       >;
+               };
+       };
+};
index 3cd1b27..a9ceb5b 100644 (file)
                                status = "disabled";
                        };
 
+                       dspi2: dspi2@400ac000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,vf610-dspi";
+                               reg = <0x400ac000 0x1000>;
+                               interrupts = <69 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks VF610_CLK_DSPI2>;
+                               clock-names = "dspi";
+                               spi-num-chipselects = <2>;
+                               status = "disabled";
+                       };
+
+                       dspi3: dspi3@400ad000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,vf610-dspi";
+                               reg = <0x400ad000 0x1000>;
+                               interrupts = <70 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks VF610_CLK_DSPI3>;
+                               clock-names = "dspi";
+                               spi-num-chipselects = <2>;
+                               status = "disabled";
+                       };
+
                        adc1: adc@400bb000 {
                                compatible = "fsl,vf610-adc";
                                reg = <0x400bb000 0x1000>;
index a1a854b..e9ef539 100644 (file)
 
                sdhc@d800a000 {
                        compatible = "wm,wm8505-sdhc";
-                       reg = <0xd800a000 0x1000>;
-                       interrupts = <20 21>;
+                       reg = <0xd800a000 0x400>;
+                       interrupts = <20>, <21>;
                        clocks = <&clksdhc>;
                        bus-width = <4>;
                };
index 1a5220e..f283ff0 100644 (file)
@@ -19,7 +19,7 @@
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <0>;
@@ -33,7 +33,7 @@
                        >;
                };
 
-               cpu@1 {
+               cpu1: cpu@1 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <1>;
                        #gpio-cells = <2>;
                        clocks = <&clkc 42>;
                        gpio-controller;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
                        interrupt-parent = <&intc>;
                        interrupts = <0 20 4>;
                        reg = <0xe000a000 0x1000>;
                slcr: slcr@f8000000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
-                       compatible = "xlnx,zynq-slcr", "syscon", "simple-bus";
+                       compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
                        reg = <0xF8000000 0x1000>;
                        ranges;
                        clkc: clkc@100 {
index 5df8f81..cb64209 100644 (file)
                        label = "sw14";
                        gpios = <&gpio0 12 0>;
                        linux,code = <108>; /* down */
-                       gpio-key,wakeup;
+                       wakeup-source;
                        autorepeat;
                };
                sw13 {
                        label = "sw13";
                        gpios = <&gpio0 14 0>;
                        linux,code = <103>; /* up */
-                       gpio-key,wakeup;
+                       wakeup-source;
                        autorepeat;
                };
        };
index 2b25b60..c773157 100644 (file)
@@ -83,7 +83,7 @@ static void mcpm_cpu_die(unsigned int cpu)
 
 #endif
 
-static struct smp_operations __initdata mcpm_smp_ops = {
+static const struct smp_operations mcpm_smp_ops __initconst = {
        .smp_boot_secondary     = mcpm_boot_secondary,
        .smp_secondary_init     = mcpm_secondary_init,
 #ifdef CONFIG_HOTPLUG_CPU
index 45f4c21..e0df333 100644 (file)
@@ -84,7 +84,7 @@ static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset)
        struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
 
        /* XXX: I'm unsure, but it seems so */
-       return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1));
+       return !!(ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1)));
 }
 
 static int scoop_gpio_direction_input(struct gpio_chip *chip,
index 31cb073..72def20 100644 (file)
@@ -10,7 +10,6 @@ CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CPUSETS=y
 CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_PERF=y
 CONFIG_CFS_BANDWIDTH=y
 CONFIG_RT_GROUP_SCHED=y
@@ -18,10 +17,6 @@ CONFIG_NAMESPACES=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_XZ=y
-CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
@@ -29,6 +24,7 @@ CONFIG_EMBEDDED=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_JUMP_LABEL=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
 CONFIG_ARCH_MULTI_V6=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_BCM=y
@@ -38,7 +34,6 @@ CONFIG_AEABI=y
 CONFIG_KSM=y
 CONFIG_CLEANCACHE=y
 CONFIG_SECCOMP=y
-CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KEXEC=y
 CONFIG_CRASH_DUMP=y
 CONFIG_VFP=y
@@ -57,7 +52,6 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_NETDEVICES=y
@@ -75,19 +69,30 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_BCM2835=y
 CONFIG_SPI=y
 CONFIG_SPI_BCM2835=y
+CONFIG_SPI_BCM2835AUX=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_BCM2835_WDT=y
 CONFIG_FB=y
 CONFIG_FB_SIMPLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_BCM2835_SOC_I2S=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC2=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_ONESHOT=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -96,17 +101,19 @@ CONFIG_LEDS_TRIGGER_GPIO=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_LEDS_TRIGGER_TRANSIENT=y
 CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_BCM2835=y
 CONFIG_STAGING=y
-CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_HOST=y
+CONFIG_MAILBOX=y
+CONFIG_BCM2835_MBOX=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_BCM2835=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_FANOTIFY=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
index a7846d6..158dde8 100644 (file)
@@ -132,6 +132,5 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_UART_PL01X=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_LIBCRC32C=y
index e0841a5..24dcd2b 100644 (file)
@@ -7,7 +7,6 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_ARCH_EXYNOS3=y
@@ -44,7 +43,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_CFG80211=y
 CONFIG_RFKILL_REGULATOR=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
@@ -74,6 +72,9 @@ CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_CYAPA=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MAX77693_HAPTIC=y
+CONFIG_INPUT_MAX8997_HAPTIC=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_SAMSUNG=y
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
@@ -87,6 +88,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y
 CONFIG_I2C_GPIO=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
 CONFIG_SPI_S3C64XX=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_POWER_SUPPLY=y
@@ -95,6 +97,7 @@ CONFIG_BATTERY_MAX17040=y
 CONFIG_BATTERY_MAX17042=y
 CONFIG_CHARGER_MAX14577=y
 CONFIG_CHARGER_MAX77693=y
+CONFIG_CHARGER_MAX8997=y
 CONFIG_CHARGER_TPS65090=y
 CONFIG_SENSORS_LM90=y
 CONFIG_SENSORS_NTC_THERMISTOR=y
@@ -113,6 +116,7 @@ CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77686=y
 CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8997=y
+CONFIG_MFD_MAX8998=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_TPS65090=y
 CONFIG_REGULATOR=y
@@ -120,6 +124,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MAX14577=y
 CONFIG_REGULATOR_MAX8997=y
+CONFIG_REGULATOR_MAX8998=y
 CONFIG_REGULATOR_MAX77686=y
 CONFIG_REGULATOR_MAX77693=y
 CONFIG_REGULATOR_MAX77802=y
@@ -138,8 +143,10 @@ CONFIG_DRM_EXYNOS=y
 CONFIG_DRM_EXYNOS_FIMD=y
 CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_MIXER=y
+CONFIG_DRM_EXYNOS_DPI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
 CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
 CONFIG_EXYNOS_VIDEO=y
 CONFIG_EXYNOS_MIPI_DSI=y
@@ -176,11 +183,15 @@ CONFIG_MMC_DW=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_PWM=y
+CONFIG_LEDS_MAX77693=y
+CONFIG_LEDS_MAX8997=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MAX8997=y
 CONFIG_RTC_DRV_MAX77686=y
 CONFIG_RTC_DRV_MAX77802=y
 CONFIG_RTC_DRV_S5M=y
@@ -195,6 +206,7 @@ CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_EXTCON=y
 CONFIG_EXTCON_MAX14577=y
 CONFIG_EXTCON_MAX77693=y
+CONFIG_EXTCON_MAX8997=y
 CONFIG_IIO=y
 CONFIG_EXYNOS_ADC=y
 CONFIG_PWM=y
@@ -203,6 +215,7 @@ CONFIG_PHY_EXYNOS5250_SATA=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
+CONFIG_AUTOFS4_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -210,6 +223,7 @@ CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_CRAMFS=y
 CONFIG_ROMFS_FS=y
 CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
index 4187f69..2d5253d 100644 (file)
@@ -42,9 +42,9 @@ CONFIG_SOC_IMX6SL=y
 CONFIG_SOC_IMX6SX=y
 CONFIG_SOC_IMX6UL=y
 CONFIG_SOC_IMX7D=y
-CONFIG_SOC_LS1021A=y
 CONFIG_SOC_VF610=y
 CONFIG_PCI=y
+CONFIG_PCI_MSI=y
 CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
 CONFIG_PREEMPT_VOLUNTARY=y
@@ -224,6 +224,7 @@ CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_IMX_IPUV3_CORE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_IMX=y
 CONFIG_DRM_IMX_FB_HELPER=y
 CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
@@ -315,6 +316,8 @@ CONFIG_MXS_DMA=y
 CONFIG_FSL_EDMA=y
 CONFIG_STAGING=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_VF610_ADC=y
 CONFIG_PWM=y
 CONFIG_PWM_IMX=y
 CONFIG_EXT2_FS=y
index 03c155f..2ae00b0 100644 (file)
@@ -147,7 +147,12 @@ CONFIG_MEMORY=y
 CONFIG_ARM_PL172_MPMC=y
 CONFIG_PWM=y
 CONFIG_PWM_LPC18XX_SCT=y
+CONFIG_IIO=y
+CONFIG_MMA7455_I2C=y
+CONFIG_IIO_SYSFS_TRIGGER=y
 CONFIG_PHY_LPC18XX_USB_OTG=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LPC18XX_EEPROM=y
 CONFIG_EXT2_FS=y
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_DNOTIFY is not set
index c100b7d..9f56ca3 100644 (file)
@@ -204,7 +204,6 @@ 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
index f69a459..1f9ca47 100644 (file)
@@ -11,10 +11,32 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_KIRKWOOD=y
-CONFIG_MACH_NETXBIG=y
 CONFIG_ARCH_MXC=y
-CONFIG_SOC_IMX25=y
 CONFIG_MACH_IMX27_DT=y
+CONFIG_SOC_IMX25=y
+CONFIG_ARCH_ORION5X=y
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_RD88F5182_DT=y
+CONFIG_MACH_KUROBOX_PRO=y
+CONFIG_MACH_DNS323=y
+CONFIG_MACH_TS209=y
+CONFIG_MACH_TERASTATION_PRO2=y
+CONFIG_MACH_LINKSTATION_PRO=y
+CONFIG_MACH_LINKSTATION_LSCHL=y
+CONFIG_MACH_LINKSTATION_MINI=y
+CONFIG_MACH_LINKSTATION_LS_HGL=y
+CONFIG_MACH_TS409=y
+CONFIG_MACH_WRT350N_V2=y
+CONFIG_MACH_TS78XX=y
+CONFIG_MACH_MV2120=y
+CONFIG_MACH_D2NET_DT=y
+CONFIG_MACH_NET2BIG=y
+CONFIG_MACH_MSS2_DT=y
+CONFIG_MACH_WNR854T=y
+CONFIG_MACH_RD88F5181L_GE=y
+CONFIG_MACH_RD88F5181L_FXO=y
+CONFIG_MACH_RD88F6183AP_GE=y
 CONFIG_ARCH_U300=y
 CONFIG_PCI_MVEBU=y
 CONFIG_PREEMPT=y
@@ -38,6 +60,8 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
+CONFIG_NET_DSA=y
+CONFIG_NET_SWITCHDEV=y
 CONFIG_NET_PKTGEN=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
@@ -53,7 +77,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ORION=y
 CONFIG_BLK_DEV_LOOP=y
@@ -66,8 +89,11 @@ CONFIG_ATA=y
 CONFIG_SATA_AHCI=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6060=y
+CONFIG_NET_DSA_MV88E6131=y
 CONFIG_NET_DSA_MV88E6123_61_65=y
 CONFIG_NET_DSA_MV88E6171=y
+CONFIG_NET_DSA_MV88E6352=y
 CONFIG_MV643XX_ETH=y
 CONFIG_R8169=y
 CONFIG_MARVELL_PHY=y
@@ -92,7 +118,6 @@ CONFIG_I2C_NOMADIK=y
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_SYSFS=y
-CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_RESET_QNAP=y
@@ -105,17 +130,16 @@ CONFIG_THERMAL=y
 CONFIG_KIRKWOOD_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_ORION_WATCHDOG=y
+# CONFIG_ABX500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_FB=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_KIRKWOOD_SOC=y
-CONFIG_SND_KIRKWOOD_SOC_T5325=y
 CONFIG_SND_SOC_ALC5623=y
 CONFIG_SND_SIMPLE_CARD=y
-# CONFIG_ABX500_CORE is not set
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_HID_DRAGONRISE=y
 CONFIG_HID_GYRATION=y
 CONFIG_HID_TWINHAN=y
@@ -162,8 +186,6 @@ CONFIG_STAGING=y
 CONFIG_FB_XGI=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=y
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_UDF_FS=m
@@ -189,7 +211,6 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_MV_CESA=y
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y
index cd7b198..314f6be 100644 (file)
@@ -11,6 +11,9 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_MULTI_V7=y
+# CONFIG_ARCH_MULTI_V5 is not set
+# CONFIG_ARCH_MULTI_V4 is not set
 CONFIG_ARCH_VIRT=y
 CONFIG_ARCH_ALPINE=y
 CONFIG_ARCH_MVEBU=y
@@ -75,7 +78,7 @@ CONFIG_MACH_SPEAR1340=y
 CONFIG_ARCH_STI=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_EXYNOS5420_MCPM=y
-CONFIG_ARCH_SHMOBILE_MULTI=y
+CONFIG_ARCH_RENESAS=y
 CONFIG_ARCH_EMEV2=y
 CONFIG_ARCH_R7S72100=y
 CONFIG_ARCH_R8A73A4=y
@@ -125,6 +128,7 @@ CONFIG_KEXEC=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT_DETAILS=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_QORIQ_CPUFREQ=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_NEON=y
@@ -152,6 +156,7 @@ CONFIG_CAN_RAW=y
 CONFIG_CAN_BCM=y
 CONFIG_CAN_DEV=y
 CONFIG_CAN_AT91=m
+CONFIG_CAN_RCAR=m
 CONFIG_CAN_XILINXCAN=y
 CONFIG_CAN_MCP251X=y
 CONFIG_CAN_SUN4I=y
@@ -169,6 +174,7 @@ CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_OMAP_OCP2SCP=y
 CONFIG_SIMPLE_PM_BUS=y
+CONFIG_SUNXI_RSB=m
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
@@ -178,17 +184,21 @@ CONFIG_MTD_NAND_ATMEL=y
 CONFIG_MTD_NAND_BRCMNAND=y
 CONFIG_MTD_NAND_DAVINCI=y
 CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_FSL_QUADSPI=m
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=y
 CONFIG_AD525X_DPOT=y
 CONFIG_AD525X_DPOT_I2C=y
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ICS932S401=y
 CONFIG_ATMEL_SSC=m
+CONFIG_QCOM_COINCELL=m
 CONFIG_APDS9802ALS=y
 CONFIG_ISL29003=y
 CONFIG_EEPROM_AT24=y
-CONFIG_EEPROM_SUNXI_SID=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_SCSI_MULTI_LUN=y
@@ -202,10 +212,12 @@ CONFIG_SATA_HIGHBANK=y
 CONFIG_SATA_MV=y
 CONFIG_SATA_RCAR=y
 CONFIG_NETDEVICES=y
+CONFIG_VIRTIO_NET=y
 CONFIG_HIX5HD2_GMAC=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_MACB=y
 CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_GIANFAR=y
 CONFIG_IGB=y
 CONFIG_MV643XX_ETH=y
 CONFIG_MVNETA=y
@@ -222,6 +234,7 @@ CONFIG_MARVELL_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_BROADCOM_PHY=y
 CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_FIXED_PHY=y
 CONFIG_USB_PEGASUS=y
@@ -241,7 +254,7 @@ CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_TEGRA=y
 CONFIG_KEYBOARD_SPEAR=y
 CONFIG_KEYBOARD_ST_KEYSCAN=y
-CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_KEYBOARD_CROS_EC=m
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_MOUSE_CYAPA=m
 CONFIG_MOUSE_ELAN_I2C=y
@@ -252,8 +265,10 @@ CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_TOUCHSCREEN_SUN4I=y
 CONFIG_TOUCHSCREEN_WM97XX=m
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MAX77693_HAPTIC=m
+CONFIG_INPUT_MAX8997_HAPTIC=m
 CONFIG_INPUT_MPU3050=y
-CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_INPUT_AXP20X_PEK=m
 CONFIG_INPUT_ADXL34X=m
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
@@ -294,6 +309,8 @@ CONFIG_SERIAL_CONEXANT_DIGICOLOR=y
 CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
 CONFIG_SERIAL_ST_ASC=y
 CONFIG_SERIAL_ST_ASC_CONSOLE=y
+CONFIG_HVC_DRIVER=y
+CONFIG_VIRTIO_CONSOLE=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_DAVINCI=y
 CONFIG_I2C_MUX=y
@@ -304,8 +321,10 @@ CONFIG_I2C_AT91=m
 CONFIG_I2C_CADENCE=y
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_DIGICOLOR=m
+CONFIG_I2C_EMEV2=m
 CONFIG_I2C_GPIO=m
 CONFIG_I2C_EXYNOS5=y
+CONFIG_I2C_IMX=m
 CONFIG_I2C_MV64XXX=y
 CONFIG_I2C_RIIC=y
 CONFIG_I2C_RK3X=y
@@ -324,6 +343,7 @@ CONFIG_SPI=y
 CONFIG_SPI_ATMEL=m
 CONFIG_SPI_CADENCE=y
 CONFIG_SPI_DAVINCI=y
+CONFIG_SPI_FSL_DSPI=m
 CONFIG_SPI_OMAP24XX=y
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
@@ -340,10 +360,18 @@ CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_SPI_XILINX=y
 CONFIG_SPI_SPIDEV=y
+CONFIG_SPMI=y
 CONFIG_PINCTRL_AS3722=y
 CONFIG_PINCTRL_PALMAS=y
 CONFIG_PINCTRL_APQ8064=y
 CONFIG_PINCTRL_APQ8084=y
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM8660=y
+CONFIG_PINCTRL_MSM8960=y
+CONFIG_PINCTRL_MSM8X74=y
+CONFIG_PINCTRL_MSM8916=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_GENERIC_PLATFORM=y
 CONFIG_GPIO_DAVINCI=y
@@ -365,6 +393,7 @@ CONFIG_BATTERY_MAX17040=m
 CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_MAX14577=m
 CONFIG_CHARGER_MAX77693=m
+CONFIG_CHARGER_MAX8997=m
 CONFIG_CHARGER_TPS65090=y
 CONFIG_AXP20X_POWER=m
 CONFIG_POWER_RESET_AS3722=y
@@ -372,10 +401,13 @@ CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_RESET_GPIO_RESTART=y
 CONFIG_POWER_RESET_KEYSTONE=y
 CONFIG_POWER_RESET_RMOBILE=y
+CONFIG_POWER_AVS=y
+CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_SENSORS_LM90=y
 CONFIG_SENSORS_LM95245=y
 CONFIG_SENSORS_NTC_THERMISTOR=m
-CONFIG_THERMAL=y
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_SENSORS_INA2XX=m
 CONFIG_CPU_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=y
 CONFIG_RCAR_THERMAL=y
@@ -385,11 +417,13 @@ CONFIG_EXYNOS_THERMAL=m
 CONFIG_ST_THERMAL_SYSCFG=y
 CONFIG_ST_THERMAL_MEMMAP=y
 CONFIG_WATCHDOG=y
+CONFIG_DA9063_WATCHDOG=m
 CONFIG_XILINX_WATCHDOG=y
 CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_ORION_WATCHDOG=y
 CONFIG_ST_LPC_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
+CONFIG_IMX2_WDT=y
 CONFIG_TEGRA_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=y
 CONFIG_DIGICOLOR_WATCHDOG=y
@@ -398,27 +432,34 @@ CONFIG_MFD_AS3722=y
 CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_MFD_BCM590XX=y
 CONFIG_MFD_AXP20X=y
-CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_AXP20X_I2C=m
+CONFIG_MFD_AXP20X_RSB=m
+CONFIG_MFD_CROS_EC=m
 CONFIG_MFD_CROS_EC_I2C=m
-CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_CROS_EC_SPI=m
+CONFIG_MFD_DA9063=m
 CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77686=y
 CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8907=y
+CONFIG_MFD_MAX8997=y
 CONFIG_MFD_RK808=y
 CONFIG_MFD_PM8921_CORE=y
 CONFIG_MFD_QCOM_RPM=y
+CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_PALMAS=y
 CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TPS65218=y
 CONFIG_MFD_TPS6586X=y
 CONFIG_MFD_TPS65910=y
 CONFIG_REGULATOR_AB8500=y
 CONFIG_REGULATOR_ACT8865=y
 CONFIG_REGULATOR_AS3711=y
 CONFIG_REGULATOR_AS3722=y
-CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_AXP20X=m
 CONFIG_REGULATOR_BCM590XX=y
 CONFIG_REGULATOR_DA9210=y
 CONFIG_REGULATOR_FAN53555=y
@@ -429,6 +470,7 @@ CONFIG_POWER_RESET_SYSCON=y
 CONFIG_REGULATOR_MAX14577=m
 CONFIG_REGULATOR_MAX8907=y
 CONFIG_REGULATOR_MAX8973=y
+CONFIG_REGULATOR_MAX8997=m
 CONFIG_REGULATOR_MAX77686=y
 CONFIG_REGULATOR_MAX77693=m
 CONFIG_REGULATOR_MAX77802=m
@@ -439,9 +481,12 @@ CONFIG_REGULATOR_QCOM_RPM=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
+CONFIG_REGULATOR_TI_ABB=y
 CONFIG_REGULATOR_TPS51632=y
 CONFIG_REGULATOR_TPS62360=y
 CONFIG_REGULATOR_TPS65090=y
+CONFIG_REGULATOR_TPS65217=y
+CONFIG_REGULATOR_TPS65218=y
 CONFIG_REGULATOR_TPS6586X=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
@@ -458,6 +503,7 @@ CONFIG_SOC_CAMERA=m
 CONFIG_SOC_CAMERA_PLATFORM=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_JPU=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=m
@@ -501,13 +547,21 @@ CONFIG_SND_HDA_INPUT_BEEP=y
 CONFIG_SND_HDA_PATCH_LOADER=y
 CONFIG_SND_HDA_CODEC_REALTEK=m
 CONFIG_SND_HDA_CODEC_HDMI=m
-CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO=m
 CONFIG_SND_SOC=m
 CONFIG_SND_ATMEL_SOC=m
 CONFIG_SND_ATMEL_SOC_WM8904=m
+CONFIG_SND_SOC_FSL_SAI=m
+CONFIG_SND_SOC_ROCKCHIP=m
+CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
+CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
+CONFIG_SND_SOC_ROCKCHIP_RT5645=m
 CONFIG_SND_SOC_SH4_FSI=m
 CONFIG_SND_SOC_RCAR=m
 CONFIG_SND_SOC_RSRC_CARD=m
+CONFIG_SND_SOC_SAMSUNG=m
+CONFIG_SND_SOC_SNOW=m
+CONFIG_SND_SOC_ODROIDX2=m
 CONFIG_SND_SOC_TEGRA=m
 CONFIG_SND_SOC_TEGRA_RT5640=m
 CONFIG_SND_SOC_TEGRA_WM8753=m
@@ -517,6 +571,8 @@ CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
 CONFIG_SND_SOC_TEGRA_ALC5632=m
 CONFIG_SND_SOC_TEGRA_MAX98090=m
 CONFIG_SND_SOC_AK4642=m
+CONFIG_SND_SOC_SGTL5000=m
+CONFIG_SND_SOC_SPDIF=m
 CONFIG_SND_SOC_WM8978=m
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
@@ -546,7 +602,6 @@ CONFIG_USB_GPIO_VBUS=y
 CONFIG_USB_ISP1301=y
 CONFIG_USB_MSM_OTG=m
 CONFIG_USB_MXS_PHY=y
-CONFIG_USB_RCAR_PHY=m
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
 CONFIG_USB_ETH=m
@@ -557,6 +612,7 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_OF_ARASAN=y
 CONFIG_MMC_SDHCI_OF_AT91=y
+CONFIG_MMC_SDHCI_OF_ESDHC=m
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_TEGRA=y
@@ -569,6 +625,7 @@ CONFIG_MMC_SDHCI_ST=y
 CONFIG_MMC_OMAP=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_MMC_SDHI=y
 CONFIG_MMC_DW=y
@@ -580,8 +637,11 @@ CONFIG_MMC_SH_MMCIF=y
 CONFIG_MMC_SUNXI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=m
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_PWM=y
+CONFIG_LEDS_MAX77693=m
+CONFIG_LEDS_MAX8997=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_ONESHOT=y
@@ -601,6 +661,7 @@ CONFIG_RTC_DRV_AS3722=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_HYM8563=m
 CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_MAX8997=m
 CONFIG_RTC_DRV_MAX77686=y
 CONFIG_RTC_DRV_RK808=m
 CONFIG_RTC_DRV_MAX77802=m
@@ -613,6 +674,7 @@ CONFIG_RTC_DRV_TPS65910=y
 CONFIG_RTC_DRV_S35390A=m
 CONFIG_RTC_DRV_RX8581=m
 CONFIG_RTC_DRV_EM3027=y
+CONFIG_RTC_DRV_DA9063=m
 CONFIG_RTC_DRV_DIGICOLOR=m
 CONFIG_RTC_DRV_S5M=m
 CONFIG_RTC_DRV_S3C=m
@@ -628,10 +690,12 @@ CONFIG_DMADEVICES=y
 CONFIG_DW_DMAC=y
 CONFIG_AT_HDMAC=y
 CONFIG_AT_XDMAC=y
+CONFIG_FSL_EDMA=m
 CONFIG_MV_XOR=y
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_SH_DMAE=y
 CONFIG_RCAR_DMAC=y
+CONFIG_RENESAS_USB_DMAC=m
 CONFIG_STE_DMA40=y
 CONFIG_SIRF_DMA=y
 CONFIG_TI_EDMA=y
@@ -653,14 +717,20 @@ CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
-CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_WCNSS_CTRL=m
+CONFIG_ROCKCHIP_PM_DOMAINS=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_CHROME_PLATFORMS=y
+CONFIG_STAGING_BOARD=y
 CONFIG_CROS_EC_CHARDEV=m
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_MAX77802=m
+CONFIG_COMMON_CLK_RK808=m
 CONFIG_COMMON_CLK_S2MPS11=m
 CONFIG_APQ_MMCC_8084=y
 CONFIG_MSM_GCC_8660=y
@@ -684,6 +754,7 @@ CONFIG_AK8975=y
 CONFIG_PWM=y
 CONFIG_PWM_ATMEL=m
 CONFIG_PWM_ATMEL_TCB=m
+CONFIG_PWM_FSL_FTM=m
 CONFIG_PWM_RENESAS_TPU=y
 CONFIG_PWM_ROCKCHIP=m
 CONFIG_PWM_SAMSUNG=m
@@ -706,6 +777,8 @@ CONFIG_PHY_STIH407_USB=y
 CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_SUN9I_USB=y
 CONFIG_PHY_SAMSUNG_USB2=m
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_EXT4_FS=y
 CONFIG_AUTOFS4_FS=y
 CONFIG_MSDOS_FS=y
@@ -732,6 +805,7 @@ CONFIG_CRYPTO_DEV_TEGRA_AES=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_KEYSTONE_IRQ=y
 CONFIG_CRYPTO_DEV_SUN4I_SS=m
+CONFIG_CRYPTO_DEV_ROCKCHIP=m
 CONFIG_ARM_CRYPTO=y
 CONFIG_CRYPTO_SHA1_ARM=m
 CONFIG_CRYPTO_SHA1_ARM_NEON=m
@@ -746,3 +820,7 @@ CONFIG_CRYPTO_GHASH_ARM_CE=m
 CONFIG_CRYPTO_DEV_ATMEL_AES=m
 CONFIG_CRYPTO_DEV_ATMEL_TDES=m
 CONFIG_CRYPTO_DEV_ATMEL_SHA=m
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_PCI_LEGACY=y
+CONFIG_VIRTIO_MMIO=y
index 85d10d2..a0345e1 100644 (file)
@@ -11,6 +11,9 @@ CONFIG_KPROBES=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V6 is not set
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MV78XX0=y
 CONFIG_MACH_DB78X00_BP=y
 CONFIG_MACH_RD78X00_MASA=y
@@ -132,7 +135,6 @@ 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
index 824de49..af29780 100644 (file)
@@ -12,8 +12,29 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_KIRKWOOD=y
-CONFIG_MACH_NETXBIG=y
-# CONFIG_CPU_FEROCEON_OLD_ID is not set
+CONFIG_ARCH_ORION5X=y
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_RD88F5182_DT=y
+CONFIG_MACH_KUROBOX_PRO=y
+CONFIG_MACH_DNS323=y
+CONFIG_MACH_TS209=y
+CONFIG_MACH_TERASTATION_PRO2=y
+CONFIG_MACH_LINKSTATION_PRO=y
+CONFIG_MACH_LINKSTATION_LSCHL=y
+CONFIG_MACH_LINKSTATION_MINI=y
+CONFIG_MACH_LINKSTATION_LS_HGL=y
+CONFIG_MACH_TS409=y
+CONFIG_MACH_WRT350N_V2=y
+CONFIG_MACH_TS78XX=y
+CONFIG_MACH_MV2120=y
+CONFIG_MACH_D2NET_DT=y
+CONFIG_MACH_NET2BIG=y
+CONFIG_MACH_MSS2_DT=y
+CONFIG_MACH_WNR854T=y
+CONFIG_MACH_RD88F5181L_GE=y
+CONFIG_MACH_RD88F5181L_FXO=y
+CONFIG_MACH_RD88F6183AP_GE=y
 CONFIG_PCI_MVEBU=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
@@ -26,6 +47,7 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT_DETAILS=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
+CONFIG_ARM_KIRKWOOD_CPUIDLE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -35,6 +57,8 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
+CONFIG_NET_DSA=y
+CONFIG_NET_SWITCHDEV=y
 CONFIG_NET_PKTGEN=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
@@ -66,8 +90,11 @@ CONFIG_ATA=y
 CONFIG_SATA_AHCI=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6060=y
+CONFIG_NET_DSA_MV88E6131=y
 CONFIG_NET_DSA_MV88E6123_61_65=y
 CONFIG_NET_DSA_MV88E6171=y
+CONFIG_NET_DSA_MV88E6352=y
 CONFIG_MV643XX_ETH=y
 CONFIG_R8169=y
 CONFIG_MARVELL_PHY=y
@@ -91,7 +118,6 @@ CONFIG_I2C_MV64XXX=y
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_SYSFS=y
-CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_RESET_QNAP=y
@@ -103,16 +129,15 @@ CONFIG_SENSORS_LM85=y
 CONFIG_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_ORION_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_FB=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_KIRKWOOD_SOC=y
-CONFIG_SND_KIRKWOOD_SOC_T5325=y
 CONFIG_SND_SOC_ALC5623=y
 CONFIG_SND_SIMPLE_CARD=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_HID_DRAGONRISE=y
 CONFIG_HID_GYRATION=y
 CONFIG_HID_TWINHAN=y
@@ -159,8 +184,6 @@ CONFIG_STAGING=y
 CONFIG_FB_XGI=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=y
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_UDF_FS=m
@@ -186,7 +209,6 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_MV_CESA=y
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y
index 25ed772..4f3dfb2 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_ARCH_FOOTBRIDGE=y
 CONFIG_ARCH_NETWINDER=y
 CONFIG_LEDS=y
 CONFIG_LEDS_CPU=y
+CONFIG_DEPRECATED_PARAM_STRUCT=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=0x301"
index 8099417..5876ce7 100644 (file)
@@ -13,6 +13,9 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_BSD_DISKLABEL=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V6 is not set
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ORION5X=y
 CONFIG_ARCH_ORION5X_DT=y
 CONFIG_MACH_DB88F5281=y
@@ -159,7 +162,6 @@ 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/pxa_defconfig b/arch/arm/configs/pxa_defconfig
new file mode 100644 (file)
index 0000000..0cb724b
--- /dev/null
@@ -0,0 +1,783 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=13
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLOB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_LDM_PARTITION=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+CONFIG_MACH_PXA3XX_DT=y
+CONFIG_ARCH_LUBBOCK=y
+CONFIG_MACH_MAINSTONE=y
+CONFIG_MACH_ZYLONITE300=y
+CONFIG_MACH_ZYLONITE320=y
+CONFIG_MACH_LITTLETON=y
+CONFIG_MACH_TAVOREVB=y
+CONFIG_MACH_SAAR=y
+CONFIG_ARCH_PXA_IDP=y
+CONFIG_ARCH_VIPER=y
+CONFIG_MACH_ARCOM_ZEUS=y
+CONFIG_MACH_BALLOON3=y
+CONFIG_MACH_CSB726=y
+CONFIG_CSB726_CSB701=y
+CONFIG_MACH_ARMCORE=y
+CONFIG_MACH_EM_X270=y
+CONFIG_MACH_EXEDA=y
+CONFIG_MACH_CM_X300=y
+CONFIG_MACH_CAPC7117=y
+CONFIG_ARCH_GUMSTIX=y
+CONFIG_MACH_INTELMOTE2=y
+CONFIG_MACH_STARGATE2=y
+CONFIG_MACH_XCEP=y
+CONFIG_TRIZEPS_PXA=y
+CONFIG_MACH_TRIZEPS4WL=y
+CONFIG_MACH_LOGICPD_PXA270=y
+CONFIG_MACH_PCM027=y
+CONFIG_MACH_PCM990_BASEBOARD=y
+CONFIG_MACH_COLIBRI=y
+CONFIG_MACH_COLIBRI_PXA270_INCOME=y
+CONFIG_MACH_COLIBRI300=y
+CONFIG_MACH_COLIBRI320=y
+CONFIG_MACH_COLIBRI_EVALBOARD=y
+CONFIG_MACH_VPAC270=y
+CONFIG_MACH_H4700=y
+CONFIG_MACH_H5000=y
+CONFIG_MACH_HIMALAYA=y
+CONFIG_MACH_MAGICIAN=y
+CONFIG_MACH_MIOA701=y
+CONFIG_PXA_EZX=y
+CONFIG_MACH_MP900C=y
+CONFIG_ARCH_PXA_PALM=y
+CONFIG_MACH_RAUMFELD_RC=y
+CONFIG_MACH_RAUMFELD_CONNECTOR=y
+CONFIG_MACH_RAUMFELD_SPEAKER=y
+CONFIG_PXA_SHARPSL=y
+CONFIG_MACH_POODLE=y
+CONFIG_MACH_CORGI=y
+CONFIG_MACH_SHEPHERD=y
+CONFIG_MACH_HUSKY=y
+CONFIG_MACH_AKITA=y
+CONFIG_MACH_BORZOI=y
+CONFIG_MACH_TOSA=y
+CONFIG_TOSA_BT=m
+CONFIG_TOSA_USE_EXT_KEYCODES=y
+CONFIG_MACH_ICONTROL=y
+CONFIG_ARCH_PXA_ESERIES=y
+CONFIG_MACH_ZIPIT2=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/ram0 ro"
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPUFREQ_DT=m
+CONFIG_ARM_PXA2xx_CPUFREQ=m
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_IEEE802154=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRDA_DEBUG=y
+CONFIG_IRTTY_SIR=m
+CONFIG_PXA_FICP=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=0
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CMDLINE_PARTS=m
+CONFIG_MTD_AFS_PARTS=m
+CONFIG_MTD_OF_PARTS=m
+CONFIG_MTD_AR7_PARTS=m
+CONFIG_MTD_BLOCK=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_OTP=y
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PXA2XX=m
+CONFIG_MTD_M25P80=m
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_DOCG3=m
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_ECC_BCH=y
+CONFIG_MTD_NAND_GPIO=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
+CONFIG_MTD_NAND_SHARPSL=m
+CONFIG_MTD_NAND_PXA3xx=m
+CONFIG_MTD_NAND_CM_X270=m
+CONFIG_MTD_NAND_TMIO=m
+CONFIG_MTD_NAND_BRCMNAND=m
+CONFIG_MTD_NAND_PLATFORM=m
+CONFIG_MTD_ONENAND=m
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_ONENAND_GENERIC=m
+CONFIG_MTD_SPI_NOR=m
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=8
+CONFIG_AD525X_DPOT=m
+CONFIG_AD525X_DPOT_I2C=m
+CONFIG_ICS932S401=m
+CONFIG_APDS9802ALS=m
+CONFIG_ISL29003=m
+CONFIG_TI_DAC7512=m
+CONFIG_EEPROM_AT24=m
+CONFIG_SENSORS_LIS3_SPI=m
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=m
+CONFIG_SATA_AHCI=m
+CONFIG_SATA_AHCI_PLATFORM=m
+CONFIG_SATA_MV=m
+CONFIG_PATA_PXA=m
+CONFIG_PATA_PCMCIA=m
+CONFIG_PATA_PLATFORM=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_MACB=m
+CONFIG_DM9000=m
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+CONFIG_IGB=m
+CONFIG_KS8851=y
+CONFIG_AX88796=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_8139TOO=m
+CONFIG_R8169=m
+CONFIG_SMC91X=m
+CONFIG_SMSC911X=m
+CONFIG_STMMAC_ETH=m
+CONFIG_PHYLIB=y
+CONFIG_AT803X_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=m
+CONFIG_MICREL_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_MDIO_BITBANG=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_BRCMFMAC=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_CS=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_RT2X00=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_INPUT_FF_MEMLESS=m
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_APMPOWER=m
+CONFIG_KEYBOARD_ATKBD=m
+CONFIG_KEYBOARD_QT1070=m
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_PXA27x=m
+CONFIG_KEYBOARD_PXA930_ROTARY=m
+CONFIG_KEYBOARD_CROS_EC=m
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_CYAPA=m
+CONFIG_MOUSE_ELAN_I2C=m
+CONFIG_MOUSE_PXA930_TRKBALL=m
+CONFIG_MOUSE_NAVPOINT_PXA27x=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_DA9034=m
+CONFIG_TOUCHSCREEN_EETI=m
+CONFIG_TOUCHSCREEN_FUJITSU=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+CONFIG_TOUCHSCREEN_HTCPEN=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_UCB1400=m
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_TOUCHSCREEN_PCAP=m
+CONFIG_TOUCHSCREEN_ST1232=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPU3050=m
+CONFIG_INPUT_AXP20X_PEK=m
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
+CONFIG_INPUT_PCAP=m
+CONFIG_INPUT_ADXL34X=m
+CONFIG_SERIO=m
+CONFIG_SERIO_SA1111=m
+CONFIG_LEGACY_PTY_COUNT=8
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=7
+CONFIG_SERIAL_8250_RUNTIME_UARTS=7
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX_PCA954x=m
+CONFIG_I2C_MUX_PINCTRL=m
+CONFIG_I2C_DESIGNWARE_PLATFORM=m
+CONFIG_I2C_PXA_SLAVE=y
+CONFIG_I2C_XILINX=m
+CONFIG_I2C_CROS_EC_TUNNEL=m
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_CADENCE=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_PXA2XX=m
+CONFIG_SPI_ROCKCHIP=m
+CONFIG_SPI_XILINX=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_PPS=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_DWAPB=m
+CONFIG_GPIO_GENERIC_PLATFORM=m
+CONFIG_GPIO_MAX732X=m
+CONFIG_GPIO_PCA953X=m
+CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_TPS6586X=y
+CONFIG_GPIO_TPS65910=y
+CONFIG_GPIO_MAX7301=m
+CONFIG_POWER_SUPPLY_DEBUG=y
+CONFIG_PDA_POWER=m
+CONFIG_BATTERY_SBS=m
+CONFIG_BATTERY_DA9030=m
+CONFIG_BATTERY_MAX17040=m
+CONFIG_BATTERY_MAX17042=m
+CONFIG_CHARGER_MAX14577=m
+CONFIG_CHARGER_MAX77693=m
+CONFIG_CHARGER_TPS65090=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_MAX6650=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM95245=m
+CONFIG_SENSORS_NTC_THERMISTOR=m
+CONFIG_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_XILINX_WATCHDOG=m
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_MFD_AS3711=y
+CONFIG_MFD_BCM590XX=m
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_CROS_EC=m
+CONFIG_MFD_CROS_EC_I2C=m
+CONFIG_MFD_CROS_EC_SPI=m
+CONFIG_MFD_ASIC3=y
+CONFIG_PMIC_DA903X=y
+CONFIG_HTC_EGPIO=y
+CONFIG_HTC_PASIC3=m
+CONFIG_MFD_MAX14577=y
+CONFIG_MFD_MAX77693=y
+CONFIG_MFD_MAX8907=m
+CONFIG_EZX_PCAP=y
+CONFIG_UCB1400_CORE=m
+CONFIG_MFD_PM8921_CORE=m
+CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
+CONFIG_MFD_T7L66XB=y
+CONFIG_MFD_TC6387XB=y
+CONFIG_MFD_TC6393XB=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=m
+CONFIG_REGULATOR_USERSPACE_CONSUMER=m
+CONFIG_REGULATOR_ACT8865=m
+CONFIG_REGULATOR_AS3711=m
+CONFIG_REGULATOR_AXP20X=m
+CONFIG_REGULATOR_BCM590XX=m
+CONFIG_REGULATOR_DA903X=m
+CONFIG_REGULATOR_DA9210=m
+CONFIG_REGULATOR_FAN53555=m
+CONFIG_REGULATOR_GPIO=m
+CONFIG_REGULATOR_MAX14577=m
+CONFIG_REGULATOR_MAX8660=m
+CONFIG_REGULATOR_MAX8907=m
+CONFIG_REGULATOR_MAX8973=m
+CONFIG_REGULATOR_MAX77693=m
+CONFIG_REGULATOR_PALMAS=m
+CONFIG_REGULATOR_PCAP=m
+CONFIG_REGULATOR_PWM=m
+CONFIG_REGULATOR_S2MPS11=m
+CONFIG_REGULATOR_S5M8767=m
+CONFIG_REGULATOR_TPS51632=m
+CONFIG_REGULATOR_TPS62360=m
+CONFIG_REGULATOR_TPS65090=m
+CONFIG_REGULATOR_TPS6586X=m
+CONFIG_REGULATOR_TPS65910=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=m
+CONFIG_SOC_CAMERA_PLATFORM=m
+CONFIG_VIDEO_PXA27x=m
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_SOC_CAMERA_MT9M111=m
+CONFIG_DRM=m
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_PXA_OVERLAY=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_PXA3XX_GCU=m
+CONFIG_FB_MBX=m
+CONFIG_FB_VIRTUAL=m
+CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CORGI=m
+CONFIG_LCD_PLATFORM=m
+CONFIG_LCD_TOSA=m
+CONFIG_BACKLIGHT_PWM=m
+CONFIG_BACKLIGHT_TOSA=m
+CONFIG_FRAMEBUFFER_CONSOLE=m
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_SND_PXA2XX_AC97=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=m
+CONFIG_SND_ATMEL_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_CORGI=m
+CONFIG_SND_PXA2XX_SOC_SPITZ=m
+CONFIG_SND_PXA2XX_SOC_Z2=m
+CONFIG_SND_PXA2XX_SOC_POODLE=m
+CONFIG_SND_PXA2XX_SOC_TOSA=m
+CONFIG_SND_PXA2XX_SOC_E740=m
+CONFIG_SND_PXA2XX_SOC_E750=m
+CONFIG_SND_PXA2XX_SOC_E800=m
+CONFIG_SND_PXA2XX_SOC_EM_X270=m
+CONFIG_SND_PXA2XX_SOC_PALM27X=y
+CONFIG_SND_SOC_ZYLONITE=m
+CONFIG_SND_SOC_RAUMFELD=m
+CONFIG_SND_PXA2XX_SOC_HX4700=m
+CONFIG_SND_PXA2XX_SOC_MAGICIAN=m
+CONFIG_SND_PXA2XX_SOC_MIOA701=m
+CONFIG_SND_PXA2XX_SOC_IMOTE2=m
+CONFIG_SND_SOC_AK4642=m
+CONFIG_SND_SOC_WM8978=m
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SOUND_PRIME=m
+CONFIG_HID=m
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=m
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=m
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD_PLATFORM=m
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_DWC3=m
+CONFIG_USB_DWC2=m
+CONFIG_USB_CHIPIDEA=m
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_ISP1760=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_ISP1301=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_PXA25X=m
+CONFIG_USB_PXA27X=m
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=m
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_SDIO_UART=m
+CONFIG_MMC_PXA=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_SDHCI_PLTFM=m
+CONFIG_MMC_TMIO=m
+CONFIG_MMC_DW=m
+CONFIG_MMC_DW_EXYNOS=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_DA903X=m
+CONFIG_LEDS_PWM=m
+CONFIG_LEDS_LT3593=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DEBUG=y
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_MAX8907=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_PALMAS=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_TPS6586X=m
+CONFIG_RTC_DRV_TPS65910=m
+CONFIG_RTC_DRV_S35390A=m
+CONFIG_RTC_DRV_RX8581=m
+CONFIG_RTC_DRV_EM3027=m
+CONFIG_RTC_DRV_S5M=m
+CONFIG_RTC_DRV_V3020=m
+CONFIG_RTC_DRV_PXA=m
+CONFIG_RTC_DRV_PCAP=m
+CONFIG_DMADEVICES=y
+CONFIG_PXA_DMA=y
+CONFIG_DW_DMAC=m
+CONFIG_UIO=y
+CONFIG_CROS_EC_CHARDEV=m
+CONFIG_COMMON_CLK_S2MPS11=m
+CONFIG_PM_DEVFREQ=y
+CONFIG_EXTCON=y
+CONFIG_MEMORY=y
+CONFIG_PWM=y
+CONFIG_PWM_PXA=m
+CONFIG_PHY_SAMSUNG_USB2=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=1
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_UBIFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_WARN=0
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_TIMER_STATS=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_DEBUG_USER=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM=m
+CONFIG_CRYPTO_SHA256_ARM=m
+CONFIG_CRYPTO_SHA512_ARM=m
+CONFIG_CRYPTO_AES_ARM=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_MINI_4x6=y
index ee54a70..7bff7bf 100644 (file)
@@ -1,8 +1,10 @@
 CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS_ALL=y
@@ -22,10 +24,10 @@ CONFIG_ARCH_MSM8X60=y
 CONFIG_ARCH_MSM8960=y
 CONFIG_ARCH_MSM8974=y
 CONFIG_SMP=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
 CONFIG_CLEANCACHE=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
@@ -78,10 +80,14 @@ CONFIG_USB_USBNET=y
 # CONFIG_USB_NET_ZAURUS is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_PMIC8XXX=y
 # CONFIG_MOUSE_PS2 is not set
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8XXX_VIBRATOR=y
+CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_LEGACY_PTYS is not set
@@ -99,13 +105,18 @@ CONFIG_PINCTRL_APQ8084=y
 CONFIG_PINCTRL_IPQ8064=y
 CONFIG_PINCTRL_MSM8960=y
 CONFIG_PINCTRL_MSM8X74=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
 CONFIG_GPIOLIB=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_CHARGER_QCOM_SMBB=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_MSM=y
 CONFIG_THERMAL=y
+CONFIG_MFD_PM8921_CORE=y
 CONFIG_MFD_QCOM_RPM=y
+CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_QCOM_RPM=y
@@ -136,6 +147,7 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PM8XXX=y
 CONFIG_DMADEVICES=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_STAGING=y
@@ -149,9 +161,9 @@ CONFIG_MSM_MMCC_8974=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
-CONFIG_QCOM_SMEM=y
 CONFIG_PHY_QCOM_APQ8064_SATA=y
 CONFIG_PHY_QCOM_IPQ806X_SATA=y
 CONFIG_EXT2_FS=y
index 1da5d9e..93efdcf 100644 (file)
@@ -1,19 +1,29 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_FULL=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_REALVIEW=y
+CONFIG_REALVIEW_DT=y
 CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_EB_ARM1136=y
+CONFIG_REALVIEW_EB_ARM1176=y
+CONFIG_REALVIEW_EB_A9MP=y
 CONFIG_REALVIEW_EB_ARM11MP=y
+CONFIG_REALVIEW_EB_ARM11MP_REVB=y
 CONFIG_MACH_REALVIEW_PB11MP=y
+CONFIG_MACH_REALVIEW_PB1176=y
+CONFIG_MACH_REALVIEW_PBA8=y
+CONFIG_MACH_REALVIEW_PBX=y
 CONFIG_SMP=y
-CONFIG_HOTPLUG_CPU=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
@@ -30,28 +40,24 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
+CONFIG_MTD_AFS_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ROM=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_ARM_CHARLCD=y
 CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_SMSC_PHY=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_VERSATILE=y
@@ -70,8 +76,8 @@ CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 # CONFIG_SND_DRIVERS is not set
 CONFIG_SND_ARMAACI=y
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_ISP1760=y
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
@@ -87,17 +93,13 @@ CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
index d02e9d9..8f56fb3 100644 (file)
@@ -1,18 +1,26 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_REALVIEW=y
+CONFIG_REALVIEW_DT=y
 CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_EB_ARM1136=y
+CONFIG_REALVIEW_EB_ARM1176=y
+CONFIG_REALVIEW_EB_A9MP=y
 CONFIG_REALVIEW_EB_ARM11MP=y
+CONFIG_REALVIEW_EB_ARM11MP_REVB=y
 CONFIG_MACH_REALVIEW_PB11MP=y
 CONFIG_MACH_REALVIEW_PB1176=y
+CONFIG_MACH_REALVIEW_PBA8=y
+CONFIG_MACH_REALVIEW_PBX=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
@@ -29,28 +37,24 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
+CONFIG_MTD_AFS_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ROM=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_ARM_CHARLCD=y
 CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_SMSC_PHY=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_VERSATILE=y
@@ -69,8 +73,8 @@ CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 # CONFIG_SND_DRIVERS is not set
 CONFIG_SND_ARMAACI=y
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_ISP1760=y
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
@@ -86,17 +90,13 @@ CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
index e2f9fa5..e0f6693 100644 (file)
@@ -5,6 +5,8 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MULTI_V6=y
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_S3C64XX=y
 CONFIG_S3C_BOOT_ERROR_RESET=y
 CONFIG_MACH_SMDK6400=y
index 63f7e6c..c11bab7 100644 (file)
@@ -129,6 +129,9 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_SAMA5D4_WATCHDOG=y
 CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
index 3aef019..9697383 100644 (file)
@@ -2,14 +2,13 @@ CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
-CONFIG_ARCH_SHMOBILE_MULTI=y
+CONFIG_ARCH_RENESAS=y
 CONFIG_ARCH_EMEV2=y
 CONFIG_ARCH_R7S72100=y
 CONFIG_ARCH_R8A73A4=y
@@ -53,6 +52,8 @@ CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
+CONFIG_CAN=y
+CONFIG_CAN_RCAR=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -99,6 +100,7 @@ CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=20
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_EMEV2=y
 CONFIG_I2C_GPIO=y
 CONFIG_I2C_RIIC=y
 CONFIG_I2C_SH_MOBILE=y
@@ -135,6 +137,7 @@ CONFIG_SOC_CAMERA=y
 CONFIG_SOC_CAMERA_PLATFORM=y
 CONFIG_VIDEO_RCAR_VIN=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_JPU=y
 CONFIG_VIDEO_RENESAS_VSP1=y
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=y
@@ -150,6 +153,7 @@ CONFIG_FB_SH_MOBILE_MERAM=y
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
@@ -163,7 +167,6 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_R8A66597_HCD=y
 CONFIG_USB_RENESAS_USBHS=y
-CONFIG_USB_RCAR_PHY=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=y
 CONFIG_USB_ETH=y
@@ -177,9 +180,13 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_RS5C372=y
 CONFIG_RTC_DRV_S35390A=y
 CONFIG_RTC_DRV_RX8581=y
+CONFIG_RTC_DRV_DA9063=y
 CONFIG_DMADEVICES=y
 CONFIG_SH_DMAE=y
 CONFIG_RCAR_DMAC=y
+CONFIG_RENESAS_USB_DMAC=y
+CONFIG_STAGING=y
+CONFIG_STAGING_BOARD=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_IIO=y
 CONFIG_AK8975=y
@@ -199,6 +206,7 @@ CONFIG_NFS_V4_1=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_ARM_UNWIND is not set
index 8128b93..f7f4e2e 100644 (file)
@@ -36,7 +36,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-CONFIG_IPV6=y
 CONFIG_NETWORK_PHY_TIMESTAMPING=y
 CONFIG_VLAN_8021Q=y
 CONFIG_VLAN_8021Q_GVRP=y
@@ -57,7 +56,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_STMMAC_ETH=y
-CONFIG_DWMAC_SOCFPGA=y
 CONFIG_MICREL_PHY=y
 CONFIG_INPUT_EVDEV=y
 # CONFIG_SERIO_SERPORT is not set
@@ -83,7 +81,8 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_USB=y
 CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_HOST=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_GADGET=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
 CONFIG_FPGA=y
@@ -92,7 +91,6 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT3_FS=y
-CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_NTFS_FS=y
 CONFIG_NTFS_RW=y
index b503a89..a9a81a7 100644 (file)
@@ -11,14 +11,12 @@ CONFIG_SMP=y
 CONFIG_NR_CPUS=8
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_VFP=y
 CONFIG_NEON=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -37,7 +35,6 @@ CONFIG_CAN_SUN4I=y
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_EEPROM_SUNXI_SID=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 CONFIG_AHCI_SUNXI=y
@@ -61,13 +58,12 @@ CONFIG_STMMAC_ETH=y
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_KEYBOARD_SUN4I_LRADC=y
 # CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_KEYBOARD_SUN4I_LRADC=y
 CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
@@ -90,6 +86,8 @@ CONFIG_CPU_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
 CONFIG_MFD_AXP20X=y
+CONFIG_MFD_AXP20X_I2C=y
+CONFIG_MFD_AXP20X_RSB=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_AXP20X=y
@@ -124,6 +122,8 @@ CONFIG_PWM=y
 CONFIG_PWM_SUN4I=y
 CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_SUN9I_USB=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
index ea49d37..295408e 100644 (file)
@@ -1,13 +1,15 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_VERSATILE=y
-CONFIG_MACH_VERSATILE_AB=y
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -47,9 +49,12 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_VERSATILE=y
+CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_MFD_SYSCON=y
 CONFIG_FB=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -59,13 +64,15 @@ CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_ARMAACI=m
 CONFIG_MMC=y
-CONFIG_MMC_ARMMMCI=m
+CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_VERSATILE=y
+CONFIG_LEDS_SYSCON=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
 CONFIG_EXT2_FS=y
 CONFIG_VFAT_FS=m
 CONFIG_JFFS2_FS=y
@@ -82,6 +89,5 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_UART_PL01X=y
 CONFIG_FONTS=y
 CONFIG_FONT_ACORN_8x8=y
index b200bb0..ab683fb 100644 (file)
@@ -83,7 +83,6 @@ CONFIG_MMC=y
 CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
index 85e374f..b23c6c8 100644 (file)
@@ -228,10 +228,26 @@ static inline int cpu_is_xsc3(void)
 }
 #endif
 
-#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
-#define        cpu_is_xscale() 0
+#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) && \
+    !defined(CONFIG_CPU_MOHAWK)
+#define        cpu_is_xscale_family() 0
 #else
-#define        cpu_is_xscale() 1
+static inline int cpu_is_xscale_family(void)
+{
+       unsigned int id;
+       id = read_cpuid_id() & 0xffffe000;
+
+       switch (id) {
+       case 0x69052000: /* Intel XScale 1 */
+       case 0x69054000: /* Intel XScale 2 */
+       case 0x69056000: /* Intel XScale 3 */
+       case 0x56056000: /* Marvell XScale 3 */
+       case 0x56158000: /* Marvell Mohawk */
+               return 1;
+       }
+
+       return 0;
+}
 #endif
 
 /*
index 662c7bd..e1f0776 100644 (file)
@@ -5,9 +5,9 @@
 #include <asm/compiler.h>
 
 /*
- * The semantics of do_div() are:
+ * The semantics of __div64_32() are:
  *
- * uint32_t do_div(uint64_t *n, uint32_t base)
+ * uint32_t __div64_32(uint64_t *n, uint32_t base)
  * {
  *     uint32_t remainder = *n % base;
  *     *n = *n / base;
@@ -16,8 +16,9 @@
  *
  * In other words, a 64-bit dividend with a 32-bit divisor producing
  * a 64-bit result and a 32-bit remainder.  To accomplish this optimally
- * we call a special __do_div64 helper with completely non standard
- * calling convention for arguments and results (beware).
+ * we override the generic version in lib/div64.c to call our __do_div64
+ * assembly implementation with completely non standard calling convention
+ * for arguments and results (beware).
  */
 
 #ifdef __ARMEB__
 #define __xh "r1"
 #endif
 
-#define __do_div_asm(n, base)                                  \
-({                                                             \
-       register unsigned int __base      asm("r4") = base;     \
-       register unsigned long long __n   asm("r0") = n;        \
-       register unsigned long long __res asm("r2");            \
-       register unsigned int __rem       asm(__xh);            \
-       asm(    __asmeq("%0", __xh)                             \
-               __asmeq("%1", "r2")                             \
-               __asmeq("%2", "r0")                             \
-               __asmeq("%3", "r4")                             \
-               "bl     __do_div64"                             \
-               : "=r" (__rem), "=r" (__res)                    \
-               : "r" (__n), "r" (__base)                       \
-               : "ip", "lr", "cc");                            \
-       n = __res;                                              \
-       __rem;                                                  \
-})
-
-#if __GNUC__ < 4 || !defined(CONFIG_AEABI)
+static inline uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+       register unsigned int __base      asm("r4") = base;
+       register unsigned long long __n   asm("r0") = *n;
+       register unsigned long long __res asm("r2");
+       register unsigned int __rem       asm(__xh);
+       asm(    __asmeq("%0", __xh)
+               __asmeq("%1", "r2")
+               __asmeq("%2", "r0")
+               __asmeq("%3", "r4")
+               "bl     __do_div64"
+               : "=r" (__rem), "=r" (__res)
+               : "r" (__n), "r" (__base)
+               : "ip", "lr", "cc");
+       *n = __res;
+       return __rem;
+}
+#define __div64_32 __div64_32
+
+#if !defined(CONFIG_AEABI)
 
 /*
- * gcc versions earlier than 4.0 are simply too problematic for the
- * optimized implementation below. First there is gcc PR 15089 that
- * tend to trig on more complex constructs, spurious .global __udivsi3
- * are inserted even if none of those symbols are referenced in the
- * generated code, and those gcc versions are not able to do constant
- * propagation on long long values anyway.
+ * In OABI configurations, some uses of the do_div function
+ * cause gcc to run out of registers. To work around that,
+ * we can force the use of the out-of-line version for
+ * configurations that build a OABI kernel.
  */
-#define do_div(n, base) __do_div_asm(n, base)
-
-#elif __GNUC__ >= 4
+#define do_div(n, base) __div64_32(&(n), base)
 
-#include <asm/bug.h>
+#else
 
 /*
- * If the divisor happens to be constant, we determine the appropriate
- * inverse at compile time to turn the division into a few inline
- * multiplications instead which is much faster. And yet only if compiling
- * for ARMv4 or higher (we need umull/umlal) and if the gcc version is
- * sufficiently recent to perform proper long long constant propagation.
- * (It is unfortunate that gcc doesn't perform all this internally.)
+ * gcc versions earlier than 4.0 are simply too problematic for the
+ * __div64_const32() code in asm-generic/div64.h. First there is
+ * gcc PR 15089 that tend to trig on more complex constructs, spurious
+ * .global __udivsi3 are inserted even if none of those symbols are
+ * referenced in the generated code, and those gcc versions are not able
+ * to do constant propagation on long long values anyway.
  */
-#define do_div(n, base)                                                        \
-({                                                                     \
-       unsigned int __r, __b = (base);                                 \
-       if (!__builtin_constant_p(__b) || __b == 0 ||                   \
-           (__LINUX_ARM_ARCH__ < 4 && (__b & (__b - 1)) != 0)) {       \
-               /* non-constant divisor (or zero): slow path */         \
-               __r = __do_div_asm(n, __b);                             \
-       } else if ((__b & (__b - 1)) == 0) {                            \
-               /* Trivial: __b is constant and a power of 2 */         \
-               /* gcc does the right thing with this code.  */         \
-               __r = n;                                                \
-               __r &= (__b - 1);                                       \
-               n /= __b;                                               \
-       } else {                                                        \
-               /* Multiply by inverse of __b: n/b = n*(p/b)/p       */ \
-               /* We rely on the fact that most of this code gets   */ \
-               /* optimized away at compile time due to constant    */ \
-               /* propagation and only a couple inline assembly     */ \
-               /* instructions should remain. Better avoid any      */ \
-               /* code construct that might prevent that.           */ \
-               unsigned long long __res, __x, __t, __m, __n = n;       \
-               unsigned int __c, __p, __z = 0;                         \
-               /* preserve low part of n for reminder computation */   \
-               __r = __n;                                              \
-               /* determine number of bits to represent __b */         \
-               __p = 1 << __div64_fls(__b);                            \
-               /* compute __m = ((__p << 64) + __b - 1) / __b */       \
-               __m = (~0ULL / __b) * __p;                              \
-               __m += (((~0ULL % __b + 1) * __p) + __b - 1) / __b;     \
-               /* compute __res = __m*(~0ULL/__b*__b-1)/(__p << 64) */ \
-               __x = ~0ULL / __b * __b - 1;                            \
-               __res = (__m & 0xffffffff) * (__x & 0xffffffff);        \
-               __res >>= 32;                                           \
-               __res += (__m & 0xffffffff) * (__x >> 32);              \
-               __t = __res;                                            \
-               __res += (__x & 0xffffffff) * (__m >> 32);              \
-               __t = (__res < __t) ? (1ULL << 32) : 0;                 \
-               __res = (__res >> 32) + __t;                            \
-               __res += (__m >> 32) * (__x >> 32);                     \
-               __res /= __p;                                           \
-               /* Now sanitize and optimize what we've got. */         \
-               if (~0ULL % (__b / (__b & -__b)) == 0) {                \
-                       /* those cases can be simplified with: */       \
-                       __n /= (__b & -__b);                            \
-                       __m = ~0ULL / (__b / (__b & -__b));             \
-                       __p = 1;                                        \
-                       __c = 1;                                        \
-               } else if (__res != __x / __b) {                        \
-                       /* We can't get away without a correction    */ \
-                       /* to compensate for bit truncation errors.  */ \
-                       /* To avoid it we'd need an additional bit   */ \
-                       /* to represent __m which would overflow it. */ \
-                       /* Instead we do m=p/b and n/b=(n*m+m)/p.    */ \
-                       __c = 1;                                        \
-                       /* Compute __m = (__p << 64) / __b */           \
-                       __m = (~0ULL / __b) * __p;                      \
-                       __m += ((~0ULL % __b + 1) * __p) / __b;         \
-               } else {                                                \
-                       /* Reduce __m/__p, and try to clear bit 31   */ \
-                       /* of __m when possible otherwise that'll    */ \
-                       /* need extra overflow handling later.       */ \
-                       unsigned int __bits = -(__m & -__m);            \
-                       __bits |= __m >> 32;                            \
-                       __bits = (~__bits) << 1;                        \
-                       /* If __bits == 0 then setting bit 31 is     */ \
-                       /* unavoidable.  Simply apply the maximum    */ \
-                       /* possible reduction in that case.          */ \
-                       /* Otherwise the MSB of __bits indicates the */ \
-                       /* best reduction we should apply.           */ \
-                       if (!__bits) {                                  \
-                               __p /= (__m & -__m);                    \
-                               __m /= (__m & -__m);                    \
-                       } else {                                        \
-                               __p >>= __div64_fls(__bits);            \
-                               __m >>= __div64_fls(__bits);            \
-                       }                                               \
-                       /* No correction needed. */                     \
-                       __c = 0;                                        \
-               }                                                       \
-               /* Now we have a combination of 2 conditions:        */ \
-               /* 1) whether or not we need a correction (__c), and */ \
-               /* 2) whether or not there might be an overflow in   */ \
-               /*    the cross product (__m & ((1<<63) | (1<<31)))  */ \
-               /* Select the best insn combination to perform the   */ \
-               /* actual __m * __n / (__p << 64) operation.         */ \
-               if (!__c) {                                             \
-                       asm (   "umull  %Q0, %R0, %Q1, %Q2\n\t"         \
-                               "mov    %Q0, #0"                        \
-                               : "=&r" (__res)                         \
-                               : "r" (__m), "r" (__n)                  \
-                               : "cc" );                               \
-               } else if (!(__m & ((1ULL << 63) | (1ULL << 31)))) {    \
-                       __res = __m;                                    \
-                       asm (   "umlal  %Q0, %R0, %Q1, %Q2\n\t"         \
-                               "mov    %Q0, #0"                        \
-                               : "+&r" (__res)                         \
-                               : "r" (__m), "r" (__n)                  \
-                               : "cc" );                               \
-               } else {                                                \
-                       asm (   "umull  %Q0, %R0, %Q1, %Q2\n\t"         \
-                               "cmn    %Q0, %Q1\n\t"                   \
-                               "adcs   %R0, %R0, %R1\n\t"              \
-                               "adc    %Q0, %3, #0"                    \
-                               : "=&r" (__res)                         \
-                               : "r" (__m), "r" (__n), "r" (__z)       \
-                               : "cc" );                               \
-               }                                                       \
-               if (!(__m & ((1ULL << 63) | (1ULL << 31)))) {           \
-                       asm (   "umlal  %R0, %Q0, %R1, %Q2\n\t"         \
-                               "umlal  %R0, %Q0, %Q1, %R2\n\t"         \
-                               "mov    %R0, #0\n\t"                    \
-                               "umlal  %Q0, %R0, %R1, %R2"             \
-                               : "+&r" (__res)                         \
-                               : "r" (__m), "r" (__n)                  \
-                               : "cc" );                               \
-               } else {                                                \
-                       asm (   "umlal  %R0, %Q0, %R2, %Q3\n\t"         \
-                               "umlal  %R0, %1, %Q2, %R3\n\t"          \
-                               "mov    %R0, #0\n\t"                    \
-                               "adds   %Q0, %1, %Q0\n\t"               \
-                               "adc    %R0, %R0, #0\n\t"               \
-                               "umlal  %Q0, %R0, %R2, %R3"             \
-                               : "+&r" (__res), "+&r" (__z)            \
-                               : "r" (__m), "r" (__n)                  \
-                               : "cc" );                               \
-               }                                                       \
-               __res /= __p;                                           \
-               /* The reminder can be computed with 32-bit regs     */ \
-               /* only, and gcc is good at that.                    */ \
-               {                                                       \
-                       unsigned int __res0 = __res;                    \
-                       unsigned int __b0 = __b;                        \
-                       __r -= __res0 * __b0;                           \
-               }                                                       \
-               /* BUG_ON(__r >= __b || __res * __b + __r != n); */     \
-               n = __res;                                              \
-       }                                                               \
-       __r;                                                            \
-})
-
-/* our own fls implementation to make sure constant propagation is fine */
-#define __div64_fls(bits)                                              \
-({                                                                     \
-       unsigned int __left = (bits), __nr = 0;                         \
-       if (__left & 0xffff0000) __nr += 16, __left >>= 16;             \
-       if (__left & 0x0000ff00) __nr +=  8, __left >>=  8;             \
-       if (__left & 0x000000f0) __nr +=  4, __left >>=  4;             \
-       if (__left & 0x0000000c) __nr +=  2, __left >>=  2;             \
-       if (__left & 0x00000002) __nr +=  1;                            \
-       __nr;                                                           \
-})
+
+#define __div64_const32_is_OK (__GNUC__ >= 4)
+
+static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias)
+{
+       unsigned long long res;
+       unsigned int tmp = 0;
+
+       if (!bias) {
+               asm (   "umull  %Q0, %R0, %Q1, %Q2\n\t"
+                       "mov    %Q0, #0"
+                       : "=&r" (res)
+                       : "r" (m), "r" (n)
+                       : "cc");
+       } else if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
+               res = m;
+               asm (   "umlal  %Q0, %R0, %Q1, %Q2\n\t"
+                       "mov    %Q0, #0"
+                       : "+&r" (res)
+                       : "r" (m), "r" (n)
+                       : "cc");
+       } else {
+               asm (   "umull  %Q0, %R0, %Q1, %Q2\n\t"
+                       "cmn    %Q0, %Q1\n\t"
+                       "adcs   %R0, %R0, %R1\n\t"
+                       "adc    %Q0, %3, #0"
+                       : "=&r" (res)
+                       : "r" (m), "r" (n), "r" (tmp)
+                       : "cc");
+       }
+
+       if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
+               asm (   "umlal  %R0, %Q0, %R1, %Q2\n\t"
+                       "umlal  %R0, %Q0, %Q1, %R2\n\t"
+                       "mov    %R0, #0\n\t"
+                       "umlal  %Q0, %R0, %R1, %R2"
+                       : "+&r" (res)
+                       : "r" (m), "r" (n)
+                       : "cc");
+       } else {
+               asm (   "umlal  %R0, %Q0, %R2, %Q3\n\t"
+                       "umlal  %R0, %1, %Q2, %R3\n\t"
+                       "mov    %R0, #0\n\t"
+                       "adds   %Q0, %1, %Q0\n\t"
+                       "adc    %R0, %R0, #0\n\t"
+                       "umlal  %Q0, %R0, %R2, %R3"
+                       : "+&r" (res), "+&r" (tmp)
+                       : "r" (m), "r" (n)
+                       : "cc");
+       }
+
+       return res;
+}
+#define __arch_xprod_64 __arch_xprod_64
+
+#include <asm-generic/div64.h>
 
 #endif
 
index ccb3aa6..6ad1ced 100644 (file)
@@ -41,13 +41,6 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
 #define HAVE_ARCH_DMA_SUPPORTED 1
 extern int dma_supported(struct device *dev, u64 mask);
 
-/*
- * Note that while the generic code provides dummy dma_{alloc,free}_noncoherent
- * implementations, we don't provide a dma_cache_sync function so drivers using
- * this API are highlighted with build warnings.
- */
-#include <asm-generic/dma-mapping-common.h>
-
 #ifdef __arch_page_to_dma
 #error Please update to __arch_pfn_to_dma
 #endif
index b4c6d99..e1b825d 100644 (file)
@@ -14,7 +14,7 @@
 #ifndef __ASM_ARM_PSCI_H
 #define __ASM_ARM_PSCI_H
 
-extern struct smp_operations psci_smp_ops;
+extern const struct smp_operations psci_smp_ops;
 
 #if defined(CONFIG_SMP) && defined(CONFIG_ARM_PSCI)
 bool psci_smp_available(void);
diff --git a/arch/arm/include/debug/dc21285.S b/arch/arm/include/debug/dc21285.S
new file mode 100644 (file)
index 0000000..02247f3
--- /dev/null
@@ -0,0 +1,42 @@
+/* arch/arm/mach-footbridge/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 <asm/hardware/dec21285.h>
+
+#include <mach/hardware.h>
+       /* For EBSA285 debugging */
+               .equ    dc21285_high, ARMCSR_BASE & 0xff000000
+               .equ    dc21285_low,  ARMCSR_BASE & 0x00ffffff
+
+               .macro  addruart, rp, rv, tmp
+               .if     dc21285_low
+               mov     \rp, #dc21285_low
+               .else
+               mov     \rp, #0
+               .endif
+               orr     \rv, \rp, #dc21285_high
+               orr     \rp, \rp, #0x42000000
+               .endm
+
+               .macro  senduart,rd,rx
+               str     \rd, [\rx, #0x160]      @ UARTDR
+               .endm
+
+               .macro  busyuart,rd,rx
+1001:          ldr     \rd, [\rx, #0x178]      @ UARTFLG
+               tst     \rd, #1 << 3
+               bne     1001b
+               .endm
+
+               .macro  waituart,rd,rx
+               .endm
index 65addcb..2e26016 100644 (file)
@@ -211,7 +211,7 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
 {
        const struct machine_desc *mdesc, *mdesc_best = NULL;
 
-#ifdef CONFIG_ARCH_MULTIPLATFORM
+#if defined(CONFIG_ARCH_MULTIPLATFORM) || defined(CONFIG_ARM_SINGLE_ARMV7M)
        DT_MACHINE_START(GENERIC_DT, "Generic DT based system")
        MACHINE_END
 
index 9d479b2..cb3fcae 100644 (file)
@@ -120,7 +120,7 @@ bool __init psci_smp_available(void)
        return (psci_ops.cpu_on != NULL);
 }
 
-struct smp_operations __initdata psci_smp_ops = {
+const struct smp_operations psci_smp_ops __initconst = {
        .smp_boot_secondary     = psci_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_disable            = psci_cpu_disable,
index bdbb885..77a2eef 100644 (file)
@@ -15,6 +15,9 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <asm/thread_notify.h>
+#include <asm/cputype.h>
+
+asm("  .arch armv5te\n");
 
 static inline void dsp_save_state(u32 *state)
 {
@@ -152,6 +155,10 @@ static int __init xscale_cp0_init(void)
 {
        u32 cp_access;
 
+       /* do not attempt to probe iwmmxt on non-xscale family CPUs */
+       if (!cpu_is_xscale_family())
+               return 0;
+
        cp_access = xscale_cp_access_read() & ~3;
        xscale_cp_access_write(cp_access | 1);
 
index 2c44b93..5c2d54f 100644 (file)
@@ -1,5 +1,6 @@
 config ARCH_ALPINE
-       bool "Annapurna Labs Alpine platform" if ARCH_MULTI_V7
+       bool "Annapurna Labs Alpine platform"
+       depends on ARCH_MULTI_V7
        select ARM_AMBA
        select ARM_GIC
        select GENERIC_IRQ_CHIP
index f78429f..dd77ea2 100644 (file)
@@ -42,7 +42,7 @@ static void __init alpine_smp_prepare_cpus(unsigned int max_cpus)
        alpine_cpu_pm_init();
 }
 
-static struct smp_operations alpine_smp_ops __initdata = {
+static const struct smp_operations alpine_smp_ops __initconst = {
        .smp_prepare_cpus       = alpine_smp_prepare_cpus,
        .smp_boot_secondary     = alpine_boot_secondary,
 };
index 28656c2..23be2e4 100644 (file)
@@ -8,7 +8,8 @@ menuconfig ARCH_AT91
 
 if ARCH_AT91
 config SOC_SAMA5D2
-       bool "SAMA5D2 family" if ARCH_MULTI_V7
+       bool "SAMA5D2 family"
+       depends on ARCH_MULTI_V7
        select SOC_SAMA5
        select CACHE_L2X0
        select HAVE_FB_ATMEL
@@ -21,7 +22,8 @@ config SOC_SAMA5D2
          Select this if ou are using one of Atmel's SAMA5D2 family SoC.
 
 config SOC_SAMA5D3
-       bool "SAMA5D3 family" if ARCH_MULTI_V7
+       bool "SAMA5D3 family"
+       depends on ARCH_MULTI_V7
        select SOC_SAMA5
        select HAVE_FB_ATMEL
        select HAVE_AT91_UTMI
@@ -33,7 +35,8 @@ config SOC_SAMA5D3
          This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
 
 config SOC_SAMA5D4
-       bool "SAMA5D4 family" if ARCH_MULTI_V7
+       bool "SAMA5D4 family"
+       depends on ARCH_MULTI_V7
        select SOC_SAMA5
        select CACHE_L2X0
        select HAVE_FB_ATMEL
@@ -46,7 +49,8 @@ config SOC_SAMA5D4
          Select this if you are using one of Atmel's SAMA5D4 family SoC.
 
 config SOC_AT91RM9200
-       bool "AT91RM9200" if ARCH_MULTI_V4T
+       bool "AT91RM9200"
+       depends on ARCH_MULTI_V4T
        select ATMEL_AIC_IRQ
        select ATMEL_ST
        select CPU_ARM920T
@@ -59,7 +63,8 @@ config SOC_AT91RM9200
          Select this if you are using Atmel's AT91RM9200 SoC.
 
 config SOC_AT91SAM9
-       bool "AT91SAM9" if ARCH_MULTI_V5
+       bool "AT91SAM9"
+       depends on ARCH_MULTI_V5
        select ATMEL_AIC_IRQ
        select ATMEL_SDRAMC
        select CPU_ARM926T
index 8be7e0a..6c6d5e7 100644 (file)
@@ -1,5 +1,6 @@
 config ARCH_AXXIA
-       bool "LSI Axxia platforms" if (ARCH_MULTI_V7 && ARM_LPAE)
+       bool "LSI Axxia platforms"
+       depends on ARCH_MULTI_V7 && ARM_LPAE
        select ARCH_DMA_ADDR_T_64BIT
        select ARM_AMBA
        select ARM_GIC
index 959d4df..ffbd71d 100644 (file)
@@ -82,7 +82,7 @@ static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
        }
 }
 
-static struct smp_operations axxia_smp_ops __initdata = {
+static const struct smp_operations axxia_smp_ops __initconst = {
        .smp_prepare_cpus       = axxia_smp_prepare_cpus,
        .smp_boot_secondary     = axxia_boot_secondary,
 };
index 8c53c55..7ef1214 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_BCM
-       bool "Broadcom SoC Support" if ARCH_MULTI_V6_V7
+       bool "Broadcom SoC Support"
+       depends on ARCH_MULTI_V6_V7
        help
          This enables support for Broadcom ARM based SoC chips
 
@@ -27,7 +28,8 @@ config ARCH_BCM_IPROC
          Currently supported SoCs are Cygnus.
 
 config ARCH_BCM_CYGNUS
-       bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
+       bool "Broadcom Cygnus Support"
+       depends on ARCH_MULTI_V7
        select ARCH_BCM_IPROC
        help
          Enable support for the Cygnus family,
@@ -36,10 +38,13 @@ config ARCH_BCM_CYGNUS
          BCM58300, BCM58302, BCM58303, BCM58305.
 
 config ARCH_BCM_NSP
-       bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7
+       bool "Broadcom Northstar Plus SoC Support"
+       depends on ARCH_MULTI_V7
        select ARCH_BCM_IPROC
        select ARM_ERRATA_754322
        select ARM_ERRATA_775420
+       select ARM_ERRATA_764369 if SMP
+       select HAVE_SMP
        help
          Support for Broadcom Northstar Plus SoC.
          Broadcom Northstar Plus family of SoCs are used for switching control
@@ -50,8 +55,14 @@ config ARCH_BCM_NSP
          NAND flash, SATA and several other IO controllers.
 
 config ARCH_BCM_5301X
-       bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
+       bool "Broadcom BCM470X / BCM5301X ARM SoC"
+       depends on ARCH_MULTI_V7
        select ARCH_BCM_IPROC
+       select ARM_ERRATA_754322
+       select ARM_ERRATA_775420
+       select ARM_ERRATA_764369 if SMP
+       select HAVE_SMP
+
        help
          Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
 
@@ -82,7 +93,8 @@ config ARCH_BCM_MOBILE
          This enables support for systems based on Broadcom mobile SoCs.
 
 config ARCH_BCM_281XX
-       bool "Broadcom BCM281XX SoC family" if ARCH_MULTI_V7
+       bool "Broadcom BCM281XX SoC family"
+       depends on ARCH_MULTI_V7
        select ARCH_BCM_MOBILE
        select HAVE_SMP
        help
@@ -91,7 +103,8 @@ config ARCH_BCM_281XX
          variants.
 
 config ARCH_BCM_21664
-       bool "Broadcom BCM21664 SoC family" if ARCH_MULTI_V7
+       bool "Broadcom BCM21664 SoC family"
+       depends on ARCH_MULTI_V7
        select ARCH_BCM_MOBILE
        select HAVE_SMP
        help
@@ -122,20 +135,23 @@ config ARCH_BCM_MOBILE_SMP
 comment "Other Architectures"
 
 config ARCH_BCM2835
-       bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
+       bool "Broadcom BCM2835 family"
+       depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
-       select ARM_ERRATA_411920
+       select ARM_ERRATA_411920 if ARCH_MULTI_V6
        select ARM_TIMER_SP804
+       select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
        select CLKSRC_OF
        select PINCTRL
        select PINCTRL_BCM2835
        help
-         This enables support for the Broadcom BCM2835 SoC. This SoC is
-         used in the Raspberry Pi and Roku 2 devices.
+         This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
+         This SoC is used in the Raspberry Pi and Roku 2 devices.
 
 config ARCH_BCM_63XX
-       bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
+       bool "Broadcom BCM63xx DSL SoC"
+       depends on ARCH_MULTI_V7
        depends on MMU
        select ARM_ERRATA_754322
        select ARM_ERRATA_764369 if SMP
@@ -152,7 +168,8 @@ config ARCH_BCM_63XX
          the BCM63138 variant.
 
 config ARCH_BRCMSTB
-       bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
+       bool "Broadcom BCM7XXX based boards"
+       depends on ARCH_MULTI_V7
        select ARM_GIC
        select ARM_ERRATA_798181 if SMP
        select HAVE_ARM_ARCH_TIMER
index 892261f..7d66515 100644 (file)
 obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  bcm_cygnus.o
 
 # Northstar Plus
-obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
+obj-$(CONFIG_ARCH_BCM_NSP)     += bcm_nsp.o
+
+ifeq ($(CONFIG_ARCH_BCM_NSP),y)
+obj-$(CONFIG_SMP)              += platsmp.o
+endif
 
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)   += board_bcm281xx.o
@@ -23,7 +27,7 @@ obj-$(CONFIG_ARCH_BCM_281XX)  += board_bcm281xx.o
 obj-$(CONFIG_ARCH_BCM_21664)   += board_bcm21664.o
 
 # BCM281XX and BCM21664 SMP support
-obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o
+obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o
 
 # BCM281XX and BCM21664 L2 cache control
 obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
@@ -39,6 +43,9 @@ obj-$(CONFIG_ARCH_BCM2835)    += board_bcm2835.o
 
 # BCM5301X
 obj-$(CONFIG_ARCH_BCM_5301X)   += bcm_5301x.o
+ifeq ($(CONFIG_ARCH_BCM_5301X),y)
+obj-$(CONFIG_SMP)              += platsmp.o
+endif
 
 # BCM63XXx
 ifeq ($(CONFIG_ARCH_BCM_63XX),y)
index 19be904..9b6727e 100644 (file)
@@ -161,7 +161,7 @@ static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
        }
 }
 
-struct smp_operations bcm63138_smp_ops __initdata = {
+static const struct smp_operations bcm63138_smp_ops __initconst = {
        .smp_prepare_cpus       = bcm63138_smp_prepare_cpus,
        .smp_boot_secondary     = bcm63138_smp_boot_secondary,
 };
index 5478fe6..c8830a2 100644 (file)
@@ -9,40 +9,6 @@
 #include <asm/hardware/cache-l2x0.h>
 
 #include <asm/mach/arch.h>
-#include <asm/siginfo.h>
-#include <asm/signal.h>
-
-
-static bool first_fault = true;
-
-static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
-                                struct pt_regs *regs)
-{
-       if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) {
-               first_fault = false;
-
-               /*
-                * These faults with codes 0x1406 (BCM4709) or 0x1c06 happens
-                * for no good reason, possibly left over from the CFE boot
-                * loader.
-                */
-               pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
-                       addr, fsr);
-
-               /* Returning non-zero causes fault display and panic */
-               return 0;
-       }
-
-       /* Others should cause a fault */
-       return 1;
-}
-
-static void __init bcm5301x_init_early(void)
-{
-       /* Install our hook */
-       hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
-                       "imprecise external abort");
-}
 
 static const char *const bcm5301x_dt_compat[] __initconst = {
        "brcm,bcm4708",
@@ -52,6 +18,5 @@ static const char *const bcm5301x_dt_compat[] __initconst = {
 DT_MACHINE_START(BCM5301X, "BCM5301X")
        .l2c_aux_val    = 0,
        .l2c_aux_mask   = ~0,
-       .init_early     = bcm5301x_init_early,
        .dt_compat      = bcm5301x_dt_compat,
 MACHINE_END
index 0f7b9ea..834d676 100644 (file)
@@ -36,7 +36,12 @@ static void __init bcm2835_init(void)
 }
 
 static const char * const bcm2835_compat[] = {
+#ifdef CONFIG_ARCH_MULTI_V6
        "brcm,bcm2835",
+#endif
+#ifdef CONFIG_ARCH_MULTI_V7
+       "brcm,bcm2836",
+#endif
        NULL
 };
 
diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c
deleted file mode 100644 (file)
index 66a0465..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2014 Broadcom Corporation
- * Copyright 2014 Linaro Limited
- *
- * This program is free software; 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/init.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/sched.h>
-
-#include <asm/smp.h>
-#include <asm/smp_plat.h>
-#include <asm/smp_scu.h>
-
-/* Size of mapped Cortex A9 SCU address space */
-#define CORTEX_A9_SCU_SIZE     0x58
-
-#define SECONDARY_TIMEOUT_NS   NSEC_PER_MSEC   /* 1 msec (in nanoseconds) */
-#define BOOT_ADDR_CPUID_MASK   0x3
-
-/* Name of device node property defining secondary boot register location */
-#define OF_SECONDARY_BOOT      "secondary-boot-reg"
-
-/* I/O address of register used to coordinate secondary core startup */
-static u32     secondary_boot;
-
-/*
- * Enable the Cortex A9 Snoop Control Unit
- *
- * By the time this is called we already know there are multiple
- * cores present.  We assume we're running on a Cortex A9 processor,
- * so any trouble getting the base address register or getting the
- * SCU base is a problem.
- *
- * Return 0 if successful or an error code otherwise.
- */
-static int __init scu_a9_enable(void)
-{
-       unsigned long config_base;
-       void __iomem *scu_base;
-
-       if (!scu_a9_has_base()) {
-               pr_err("no configuration base address register!\n");
-               return -ENXIO;
-       }
-
-       /* Config base address register value is zero for uniprocessor */
-       config_base = scu_a9_get_base();
-       if (!config_base) {
-               pr_err("hardware reports only one core\n");
-               return -ENOENT;
-       }
-
-       scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
-       if (!scu_base) {
-               pr_err("failed to remap config base (%lu/%u) for SCU\n",
-                       config_base, CORTEX_A9_SCU_SIZE);
-               return -ENOMEM;
-       }
-
-       scu_enable(scu_base);
-
-       iounmap(scu_base);      /* That's the last we'll need of this */
-
-       return 0;
-}
-
-static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
-{
-       static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
-       struct device_node *node;
-       int ret;
-
-       BUG_ON(secondary_boot);         /* We're called only once */
-
-       /*
-        * This function is only called via smp_ops->smp_prepare_cpu().
-        * That only happens if a "/cpus" device tree node exists
-        * and has an "enable-method" property that selects the SMP
-        * operations defined herein.
-        */
-       node = of_find_node_by_path("/cpus");
-       BUG_ON(!node);
-
-       /*
-        * Our secondary enable method requires a "secondary-boot-reg"
-        * property to specify a register address used to request the
-        * ROM code boot a secondary code.  If we have any trouble
-        * getting this we fall back to uniprocessor mode.
-        */
-       if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
-               pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
-                       node->name);
-               ret = -ENOENT;          /* Arrange to disable SMP */
-               goto out;
-       }
-
-       /*
-        * Enable the SCU on Cortex A9 based SoCs.  If -ENOENT is
-        * returned, the SoC reported a uniprocessor configuration.
-        * We bail on any other error.
-        */
-       ret = scu_a9_enable();
-out:
-       of_node_put(node);
-       if (ret) {
-               /* Update the CPU present map to reflect uniprocessor mode */
-               BUG_ON(ret != -ENOENT);
-               pr_warn("disabling SMP\n");
-               init_cpu_present(&only_cpu_0);
-       }
-}
-
-/*
- * The ROM code has the secondary cores looping, waiting for an event.
- * When an event occurs each core examines the bottom two bits of the
- * secondary boot register.  When a core finds those bits contain its
- * own core id, it performs initialization, including computing its boot
- * address by clearing the boot register value's bottom two bits.  The
- * core signals that it is beginning its execution by writing its boot
- * address back to the secondary boot register, and finally jumps to
- * that address.
- *
- * So to start a core executing we need to:
- * - Encode the (hardware) CPU id with the bottom bits of the secondary
- *   start address.
- * - Write that value into the secondary boot register.
- * - Generate an event to wake up the secondary CPU(s).
- * - Wait for the secondary boot register to be re-written, which
- *   indicates the secondary core has started.
- */
-static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       void __iomem *boot_reg;
-       phys_addr_t boot_func;
-       u64 start_clock;
-       u32 cpu_id;
-       u32 boot_val;
-       bool timeout = false;
-
-       cpu_id = cpu_logical_map(cpu);
-       if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
-               pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK);
-               return -EINVAL;
-       }
-
-       if (!secondary_boot) {
-               pr_err("required secondary boot register not specified\n");
-               return -EINVAL;
-       }
-
-       boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
-       if (!boot_reg) {
-               pr_err("unable to map boot register for cpu %u\n", cpu_id);
-               return -ENOSYS;
-       }
-
-       /*
-        * Secondary cores will start in secondary_startup(),
-        * defined in "arch/arm/kernel/head.S"
-        */
-       boot_func = virt_to_phys(secondary_startup);
-       BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK);
-       BUG_ON(boot_func > (phys_addr_t)U32_MAX);
-
-       /* The core to start is encoded in the low bits */
-       boot_val = (u32)boot_func | cpu_id;
-       writel_relaxed(boot_val, boot_reg);
-
-       sev();
-
-       /* The low bits will be cleared once the core has started */
-       start_clock = local_clock();
-       while (!timeout && readl_relaxed(boot_reg) == boot_val)
-               timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS;
-
-       iounmap(boot_reg);
-
-       if (!timeout)
-               return 0;
-
-       pr_err("timeout waiting for cpu %u to start\n", cpu_id);
-
-       return -ENOSYS;
-}
-
-static struct smp_operations bcm_smp_ops __initdata = {
-       .smp_prepare_cpus       = bcm_smp_prepare_cpus,
-       .smp_boot_secondary     = bcm_boot_secondary,
-};
-CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
-                       &bcm_smp_ops);
index 44d6bdd..40dc844 100644 (file)
@@ -356,7 +356,7 @@ static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-static struct smp_operations brcmstb_smp_ops __initdata = {
+static const struct smp_operations brcmstb_smp_ops __initconst = {
        .smp_prepare_cpus       = brcmstb_cpu_ctrl_setup,
        .smp_boot_secondary     = brcmstb_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c
new file mode 100644 (file)
index 0000000..575defc
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2014-2015 Broadcom Corporation
+ * Copyright 2014 Linaro Limited
+ *
+ * This program is free software; 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/cpumask.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+/* Size of mapped Cortex A9 SCU address space */
+#define CORTEX_A9_SCU_SIZE     0x58
+
+#define SECONDARY_TIMEOUT_NS   NSEC_PER_MSEC   /* 1 msec (in nanoseconds) */
+#define BOOT_ADDR_CPUID_MASK   0x3
+
+/* Name of device node property defining secondary boot register location */
+#define OF_SECONDARY_BOOT      "secondary-boot-reg"
+#define MPIDR_CPUID_BITMASK    0x3
+
+/* I/O address of register used to coordinate secondary core startup */
+static u32     secondary_boot_addr;
+
+/*
+ * Enable the Cortex A9 Snoop Control Unit
+ *
+ * By the time this is called we already know there are multiple
+ * cores present.  We assume we're running on a Cortex A9 processor,
+ * so any trouble getting the base address register or getting the
+ * SCU base is a problem.
+ *
+ * Return 0 if successful or an error code otherwise.
+ */
+static int __init scu_a9_enable(void)
+{
+       unsigned long config_base;
+       void __iomem *scu_base;
+
+       if (!scu_a9_has_base()) {
+               pr_err("no configuration base address register!\n");
+               return -ENXIO;
+       }
+
+       /* Config base address register value is zero for uniprocessor */
+       config_base = scu_a9_get_base();
+       if (!config_base) {
+               pr_err("hardware reports only one core\n");
+               return -ENOENT;
+       }
+
+       scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
+       if (!scu_base) {
+               pr_err("failed to remap config base (%lu/%u) for SCU\n",
+                       config_base, CORTEX_A9_SCU_SIZE);
+               return -ENOMEM;
+       }
+
+       scu_enable(scu_base);
+
+       iounmap(scu_base);      /* That's the last we'll need of this */
+
+       return 0;
+}
+
+static int nsp_write_lut(void)
+{
+       void __iomem *sku_rom_lut;
+       phys_addr_t secondary_startup_phy;
+
+       if (!secondary_boot_addr) {
+               pr_warn("required secondary boot register not specified\n");
+               return -EINVAL;
+       }
+
+       sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr,
+                                               sizeof(secondary_boot_addr));
+       if (!sku_rom_lut) {
+               pr_warn("unable to ioremap SKU-ROM LUT register\n");
+               return -ENOMEM;
+       }
+
+       secondary_startup_phy = virt_to_phys(secondary_startup);
+       BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX);
+
+       writel_relaxed(secondary_startup_phy, sku_rom_lut);
+
+       /* Ensure the write is visible to the secondary core */
+       smp_wmb();
+
+       iounmap(sku_rom_lut);
+
+       return 0;
+}
+
+static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
+{
+       static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
+       struct device_node *cpus_node = NULL;
+       struct device_node *cpu_node = NULL;
+       int ret;
+
+       /*
+        * This function is only called via smp_ops->smp_prepare_cpu().
+        * That only happens if a "/cpus" device tree node exists
+        * and has an "enable-method" property that selects the SMP
+        * operations defined herein.
+        */
+       cpus_node = of_find_node_by_path("/cpus");
+       if (!cpus_node)
+               return;
+
+       for_each_child_of_node(cpus_node, cpu_node) {
+               u32 cpuid;
+
+               if (of_node_cmp(cpu_node->type, "cpu"))
+                       continue;
+
+               if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
+                       pr_debug("%s: missing reg property\n",
+                                    cpu_node->full_name);
+                       ret = -ENOENT;
+                       goto out;
+               }
+
+               /*
+                * "secondary-boot-reg" property should be defined only
+                * for secondary cpu
+                */
+               if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
+                       /*
+                        * Our secondary enable method requires a
+                        * "secondary-boot-reg" property to specify a register
+                        * address used to request the ROM code boot a secondary
+                        * core. If we have any trouble getting this we fall
+                        * back to uniprocessor mode.
+                        */
+                       if (of_property_read_u32(cpu_node,
+                                               OF_SECONDARY_BOOT,
+                                               &secondary_boot_addr)) {
+                               pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
+                                       cpu_node->name);
+                               ret = -ENOENT;
+                               goto out;
+                       }
+               }
+       }
+
+       /*
+        * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
+        * returned, the SoC reported a uniprocessor configuration.
+        * We bail on any other error.
+        */
+       ret = scu_a9_enable();
+out:
+       of_node_put(cpu_node);
+       of_node_put(cpus_node);
+
+       if (ret) {
+               /* Update the CPU present map to reflect uniprocessor mode */
+               pr_warn("disabling SMP\n");
+               init_cpu_present(&only_cpu_0);
+       }
+}
+
+/*
+ * The ROM code has the secondary cores looping, waiting for an event.
+ * When an event occurs each core examines the bottom two bits of the
+ * secondary boot register.  When a core finds those bits contain its
+ * own core id, it performs initialization, including computing its boot
+ * address by clearing the boot register value's bottom two bits.  The
+ * core signals that it is beginning its execution by writing its boot
+ * address back to the secondary boot register, and finally jumps to
+ * that address.
+ *
+ * So to start a core executing we need to:
+ * - Encode the (hardware) CPU id with the bottom bits of the secondary
+ *   start address.
+ * - Write that value into the secondary boot register.
+ * - Generate an event to wake up the secondary CPU(s).
+ * - Wait for the secondary boot register to be re-written, which
+ *   indicates the secondary core has started.
+ */
+static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       void __iomem *boot_reg;
+       phys_addr_t boot_func;
+       u64 start_clock;
+       u32 cpu_id;
+       u32 boot_val;
+       bool timeout = false;
+
+       cpu_id = cpu_logical_map(cpu);
+       if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
+               pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK);
+               return -EINVAL;
+       }
+
+       if (!secondary_boot_addr) {
+               pr_err("required secondary boot register not specified\n");
+               return -EINVAL;
+       }
+
+       boot_reg = ioremap_nocache(
+                       (phys_addr_t)secondary_boot_addr, sizeof(u32));
+       if (!boot_reg) {
+               pr_err("unable to map boot register for cpu %u\n", cpu_id);
+               return -ENOMEM;
+       }
+
+       /*
+        * Secondary cores will start in secondary_startup(),
+        * defined in "arch/arm/kernel/head.S"
+        */
+       boot_func = virt_to_phys(secondary_startup);
+       BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK);
+       BUG_ON(boot_func > (phys_addr_t)U32_MAX);
+
+       /* The core to start is encoded in the low bits */
+       boot_val = (u32)boot_func | cpu_id;
+       writel_relaxed(boot_val, boot_reg);
+
+       sev();
+
+       /* The low bits will be cleared once the core has started */
+       start_clock = local_clock();
+       while (!timeout && readl_relaxed(boot_reg) == boot_val)
+               timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS;
+
+       iounmap(boot_reg);
+
+       if (!timeout)
+               return 0;
+
+       pr_err("timeout waiting for cpu %u to start\n", cpu_id);
+
+       return -ENXIO;
+}
+
+static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       int ret;
+
+       /*
+        * After wake up, secondary core branches to the startup
+        * address programmed at SKU ROM LUT location.
+        */
+       ret = nsp_write_lut();
+       if (ret) {
+               pr_err("unable to write startup addr to SKU ROM LUT\n");
+               goto out;
+       }
+
+       /* Send a CPU wakeup interrupt to the secondary core */
+       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+out:
+       return ret;
+}
+
+static const struct smp_operations bcm_smp_ops __initconst = {
+       .smp_prepare_cpus       = bcm_smp_prepare_cpus,
+       .smp_boot_secondary     = kona_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
+                       &bcm_smp_ops);
+
+struct smp_operations nsp_smp_ops __initdata = {
+       .smp_prepare_cpus       = bcm_smp_prepare_cpus,
+       .smp_boot_secondary     = nsp_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
index 742d53a..ffbfa0b 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_BERLIN
-       bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
+       bool "Marvell Berlin SoCs"
+       depends on ARCH_MULTI_V7
        select ARCH_HAS_RESET_CONTROLLER
        select ARCH_REQUIRE_GPIOLIB
        select ARM_GIC
index 405cd37..93f9068 100644 (file)
@@ -119,7 +119,7 @@ static int berlin_cpu_kill(unsigned int cpu)
 }
 #endif
 
-static struct smp_operations berlin_smp_ops __initdata = {
+static const struct smp_operations berlin_smp_ops __initconst = {
        .smp_prepare_cpus       = berlin_smp_prepare_cpus,
        .smp_boot_secondary     = berlin_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index 3c22a19..eb14a0f 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_CNS3XXX
-       bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
+       bool "Cavium Networks CNS3XXX family"
+       depends on ARCH_MULTI_V6
        select ARM_GIC
        select PCI_DOMAINS if PCI
        help
index dd8f531..bcaf1d0 100644 (file)
@@ -34,7 +34,8 @@ config ARCH_DAVINCI_DA830
        bool "DA830/OMAP-L137/AM17x based system"
        depends on !ARCH_DAVINCI_DMx || AUTO_ZRELADDR
        select ARCH_DAVINCI_DA8XX
-       select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
+       # needed on silicon revs 1.0, 1.1:
+       select CPU_DCACHE_WRITETHROUGH if !CPU_DCACHE_DISABLE
        select CP_INTC
 
 config ARCH_DAVINCI_DA850
index f8f62fb..3d8cf8c 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
 #include <mach/mux.h>
 #include <mach/da8xx.h>
 
index 9cc7b81..8e4539f 100644 (file)
 #include <linux/spi/flash.h>
 
 #include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
 #include <mach/da8xx.h>
 #include <mach/mux.h>
-#include <mach/sram.h>
+#include "sram.h"
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index c71dd99..1844076 100644 (file)
@@ -384,9 +384,7 @@ static __init void dm355_evm_init(void)
        dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1);
 
        aemif = clk_get(&dm355evm_dm9000.dev, "aemif");
-       if (IS_ERR(aemif))
-               WARN("%s: unable to get AEMIF clock\n", __func__);
-       else
+       if (!WARN(IS_ERR(aemif), "unable to get AEMIF clock\n"))
                clk_prepare_enable(aemif);
 
        platform_add_devices(davinci_evm_devices,
index 680a7a2..284ff27 100644 (file)
@@ -242,9 +242,7 @@ static __init void dm355_leopard_init(void)
        dm355leopard_dm9000_rsrc[2].start = gpio_to_irq(9);
 
        aemif = clk_get(&dm355leopard_dm9000.dev, "aemif");
-       if (IS_ERR(aemif))
-               WARN("%s: unable to get AEMIF clock\n", __func__);
-       else
+       if (!WARN(IS_ERR(aemif), "unable to get AEMIF clock\n"))
                clk_prepare_enable(aemif);
 
        platform_add_devices(davinci_leopard_devices,
index 8cfbfe0..de1316b 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
 #include <mach/da8xx.h>
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
index 2aac51d..ee62486 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
 #include <mach/da8xx.h>
 #include <mach/mux.h>
 
index 3caff96..3424eac 100644 (file)
@@ -23,7 +23,7 @@
 #include <mach/hardware.h>
 
 #include <mach/clock.h>
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/cputype.h>
 #include "clock.h"
 
index 507aad4..1a68d24 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/of_irq.h>
 
 #include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
 
 static inline unsigned int cp_intc_read(unsigned offset)
 {
diff --git a/arch/arm/mach-davinci/cp_intc.h b/arch/arm/mach-davinci/cp_intc.h
new file mode 100644 (file)
index 0000000..827bbe9
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * TI Common Platform Interrupt Controller (cp_intc) definitions
+ *
+ * Author: Steve Chen <schen@mvista.com>
+ * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef __ASM_HARDWARE_CP_INTC_H
+#define __ASM_HARDWARE_CP_INTC_H
+
+#define CP_INTC_REV                    0x00
+#define CP_INTC_CTRL                   0x04
+#define CP_INTC_HOST_CTRL              0x0C
+#define CP_INTC_GLOBAL_ENABLE          0x10
+#define CP_INTC_GLOBAL_NESTING_LEVEL   0x1C
+#define CP_INTC_SYS_STAT_IDX_SET       0x20
+#define CP_INTC_SYS_STAT_IDX_CLR       0x24
+#define CP_INTC_SYS_ENABLE_IDX_SET     0x28
+#define CP_INTC_SYS_ENABLE_IDX_CLR     0x2C
+#define CP_INTC_GLOBAL_WAKEUP_ENABLE   0x30
+#define CP_INTC_HOST_ENABLE_IDX_SET    0x34
+#define CP_INTC_HOST_ENABLE_IDX_CLR    0x38
+#define CP_INTC_PACING_PRESCALE        0x40
+#define CP_INTC_VECTOR_BASE            0x50
+#define CP_INTC_VECTOR_SIZE            0x54
+#define CP_INTC_VECTOR_NULL            0x58
+#define CP_INTC_PRIO_IDX               0x80
+#define CP_INTC_PRIO_VECTOR            0x84
+#define CP_INTC_SECURE_ENABLE          0x90
+#define CP_INTC_SECURE_PRIO_IDX        0x94
+#define CP_INTC_PACING_PARAM(n)        (0x0100 + (n << 4))
+#define CP_INTC_PACING_DEC(n)          (0x0104 + (n << 4))
+#define CP_INTC_PACING_MAP(n)          (0x0108 + (n << 4))
+#define CP_INTC_SYS_RAW_STAT(n)        (0x0200 + (n << 2))
+#define CP_INTC_SYS_STAT_CLR(n)        (0x0280 + (n << 2))
+#define CP_INTC_SYS_ENABLE_SET(n)      (0x0300 + (n << 2))
+#define CP_INTC_SYS_ENABLE_CLR(n)      (0x0380 + (n << 2))
+#define CP_INTC_CHAN_MAP(n)            (0x0400 + (n << 2))
+#define CP_INTC_HOST_MAP(n)            (0x0800 + (n << 2))
+#define CP_INTC_HOST_PRIO_IDX(n)       (0x0900 + (n << 2))
+#define CP_INTC_SYS_POLARITY(n)        (0x0D00 + (n << 2))
+#define CP_INTC_SYS_TYPE(n)            (0x0D80 + (n << 2))
+#define CP_INTC_WAKEUP_ENABLE(n)       (0x0E00 + (n << 2))
+#define CP_INTC_DEBUG_SELECT(n)        (0x0F00 + (n << 2))
+#define CP_INTC_SYS_SECURE_ENABLE(n)   (0x1000 + (n << 2))
+#define CP_INTC_HOST_NESTING_LEVEL(n)  (0x1100 + (n << 2))
+#define CP_INTC_HOST_ENABLE(n)         (0x1500 + (n << 2))
+#define CP_INTC_HOST_PRIO_VECTOR(n)    (0x1600 + (n << 2))
+#define CP_INTC_VECTOR_ADDR(n)         (0x2000 + (n << 2))
+
+void cp_intc_init(void);
+int cp_intc_of_init(struct device_node *, struct device_node *);
+
+#endif /* __ASM_HARDWARE_CP_INTC_H */
index 306ebc5..1b8f085 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/export.h>
 #include <asm/cpuidle.h>
 
-#include <mach/cpuidle.h>
-#include <mach/ddr2.h>
+#include "cpuidle.h"
+#include "ddr2.h"
 
 #define DAVINCI_CPUIDLE_MAX_STATES     2
 
diff --git a/arch/arm/mach-davinci/cpuidle.h b/arch/arm/mach-davinci/cpuidle.h
new file mode 100644 (file)
index 0000000..74f088b
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * TI DaVinci cpuidle platform 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_CPUIDLE_H
+#define _MACH_DAVINCI_CPUIDLE_H
+
+struct davinci_cpuidle_config {
+       u32 ddr2_pdown;
+       void __iomem *ddr2_ctlr_base;
+};
+
+#endif
index 115d573..7187e7f 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/common.h>
index 6769978..97d8779 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/common.h>
index 06b6451..c4b5808 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
 #include <mach/da8xx.h>
 
 #define DA8XX_NUM_UARTS        3
diff --git a/arch/arm/mach-davinci/ddr2.h b/arch/arm/mach-davinci/ddr2.h
new file mode 100644 (file)
index 0000000..c19e047
--- /dev/null
@@ -0,0 +1,4 @@
+#define DDR2_SDRCR_OFFSET      0xc
+#define DDR2_SRPD_BIT          (1 << 23)
+#define DDR2_MCLKSTOPEN_BIT    (1 << 30)
+#define DDR2_LPMODEN_BIT       (1 << 31)
index 28c90bc..e88b7a5 100644 (file)
@@ -22,8 +22,8 @@
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <mach/cpuidle.h>
-#include <mach/sram.h>
+#include "cpuidle.h"
+#include "sram.h"
 
 #include "clock.h"
 #include "asp.h"
index 609950b..c7c1458 100644 (file)
@@ -21,7 +21,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/cputype.h>
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/mux.h>
 #include <mach/irqs.h>
 #include <mach/time.h>
index 2068cbe..01843fb 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/cputype.h>
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/mux.h>
 #include <mach/irqs.h>
 #include <mach/time.h>
index d38f504..b28071a 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/mux.h>
 #include <mach/time.h>
 #include <mach/serial.h>
index 70eb427..cf80786 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include <mach/psc.h>
+#include "psc.h"
 #include <mach/mux.h>
 #include <mach/time.h>
 #include <mach/serial.h>
diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h
deleted file mode 100644 (file)
index 827bbe9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * TI Common Platform Interrupt Controller (cp_intc) definitions
- *
- * Author: Steve Chen <schen@mvista.com>
- * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-#ifndef __ASM_HARDWARE_CP_INTC_H
-#define __ASM_HARDWARE_CP_INTC_H
-
-#define CP_INTC_REV                    0x00
-#define CP_INTC_CTRL                   0x04
-#define CP_INTC_HOST_CTRL              0x0C
-#define CP_INTC_GLOBAL_ENABLE          0x10
-#define CP_INTC_GLOBAL_NESTING_LEVEL   0x1C
-#define CP_INTC_SYS_STAT_IDX_SET       0x20
-#define CP_INTC_SYS_STAT_IDX_CLR       0x24
-#define CP_INTC_SYS_ENABLE_IDX_SET     0x28
-#define CP_INTC_SYS_ENABLE_IDX_CLR     0x2C
-#define CP_INTC_GLOBAL_WAKEUP_ENABLE   0x30
-#define CP_INTC_HOST_ENABLE_IDX_SET    0x34
-#define CP_INTC_HOST_ENABLE_IDX_CLR    0x38
-#define CP_INTC_PACING_PRESCALE        0x40
-#define CP_INTC_VECTOR_BASE            0x50
-#define CP_INTC_VECTOR_SIZE            0x54
-#define CP_INTC_VECTOR_NULL            0x58
-#define CP_INTC_PRIO_IDX               0x80
-#define CP_INTC_PRIO_VECTOR            0x84
-#define CP_INTC_SECURE_ENABLE          0x90
-#define CP_INTC_SECURE_PRIO_IDX        0x94
-#define CP_INTC_PACING_PARAM(n)        (0x0100 + (n << 4))
-#define CP_INTC_PACING_DEC(n)          (0x0104 + (n << 4))
-#define CP_INTC_PACING_MAP(n)          (0x0108 + (n << 4))
-#define CP_INTC_SYS_RAW_STAT(n)        (0x0200 + (n << 2))
-#define CP_INTC_SYS_STAT_CLR(n)        (0x0280 + (n << 2))
-#define CP_INTC_SYS_ENABLE_SET(n)      (0x0300 + (n << 2))
-#define CP_INTC_SYS_ENABLE_CLR(n)      (0x0380 + (n << 2))
-#define CP_INTC_CHAN_MAP(n)            (0x0400 + (n << 2))
-#define CP_INTC_HOST_MAP(n)            (0x0800 + (n << 2))
-#define CP_INTC_HOST_PRIO_IDX(n)       (0x0900 + (n << 2))
-#define CP_INTC_SYS_POLARITY(n)        (0x0D00 + (n << 2))
-#define CP_INTC_SYS_TYPE(n)            (0x0D80 + (n << 2))
-#define CP_INTC_WAKEUP_ENABLE(n)       (0x0E00 + (n << 2))
-#define CP_INTC_DEBUG_SELECT(n)        (0x0F00 + (n << 2))
-#define CP_INTC_SYS_SECURE_ENABLE(n)   (0x1000 + (n << 2))
-#define CP_INTC_HOST_NESTING_LEVEL(n)  (0x1100 + (n << 2))
-#define CP_INTC_HOST_ENABLE(n)         (0x1500 + (n << 2))
-#define CP_INTC_HOST_PRIO_VECTOR(n)    (0x1600 + (n << 2))
-#define CP_INTC_VECTOR_ADDR(n)         (0x2000 + (n << 2))
-
-void cp_intc_init(void);
-int cp_intc_of_init(struct device_node *, struct device_node *);
-
-#endif /* __ASM_HARDWARE_CP_INTC_H */
diff --git a/arch/arm/mach-davinci/include/mach/cpuidle.h b/arch/arm/mach-davinci/include/mach/cpuidle.h
deleted file mode 100644 (file)
index 74f088b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * TI DaVinci cpuidle platform 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_CPUIDLE_H
-#define _MACH_DAVINCI_CPUIDLE_H
-
-struct davinci_cpuidle_config {
-       u32 ddr2_pdown;
-       void __iomem *ddr2_ctlr_base;
-};
-
-#endif
diff --git a/arch/arm/mach-davinci/include/mach/ddr2.h b/arch/arm/mach-davinci/include/mach/ddr2.h
deleted file mode 100644 (file)
index c19e047..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#define DDR2_SDRCR_OFFSET      0xc
-#define DDR2_SRPD_BIT          (1 << 23)
-#define DDR2_MCLKSTOPEN_BIT    (1 << 30)
-#define DDR2_LPMODEN_BIT       (1 << 31)
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
deleted file mode 100644 (file)
index 99d47cf..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- *  DaVinci Power & Sleep Controller (PSC) defines
- *
- *  Copyright (C) 2006 Texas Instruments.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#ifndef __ASM_ARCH_PSC_H
-#define __ASM_ARCH_PSC_H
-
-#define        DAVINCI_PWR_SLEEP_CNTRL_BASE    0x01C41000
-
-/* Power and Sleep Controller (PSC) Domains */
-#define DAVINCI_GPSC_ARMDOMAIN         0
-#define DAVINCI_GPSC_DSPDOMAIN         1
-
-#define DAVINCI_LPSC_VPSSMSTR          0
-#define DAVINCI_LPSC_VPSSSLV           1
-#define DAVINCI_LPSC_TPCC              2
-#define DAVINCI_LPSC_TPTC0             3
-#define DAVINCI_LPSC_TPTC1             4
-#define DAVINCI_LPSC_EMAC              5
-#define DAVINCI_LPSC_EMAC_WRAPPER      6
-#define DAVINCI_LPSC_USB               9
-#define DAVINCI_LPSC_ATA               10
-#define DAVINCI_LPSC_VLYNQ             11
-#define DAVINCI_LPSC_UHPI              12
-#define DAVINCI_LPSC_DDR_EMIF          13
-#define DAVINCI_LPSC_AEMIF             14
-#define DAVINCI_LPSC_MMC_SD            15
-#define DAVINCI_LPSC_McBSP             17
-#define DAVINCI_LPSC_I2C               18
-#define DAVINCI_LPSC_UART0             19
-#define DAVINCI_LPSC_UART1             20
-#define DAVINCI_LPSC_UART2             21
-#define DAVINCI_LPSC_SPI               22
-#define DAVINCI_LPSC_PWM0              23
-#define DAVINCI_LPSC_PWM1              24
-#define DAVINCI_LPSC_PWM2              25
-#define DAVINCI_LPSC_GPIO              26
-#define DAVINCI_LPSC_TIMER0            27
-#define DAVINCI_LPSC_TIMER1            28
-#define DAVINCI_LPSC_TIMER2            29
-#define DAVINCI_LPSC_SYSTEM_SUBSYS     30
-#define DAVINCI_LPSC_ARM               31
-#define DAVINCI_LPSC_SCR2              32
-#define DAVINCI_LPSC_SCR3              33
-#define DAVINCI_LPSC_SCR4              34
-#define DAVINCI_LPSC_CROSSBAR          35
-#define DAVINCI_LPSC_CFG27             36
-#define DAVINCI_LPSC_CFG3              37
-#define DAVINCI_LPSC_CFG5              38
-#define DAVINCI_LPSC_GEM               39
-#define DAVINCI_LPSC_IMCOP             40
-
-#define DM355_LPSC_TIMER3              5
-#define DM355_LPSC_SPI1                        6
-#define DM355_LPSC_MMC_SD1             7
-#define DM355_LPSC_McBSP1              8
-#define DM355_LPSC_PWM3                        10
-#define DM355_LPSC_SPI2                        11
-#define DM355_LPSC_RTO                 12
-#define DM355_LPSC_VPSS_DAC            41
-
-/* DM365 */
-#define DM365_LPSC_TIMER3      5
-#define DM365_LPSC_SPI1                6
-#define DM365_LPSC_MMC_SD1     7
-#define DM365_LPSC_McBSP1      8
-#define DM365_LPSC_PWM3                10
-#define DM365_LPSC_SPI2                11
-#define DM365_LPSC_RTO         12
-#define DM365_LPSC_TIMER4      17
-#define DM365_LPSC_SPI0                22
-#define DM365_LPSC_SPI3                38
-#define DM365_LPSC_SPI4                39
-#define DM365_LPSC_EMAC                40
-#define DM365_LPSC_VOICE_CODEC 44
-#define DM365_LPSC_DAC_CLK     46
-#define DM365_LPSC_VPSSMSTR    47
-#define DM365_LPSC_MJCP                50
-
-/*
- * LPSC Assignments
- */
-#define DM646X_LPSC_ARM                0
-#define DM646X_LPSC_C64X_CPU   1
-#define DM646X_LPSC_HDVICP0    2
-#define DM646X_LPSC_HDVICP1    3
-#define DM646X_LPSC_TPCC       4
-#define DM646X_LPSC_TPTC0      5
-#define DM646X_LPSC_TPTC1      6
-#define DM646X_LPSC_TPTC2      7
-#define DM646X_LPSC_TPTC3      8
-#define DM646X_LPSC_PCI                13
-#define DM646X_LPSC_EMAC       14
-#define DM646X_LPSC_VDCE       15
-#define DM646X_LPSC_VPSSMSTR   16
-#define DM646X_LPSC_VPSSSLV    17
-#define DM646X_LPSC_TSIF0      18
-#define DM646X_LPSC_TSIF1      19
-#define DM646X_LPSC_DDR_EMIF   20
-#define DM646X_LPSC_AEMIF      21
-#define DM646X_LPSC_McASP0     22
-#define DM646X_LPSC_McASP1     23
-#define DM646X_LPSC_CRGEN0     24
-#define DM646X_LPSC_CRGEN1     25
-#define DM646X_LPSC_UART0      26
-#define DM646X_LPSC_UART1      27
-#define DM646X_LPSC_UART2      28
-#define DM646X_LPSC_PWM0       29
-#define DM646X_LPSC_PWM1       30
-#define DM646X_LPSC_I2C                31
-#define DM646X_LPSC_SPI                32
-#define DM646X_LPSC_GPIO       33
-#define DM646X_LPSC_TIMER0     34
-#define DM646X_LPSC_TIMER1     35
-#define DM646X_LPSC_ARM_INTC   45
-
-/* PSC0 defines */
-#define DA8XX_LPSC0_TPCC               0
-#define DA8XX_LPSC0_TPTC0              1
-#define DA8XX_LPSC0_TPTC1              2
-#define DA8XX_LPSC0_EMIF25             3
-#define DA8XX_LPSC0_SPI0               4
-#define DA8XX_LPSC0_MMC_SD             5
-#define DA8XX_LPSC0_AINTC              6
-#define DA8XX_LPSC0_ARM_RAM_ROM                7
-#define DA8XX_LPSC0_SECU_MGR           8
-#define DA8XX_LPSC0_UART0              9
-#define DA8XX_LPSC0_SCR0_SS            10
-#define DA8XX_LPSC0_SCR1_SS            11
-#define DA8XX_LPSC0_SCR2_SS            12
-#define DA8XX_LPSC0_PRUSS              13
-#define DA8XX_LPSC0_ARM                        14
-#define DA8XX_LPSC0_GEM                        15
-
-/* PSC1 defines */
-#define DA850_LPSC1_TPCC1              0
-#define DA8XX_LPSC1_USB20              1
-#define DA8XX_LPSC1_USB11              2
-#define DA8XX_LPSC1_GPIO               3
-#define DA8XX_LPSC1_UHPI               4
-#define DA8XX_LPSC1_CPGMAC             5
-#define DA8XX_LPSC1_EMIF3C             6
-#define DA8XX_LPSC1_McASP0             7
-#define DA830_LPSC1_McASP1             8
-#define DA850_LPSC1_SATA               8
-#define DA830_LPSC1_McASP2             9
-#define DA850_LPSC1_VPIF               9
-#define DA8XX_LPSC1_SPI1               10
-#define DA8XX_LPSC1_I2C                        11
-#define DA8XX_LPSC1_UART1              12
-#define DA8XX_LPSC1_UART2              13
-#define DA8XX_LPSC1_LCDC               16
-#define DA8XX_LPSC1_PWM                        17
-#define DA850_LPSC1_MMC_SD1            18
-#define DA8XX_LPSC1_ECAP               20
-#define DA830_LPSC1_EQEP               21
-#define DA850_LPSC1_TPTC2              21
-#define DA8XX_LPSC1_SCR_P0_SS          24
-#define DA8XX_LPSC1_SCR_P1_SS          25
-#define DA8XX_LPSC1_CR_P3_SS           26
-#define DA8XX_LPSC1_L3_CBA_RAM         31
-
-/* PSC register offsets */
-#define EPCPR          0x070
-#define PTCMD          0x120
-#define PTSTAT         0x128
-#define PDSTAT         0x200
-#define PDCTL          0x300
-#define MDSTAT         0x800
-#define MDCTL          0xA00
-
-/* PSC module states */
-#define PSC_STATE_SWRSTDISABLE 0
-#define PSC_STATE_SYNCRST      1
-#define PSC_STATE_DISABLE      2
-#define PSC_STATE_ENABLE       3
-
-#define MDSTAT_STATE_MASK      0x3f
-#define PDSTAT_STATE_MASK      0x1f
-#define MDCTL_LRST             BIT(8)
-#define MDCTL_FORCE            BIT(31)
-#define PDCTL_NEXT             BIT(0)
-#define PDCTL_EPCGOOD          BIT(8)
-
-#ifndef __ASSEMBLER__
-
-extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
-extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
-               bool reset);
-extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, bool enable, u32 flags);
-
-#endif
-
-#endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/include/mach/sram.h
deleted file mode 100644 (file)
index 4e5db56..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * mach/sram.h - DaVinci simple SRAM allocator
- *
- * Copyright (C) 2009 David Brownell
- *
- * 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 __MACH_SRAM_H
-#define __MACH_SRAM_H
-
-/* ARBITRARY:  SRAM allocations are multiples of this 2^N size */
-#define SRAM_GRANULARITY       512
-
-/*
- * SRAM allocations return a CPU virtual address, or NULL on error.
- * If a DMA address is requested and the SRAM supports DMA, its
- * mapped address is also returned.
- *
- * Errors include SRAM memory not being available, and requesting
- * DMA mapped SRAM on systems which don't allow that.
- */
-extern void *sram_alloc(size_t len, dma_addr_t *dma);
-extern void sram_free(void *addr, size_t len);
-
-/* Get the struct gen_pool * for use in platform data */
-extern struct gen_pool *sram_get_gen_pool(void);
-
-#endif /* __MACH_SRAM_H */
index 07e23ba..8929569 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <mach/common.h>
 #include <mach/da8xx.h>
-#include <mach/sram.h>
+#include "sram.h"
 #include <mach/pm.h>
 
 #include "clock.h"
index 82fdc69..e5dc6bf 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/io.h>
 
 #include <mach/cputype.h>
-#include <mach/psc.h>
+#include "psc.h"
 
 #include "clock.h"
 
diff --git a/arch/arm/mach-davinci/psc.h b/arch/arm/mach-davinci/psc.h
new file mode 100644 (file)
index 0000000..99d47cf
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ *  DaVinci Power & Sleep Controller (PSC) defines
+ *
+ *  Copyright (C) 2006 Texas Instruments.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_PSC_H
+#define __ASM_ARCH_PSC_H
+
+#define        DAVINCI_PWR_SLEEP_CNTRL_BASE    0x01C41000
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN         0
+#define DAVINCI_GPSC_DSPDOMAIN         1
+
+#define DAVINCI_LPSC_VPSSMSTR          0
+#define DAVINCI_LPSC_VPSSSLV           1
+#define DAVINCI_LPSC_TPCC              2
+#define DAVINCI_LPSC_TPTC0             3
+#define DAVINCI_LPSC_TPTC1             4
+#define DAVINCI_LPSC_EMAC              5
+#define DAVINCI_LPSC_EMAC_WRAPPER      6
+#define DAVINCI_LPSC_USB               9
+#define DAVINCI_LPSC_ATA               10
+#define DAVINCI_LPSC_VLYNQ             11
+#define DAVINCI_LPSC_UHPI              12
+#define DAVINCI_LPSC_DDR_EMIF          13
+#define DAVINCI_LPSC_AEMIF             14
+#define DAVINCI_LPSC_MMC_SD            15
+#define DAVINCI_LPSC_McBSP             17
+#define DAVINCI_LPSC_I2C               18
+#define DAVINCI_LPSC_UART0             19
+#define DAVINCI_LPSC_UART1             20
+#define DAVINCI_LPSC_UART2             21
+#define DAVINCI_LPSC_SPI               22
+#define DAVINCI_LPSC_PWM0              23
+#define DAVINCI_LPSC_PWM1              24
+#define DAVINCI_LPSC_PWM2              25
+#define DAVINCI_LPSC_GPIO              26
+#define DAVINCI_LPSC_TIMER0            27
+#define DAVINCI_LPSC_TIMER1            28
+#define DAVINCI_LPSC_TIMER2            29
+#define DAVINCI_LPSC_SYSTEM_SUBSYS     30
+#define DAVINCI_LPSC_ARM               31
+#define DAVINCI_LPSC_SCR2              32
+#define DAVINCI_LPSC_SCR3              33
+#define DAVINCI_LPSC_SCR4              34
+#define DAVINCI_LPSC_CROSSBAR          35
+#define DAVINCI_LPSC_CFG27             36
+#define DAVINCI_LPSC_CFG3              37
+#define DAVINCI_LPSC_CFG5              38
+#define DAVINCI_LPSC_GEM               39
+#define DAVINCI_LPSC_IMCOP             40
+
+#define DM355_LPSC_TIMER3              5
+#define DM355_LPSC_SPI1                        6
+#define DM355_LPSC_MMC_SD1             7
+#define DM355_LPSC_McBSP1              8
+#define DM355_LPSC_PWM3                        10
+#define DM355_LPSC_SPI2                        11
+#define DM355_LPSC_RTO                 12
+#define DM355_LPSC_VPSS_DAC            41
+
+/* DM365 */
+#define DM365_LPSC_TIMER3      5
+#define DM365_LPSC_SPI1                6
+#define DM365_LPSC_MMC_SD1     7
+#define DM365_LPSC_McBSP1      8
+#define DM365_LPSC_PWM3                10
+#define DM365_LPSC_SPI2                11
+#define DM365_LPSC_RTO         12
+#define DM365_LPSC_TIMER4      17
+#define DM365_LPSC_SPI0                22
+#define DM365_LPSC_SPI3                38
+#define DM365_LPSC_SPI4                39
+#define DM365_LPSC_EMAC                40
+#define DM365_LPSC_VOICE_CODEC 44
+#define DM365_LPSC_DAC_CLK     46
+#define DM365_LPSC_VPSSMSTR    47
+#define DM365_LPSC_MJCP                50
+
+/*
+ * LPSC Assignments
+ */
+#define DM646X_LPSC_ARM                0
+#define DM646X_LPSC_C64X_CPU   1
+#define DM646X_LPSC_HDVICP0    2
+#define DM646X_LPSC_HDVICP1    3
+#define DM646X_LPSC_TPCC       4
+#define DM646X_LPSC_TPTC0      5
+#define DM646X_LPSC_TPTC1      6
+#define DM646X_LPSC_TPTC2      7
+#define DM646X_LPSC_TPTC3      8
+#define DM646X_LPSC_PCI                13
+#define DM646X_LPSC_EMAC       14
+#define DM646X_LPSC_VDCE       15
+#define DM646X_LPSC_VPSSMSTR   16
+#define DM646X_LPSC_VPSSSLV    17
+#define DM646X_LPSC_TSIF0      18
+#define DM646X_LPSC_TSIF1      19
+#define DM646X_LPSC_DDR_EMIF   20
+#define DM646X_LPSC_AEMIF      21
+#define DM646X_LPSC_McASP0     22
+#define DM646X_LPSC_McASP1     23
+#define DM646X_LPSC_CRGEN0     24
+#define DM646X_LPSC_CRGEN1     25
+#define DM646X_LPSC_UART0      26
+#define DM646X_LPSC_UART1      27
+#define DM646X_LPSC_UART2      28
+#define DM646X_LPSC_PWM0       29
+#define DM646X_LPSC_PWM1       30
+#define DM646X_LPSC_I2C                31
+#define DM646X_LPSC_SPI                32
+#define DM646X_LPSC_GPIO       33
+#define DM646X_LPSC_TIMER0     34
+#define DM646X_LPSC_TIMER1     35
+#define DM646X_LPSC_ARM_INTC   45
+
+/* PSC0 defines */
+#define DA8XX_LPSC0_TPCC               0
+#define DA8XX_LPSC0_TPTC0              1
+#define DA8XX_LPSC0_TPTC1              2
+#define DA8XX_LPSC0_EMIF25             3
+#define DA8XX_LPSC0_SPI0               4
+#define DA8XX_LPSC0_MMC_SD             5
+#define DA8XX_LPSC0_AINTC              6
+#define DA8XX_LPSC0_ARM_RAM_ROM                7
+#define DA8XX_LPSC0_SECU_MGR           8
+#define DA8XX_LPSC0_UART0              9
+#define DA8XX_LPSC0_SCR0_SS            10
+#define DA8XX_LPSC0_SCR1_SS            11
+#define DA8XX_LPSC0_SCR2_SS            12
+#define DA8XX_LPSC0_PRUSS              13
+#define DA8XX_LPSC0_ARM                        14
+#define DA8XX_LPSC0_GEM                        15
+
+/* PSC1 defines */
+#define DA850_LPSC1_TPCC1              0
+#define DA8XX_LPSC1_USB20              1
+#define DA8XX_LPSC1_USB11              2
+#define DA8XX_LPSC1_GPIO               3
+#define DA8XX_LPSC1_UHPI               4
+#define DA8XX_LPSC1_CPGMAC             5
+#define DA8XX_LPSC1_EMIF3C             6
+#define DA8XX_LPSC1_McASP0             7
+#define DA830_LPSC1_McASP1             8
+#define DA850_LPSC1_SATA               8
+#define DA830_LPSC1_McASP2             9
+#define DA850_LPSC1_VPIF               9
+#define DA8XX_LPSC1_SPI1               10
+#define DA8XX_LPSC1_I2C                        11
+#define DA8XX_LPSC1_UART1              12
+#define DA8XX_LPSC1_UART2              13
+#define DA8XX_LPSC1_LCDC               16
+#define DA8XX_LPSC1_PWM                        17
+#define DA850_LPSC1_MMC_SD1            18
+#define DA8XX_LPSC1_ECAP               20
+#define DA830_LPSC1_EQEP               21
+#define DA850_LPSC1_TPTC2              21
+#define DA8XX_LPSC1_SCR_P0_SS          24
+#define DA8XX_LPSC1_SCR_P1_SS          25
+#define DA8XX_LPSC1_CR_P3_SS           26
+#define DA8XX_LPSC1_L3_CBA_RAM         31
+
+/* PSC register offsets */
+#define EPCPR          0x070
+#define PTCMD          0x120
+#define PTSTAT         0x128
+#define PDSTAT         0x200
+#define PDCTL          0x300
+#define MDSTAT         0x800
+#define MDCTL          0xA00
+
+/* PSC module states */
+#define PSC_STATE_SWRSTDISABLE 0
+#define PSC_STATE_SYNCRST      1
+#define PSC_STATE_DISABLE      2
+#define PSC_STATE_ENABLE       3
+
+#define MDSTAT_STATE_MASK      0x3f
+#define PDSTAT_STATE_MASK      0x1f
+#define MDCTL_LRST             BIT(8)
+#define MDCTL_FORCE            BIT(31)
+#define PDCTL_NEXT             BIT(0)
+#define PDCTL_EPCGOOD          BIT(8)
+
+#ifndef __ASSEMBLER__
+
+extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
+extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
+               bool reset);
+extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+               unsigned int id, bool enable, u32 flags);
+
+#endif
+
+#endif /* __ASM_ARCH_PSC_H */
index a5336a5..cd350de 100644 (file)
@@ -21,8 +21,8 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <mach/psc.h>
-#include <mach/ddr2.h>
+#include "psc.h"
+#include "ddr2.h"
 
 #include "clock.h"
 
index 8540ddd..668b6e7 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/genalloc.h>
 
 #include <mach/common.h>
-#include <mach/sram.h>
+#include "sram.h"
 
 static struct gen_pool *sram_pool;
 
diff --git a/arch/arm/mach-davinci/sram.h b/arch/arm/mach-davinci/sram.h
new file mode 100644 (file)
index 0000000..4e5db56
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * mach/sram.h - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * 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 __MACH_SRAM_H
+#define __MACH_SRAM_H
+
+/* ARBITRARY:  SRAM allocations are multiples of this 2^N size */
+#define SRAM_GRANULARITY       512
+
+/*
+ * SRAM allocations return a CPU virtual address, or NULL on error.
+ * If a DMA address is requested and the SRAM supports DMA, its
+ * mapped address is also returned.
+ *
+ * Errors include SRAM memory not being available, and requesting
+ * DMA mapped SRAM on systems which don't allow that.
+ */
+extern void *sram_alloc(size_t len, dma_addr_t *dma);
+extern void sram_free(void *addr, size_t len);
+
+/* Get the struct gen_pool * for use in platform data */
+extern struct gen_pool *sram_get_gen_pool(void);
+
+#endif /* __MACH_SRAM_H */
index 0dc39cf..b9a7c33 100644 (file)
@@ -88,6 +88,7 @@ static void __init cm_a510_init(void)
 
 MACHINE_START(CM_A510, "Compulab CM-A510 Board")
        .atag_offset    = 0x100,
+       .nr_irqs        = DOVE_NR_IRQS,
        .init_machine   = cm_a510_init,
        .map_io         = dove_map_io,
        .init_early     = dove_init_early,
index 0d1a892..0cdaa38 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_data/dma-mv_xor.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <linux/platform_device.h>
+#include <linux/soc/dove/pmu.h>
 #include <asm/hardware/cache-tauros2.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -375,6 +376,47 @@ void __init dove_setup_cpu_wins(void)
                                    DOVE_SCRATCHPAD_SIZE);
 }
 
+static struct resource orion_wdt_resource[] = {
+               DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04),
+               DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04),
+};
+
+static struct platform_device orion_wdt_device = {
+       .name           = "orion_wdt",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(orion_wdt_resource),
+       .resource       = orion_wdt_resource,
+};
+
+static void __init __maybe_unused orion_wdt_init(void)
+{
+       platform_device_register(&orion_wdt_device);
+}
+
+static const struct dove_pmu_domain_initdata pmu_domains[] __initconst = {
+       {
+               .pwr_mask = PMU_PWR_VPU_PWR_DWN_MASK,
+               .rst_mask = PMU_SW_RST_VIDEO_MASK,
+               .iso_mask = PMU_ISO_VIDEO_MASK,
+               .name = "vpu-domain",
+       }, {
+               .pwr_mask = PMU_PWR_GPU_PWR_DWN_MASK,
+               .rst_mask = PMU_SW_RST_GPU_MASK,
+               .iso_mask = PMU_ISO_GPU_MASK,
+               .name = "gpu-domain",
+       }, {
+               /* sentinel */
+       },
+};
+
+static const struct dove_pmu_initdata pmu_data __initconst = {
+       .pmc_base = DOVE_PMU_VIRT_BASE,
+       .pmu_base = DOVE_PMU_VIRT_BASE + 0x8000,
+       .irq = IRQ_DOVE_PMU,
+       .irq_domain_start = IRQ_DOVE_PMU_START,
+       .domains = pmu_domains,
+};
+
 void __init dove_init(void)
 {
        pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
@@ -389,6 +431,7 @@ void __init dove_init(void)
        dove_clk_init();
 
        /* internal devices that every board has */
+       dove_init_pmu_legacy(&pmu_data);
        dove_rtc_init();
        dove_xor0_init();
        dove_xor1_init();
index 76e26f9..bcb678f 100644 (file)
@@ -94,6 +94,7 @@ static void __init dove_db_init(void)
 
 MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
        .atag_offset    = 0x100,
+       .nr_irqs        = DOVE_NR_IRQS,
        .init_machine   = dove_db_init,
        .map_io         = dove_map_io,
        .init_early     = dove_init_early,
index 0c4b35f..00f4545 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef __ASM_ARCH_DOVE_H
 #define __ASM_ARCH_DOVE_H
 
+#include <mach/irqs.h>
+
 /*
  * Marvell Dove address maps.
  *
diff --git a/arch/arm/mach-dove/include/mach/entry-macro.S b/arch/arm/mach-dove/include/mach/entry-macro.S
deleted file mode 100644 (file)
index df1d44b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-dove/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for Marvell Dove platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <mach/bridge-regs.h>
-
-       .macro  get_irqnr_preamble, base, tmp
-       ldr     \base, =IRQ_VIRT_BASE
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       @ check low interrupts
-       ldr     \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
-       ldr     \tmp, [\base, #IRQ_MASK_LOW_OFF]
-       mov     \irqnr, #32
-       ands    \irqstat, \irqstat, \tmp
-
-       @ if no low interrupts set, check high interrupts
-       ldreq   \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
-       ldreq   \tmp, [\base, #IRQ_MASK_HIGH_OFF]
-       moveq   \irqnr, #64
-       andeqs  \irqstat, \irqstat, \tmp
-
-       @ find first active interrupt source
-       clzne   \irqstat, \irqstat
-       subne   \irqnr, \irqnr, \irqstat
-       .endm
index 3f29e6b..8ff0fa8 100644 (file)
@@ -90,7 +90,7 @@
 #define NR_PMU_IRQS            7
 #define IRQ_DOVE_RTC           (IRQ_DOVE_PMU_START + 5)
 
-#define NR_IRQS                        (IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+#define DOVE_NR_IRQS           (IRQ_DOVE_PMU_START + NR_PMU_IRQS)
 
 
 #endif
index b47f750..d22b9b1 100644 (file)
 #define  CLOCK_GATING_GIGA_PHY_MASK    (1 << CLOCK_GATING_BIT_GIGA_PHY)
 
 #define PMU_INTERRUPT_CAUSE    (DOVE_PMU_VIRT_BASE + 0x50)
-#define PMU_INTERRUPT_MASK     (DOVE_PMU_VIRT_BASE + 0x54)
 
-static inline int pmu_to_irq(int pin)
-{
-       if (pin < NR_PMU_IRQS)
-               return pin + IRQ_DOVE_PMU_START;
+#define  PMU_SW_RST_VIDEO_MASK         BIT(16)
+#define  PMU_SW_RST_GPU_MASK           BIT(18)
 
-       return -EINVAL;
-}
+#define  PMU_PWR_GPU_PWR_DWN_MASK      BIT(2)
+#define  PMU_PWR_VPU_PWR_DWN_MASK      BIT(3)
 
-static inline int irq_to_pmu(int irq)
-{
-       if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
-               return irq - IRQ_DOVE_PMU_START;
-
-       return -EINVAL;
-}
+#define  PMU_ISO_VIDEO_MASK            BIT(0)
+#define  PMU_ISO_GPU_MASK              BIT(1)
 
 #endif
index bfb3703..d6627c1 100644 (file)
@@ -7,87 +7,15 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/io.h>
-#include <asm/mach/arch.h>
+#include <asm/exception.h>
 #include <plat/irq.h>
-#include <asm/mach/irq.h>
-#include <mach/pm.h>
 #include <mach/bridge-regs.h>
 #include <plat/orion-gpio.h>
 #include "common.h"
 
-static void pmu_irq_mask(struct irq_data *d)
-{
-       int pin = irq_to_pmu(d->irq);
-       u32 u;
-
-       u = readl(PMU_INTERRUPT_MASK);
-       u &= ~(1 << (pin & 31));
-       writel(u, PMU_INTERRUPT_MASK);
-}
-
-static void pmu_irq_unmask(struct irq_data *d)
-{
-       int pin = irq_to_pmu(d->irq);
-       u32 u;
-
-       u = readl(PMU_INTERRUPT_MASK);
-       u |= 1 << (pin & 31);
-       writel(u, PMU_INTERRUPT_MASK);
-}
-
-static void pmu_irq_ack(struct irq_data *d)
-{
-       int pin = irq_to_pmu(d->irq);
-       u32 u;
-
-       /*
-        * The PMU mask register is not RW0C: it is RW.  This means that
-        * the bits take whatever value is written to them; if you write
-        * a '1', you will set the interrupt.
-        *
-        * Unfortunately this means there is NO race free way to clear
-        * these interrupts.
-        *
-        * So, let's structure the code so that the window is as small as
-        * possible.
-        */
-       u = ~(1 << (pin & 31));
-       u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
-       writel_relaxed(u, PMU_INTERRUPT_CAUSE);
-}
-
-static struct irq_chip pmu_irq_chip = {
-       .name           = "pmu_irq",
-       .irq_mask       = pmu_irq_mask,
-       .irq_unmask     = pmu_irq_unmask,
-       .irq_ack        = pmu_irq_ack,
-};
-
-static void pmu_irq_handler(struct irq_desc *desc)
-{
-       unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
-       unsigned int irq;
-
-       cause &= readl(PMU_INTERRUPT_MASK);
-       if (cause == 0) {
-               do_bad_IRQ(desc);
-               return;
-       }
-
-       for (irq = 0; irq < NR_PMU_IRQS; irq++) {
-               if (!(cause & (1 << irq)))
-                       continue;
-               irq = pmu_to_irq(irq);
-               generic_handle_irq(irq);
-       }
-}
-
 static int __initdata gpio0_irqs[4] = {
        IRQ_DOVE_GPIO_0_7,
        IRQ_DOVE_GPIO_8_15,
@@ -109,14 +37,6 @@ static int __initdata gpio2_irqs[4] = {
        0,
 };
 
-#ifdef CONFIG_MULTI_IRQ_HANDLER
-/*
- * Compiling with both non-DT and DT support enabled, will
- * break asm irq handler used by non-DT boards. Therefore,
- * we provide a C-style irq handler even for non-DT boards,
- * if MULTI_IRQ_HANDLER is set.
- */
-
 static void __iomem *dove_irq_base = IRQ_VIRT_BASE;
 
 static asmlinkage void
@@ -139,18 +59,13 @@ __exception_irq_entry dove_legacy_handle_irq(struct pt_regs *regs)
                return;
        }
 }
-#endif
 
 void __init dove_init_irq(void)
 {
-       int i;
-
        orion_irq_init(1, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
        orion_irq_init(33, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
 
-#ifdef CONFIG_MULTI_IRQ_HANDLER
        set_handle_irq(dove_legacy_handle_irq);
-#endif
 
        /*
         * Initialize gpiolib for GPIOs 0-71.
@@ -163,17 +78,4 @@ void __init dove_init_irq(void)
 
        orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
                        IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
-
-       /*
-        * Mask and clear PMU interrupts
-        */
-       writel(0, PMU_INTERRUPT_MASK);
-       writel(0, PMU_INTERRUPT_CAUSE);
-
-       for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
-               irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq);
-               irq_set_status_flags(i, IRQ_LEVEL);
-               irq_clear_status_flags(i, IRQ_NOREQUEST);
-       }
-       irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
 }
index ff10539..652a0bb 100644 (file)
@@ -8,7 +8,8 @@
 # Configuration options for the EXYNOS4
 
 menuconfig ARCH_EXYNOS
-       bool "Samsung EXYNOS" if ARCH_MULTI_V7
+       bool "Samsung EXYNOS"
+       depends on ARCH_MULTI_V7
        select ARCH_HAS_BANDGAP
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_REQUIRE_GPIOLIB
@@ -28,6 +29,9 @@ menuconfig ARCH_EXYNOS
        select THERMAL
        select MFD_SYSCON
        select CLKSRC_EXYNOS_MCT
+       select POWER_RESET
+       select POWER_RESET_SYSCON
+       select POWER_RESET_SYSCON_POWEROFF
        help
          Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
 
index 1534925..e349a03 100644 (file)
@@ -149,7 +149,7 @@ static inline void exynos_pm_init(void) {}
 extern void exynos_cpu_resume(void);
 extern void exynos_cpu_resume_ns(void);
 
-extern struct smp_operations exynos_smp_ops;
+extern const struct smp_operations exynos_smp_ops;
 
 extern void exynos_cpu_power_down(int cpu);
 extern void exynos_cpu_power_up(int cpu);
index 98a2c0c..5bd9559 100644 (file)
@@ -479,7 +479,7 @@ static void exynos_cpu_die(unsigned int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-struct smp_operations exynos_smp_ops __initdata = {
+const struct smp_operations exynos_smp_ops __initconst = {
        .smp_init_cpus          = exynos_smp_init_cpus,
        .smp_prepare_cpus       = exynos_smp_prepare_cpus,
        .smp_secondary_init     = exynos_secondary_init,
index c21e41d..dbf9fe9 100644 (file)
@@ -14,9 +14,8 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
 
+#include <asm/cputype.h>
 
 #include "exynos-pmu.h"
 #include "regs-pmu.h"
@@ -681,23 +680,6 @@ static unsigned int const exynos5420_list_disable_pmu_reg[] = {
        EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
 };
 
-static void exynos_power_off(void)
-{
-       unsigned int tmp;
-
-       pr_info("Power down.\n");
-       tmp = pmu_raw_readl(EXYNOS_PS_HOLD_CONTROL);
-       tmp ^= (1 << 8);
-       pmu_raw_writel(tmp, EXYNOS_PS_HOLD_CONTROL);
-
-       /* Wait a little so we don't give a false warning below */
-       mdelay(100);
-
-       pr_err("Power down failed, please power off system manually.\n");
-       while (1)
-               ;
-}
-
 static void exynos5420_powerdown_conf(enum sys_powerdown mode)
 {
        u32 this_cluster;
@@ -879,14 +861,6 @@ static void exynos5420_pmu_init(void)
        pr_info("EXYNOS5420 PMU initialized\n");
 }
 
-static int pmu_restart_notify(struct notifier_block *this,
-               unsigned long code, void *unused)
-{
-       pmu_raw_writel(0x1, EXYNOS_SWRESET);
-
-       return NOTIFY_DONE;
-}
-
 static const struct exynos_pmu_data exynos3250_pmu_data = {
        .pmu_config     = exynos3250_pmu_config,
        .pmu_init       = exynos3250_pmu_init,
@@ -912,7 +886,7 @@ static const struct exynos_pmu_data exynos5250_pmu_data = {
        .powerdown_conf = exynos5_powerdown_conf,
 };
 
-static struct exynos_pmu_data exynos5420_pmu_data = {
+static const struct exynos_pmu_data exynos5420_pmu_data = {
        .pmu_config     = exynos5420_pmu_config,
        .pmu_init       = exynos5420_pmu_init,
        .powerdown_conf = exynos5420_powerdown_conf,
@@ -944,20 +918,11 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = {
        { /*sentinel*/ },
 };
 
-/*
- * Exynos PMU restart notifier, handles restart functionality
- */
-static struct notifier_block pmu_restart_handler = {
-       .notifier_call = pmu_restart_notify,
-       .priority = 128,
-};
-
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match;
        struct device *dev = &pdev->dev;
        struct resource *res;
-       int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        pmu_base_addr = devm_ioremap_resource(dev, res);
@@ -982,12 +947,6 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, pmu_context);
 
-       ret = register_restart_handler(&pmu_restart_handler);
-       if (ret)
-               dev_warn(dev, "can't register restart handler err=%d\n", ret);
-
-       pm_power_off = exynos_power_off;
-
        dev_dbg(dev, "Exynos PMU Driver probe done\n");
        return 0;
 }
index fba9068..5e4f4c2 100644 (file)
 
 #define EXYNOS5420_SWRESET_KFC_SEL                             0x3
 
-#include <asm/cputype.h>
-#define MAX_CPUS_IN_CLUSTER    4
-
-static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
-{
-       return ((MPIDR_AFFINITY_LEVEL(mpidr, 1) * MAX_CPUS_IN_CLUSTER)
-                + MPIDR_AFFINITY_LEVEL(mpidr, 0));
-}
-
 /* Only for EXYNOS5420 */
 #define EXYNOS5420_ISP_ARM_OPTION                              0x2488
 #define EXYNOS5420_L2RSTDISABLE_VALUE                          BIT(3)
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S
deleted file mode 100644 (file)
index 02247f3..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* arch/arm/mach-footbridge/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 <asm/hardware/dec21285.h>
-
-#include <mach/hardware.h>
-       /* For EBSA285 debugging */
-               .equ    dc21285_high, ARMCSR_BASE & 0xff000000
-               .equ    dc21285_low,  ARMCSR_BASE & 0x00ffffff
-
-               .macro  addruart, rp, rv, tmp
-               .if     dc21285_low
-               mov     \rp, #dc21285_low
-               .else
-               mov     \rp, #0
-               .endif
-               orr     \rv, \rp, #dc21285_high
-               orr     \rp, \rp, #0x42000000
-               .endm
-
-               .macro  senduart,rd,rx
-               str     \rd, [\rx, #0x160]      @ UARTDR
-               .endm
-
-               .macro  busyuart,rd,rx
-1001:          ldr     \rd, [\rx, #0x178]      @ UARTFLG
-               tst     \rd, #1 << 3
-               bne     1001b
-               .endm
-
-               .macro  waituart,rd,rx
-               .endm
index 31aa866..81110ec 100644 (file)
@@ -1,5 +1,6 @@
 config ARCH_HIGHBANK
-       bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
+       bool "Calxeda ECX-1000/2000 (Highbank/Midway)"
+       depends on ARCH_MULTI_V7
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_SUPPORTS_BIG_ENDIAN
index 83061ad..a3b091a 100644 (file)
@@ -13,7 +13,8 @@ if ARCH_HISI
 menu "Hisilicon platform type"
 
 config ARCH_HI3xxx
-       bool "Hisilicon Hi36xx family" if ARCH_MULTI_V7
+       bool "Hisilicon Hi36xx family"
+       depends on ARCH_MULTI_V7
        select CACHE_L2X0
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
@@ -23,7 +24,8 @@ config ARCH_HI3xxx
          Support for Hisilicon Hi36xx SoC family
 
 config ARCH_HIP01
-       bool "Hisilicon HIP01 family" if ARCH_MULTI_V7
+       bool "Hisilicon HIP01 family"
+       depends on ARCH_MULTI_V7
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select ARM_GLOBAL_TIMER
@@ -31,7 +33,8 @@ config ARCH_HIP01
          Support for Hisilicon HIP01 SoC family
 
 config ARCH_HIP04
-       bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
+       bool "Hisilicon HiP04 Cortex A15 family"
+       depends on ARCH_MULTI_V7
        select ARM_ERRATA_798181 if SMP
        select HAVE_ARM_ARCH_TIMER
        select MCPM if SMP
@@ -40,7 +43,8 @@ config ARCH_HIP04
          Support for Hisilicon HiP04 SoC family
 
 config ARCH_HIX5HD2
-       bool "Hisilicon X5HD2 family" if ARCH_MULTI_V7
+       bool "Hisilicon X5HD2 family"
+       depends on ARCH_MULTI_V7
        select CACHE_L2X0
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
index c7648ef..e883583 100644 (file)
@@ -6,17 +6,14 @@
 extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
 extern int hi3xxx_get_cpu_jump(int cpu);
 extern void secondary_startup(void);
-extern struct smp_operations hi3xxx_smp_ops;
 
 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 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
index b5f8f5f..4b653a8 100644 (file)
@@ -239,7 +239,7 @@ err:
 }
 #endif
 
-static struct smp_operations __initdata hip04_smp_ops = {
+static const struct smp_operations hip04_smp_ops __initconst = {
        .smp_boot_secondary     = hip04_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_die                = hip04_cpu_die,
index 5174412..47ed32c 100644 (file)
@@ -89,7 +89,7 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-struct smp_operations hi3xxx_smp_ops __initdata = {
+static const struct smp_operations hi3xxx_smp_ops __initconst = {
        .smp_prepare_cpus       = hi3xxx_smp_prepare_cpus,
        .smp_boot_secondary     = hi3xxx_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
 }
 
 
-struct smp_operations hix5hd2_smp_ops __initdata = {
+static const struct smp_operations hix5hd2_smp_ops __initconst = {
        .smp_prepare_cpus       = hisi_common_smp_prepare_cpus,
        .smp_boot_secondary     = hix5hd2_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -176,7 +176,7 @@ static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-struct smp_operations hip01_smp_ops __initdata = {
+static const struct smp_operations hip01_smp_ops __initconst = {
        .smp_prepare_cpus       = hisi_common_smp_prepare_cpus,
        .smp_boot_secondary     = hip01_boot_secondary,
 };
index 8ceda28..15df34f 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_MXC
-       bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
+       bool "Freescale i.MX family"
+       depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
        select CLKSRC_IMX_GPT
@@ -562,6 +563,7 @@ config SOC_IMX7D
        select ARM_GIC
        select HAVE_IMX_ANATOP
        select HAVE_IMX_MMDC
+       select HAVE_IMX_SRC
        help
                This enables support for Freescale i.MX7 Dual processor.
 
@@ -596,7 +598,8 @@ choice
        default VF_USE_ARM_GLOBAL_TIMER
 
        config VF_USE_ARM_GLOBAL_TIMER
-               bool "Use ARM Global Timer" if ARCH_MULTI_V7
+               bool "Use ARM Global Timer"
+               depends on ARCH_MULTI_V7
                select ARM_GLOBAL_TIMER
                select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
                help
index e2d5383..32b83f0 100644 (file)
@@ -153,7 +153,7 @@ void imx_init_l2cache(void);
 static inline void imx_init_l2cache(void) {}
 #endif
 
-extern struct smp_operations imx_smp_ops;
-extern struct smp_operations ls1021a_smp_ops;
+extern const struct smp_operations imx_smp_ops;
+extern const struct smp_operations ls1021a_smp_ops;
 
 #endif
index 6dd22ca..0b5ba4b 100644 (file)
@@ -100,7 +100,7 @@ int mxc_iomux_alloc_pin(unsigned int pin, const char *label)
        unsigned pad = pin & IOMUX_PADNUM_MASK;
 
        if (pad >= (PIN_MAX + 1)) {
-               printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+               printk(KERN_ERR "mxc_iomux: Attempt to request nonexistent pin %u for \"%s\"\n",
                        pad, label ? label : "?");
                return -EINVAL;
        }
index acaf705..a38b16b 100644 (file)
@@ -84,7 +84,7 @@ static void __init imx6ul_init_late(void)
                platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
 }
 
-static const char *imx6ul_dt_compat[] __initconst = {
+static const char * const imx6ul_dt_compat[] __initconst = {
        "fsl,imx6ul",
        NULL,
 };
index b450f52..5a27f20 100644 (file)
@@ -105,6 +105,11 @@ static void __init imx7d_init_irq(void)
        irqchip_init();
 }
 
+static void __init imx7d_init_late(void)
+{
+       platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
 static const char *const imx7d_dt_compat[] __initconst = {
        "fsl,imx7d",
        NULL,
@@ -112,6 +117,7 @@ static const char *const imx7d_dt_compat[] __initconst = {
 
 DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
        .init_irq       = imx7d_init_irq,
+       .init_late      = imx7d_init_late,
        .init_machine   = imx7d_init_machine,
        .dt_compat      = imx7d_dt_compat,
 MACHINE_END
index 7f27001..711dbbd 100644 (file)
@@ -88,7 +88,7 @@ static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
        sync_cache_w(&g_diag_reg);
 }
 
-struct smp_operations  imx_smp_ops __initdata = {
+const struct smp_operations imx_smp_ops __initconst = {
        .smp_init_cpus          = imx_smp_init_cpus,
        .smp_prepare_cpus       = imx_smp_prepare_cpus,
        .smp_boot_secondary     = imx_boot_secondary,
@@ -123,7 +123,7 @@ static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
        iounmap(dcfg_base);
 }
 
-struct smp_operations  ls1021a_smp_ops __initdata = {
+const struct smp_operations ls1021a_smp_ops __initconst = {
        .smp_prepare_cpus       = ls1021a_smp_prepare_cpus,
        .smp_boot_secondary     = ls1021a_boot_secondary,
 };
index 02d0834..b01bdc9 100644 (file)
@@ -1,5 +1,6 @@
-config ARCH_INTEGRATOR
-       bool "ARM Ltd. Integrator family" if (ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+menuconfig ARCH_INTEGRATOR
+       bool "ARM Ltd. Integrator family"
+       depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6
        select ARM_AMBA
        select ARM_PATCH_PHYS_VIRT if MMU
        select AUTO_ZRELADDR
@@ -23,8 +24,6 @@ config ARCH_INTEGRATOR
 
 if ARCH_INTEGRATOR
 
-menu "Integrator Options"
-
 config ARCH_INTEGRATOR_AP
        bool "Support Integrator/AP and Integrator/PP2 platforms"
        select CLKSRC_MMIO
@@ -36,19 +35,6 @@ config ARCH_INTEGRATOR_AP
          Include support for the ARM(R) Integrator/AP and
          Integrator/PP2 platforms.
 
-config ARCH_INTEGRATOR_CP
-       bool "Support Integrator/CP platform"
-       select ARCH_CINTEGRATOR
-       select ARM_TIMER_SP804
-       select SERIAL_AMBA_PL011 if TTY
-       select SERIAL_AMBA_PL011_CONSOLE if TTY
-       select SOC_BUS
-       help
-         Include support for the ARM(R) Integrator CP platform.
-
-config ARCH_CINTEGRATOR
-       bool
-
 config INTEGRATOR_IMPD1
        bool "Include support for Integrator/IM-PD1"
        depends on ARCH_INTEGRATOR_AP
@@ -63,6 +49,119 @@ config INTEGRATOR_IMPD1
          To compile this driver as a module, choose M here: the
          module will be called impd1.
 
-endmenu
+config INTEGRATOR_CM7TDMI
+       bool "Integrator/CM7TDMI core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4 && !MMU
+       select CPU_ARM7TDMI
+
+config INTEGRATOR_CM720T
+       bool "Integrator/CM720T core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4T
+       select CPU_ARM720T
+
+config INTEGRATOR_CM740T
+       bool "Integrator/CM740T core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4T && !MMU
+       select CPU_ARM740T
+
+config INTEGRATOR_CM920T
+       bool "Integrator/CM920T core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4T
+       select CPU_ARM920T
+
+config INTEGRATOR_CM922T_XA10
+       bool "Integrator/CM922T-XA10 core module"
+       depends on ARCH_MULTI_V4T
+       depends on ARCH_INTEGRATOR_AP
+       select CPU_ARM922T
+
+config INTEGRATOR_CM926EJS
+       bool "Integrator/CM926EJ-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM926T
+
+config INTEGRATOR_CM940T
+       bool "Integrator/CM940T core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4T && !MMU
+       select CPU_ARM940T
+
+config INTEGRATOR_CM946ES
+       bool "Integrator/CM946E-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5 && !MMU
+       select CPU_ARM946E
+
+config INTEGRATOR_CM966ES
+       bool "Integrator/CM966E-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on BROKEN # no kernel support
+
+config INTEGRATOR_CM10200E_REV0
+       bool "Integrator/CM10200E rev.0 core module"
+       depends on ARCH_INTEGRATOR_AP && n
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1020
+
+config INTEGRATOR_CM10200E
+       bool "Integrator/CM10200E core module"
+       depends on ARCH_INTEGRATOR_AP && n
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1020E
+
+config INTEGRATOR_CM10220E
+       bool "Integrator/CM10220E core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1022
+
+config INTEGRATOR_CM1026EJS
+       bool "Integrator/CM1026EJ-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1026
+
+config INTEGRATOR_CM1136JFS
+       bool "Integrator/CM1136JF-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V6
+       select CPU_V6
+
+config ARCH_INTEGRATOR_CP
+       bool "Support Integrator/CP platform"
+       depends on (!MMU || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+       select ARM_TIMER_SP804
+       select SERIAL_AMBA_PL011 if TTY
+       select SERIAL_AMBA_PL011_CONSOLE if TTY
+       select SOC_BUS
+       help
+         Include support for the ARM(R) Integrator CP platform.
+
+config INTEGRATOR_CT7T
+       bool "Integrator/CT7TD (ARM7TDMI) core tile"
+       depends on ARCH_INTEGRATOR_CP
+       depends on ARCH_MULTI_V4T && !MMU
+       select CPU_ARM7TDMI
+
+config INTEGRATOR_CT926
+       bool "Integrator/CT926 (ARM926EJ-S) core tile"
+       depends on ARCH_INTEGRATOR_CP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM926T
+
+config INTEGRATOR_CTB36
+       bool "Integrator/CTB36 (ARM1136JF-S) core tile"
+       depends on ARCH_INTEGRATOR_CP
+       depends on ARCH_MULTI_V6
+       select CPU_V6
+
+config ARCH_CINTEGRATOR
+       depends on ARCH_INTEGRATOR_CP
+       def_bool y
 
 endif
diff --git a/arch/arm/mach-iop13xx/include/mach/msi.h b/arch/arm/mach-iop13xx/include/mach/msi.h
deleted file mode 100644 (file)
index b80c5ae..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _IOP13XX_MSI_H_
-#define _IOP13XX_MSI_H_
-#ifdef CONFIG_PCI_MSI
-void iop13xx_msi_init(void);
-#else
-static inline void iop13xx_msi_init(void)
-{
-       return;
-}
-#endif
-#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
deleted file mode 100644 (file)
index 59f42b5..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _IOP13XX_PCI_H_
-#define _IOP13XX_PCI_H_
-#include <linux/io.h>
-#include <mach/irqs.h>
-
-struct pci_sys_data;
-struct hw_pci;
-int iop13xx_pci_setup(int nr, struct pci_sys_data *sys);
-struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *);
-void iop13xx_atu_select(struct hw_pci *plat_pci);
-void iop13xx_pci_init(void);
-void iop13xx_map_pci_memory(void);
-
-#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |           \
-                              PCI_STATUS_SIG_TARGET_ABORT | \
-                              PCI_STATUS_REC_TARGET_ABORT | \
-                              PCI_STATUS_REC_TARGET_ABORT | \
-                              PCI_STATUS_REC_MASTER_ABORT | \
-                              PCI_STATUS_SIG_SYSTEM_ERROR | \
-                              PCI_STATUS_DETECTED_PARITY)
-
-#define IOP13XX_ATUE_ATUISR_ERROR (IOP13XX_ATUE_STAT_HALT_ON_ERROR |  \
-                                   IOP13XX_ATUE_STAT_ROOT_SYS_ERR |   \
-                                   IOP13XX_ATUE_STAT_PCI_IFACE_ERR |  \
-                                   IOP13XX_ATUE_STAT_ERR_COR |        \
-                                   IOP13XX_ATUE_STAT_ERR_UNCOR |      \
-                                   IOP13XX_ATUE_STAT_CRS |            \
-                                   IOP13XX_ATUE_STAT_DET_PAR_ERR |    \
-                                   IOP13XX_ATUE_STAT_EXT_REC_MABORT | \
-                                   IOP13XX_ATUE_STAT_SIG_TABORT |     \
-                                   IOP13XX_ATUE_STAT_EXT_REC_TABORT | \
-                                   IOP13XX_ATUE_STAT_MASTER_DATA_PAR)
-
-#define IOP13XX_ATUX_ATUISR_ERROR (IOP13XX_ATUX_STAT_TX_SCEM |        \
-                                   IOP13XX_ATUX_STAT_REC_SCEM |       \
-                                   IOP13XX_ATUX_STAT_TX_SERR |        \
-                                   IOP13XX_ATUX_STAT_DET_PAR_ERR |    \
-                                   IOP13XX_ATUX_STAT_INT_REC_MABORT | \
-                                   IOP13XX_ATUX_STAT_REC_SERR |       \
-                                   IOP13XX_ATUX_STAT_EXT_REC_MABORT | \
-                                   IOP13XX_ATUX_STAT_EXT_REC_TABORT | \
-                                   IOP13XX_ATUX_STAT_EXT_SIG_TABORT | \
-                                   IOP13XX_ATUX_STAT_MASTER_DATA_PAR)
-
-/* PCI interrupts
- */
-#define ATUX_INTA IRQ_IOP13XX_XINT0
-#define ATUX_INTB IRQ_IOP13XX_XINT1
-#define ATUX_INTC IRQ_IOP13XX_XINT2
-#define ATUX_INTD IRQ_IOP13XX_XINT3
-
-#define ATUE_INTA IRQ_IOP13XX_ATUE_IMA
-#define ATUE_INTB IRQ_IOP13XX_ATUE_IMB
-#define ATUE_INTC IRQ_IOP13XX_ATUE_IMC
-#define ATUE_INTD IRQ_IOP13XX_ATUE_IMD
-
-#endif /* _IOP13XX_PCI_H_ */
index 9cd07d3..d255ab5 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/pci.h>
+#include "pci.h"
 #include <asm/mach/time.h>
 #include <mach/time.h>
 
index b3ec11c..33eeaf1 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/pci.h>
+#include "pci.h"
 #include <asm/mach/time.h>
 #include <mach/time.h>
 
index 623d85a..c702cc4 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <mach/msi.h>
+#include "msi.h"
 
 /* INTCTL0 CP6 R0 Page 4
  */
diff --git a/arch/arm/mach-iop13xx/msi.h b/arch/arm/mach-iop13xx/msi.h
new file mode 100644 (file)
index 0000000..b80c5ae
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _IOP13XX_MSI_H_
+#define _IOP13XX_MSI_H_
+#ifdef CONFIG_PCI_MSI
+void iop13xx_msi_init(void);
+#else
+static inline void iop13xx_msi_init(void)
+{
+       return;
+}
+#endif
+#endif
index 9082b84..204eb44 100644 (file)
@@ -27,7 +27,7 @@
 #include <asm/sizes.h>
 #include <asm/signal.h>
 #include <asm/mach/pci.h>
-#include <mach/pci.h>
+#include "pci.h"
 
 #define IOP13XX_PCI_DEBUG 0
 #define PRINTK(x...) ((void)(IOP13XX_PCI_DEBUG && printk(x)))
index d45a80b..71b9c57 100644 (file)
@@ -1,6 +1,64 @@
+#ifndef _IOP13XX_PCI_H_
+#define _IOP13XX_PCI_H_
+#include <linux/io.h>
+#include <mach/irqs.h>
+
 #include <linux/types.h>
 
 extern void __iomem *iop13xx_atue_mem_base;
 extern void __iomem *iop13xx_atux_mem_base;
 extern size_t iop13xx_atue_mem_size;
 extern size_t iop13xx_atux_mem_size;
+
+struct pci_sys_data;
+struct hw_pci;
+int iop13xx_pci_setup(int nr, struct pci_sys_data *sys);
+struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *);
+void iop13xx_atu_select(struct hw_pci *plat_pci);
+void iop13xx_pci_init(void);
+void iop13xx_map_pci_memory(void);
+
+#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |           \
+                              PCI_STATUS_SIG_TARGET_ABORT | \
+                              PCI_STATUS_REC_TARGET_ABORT | \
+                              PCI_STATUS_REC_TARGET_ABORT | \
+                              PCI_STATUS_REC_MASTER_ABORT | \
+                              PCI_STATUS_SIG_SYSTEM_ERROR | \
+                              PCI_STATUS_DETECTED_PARITY)
+
+#define IOP13XX_ATUE_ATUISR_ERROR (IOP13XX_ATUE_STAT_HALT_ON_ERROR |  \
+                                   IOP13XX_ATUE_STAT_ROOT_SYS_ERR |   \
+                                   IOP13XX_ATUE_STAT_PCI_IFACE_ERR |  \
+                                   IOP13XX_ATUE_STAT_ERR_COR |        \
+                                   IOP13XX_ATUE_STAT_ERR_UNCOR |      \
+                                   IOP13XX_ATUE_STAT_CRS |            \
+                                   IOP13XX_ATUE_STAT_DET_PAR_ERR |    \
+                                   IOP13XX_ATUE_STAT_EXT_REC_MABORT | \
+                                   IOP13XX_ATUE_STAT_SIG_TABORT |     \
+                                   IOP13XX_ATUE_STAT_EXT_REC_TABORT | \
+                                   IOP13XX_ATUE_STAT_MASTER_DATA_PAR)
+
+#define IOP13XX_ATUX_ATUISR_ERROR (IOP13XX_ATUX_STAT_TX_SCEM |        \
+                                   IOP13XX_ATUX_STAT_REC_SCEM |       \
+                                   IOP13XX_ATUX_STAT_TX_SERR |        \
+                                   IOP13XX_ATUX_STAT_DET_PAR_ERR |    \
+                                   IOP13XX_ATUX_STAT_INT_REC_MABORT | \
+                                   IOP13XX_ATUX_STAT_REC_SERR |       \
+                                   IOP13XX_ATUX_STAT_EXT_REC_MABORT | \
+                                   IOP13XX_ATUX_STAT_EXT_REC_TABORT | \
+                                   IOP13XX_ATUX_STAT_EXT_SIG_TABORT | \
+                                   IOP13XX_ATUX_STAT_MASTER_DATA_PAR)
+
+/* PCI interrupts
+ */
+#define ATUX_INTA IRQ_IOP13XX_XINT0
+#define ATUX_INTB IRQ_IOP13XX_XINT1
+#define ATUX_INTC IRQ_IOP13XX_XINT2
+#define ATUX_INTD IRQ_IOP13XX_XINT3
+
+#define ATUE_INTA IRQ_IOP13XX_ATUE_IMA
+#define ATUE_INTB IRQ_IOP13XX_ATUE_IMB
+#define ATUE_INTC IRQ_IOP13XX_ATUE_IMC
+#define ATUE_INTD IRQ_IOP13XX_ATUE_IMD
+
+#endif /* _IOP13XX_PCI_H_ */
index cd04a1c..33eaa03 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef __ASSEMBLER__
 
-extern struct smp_operations keystone_smp_ops;
+extern const struct smp_operations keystone_smp_ops;
 extern void secondary_startup(void);
 extern u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr);
 extern int keystone_pm_runtime_init(void);
index 4bbb184..5665276 100644 (file)
@@ -39,6 +39,6 @@ static int keystone_smp_boot_secondary(unsigned int cpu,
        return error;
 }
 
-struct smp_operations keystone_smp_ops __initdata = {
+const struct smp_operations keystone_smp_ops __initconst = {
        .smp_boot_secondary     = keystone_smp_boot_secondary,
 };
index 9f9c044..e4d709c 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/devices.h>
+#include "devices.h"
 #include <mach/gpio-ks8695.h>
 
 #include "generic.h"
index d37c218..13537e9 100644 (file)
@@ -28,7 +28,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/devices.h>
+#include "devices.h"
 #include <mach/gpio-ks8695.h>
 
 #include "generic.h"
index 3acbdfd..69cfb99 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/gpio-ks8695.h>
-#include <mach/devices.h>
+#include "devices.h"
 
 #include "generic.h"
 
index f265816..1f4f2f4 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <mach/devices.h>
+#include "devices.h"
 #include <mach/regs-gpio.h>
 #include <mach/gpio-ks8695.h>
 #include "generic.h"
index fdf2352..46e455c 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/mtd/partitions.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/devices.h>
+#include "devices.h"
 #include "generic.h"
 
 /*
index ddb2422..474a050 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/regs-sys.h>
+#include "regs-sys.h"
 #include <mach/regs-misc.h>
 
 
index 47399bc..61cf20b 100644 (file)
@@ -24,9 +24,9 @@
 #include <linux/platform_device.h>
 
 #include <mach/irqs.h>
-#include <mach/regs-wan.h>
-#include <mach/regs-lan.h>
-#include <mach/regs-hpna.h>
+#include "regs-wan.h"
+#include "regs-lan.h"
+#include "regs-hpna.h"
 #include <mach/regs-switch.h>
 #include <mach/regs-misc.h>
 
diff --git a/arch/arm/mach-ks8695/devices.h b/arch/arm/mach-ks8695/devices.h
new file mode 100644 (file)
index 0000000..1e6594a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/devices.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * 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_DEVICES_H
+#define __ASM_ARCH_DEVICES_H
+
+#include <linux/pci.h>
+
+ /* Ethernet */
+extern void __init ks8695_add_device_wan(void);
+extern void __init ks8695_add_device_lan(void);
+extern void __init ks8695_add_device_hpna(void);
+
+ /* PCI */
+#define KS8695_MODE_PCI                0
+#define KS8695_MODE_MINIPCI    1
+#define KS8695_MODE_CARDBUS    2
+
+struct ks8695_pci_cfg {
+       short mode;
+       int (*map_irq)(const struct pci_dev *, u8, u8);
+};
+extern __init void ks8695_init_pci(struct ks8695_pci_cfg *);
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/devices.h b/arch/arm/mach-ks8695/include/mach/devices.h
deleted file mode 100644 (file)
index 1e6594a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/devices.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * 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_DEVICES_H
-#define __ASM_ARCH_DEVICES_H
-
-#include <linux/pci.h>
-
- /* Ethernet */
-extern void __init ks8695_add_device_wan(void);
-extern void __init ks8695_add_device_lan(void);
-extern void __init ks8695_add_device_hpna(void);
-
- /* PCI */
-#define KS8695_MODE_PCI                0
-#define KS8695_MODE_MINIPCI    1
-#define KS8695_MODE_CARDBUS    2
-
-struct ks8695_pci_cfg {
-       short mode;
-       int (*map_irq)(const struct pci_dev *, u8, u8);
-};
-extern __init void ks8695_init_pci(struct ks8695_pci_cfg *);
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-hpna.h b/arch/arm/mach-ks8695/include/mach/regs-hpna.h
deleted file mode 100644 (file)
index 815ce5c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-wan.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - HPNA Registers and bit definitions.
- *
- * 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 KS8695_HPNA_H
-#define KS8695_HPNA_H
-
-#define KS8695_HPNA_OFFSET     (0xF0000 + 0xA000)
-#define KS8695_HPNA_VA         (KS8695_IO_VA + KS8695_HPNA_OFFSET)
-#define KS8695_HPNA_PA         (KS8695_IO_PA + KS8695_HPNA_OFFSET)
-
-
-/*
- * HPNA registers
- */
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-lan.h b/arch/arm/mach-ks8695/include/mach/regs-lan.h
deleted file mode 100644 (file)
index 82c5f37..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-lan.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - LAN Registers and bit definitions.
- *
- * 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 KS8695_LAN_H
-#define KS8695_LAN_H
-
-#define KS8695_LAN_OFFSET      (0xF0000 + 0x8000)
-#define KS8695_LAN_VA          (KS8695_IO_VA + KS8695_LAN_OFFSET)
-#define KS8695_LAN_PA          (KS8695_IO_PA + KS8695_LAN_OFFSET)
-
-
-/*
- * LAN registers
- */
-#define KS8695_LMDTXC          (0x00)          /* DMA Transmit Control */
-#define KS8695_LMDRXC          (0x04)          /* DMA Receive Control */
-#define KS8695_LMDTSC          (0x08)          /* DMA Transmit Start Command */
-#define KS8695_LMDRSC          (0x0c)          /* DMA Receive Start Command */
-#define KS8695_LTDLB           (0x10)          /* Transmit Descriptor List Base Address */
-#define KS8695_LRDLB           (0x14)          /* Receive Descriptor List Base Address */
-#define KS8695_LMAL            (0x18)          /* MAC Station Address Low */
-#define KS8695_LMAH            (0x1c)          /* MAC Station Address High */
-#define KS8695_LMAAL(n)                (0x80 + ((n)*8))        /* MAC Additional Station Address (0..15) Low */
-#define KS8695_LMAAH(n)                (0x84 + ((n)*8))        /* MAC Additional Station Address (0..15) High */
-
-
-/* DMA Transmit Control Register */
-#define LMDTXC_LMTRST          (1    << 31)    /* Soft Reset */
-#define LMDTXC_LMTBS           (0x3f << 24)    /* Transmit Burst Size */
-#define LMDTXC_LMTUCG          (1    << 18)    /* Transmit UDP Checksum Generate */
-#define LMDTXC_LMTTCG          (1    << 17)    /* Transmit TCP Checksum Generate */
-#define LMDTXC_LMTICG          (1    << 16)    /* Transmit IP Checksum Generate */
-#define LMDTXC_LMTFCE          (1    <<  9)    /* Transmit Flow Control Enable */
-#define LMDTXC_LMTLB           (1    <<  8)    /* Loopback mode */
-#define LMDTXC_LMTEP           (1    <<  2)    /* Transmit Enable Padding */
-#define LMDTXC_LMTAC           (1    <<  1)    /* Transmit Add CRC */
-#define LMDTXC_LMTE            (1    <<  0)    /* TX Enable */
-
-/* DMA Receive Control Register */
-#define LMDRXC_LMRBS           (0x3f << 24)    /* Receive Burst Size */
-#define LMDRXC_LMRUCC          (1    << 18)    /* Receive UDP Checksum check */
-#define LMDRXC_LMRTCG          (1    << 17)    /* Receive TCP Checksum check */
-#define LMDRXC_LMRICG          (1    << 16)    /* Receive IP Checksum check */
-#define LMDRXC_LMRFCE          (1    <<  9)    /* Receive Flow Control Enable */
-#define LMDRXC_LMRB            (1    <<  6)    /* Receive Broadcast */
-#define LMDRXC_LMRM            (1    <<  5)    /* Receive Multicast */
-#define LMDRXC_LMRU            (1    <<  4)    /* Receive Unicast */
-#define LMDRXC_LMRERR          (1    <<  3)    /* Receive Error Frame */
-#define LMDRXC_LMRA            (1    <<  2)    /* Receive All */
-#define LMDRXC_LMRE            (1    <<  1)    /* RX Enable */
-
-/* Additional Station Address High */
-#define LMAAH_E                        (1    << 31)    /* Address Enabled */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-mem.h b/arch/arm/mach-ks8695/include/mach/regs-mem.h
deleted file mode 100644 (file)
index 55806bc..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-mem.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - Memory Controller registers and bit definitions
- *
- * 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 KS8695_MEM_H
-#define KS8695_MEM_H
-
-#define KS8695_MEM_OFFSET      (0xF0000 + 0x4000)
-#define KS8695_MEM_VA          (KS8695_IO_VA + KS8695_MEM_OFFSET)
-#define KS8695_MEM_PA          (KS8695_IO_PA + KS8695_MEM_OFFSET)
-
-
-/*
- * Memory Controller Registers
- */
-#define KS8695_EXTACON0                (0x00)          /* External I/O 0 Access Control */
-#define KS8695_EXTACON1                (0x04)          /* External I/O 1 Access Control */
-#define KS8695_EXTACON2                (0x08)          /* External I/O 2 Access Control */
-#define KS8695_ROMCON0         (0x10)          /* ROM/SRAM/Flash 1 Control Register */
-#define KS8695_ROMCON1         (0x14)          /* ROM/SRAM/Flash 2 Control Register */
-#define KS8695_ERGCON          (0x20)          /* External I/O and ROM/SRAM/Flash General Register */
-#define KS8695_SDCON0          (0x30)          /* SDRAM Control Register 0 */
-#define KS8695_SDCON1          (0x34)          /* SDRAM Control Register 1 */
-#define KS8695_SDGCON          (0x38)          /* SDRAM General Control */
-#define KS8695_SDBCON          (0x3c)          /* SDRAM Buffer Control */
-#define KS8695_REFTIM          (0x40)          /* SDRAM Refresh Timer */
-
-
-/* External I/O Access Control Registers */
-#define EXTACON_EBNPTR         (0x3ff << 22)           /* Last Address Pointer */
-#define EXTACON_EBBPTR         (0x3ff << 12)           /* Base Pointer */
-#define EXTACON_EBTACT         (7     <<  9)           /* Write Enable/Output Enable Active Time */
-#define EXTACON_EBTCOH         (7     <<  6)           /* Chip Select Hold Time */
-#define EXTACON_EBTACS         (7     <<  3)           /* Address Setup Time before ECSN */
-#define EXTACON_EBTCOS         (7     <<  0)           /* Chip Select Time before OEN */
-
-/* ROM/SRAM/Flash Control Register */
-#define ROMCON_RBNPTR          (0x3ff << 22)           /* Next Pointer */
-#define ROMCON_RBBPTR          (0x3ff << 12)           /* Base Pointer */
-#define ROMCON_RBTACC          (7     <<  4)           /* Access Cycle Time */
-#define ROMCON_RBTPA           (3     <<  2)           /* Page Address Access Time */
-#define ROMCON_PMC             (3     <<  0)           /* Page Mode Configuration */
-#define                PMC_NORMAL              (0 << 0)
-#define                PMC_4WORD               (1 << 0)
-#define                PMC_8WORD               (2 << 0)
-#define                PMC_16WORD              (3 << 0)
-
-/* External I/O and ROM/SRAM/Flash General Register */
-#define ERGCON_TMULT           (3 << 28)               /* Time Multiplier */
-#define ERGCON_DSX2            (3 << 20)               /* Data Width (External I/O Bank 2) */
-#define ERGCON_DSX1            (3 << 18)               /* Data Width (External I/O Bank 1) */
-#define ERGCON_DSX0            (3 << 16)               /* Data Width (External I/O Bank 0) */
-#define ERGCON_DSR1            (3 <<  2)               /* Data Width (ROM/SRAM/Flash Bank 1) */
-#define ERGCON_DSR0            (3 <<  0)               /* Data Width (ROM/SRAM/Flash Bank 0) */
-
-/* SDRAM Control Register */
-#define SDCON_DBNPTR           (0x3ff << 22)           /* Last Address Pointer */
-#define SDCON_DBBPTR           (0x3ff << 12)           /* Base Pointer */
-#define SDCON_DBCAB            (3     <<  8)           /* Column Address Bits */
-#define SDCON_DBBNUM           (1     <<  3)           /* Number of Banks */
-#define SDCON_DBDBW            (3     <<  1)           /* Data Bus Width */
-
-/* SDRAM General Control Register */
-#define SDGCON_SDTRC           (3 << 2)                /* RAS to CAS latency */
-#define SDGCON_SDCAS           (3 << 0)                /* CAS latency */
-
-/* SDRAM Buffer Control Register */
-#define SDBCON_SDESTA          (1 << 31)               /* SDRAM Engine Status */
-#define SDBCON_RBUFBDIS                (1 << 24)               /* Read Buffer Burst Enable */
-#define SDBCON_WFIFOEN         (1 << 23)               /* Write FIFO Enable */
-#define SDBCON_RBUFEN          (1 << 22)               /* Read Buffer Enable */
-#define SDBCON_FLUSHWFIFO      (1 << 21)               /* Flush Write FIFO */
-#define SDBCON_RBUFINV         (1 << 20)               /* Read Buffer Invalidate */
-#define SDBCON_SDINI           (3 << 16)               /* SDRAM Initialization Control */
-#define SDBCON_SDMODE          (0x3fff << 0)           /* SDRAM Mode Register Value Program */
-
-/* SDRAM Refresh Timer Register */
-#define REFTIM_REFTIM          (0xffff << 0)           /* Refresh Timer Value */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-pci.h b/arch/arm/mach-ks8695/include/mach/regs-pci.h
deleted file mode 100644 (file)
index 75a9db6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-pci.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - PCI bridge registers and bit definitions.
- *
- * 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.
- */
-
-#define KS8695_PCI_OFFSET      (0xF0000 + 0x2000)
-#define KS8695_PCI_VA          (KS8695_IO_VA + KS8695_PCI_OFFSET)
-#define KS8695_PCI_PA          (KS8695_IO_PA + KS8695_PCI_OFFSET)
-
-
-#define KS8695_CRCFID          (0x000)         /* Configuration: Identification */
-#define KS8695_CRCFCS          (0x004)         /* Configuration: Command and Status */
-#define KS8695_CRCFRV          (0x008)         /* Configuration: Revision */
-#define KS8695_CRCFLT          (0x00C)         /* Configuration: Latency Timer */
-#define KS8695_CRCBMA          (0x010)         /* Configuration: Base Memory Address */
-#define KS8695_CRCSID          (0x02C)         /* Configuration: Subsystem ID */
-#define KS8695_CRCFIT          (0x03C)         /* Configuration: Interrupt */
-#define KS8695_PBCA            (0x100)         /* Bridge Configuration Address */
-#define KS8695_PBCD            (0x104)         /* Bridge Configuration Data */
-#define KS8695_PBM             (0x200)         /* Bridge Mode */
-#define KS8695_PBCS            (0x204)         /* Bridge Control and Status */
-#define KS8695_PMBA            (0x208)         /* Bridge Memory Base Address */
-#define KS8695_PMBAC           (0x20C)         /* Bridge Memory Base Address Control */
-#define KS8695_PMBAM           (0x210)         /* Bridge Memory Base Address Mask */
-#define KS8695_PMBAT           (0x214)         /* Bridge Memory Base Address Translation */
-#define KS8695_PIOBA           (0x218)         /* Bridge I/O Base Address */
-#define KS8695_PIOBAC          (0x21C)         /* Bridge I/O Base Address Control */
-#define KS8695_PIOBAM          (0x220)         /* Bridge I/O Base Address Mask */
-#define KS8695_PIOBAT          (0x224)         /* Bridge I/O Base Address Translation */
-
-
-/* Configuration: Identification */
-
-/* Configuration: Command and Status */
-
-/* Configuration: Revision */
-
-
-
-#define CFRV_GUEST             (1 << 23)
-
-#define PBCA_TYPE1             (1)
-#define PBCA_ENABLE            (1 << 31)
-
-
diff --git a/arch/arm/mach-ks8695/include/mach/regs-sys.h b/arch/arm/mach-ks8695/include/mach/regs-sys.h
deleted file mode 100644 (file)
index 57c20be..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-sys.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - System control registers and bit definitions
- *
- * 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 KS8695_SYS_H
-#define KS8695_SYS_H
-
-#define KS8695_SYS_OFFSET      (0xF0000 + 0x0000)
-#define KS8695_SYS_VA          (KS8695_IO_VA + KS8695_SYS_OFFSET)
-#define KS8695_SYS_PA          (KS8695_IO_PA + KS8695_SYS_OFFSET)
-
-
-#define KS8695_SYSCFG          (0x00)          /* System Configuration Register */
-#define KS8695_CLKCON          (0x04)          /* System Clock and Bus Control Register */
-
-
-/* System Configuration Register */
-#define SYSCFG_SPRBP           (0x3ff << 16)   /* Register Bank Base Pointer */
-
-/* System Clock and Bus Control Register */
-#define CLKCON_SFMODE          (1 << 8)        /* System Fast Mode for Simulation */
-#define CLKCON_SCDC            (7 << 0)        /* System Clock Divider Select */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-wan.h b/arch/arm/mach-ks8695/include/mach/regs-wan.h
deleted file mode 100644 (file)
index c475bed..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-wan.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - WAN Registers and bit definitions.
- *
- * 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 KS8695_WAN_H
-#define KS8695_WAN_H
-
-#define KS8695_WAN_OFFSET      (0xF0000 + 0x6000)
-#define KS8695_WAN_VA          (KS8695_IO_VA + KS8695_WAN_OFFSET)
-#define KS8695_WAN_PA          (KS8695_IO_PA + KS8695_WAN_OFFSET)
-
-
-/*
- * WAN registers
- */
-#define KS8695_WMDTXC          (0x00)          /* DMA Transmit Control */
-#define KS8695_WMDRXC          (0x04)          /* DMA Receive Control */
-#define KS8695_WMDTSC          (0x08)          /* DMA Transmit Start Command */
-#define KS8695_WMDRSC          (0x0c)          /* DMA Receive Start Command */
-#define KS8695_WTDLB           (0x10)          /* Transmit Descriptor List Base Address */
-#define KS8695_WRDLB           (0x14)          /* Receive Descriptor List Base Address */
-#define KS8695_WMAL            (0x18)          /* MAC Station Address Low */
-#define KS8695_WMAH            (0x1c)          /* MAC Station Address High */
-#define KS8695_WMAAL(n)                (0x80 + ((n)*8))        /* MAC Additional Station Address (0..15) Low */
-#define KS8695_WMAAH(n)                (0x84 + ((n)*8))        /* MAC Additional Station Address (0..15) High */
-
-
-/* DMA Transmit Control Register */
-#define WMDTXC_WMTRST          (1    << 31)    /* Soft Reset */
-#define WMDTXC_WMTBS           (0x3f << 24)    /* Transmit Burst Size */
-#define WMDTXC_WMTUCG          (1    << 18)    /* Transmit UDP Checksum Generate */
-#define WMDTXC_WMTTCG          (1    << 17)    /* Transmit TCP Checksum Generate */
-#define WMDTXC_WMTICG          (1    << 16)    /* Transmit IP Checksum Generate */
-#define WMDTXC_WMTFCE          (1    <<  9)    /* Transmit Flow Control Enable */
-#define WMDTXC_WMTLB           (1    <<  8)    /* Loopback mode */
-#define WMDTXC_WMTEP           (1    <<  2)    /* Transmit Enable Padding */
-#define WMDTXC_WMTAC           (1    <<  1)    /* Transmit Add CRC */
-#define WMDTXC_WMTE            (1    <<  0)    /* TX Enable */
-
-/* DMA Receive Control Register */
-#define WMDRXC_WMRBS           (0x3f << 24)    /* Receive Burst Size */
-#define WMDRXC_WMRUCC          (1    << 18)    /* Receive UDP Checksum check */
-#define WMDRXC_WMRTCG          (1    << 17)    /* Receive TCP Checksum check */
-#define WMDRXC_WMRICG          (1    << 16)    /* Receive IP Checksum check */
-#define WMDRXC_WMRFCE          (1    <<  9)    /* Receive Flow Control Enable */
-#define WMDRXC_WMRB            (1    <<  6)    /* Receive Broadcast */
-#define WMDRXC_WMRM            (1    <<  5)    /* Receive Multicast */
-#define WMDRXC_WMRU            (1    <<  4)    /* Receive Unicast */
-#define WMDRXC_WMRERR          (1    <<  3)    /* Receive Error Frame */
-#define WMDRXC_WMRA            (1    <<  2)    /* Receive All */
-#define WMDRXC_WMRE            (1    <<  0)    /* RX Enable */
-
-/* Additional Station Address High */
-#define WMAAH_E                        (1    << 31)    /* Address Enabled */
-
-
-#endif
index c1bc4c3..577a35f 100644 (file)
@@ -33,8 +33,8 @@
 #include <asm/mach/pci.h>
 #include <mach/hardware.h>
 
-#include <mach/devices.h>
-#include <mach/regs-pci.h>
+#include "devices.h"
+#include "regs-pci.h"
 
 
 static int pci_dbg;
diff --git a/arch/arm/mach-ks8695/regs-hpna.h b/arch/arm/mach-ks8695/regs-hpna.h
new file mode 100644 (file)
index 0000000..815ce5c
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-wan.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - HPNA Registers and bit definitions.
+ *
+ * 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 KS8695_HPNA_H
+#define KS8695_HPNA_H
+
+#define KS8695_HPNA_OFFSET     (0xF0000 + 0xA000)
+#define KS8695_HPNA_VA         (KS8695_IO_VA + KS8695_HPNA_OFFSET)
+#define KS8695_HPNA_PA         (KS8695_IO_PA + KS8695_HPNA_OFFSET)
+
+
+/*
+ * HPNA registers
+ */
+
+#endif
diff --git a/arch/arm/mach-ks8695/regs-lan.h b/arch/arm/mach-ks8695/regs-lan.h
new file mode 100644 (file)
index 0000000..82c5f37
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-lan.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - LAN Registers and bit definitions.
+ *
+ * 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 KS8695_LAN_H
+#define KS8695_LAN_H
+
+#define KS8695_LAN_OFFSET      (0xF0000 + 0x8000)
+#define KS8695_LAN_VA          (KS8695_IO_VA + KS8695_LAN_OFFSET)
+#define KS8695_LAN_PA          (KS8695_IO_PA + KS8695_LAN_OFFSET)
+
+
+/*
+ * LAN registers
+ */
+#define KS8695_LMDTXC          (0x00)          /* DMA Transmit Control */
+#define KS8695_LMDRXC          (0x04)          /* DMA Receive Control */
+#define KS8695_LMDTSC          (0x08)          /* DMA Transmit Start Command */
+#define KS8695_LMDRSC          (0x0c)          /* DMA Receive Start Command */
+#define KS8695_LTDLB           (0x10)          /* Transmit Descriptor List Base Address */
+#define KS8695_LRDLB           (0x14)          /* Receive Descriptor List Base Address */
+#define KS8695_LMAL            (0x18)          /* MAC Station Address Low */
+#define KS8695_LMAH            (0x1c)          /* MAC Station Address High */
+#define KS8695_LMAAL(n)                (0x80 + ((n)*8))        /* MAC Additional Station Address (0..15) Low */
+#define KS8695_LMAAH(n)                (0x84 + ((n)*8))        /* MAC Additional Station Address (0..15) High */
+
+
+/* DMA Transmit Control Register */
+#define LMDTXC_LMTRST          (1    << 31)    /* Soft Reset */
+#define LMDTXC_LMTBS           (0x3f << 24)    /* Transmit Burst Size */
+#define LMDTXC_LMTUCG          (1    << 18)    /* Transmit UDP Checksum Generate */
+#define LMDTXC_LMTTCG          (1    << 17)    /* Transmit TCP Checksum Generate */
+#define LMDTXC_LMTICG          (1    << 16)    /* Transmit IP Checksum Generate */
+#define LMDTXC_LMTFCE          (1    <<  9)    /* Transmit Flow Control Enable */
+#define LMDTXC_LMTLB           (1    <<  8)    /* Loopback mode */
+#define LMDTXC_LMTEP           (1    <<  2)    /* Transmit Enable Padding */
+#define LMDTXC_LMTAC           (1    <<  1)    /* Transmit Add CRC */
+#define LMDTXC_LMTE            (1    <<  0)    /* TX Enable */
+
+/* DMA Receive Control Register */
+#define LMDRXC_LMRBS           (0x3f << 24)    /* Receive Burst Size */
+#define LMDRXC_LMRUCC          (1    << 18)    /* Receive UDP Checksum check */
+#define LMDRXC_LMRTCG          (1    << 17)    /* Receive TCP Checksum check */
+#define LMDRXC_LMRICG          (1    << 16)    /* Receive IP Checksum check */
+#define LMDRXC_LMRFCE          (1    <<  9)    /* Receive Flow Control Enable */
+#define LMDRXC_LMRB            (1    <<  6)    /* Receive Broadcast */
+#define LMDRXC_LMRM            (1    <<  5)    /* Receive Multicast */
+#define LMDRXC_LMRU            (1    <<  4)    /* Receive Unicast */
+#define LMDRXC_LMRERR          (1    <<  3)    /* Receive Error Frame */
+#define LMDRXC_LMRA            (1    <<  2)    /* Receive All */
+#define LMDRXC_LMRE            (1    <<  1)    /* RX Enable */
+
+/* Additional Station Address High */
+#define LMAAH_E                        (1    << 31)    /* Address Enabled */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/regs-mem.h b/arch/arm/mach-ks8695/regs-mem.h
new file mode 100644 (file)
index 0000000..55806bc
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-mem.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - Memory Controller registers and bit definitions
+ *
+ * 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 KS8695_MEM_H
+#define KS8695_MEM_H
+
+#define KS8695_MEM_OFFSET      (0xF0000 + 0x4000)
+#define KS8695_MEM_VA          (KS8695_IO_VA + KS8695_MEM_OFFSET)
+#define KS8695_MEM_PA          (KS8695_IO_PA + KS8695_MEM_OFFSET)
+
+
+/*
+ * Memory Controller Registers
+ */
+#define KS8695_EXTACON0                (0x00)          /* External I/O 0 Access Control */
+#define KS8695_EXTACON1                (0x04)          /* External I/O 1 Access Control */
+#define KS8695_EXTACON2                (0x08)          /* External I/O 2 Access Control */
+#define KS8695_ROMCON0         (0x10)          /* ROM/SRAM/Flash 1 Control Register */
+#define KS8695_ROMCON1         (0x14)          /* ROM/SRAM/Flash 2 Control Register */
+#define KS8695_ERGCON          (0x20)          /* External I/O and ROM/SRAM/Flash General Register */
+#define KS8695_SDCON0          (0x30)          /* SDRAM Control Register 0 */
+#define KS8695_SDCON1          (0x34)          /* SDRAM Control Register 1 */
+#define KS8695_SDGCON          (0x38)          /* SDRAM General Control */
+#define KS8695_SDBCON          (0x3c)          /* SDRAM Buffer Control */
+#define KS8695_REFTIM          (0x40)          /* SDRAM Refresh Timer */
+
+
+/* External I/O Access Control Registers */
+#define EXTACON_EBNPTR         (0x3ff << 22)           /* Last Address Pointer */
+#define EXTACON_EBBPTR         (0x3ff << 12)           /* Base Pointer */
+#define EXTACON_EBTACT         (7     <<  9)           /* Write Enable/Output Enable Active Time */
+#define EXTACON_EBTCOH         (7     <<  6)           /* Chip Select Hold Time */
+#define EXTACON_EBTACS         (7     <<  3)           /* Address Setup Time before ECSN */
+#define EXTACON_EBTCOS         (7     <<  0)           /* Chip Select Time before OEN */
+
+/* ROM/SRAM/Flash Control Register */
+#define ROMCON_RBNPTR          (0x3ff << 22)           /* Next Pointer */
+#define ROMCON_RBBPTR          (0x3ff << 12)           /* Base Pointer */
+#define ROMCON_RBTACC          (7     <<  4)           /* Access Cycle Time */
+#define ROMCON_RBTPA           (3     <<  2)           /* Page Address Access Time */
+#define ROMCON_PMC             (3     <<  0)           /* Page Mode Configuration */
+#define                PMC_NORMAL              (0 << 0)
+#define                PMC_4WORD               (1 << 0)
+#define                PMC_8WORD               (2 << 0)
+#define                PMC_16WORD              (3 << 0)
+
+/* External I/O and ROM/SRAM/Flash General Register */
+#define ERGCON_TMULT           (3 << 28)               /* Time Multiplier */
+#define ERGCON_DSX2            (3 << 20)               /* Data Width (External I/O Bank 2) */
+#define ERGCON_DSX1            (3 << 18)               /* Data Width (External I/O Bank 1) */
+#define ERGCON_DSX0            (3 << 16)               /* Data Width (External I/O Bank 0) */
+#define ERGCON_DSR1            (3 <<  2)               /* Data Width (ROM/SRAM/Flash Bank 1) */
+#define ERGCON_DSR0            (3 <<  0)               /* Data Width (ROM/SRAM/Flash Bank 0) */
+
+/* SDRAM Control Register */
+#define SDCON_DBNPTR           (0x3ff << 22)           /* Last Address Pointer */
+#define SDCON_DBBPTR           (0x3ff << 12)           /* Base Pointer */
+#define SDCON_DBCAB            (3     <<  8)           /* Column Address Bits */
+#define SDCON_DBBNUM           (1     <<  3)           /* Number of Banks */
+#define SDCON_DBDBW            (3     <<  1)           /* Data Bus Width */
+
+/* SDRAM General Control Register */
+#define SDGCON_SDTRC           (3 << 2)                /* RAS to CAS latency */
+#define SDGCON_SDCAS           (3 << 0)                /* CAS latency */
+
+/* SDRAM Buffer Control Register */
+#define SDBCON_SDESTA          (1 << 31)               /* SDRAM Engine Status */
+#define SDBCON_RBUFBDIS                (1 << 24)               /* Read Buffer Burst Enable */
+#define SDBCON_WFIFOEN         (1 << 23)               /* Write FIFO Enable */
+#define SDBCON_RBUFEN          (1 << 22)               /* Read Buffer Enable */
+#define SDBCON_FLUSHWFIFO      (1 << 21)               /* Flush Write FIFO */
+#define SDBCON_RBUFINV         (1 << 20)               /* Read Buffer Invalidate */
+#define SDBCON_SDINI           (3 << 16)               /* SDRAM Initialization Control */
+#define SDBCON_SDMODE          (0x3fff << 0)           /* SDRAM Mode Register Value Program */
+
+/* SDRAM Refresh Timer Register */
+#define REFTIM_REFTIM          (0xffff << 0)           /* Refresh Timer Value */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/regs-pci.h b/arch/arm/mach-ks8695/regs-pci.h
new file mode 100644 (file)
index 0000000..75a9db6
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-pci.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - PCI bridge registers and bit definitions.
+ *
+ * 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.
+ */
+
+#define KS8695_PCI_OFFSET      (0xF0000 + 0x2000)
+#define KS8695_PCI_VA          (KS8695_IO_VA + KS8695_PCI_OFFSET)
+#define KS8695_PCI_PA          (KS8695_IO_PA + KS8695_PCI_OFFSET)
+
+
+#define KS8695_CRCFID          (0x000)         /* Configuration: Identification */
+#define KS8695_CRCFCS          (0x004)         /* Configuration: Command and Status */
+#define KS8695_CRCFRV          (0x008)         /* Configuration: Revision */
+#define KS8695_CRCFLT          (0x00C)         /* Configuration: Latency Timer */
+#define KS8695_CRCBMA          (0x010)         /* Configuration: Base Memory Address */
+#define KS8695_CRCSID          (0x02C)         /* Configuration: Subsystem ID */
+#define KS8695_CRCFIT          (0x03C)         /* Configuration: Interrupt */
+#define KS8695_PBCA            (0x100)         /* Bridge Configuration Address */
+#define KS8695_PBCD            (0x104)         /* Bridge Configuration Data */
+#define KS8695_PBM             (0x200)         /* Bridge Mode */
+#define KS8695_PBCS            (0x204)         /* Bridge Control and Status */
+#define KS8695_PMBA            (0x208)         /* Bridge Memory Base Address */
+#define KS8695_PMBAC           (0x20C)         /* Bridge Memory Base Address Control */
+#define KS8695_PMBAM           (0x210)         /* Bridge Memory Base Address Mask */
+#define KS8695_PMBAT           (0x214)         /* Bridge Memory Base Address Translation */
+#define KS8695_PIOBA           (0x218)         /* Bridge I/O Base Address */
+#define KS8695_PIOBAC          (0x21C)         /* Bridge I/O Base Address Control */
+#define KS8695_PIOBAM          (0x220)         /* Bridge I/O Base Address Mask */
+#define KS8695_PIOBAT          (0x224)         /* Bridge I/O Base Address Translation */
+
+
+/* Configuration: Identification */
+
+/* Configuration: Command and Status */
+
+/* Configuration: Revision */
+
+
+
+#define CFRV_GUEST             (1 << 23)
+
+#define PBCA_TYPE1             (1)
+#define PBCA_ENABLE            (1 << 31)
+
+
diff --git a/arch/arm/mach-ks8695/regs-sys.h b/arch/arm/mach-ks8695/regs-sys.h
new file mode 100644 (file)
index 0000000..57c20be
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-sys.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - System control registers and bit definitions
+ *
+ * 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 KS8695_SYS_H
+#define KS8695_SYS_H
+
+#define KS8695_SYS_OFFSET      (0xF0000 + 0x0000)
+#define KS8695_SYS_VA          (KS8695_IO_VA + KS8695_SYS_OFFSET)
+#define KS8695_SYS_PA          (KS8695_IO_PA + KS8695_SYS_OFFSET)
+
+
+#define KS8695_SYSCFG          (0x00)          /* System Configuration Register */
+#define KS8695_CLKCON          (0x04)          /* System Clock and Bus Control Register */
+
+
+/* System Configuration Register */
+#define SYSCFG_SPRBP           (0x3ff << 16)   /* Register Bank Base Pointer */
+
+/* System Clock and Bus Control Register */
+#define CLKCON_SFMODE          (1 << 8)        /* System Fast Mode for Simulation */
+#define CLKCON_SCDC            (7 << 0)        /* System Clock Divider Select */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/regs-wan.h b/arch/arm/mach-ks8695/regs-wan.h
new file mode 100644 (file)
index 0000000..c475bed
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-wan.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - WAN Registers and bit definitions.
+ *
+ * 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 KS8695_WAN_H
+#define KS8695_WAN_H
+
+#define KS8695_WAN_OFFSET      (0xF0000 + 0x6000)
+#define KS8695_WAN_VA          (KS8695_IO_VA + KS8695_WAN_OFFSET)
+#define KS8695_WAN_PA          (KS8695_IO_PA + KS8695_WAN_OFFSET)
+
+
+/*
+ * WAN registers
+ */
+#define KS8695_WMDTXC          (0x00)          /* DMA Transmit Control */
+#define KS8695_WMDRXC          (0x04)          /* DMA Receive Control */
+#define KS8695_WMDTSC          (0x08)          /* DMA Transmit Start Command */
+#define KS8695_WMDRSC          (0x0c)          /* DMA Receive Start Command */
+#define KS8695_WTDLB           (0x10)          /* Transmit Descriptor List Base Address */
+#define KS8695_WRDLB           (0x14)          /* Receive Descriptor List Base Address */
+#define KS8695_WMAL            (0x18)          /* MAC Station Address Low */
+#define KS8695_WMAH            (0x1c)          /* MAC Station Address High */
+#define KS8695_WMAAL(n)                (0x80 + ((n)*8))        /* MAC Additional Station Address (0..15) Low */
+#define KS8695_WMAAH(n)                (0x84 + ((n)*8))        /* MAC Additional Station Address (0..15) High */
+
+
+/* DMA Transmit Control Register */
+#define WMDTXC_WMTRST          (1    << 31)    /* Soft Reset */
+#define WMDTXC_WMTBS           (0x3f << 24)    /* Transmit Burst Size */
+#define WMDTXC_WMTUCG          (1    << 18)    /* Transmit UDP Checksum Generate */
+#define WMDTXC_WMTTCG          (1    << 17)    /* Transmit TCP Checksum Generate */
+#define WMDTXC_WMTICG          (1    << 16)    /* Transmit IP Checksum Generate */
+#define WMDTXC_WMTFCE          (1    <<  9)    /* Transmit Flow Control Enable */
+#define WMDTXC_WMTLB           (1    <<  8)    /* Loopback mode */
+#define WMDTXC_WMTEP           (1    <<  2)    /* Transmit Enable Padding */
+#define WMDTXC_WMTAC           (1    <<  1)    /* Transmit Add CRC */
+#define WMDTXC_WMTE            (1    <<  0)    /* TX Enable */
+
+/* DMA Receive Control Register */
+#define WMDRXC_WMRBS           (0x3f << 24)    /* Receive Burst Size */
+#define WMDRXC_WMRUCC          (1    << 18)    /* Receive UDP Checksum check */
+#define WMDRXC_WMRTCG          (1    << 17)    /* Receive TCP Checksum check */
+#define WMDRXC_WMRICG          (1    << 16)    /* Receive IP Checksum check */
+#define WMDRXC_WMRFCE          (1    <<  9)    /* Receive Flow Control Enable */
+#define WMDRXC_WMRB            (1    <<  6)    /* Receive Broadcast */
+#define WMDRXC_WMRM            (1    <<  5)    /* Receive Multicast */
+#define WMDRXC_WMRU            (1    <<  4)    /* Receive Unicast */
+#define WMDRXC_WMRERR          (1    <<  3)    /* Receive Error Frame */
+#define WMDRXC_WMRA            (1    <<  2)    /* Receive All */
+#define WMDRXC_WMRE            (1    <<  0)    /* RX Enable */
+
+/* Additional Station Address High */
+#define WMAAH_E                        (1    << 31)    /* Address Enabled */
+
+
+#endif
index aeece17..0abcc51 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_MEDIATEK
-       bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
+       bool "Mediatek MT65xx & MT81xx SoC"
+       depends on ARCH_MULTI_V7
        select ARM_GIC
        select PINCTRL
        select MTK_TIMER
index d019a08..2f9f09a 100644 (file)
@@ -44,6 +44,7 @@ static void __init mediatek_timer_init(void)
 };
 
 static const char * const mediatek_board_dt_compat[] = {
+       "mediatek,mt2701",
        "mediatek,mt6589",
        "mediatek,mt6592",
        "mediatek,mt8127",
index 8141f3f..a1b07ee 100644 (file)
@@ -128,13 +128,13 @@ static void __init mtk_smp_prepare_cpus(unsigned int max_cpus)
        __mtk_smp_prepare_cpus(max_cpus, 0);
 }
 
-static struct smp_operations mt81xx_tz_smp_ops __initdata = {
+static const struct smp_operations mt81xx_tz_smp_ops __initconst = {
        .smp_prepare_cpus = mtk_tz_smp_prepare_cpus,
        .smp_boot_secondary = mtk_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops);
 
-static struct smp_operations mt6589_smp_ops __initdata = {
+static const struct smp_operations mt6589_smp_ops __initconst = {
        .smp_prepare_cpus = mtk_smp_prepare_cpus,
        .smp_boot_secondary = mtk_boot_secondary,
 };
index 5d56f86..31bdd91 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_MESON
-       bool "Amlogic Meson SoCs" if ARCH_MULTI_V7
+       bool "Amlogic Meson SoCs"
+       depends on ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_IRQ_CHIP
        select ARM_GIC
index fdbfadf..01c57d3 100644 (file)
@@ -1,9 +1,22 @@
+menuconfig ARCH_MMP
+       bool "Marvell PXA168/910/MMP2"
+       depends on ARCH_MULTI_V5 || ARCH_MULTI_V7
+       select ARCH_REQUIRE_GPIOLIB
+       select GPIO_PXA
+       select PINCTRL
+       select PLAT_PXA
+       help
+         Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
+
 if ARCH_MMP
 
-menu "Marvell PXA168/910/MMP2 Implmentations"
+menu "Marvell PXA168/910/MMP2 Implementations"
+
+if ATAGS
 
 config MACH_ASPENITE
        bool "Marvell's PXA168 Aspenite Development Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA168
        help
          Say 'Y' here if you want to support the Marvell PXA168-based
@@ -11,6 +24,7 @@ config MACH_ASPENITE
 
 config MACH_ZYLONITE2
        bool "Marvell's PXA168 Zylonite2 Development Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA168
        help
          Say 'Y' here if you want to support the Marvell PXA168-based
@@ -18,6 +32,7 @@ config MACH_ZYLONITE2
 
 config MACH_AVENGERS_LITE
        bool "Marvell's PXA168 Avengers Lite Development Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA168
        help
          Say 'Y' here if you want to support the Marvell PXA168-based
@@ -25,6 +40,7 @@ config MACH_AVENGERS_LITE
 
 config MACH_TAVOREVB
        bool "Marvell's PXA910 TavorEVB Development Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA910
        help
          Say 'Y' here if you want to support the Marvell PXA910-based
@@ -32,6 +48,7 @@ config MACH_TAVOREVB
 
 config MACH_TTC_DKB
        bool "Marvell's PXA910 TavorEVB Development Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA910
        help
          Say 'Y' here if you want to support the Marvell PXA910-based
@@ -39,7 +56,7 @@ config MACH_TTC_DKB
 
 config MACH_BROWNSTONE
        bool "Marvell's Brownstone Development Platform"
-       depends on !CPU_MOHAWK
+       depends on ARCH_MULTI_V7
        select CPU_MMP2
        help
          Say 'Y' here if you want to support the Marvell MMP2-based
@@ -50,7 +67,7 @@ config MACH_BROWNSTONE
 
 config MACH_FLINT
        bool "Marvell's Flint Development Platform"
-       depends on !CPU_MOHAWK
+       depends on ARCH_MULTI_V7
        select CPU_MMP2
        help
          Say 'Y' here if you want to support the Marvell MMP2-based
@@ -61,7 +78,7 @@ config MACH_FLINT
 
 config MACH_MARVELL_JASPER
        bool "Marvell's Jasper Development Platform"
-       depends on !CPU_MOHAWK
+       depends on ARCH_MULTI_V7
        select CPU_MMP2
        help
          Say 'Y' here if you want to support the Marvell MMP2-base
@@ -72,6 +89,7 @@ config MACH_MARVELL_JASPER
 
 config MACH_TETON_BGA
        bool "Marvell's PXA168 Teton BGA Development Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA168
        help
          Say 'Y' here if you want to support the Marvell PXA168-based
@@ -79,14 +97,16 @@ config MACH_TETON_BGA
 
 config MACH_GPLUGD
        bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
+       depends on ARCH_MULTI_V5
        select CPU_PXA168
        help
          Say 'Y' here if you want to support the Marvell PXA168-based
          GuruPlug Display (gplugD) Board
+endif
 
 config MACH_MMP_DT
        bool "Support MMP (ARMv5) platforms from device tree"
-       select USE_OF
+       depends on ARCH_MULTI_V5
        select PINCTRL
        select PINCTRL_SINGLE
        select COMMON_CLK
@@ -99,11 +119,9 @@ config MACH_MMP_DT
 
 config MACH_MMP2_DT
        bool "Support MMP2 (ARMv7) platforms from device tree"
-       depends on !CPU_MOHAWK
-       select USE_OF
+       depends on ARCH_MULTI_V7
        select PINCTRL
        select PINCTRL_SINGLE
-       select COMMON_CLK
        select ARCH_HAS_RESET_CONTROLLER
        select CPU_PJ4
        help
index 98f0f63..7677ad5 100644 (file)
@@ -1,6 +1,7 @@
 #
 # Makefile for Marvell's PXA168 processors line
 #
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-pxa/include
 
 obj-y                          += common.o devices.o time.o
 
diff --git a/arch/arm/mach-mmp/addr-map.h b/arch/arm/mach-mmp/addr-map.h
new file mode 100644 (file)
index 0000000..2739d27
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *   Common address map definitions
+ *
+ * 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_MACH_ADDR_MAP_H
+#define __ASM_MACH_ADDR_MAP_H
+
+/* APB - Application Subsystem Peripheral Bus
+ *
+ * NOTE: the DMA controller registers are actually on the AXI fabric #1
+ * slave port to AHB/APB bridge, due to its close relationship to those
+ * peripherals on APB, let's count it into the ABP mapping area.
+ */
+#define APB_PHYS_BASE          0xd4000000
+#define APB_VIRT_BASE          IOMEM(0xfe000000)
+#define APB_PHYS_SIZE          0x00200000
+
+#define AXI_PHYS_BASE          0xd4200000
+#define AXI_VIRT_BASE          IOMEM(0xfe200000)
+#define AXI_PHYS_SIZE          0x00200000
+
+/* Static Memory Controller - Chip Select 0 and 1 */
+#define SMC_CS0_PHYS_BASE      0x80000000
+#define SMC_CS0_PHYS_SIZE      0x10000000
+#define SMC_CS1_PHYS_BASE      0x90000000
+#define SMC_CS1_PHYS_SIZE      0x10000000
+
+#define APMU_VIRT_BASE         (AXI_VIRT_BASE + 0x82800)
+#define APMU_REG(x)            (APMU_VIRT_BASE + (x))
+
+#define APBC_VIRT_BASE         (APB_VIRT_BASE + 0x015000)
+#define APBC_REG(x)            (APBC_VIRT_BASE + (x))
+
+#define MPMU_VIRT_BASE         (APB_VIRT_BASE + 0x50000)
+#define MPMU_REG(x)            (MPMU_VIRT_BASE + (x))
+
+#define CIU_VIRT_BASE          (AXI_VIRT_BASE + 0x82c00)
+#define CIU_REG(x)             (CIU_VIRT_BASE + (x))
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
index 7e02485..5db0edf 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-pxa168.h>
-#include <mach/pxa168.h>
-#include <mach/irqs.h>
 #include <video/pxa168fb.h>
 #include <linux/input.h>
 #include <linux/platform_data/keypad-pxa27x.h>
 
+#include "addr-map.h"
+#include "mfp-pxa168.h"
+#include "pxa168.h"
+#include "irqs.h"
 #include "common.h"
 
 static unsigned long common_pin_config[] __initdata = {
index a451a0f..3d2aea8 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-pxa168.h>
-#include <mach/pxa168.h>
-#include <mach/irqs.h>
+#include "addr-map.h"
+#include "mfp-pxa168.h"
+#include "pxa168.h"
+#include "irqs.h"
 
 
 #include "common.h"
index ac25544..d1613b9 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-mmp2.h>
-#include <mach/mmp2.h>
-#include <mach/irqs.h>
+#include "addr-map.h"
+#include "mfp-mmp2.h"
+#include "mmp2.h"
+#include "irqs.h"
 
 #include "common.h"
 
index 53d77cb..835c3e7 100644 (file)
@@ -4,8 +4,9 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clk/mmp.h>
 
-#include <mach/addr-map.h>
+#include "addr-map.h"
 
 #include "common.h"
 #include "clock.h"
@@ -105,7 +106,8 @@ static struct clk_lookup mmp2_clkregs[] = {
        INIT_CLKREG(&clk_sdh3, "sdhci-pxav3.3", "PXA-SDHCLK"),
 };
 
-void __init mmp2_clk_init(void)
+void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+                         phys_addr_t apbc_phys)
 {
        clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
 }
index c572f21..f726a36 100644 (file)
@@ -4,8 +4,9 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clk/mmp.h>
 
-#include <mach/addr-map.h>
+#include "addr-map.h"
 
 #include "common.h"
 #include "clock.h"
@@ -85,7 +86,8 @@ static struct clk_lookup pxa168_clkregs[] = {
        INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
-void __init pxa168_clk_init(void)
+void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+                           phys_addr_t apbc_phys)
 {
        clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
 }
index 379e1df..bca60a2 100644 (file)
@@ -4,8 +4,9 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clk/mmp.h>
 
-#include <mach/addr-map.h>
+#include "addr-map.h"
 
 #include "common.h"
 #include "clock.h"
@@ -61,7 +62,8 @@ static struct clk_lookup pxa910_clkregs[] = {
        INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
-void __init pxa910_clk_init(void)
+void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+                           phys_addr_t apbc_phys, phys_addr_t apbcp_phys)
 {
        clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
 }
index 7c6f95f..ac6633d 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <mach/regs-apbc.h>
+#include "regs-apbc.h"
 #include "clock.h"
 
 static void apbc_clk_enable(struct clk *clk)
index 149b30c..8194445 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/arm/mach-mmp/clock.h
- *
  *  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.
index c03b4ab..685a099 100644 (file)
@@ -15,8 +15,8 @@
 #include <asm/page.h>
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
-#include <mach/addr-map.h>
-#include <mach/cputype.h>
+#include "addr-map.h"
+#include "cputype.h"
 
 #include "common.h"
 
index cf445ba..7453a90 100644 (file)
@@ -5,6 +5,3 @@ extern void timer_init(int irq);
 
 extern void __init mmp_map_io(void);
 extern void mmp_restart(enum reboot_mode, const char *);
-extern void __init pxa168_clk_init(void);
-extern void __init pxa910_clk_init(void);
-extern void __init mmp2_clk_init(void);
diff --git a/arch/arm/mach-mmp/cputype.h b/arch/arm/mach-mmp/cputype.h
new file mode 100644 (file)
index 0000000..8a3b56d
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __ASM_MACH_CPUTYPE_H
+#define __ASM_MACH_CPUTYPE_H
+
+#include <asm/cputype.h>
+
+/*
+ *  CPU   Stepping   CPU_ID      CHIP_ID
+ *
+ * PXA168    S0    0x56158400   0x0000C910
+ * PXA168    A0    0x56158400   0x00A0A168
+ * PXA910    Y1    0x56158400   0x00F2C920
+ * PXA910    A0    0x56158400   0x00F2C910
+ * PXA910    A1    0x56158400   0x00A0C910
+ * PXA920    Y0    0x56158400   0x00F2C920
+ * PXA920    A0    0x56158400   0x00A0C920
+ * PXA920    A1    0x56158400   0x00A1C920
+ * MMP2             Z0    0x560f5811   0x00F00410
+ * MMP2      Z1    0x560f5811   0x00E00410
+ * MMP2      A0    0x560f5811   0x00A0A610
+ */
+
+extern unsigned int mmp_chip_id;
+
+#ifdef CONFIG_CPU_PXA168
+static inline int cpu_is_pxa168(void)
+{
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+               ((mmp_chip_id & 0xfff) == 0x168);
+}
+#else
+#define cpu_is_pxa168()        (0)
+#endif
+
+/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */
+#ifdef CONFIG_CPU_PXA910
+static inline int cpu_is_pxa910(void)
+{
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+               (((mmp_chip_id & 0xfff) == 0x910) ||
+                ((mmp_chip_id & 0xfff) == 0x920));
+}
+#else
+#define cpu_is_pxa910()        (0)
+#endif
+
+#ifdef CONFIG_CPU_MMP2
+static inline int cpu_is_mmp2(void)
+{
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x58);
+}
+#else
+#define cpu_is_mmp2()  (0)
+#endif
+
+#endif /* __ASM_MACH_CPUTYPE_H */
index 2bcb766..3330ac7 100644 (file)
 #include <linux/delay.h>
 
 #include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/devices.h>
-#include <mach/cputype.h>
-#include <mach/regs-usb.h>
+#include "irqs.h"
+#include "devices.h"
+#include "cputype.h"
+#include "regs-usb.h"
 
 int __init pxa_register_device(struct pxa_device_desc *desc,
                                void *data, size_t size)
@@ -73,6 +73,8 @@ int __init pxa_register_device(struct pxa_device_desc *desc,
 }
 
 #if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET)
+#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
+#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)
 
 /*****************************************************************************
  * The registers read/write routines
@@ -112,9 +114,6 @@ static void u2o_write(void __iomem *base, unsigned int offset,
        readl_relaxed(base + offset);
 }
 
-#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
-
-#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)
 
 static DEFINE_MUTEX(phy_lock);
 static int phy_init_cnt;
diff --git a/arch/arm/mach-mmp/devices.h b/arch/arm/mach-mmp/devices.h
new file mode 100644 (file)
index 0000000..21217ef
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef __MACH_DEVICE_H
+#define __MACH_DEVICE_H
+
+#include <linux/types.h>
+
+#define MAX_RESOURCE_DMA       2
+
+/* structure for describing the on-chip devices */
+struct pxa_device_desc {
+       const char      *dev_name;
+       const char      *drv_name;
+       int             id;
+       int             irq;
+       unsigned long   start;
+       unsigned long   size;
+       int             dma[MAX_RESOURCE_DMA];
+};
+
+#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)  \
+struct pxa_device_desc pxa168_device_##_name __initdata = {            \
+       .dev_name       = "pxa168-" #_name,                             \
+       .drv_name       = _drv,                                         \
+       .id             = _id,                                          \
+       .irq            = IRQ_PXA168_##_irq,                            \
+       .start          = _start,                                       \
+       .size           = _size,                                        \
+       .dma            = { _dma },                                     \
+};
+
+#define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)  \
+struct pxa_device_desc pxa910_device_##_name __initdata = {            \
+       .dev_name       = "pxa910-" #_name,                             \
+       .drv_name       = _drv,                                         \
+       .id             = _id,                                          \
+       .irq            = IRQ_PXA910_##_irq,                            \
+       .start          = _start,                                       \
+       .size           = _size,                                        \
+       .dma            = { _dma },                                     \
+};
+
+#define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)    \
+struct pxa_device_desc mmp2_device_##_name __initdata = {              \
+       .dev_name       = "mmp2-" #_name,                               \
+       .drv_name       = _drv,                                         \
+       .id             = _id,                                          \
+       .irq            = IRQ_MMP2_##_irq,                              \
+       .start          = _start,                                       \
+       .size           = _size,                                        \
+       .dma            = { _dma },                                     \
+}
+
+extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
+extern int pxa_usb_phy_init(void __iomem *phy_reg);
+extern void pxa_usb_phy_deinit(void __iomem *phy_reg);
+
+#endif /* __MACH_DEVICE_H */
index 6291c33..078b980 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-mmp2.h>
-#include <mach/mmp2.h>
-#include <mach/irqs.h>
+#include "addr-map.h"
+#include "mfp-mmp2.h"
+#include "mmp2.h"
+#include "irqs.h"
 
 #include "common.h"
 
index 22762a1..c224119 100644 (file)
@@ -16,9 +16,9 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/irqs.h>
-#include <mach/pxa168.h>
-#include <mach/mfp-pxa168.h>
+#include "irqs.h"
+#include "pxa168.h"
+#include "mfp-pxa168.h"
 
 #include "common.h"
 
diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h
deleted file mode 100644 (file)
index f88a44c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/addr-map.h
- *
- *   Common address map definitions
- *
- * 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_MACH_ADDR_MAP_H
-#define __ASM_MACH_ADDR_MAP_H
-
-/* APB - Application Subsystem Peripheral Bus
- *
- * NOTE: the DMA controller registers are actually on the AXI fabric #1
- * slave port to AHB/APB bridge, due to its close relationship to those
- * peripherals on APB, let's count it into the ABP mapping area.
- */
-#define APB_PHYS_BASE          0xd4000000
-#define APB_VIRT_BASE          IOMEM(0xfe000000)
-#define APB_PHYS_SIZE          0x00200000
-
-#define AXI_PHYS_BASE          0xd4200000
-#define AXI_VIRT_BASE          IOMEM(0xfe200000)
-#define AXI_PHYS_SIZE          0x00200000
-
-/* Static Memory Controller - Chip Select 0 and 1 */
-#define SMC_CS0_PHYS_BASE      0x80000000
-#define SMC_CS0_PHYS_SIZE      0x10000000
-#define SMC_CS1_PHYS_BASE      0x90000000
-#define SMC_CS1_PHYS_SIZE      0x10000000
-
-#define APMU_VIRT_BASE         (AXI_VIRT_BASE + 0x82800)
-#define APMU_REG(x)            (APMU_VIRT_BASE + (x))
-
-#define APBC_VIRT_BASE         (APB_VIRT_BASE + 0x015000)
-#define APBC_REG(x)            (APBC_VIRT_BASE + (x))
-
-#define MPMU_VIRT_BASE         (APB_VIRT_BASE + 0x50000)
-#define MPMU_REG(x)            (MPMU_VIRT_BASE + (x))
-
-#define CIU_VIRT_BASE          (AXI_VIRT_BASE + 0x82c00)
-#define CIU_REG(x)             (CIU_VIRT_BASE + (x))
-
-#endif /* __ASM_MACH_ADDR_MAP_H */
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h
deleted file mode 100644 (file)
index 8a3b56d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __ASM_MACH_CPUTYPE_H
-#define __ASM_MACH_CPUTYPE_H
-
-#include <asm/cputype.h>
-
-/*
- *  CPU   Stepping   CPU_ID      CHIP_ID
- *
- * PXA168    S0    0x56158400   0x0000C910
- * PXA168    A0    0x56158400   0x00A0A168
- * PXA910    Y1    0x56158400   0x00F2C920
- * PXA910    A0    0x56158400   0x00F2C910
- * PXA910    A1    0x56158400   0x00A0C910
- * PXA920    Y0    0x56158400   0x00F2C920
- * PXA920    A0    0x56158400   0x00A0C920
- * PXA920    A1    0x56158400   0x00A1C920
- * MMP2             Z0    0x560f5811   0x00F00410
- * MMP2      Z1    0x560f5811   0x00E00410
- * MMP2      A0    0x560f5811   0x00A0A610
- */
-
-extern unsigned int mmp_chip_id;
-
-#ifdef CONFIG_CPU_PXA168
-static inline int cpu_is_pxa168(void)
-{
-       return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
-               ((mmp_chip_id & 0xfff) == 0x168);
-}
-#else
-#define cpu_is_pxa168()        (0)
-#endif
-
-/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */
-#ifdef CONFIG_CPU_PXA910
-static inline int cpu_is_pxa910(void)
-{
-       return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
-               (((mmp_chip_id & 0xfff) == 0x910) ||
-                ((mmp_chip_id & 0xfff) == 0x920));
-}
-#else
-#define cpu_is_pxa910()        (0)
-#endif
-
-#ifdef CONFIG_CPU_MMP2
-static inline int cpu_is_mmp2(void)
-{
-       return (((read_cpuid_id() >> 8) & 0xff) == 0x58);
-}
-#else
-#define cpu_is_mmp2()  (0)
-#endif
-
-#endif /* __ASM_MACH_CPUTYPE_H */
diff --git a/arch/arm/mach-mmp/include/mach/devices.h b/arch/arm/mach-mmp/include/mach/devices.h
deleted file mode 100644 (file)
index 21217ef..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __MACH_DEVICE_H
-#define __MACH_DEVICE_H
-
-#include <linux/types.h>
-
-#define MAX_RESOURCE_DMA       2
-
-/* structure for describing the on-chip devices */
-struct pxa_device_desc {
-       const char      *dev_name;
-       const char      *drv_name;
-       int             id;
-       int             irq;
-       unsigned long   start;
-       unsigned long   size;
-       int             dma[MAX_RESOURCE_DMA];
-};
-
-#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)  \
-struct pxa_device_desc pxa168_device_##_name __initdata = {            \
-       .dev_name       = "pxa168-" #_name,                             \
-       .drv_name       = _drv,                                         \
-       .id             = _id,                                          \
-       .irq            = IRQ_PXA168_##_irq,                            \
-       .start          = _start,                                       \
-       .size           = _size,                                        \
-       .dma            = { _dma },                                     \
-};
-
-#define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)  \
-struct pxa_device_desc pxa910_device_##_name __initdata = {            \
-       .dev_name       = "pxa910-" #_name,                             \
-       .drv_name       = _drv,                                         \
-       .id             = _id,                                          \
-       .irq            = IRQ_PXA910_##_irq,                            \
-       .start          = _start,                                       \
-       .size           = _size,                                        \
-       .dma            = { _dma },                                     \
-};
-
-#define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)    \
-struct pxa_device_desc mmp2_device_##_name __initdata = {              \
-       .dev_name       = "mmp2-" #_name,                               \
-       .drv_name       = _drv,                                         \
-       .id             = _id,                                          \
-       .irq            = IRQ_MMP2_##_irq,                              \
-       .start          = _start,                                       \
-       .size           = _size,                                        \
-       .dma            = { _dma },                                     \
-}
-
-extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
-extern int pxa_usb_phy_init(void __iomem *phy_reg);
-extern void pxa_usb_phy_deinit(void __iomem *phy_reg);
-
-#endif /* __MACH_DEVICE_H */
diff --git a/arch/arm/mach-mmp/include/mach/dma.h b/arch/arm/mach-mmp/include/mach/dma.h
deleted file mode 100644 (file)
index 1d69145..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/dma.h
- */
-
-#ifndef __ASM_MACH_DMA_H
-#define __ASM_MACH_DMA_H
-
-#include <mach/addr-map.h>
-
-#define DMAC_REGS_VIRT (APB_VIRT_BASE + 0x00000)
-
-#include <plat/dma.h>
-#endif /* __ASM_MACH_DMA_H */
diff --git a/arch/arm/mach-mmp/include/mach/hardware.h b/arch/arm/mach-mmp/include/mach/hardware.h
deleted file mode 100644 (file)
index 99264a5..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __ASM_MACH_HARDWARE_H
-#define __ASM_MACH_HARDWARE_H
-
-#endif /* __ASM_MACH_HARDWARE_H */
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
deleted file mode 100644 (file)
index fb492a5..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-#ifndef __ASM_MACH_IRQS_H
-#define __ASM_MACH_IRQS_H
-
-/*
- * Interrupt numbers for PXA168
- */
-#define IRQ_PXA168_NONE                        (-1)
-#define IRQ_PXA168_SSP4                        0
-#define IRQ_PXA168_SSP3                        1
-#define IRQ_PXA168_SSP2                        2
-#define IRQ_PXA168_SSP1                        3
-#define IRQ_PXA168_PMIC_INT            4
-#define IRQ_PXA168_RTC_INT             5
-#define IRQ_PXA168_RTC_ALARM           6
-#define IRQ_PXA168_TWSI0               7
-#define IRQ_PXA168_GPU                 8
-#define IRQ_PXA168_KEYPAD              9
-#define IRQ_PXA168_ONEWIRE             12
-#define IRQ_PXA168_TIMER1              13
-#define IRQ_PXA168_TIMER2              14
-#define IRQ_PXA168_TIMER3              15
-#define IRQ_PXA168_CMU                 16
-#define IRQ_PXA168_SSP5                        17
-#define IRQ_PXA168_MSP_WAKEUP          19
-#define IRQ_PXA168_CF_WAKEUP           20
-#define IRQ_PXA168_XD_WAKEUP           21
-#define IRQ_PXA168_MFU                 22
-#define IRQ_PXA168_MSP                 23
-#define IRQ_PXA168_CF                  24
-#define IRQ_PXA168_XD                  25
-#define IRQ_PXA168_DDR_INT             26
-#define IRQ_PXA168_UART1               27
-#define IRQ_PXA168_UART2               28
-#define IRQ_PXA168_UART3               29
-#define IRQ_PXA168_WDT                 35
-#define IRQ_PXA168_MAIN_PMU            36
-#define IRQ_PXA168_FRQ_CHANGE          38
-#define IRQ_PXA168_SDH1                        39
-#define IRQ_PXA168_SDH2                        40
-#define IRQ_PXA168_LCD                 41
-#define IRQ_PXA168_CI                  42
-#define IRQ_PXA168_USB1                        44
-#define IRQ_PXA168_NAND                        45
-#define IRQ_PXA168_HIFI_DMA            46
-#define IRQ_PXA168_DMA_INT0            47
-#define IRQ_PXA168_DMA_INT1            48
-#define IRQ_PXA168_GPIOX               49
-#define IRQ_PXA168_USB2                        51
-#define IRQ_PXA168_AC97                        57
-#define IRQ_PXA168_TWSI1               58
-#define IRQ_PXA168_AP_PMU              60
-#define IRQ_PXA168_SM_INT              63
-
-/*
- * Interrupt numbers for PXA910
- */
-#define IRQ_PXA910_NONE                        (-1)
-#define IRQ_PXA910_AIRQ                        0
-#define IRQ_PXA910_SSP3                        1
-#define IRQ_PXA910_SSP2                        2
-#define IRQ_PXA910_SSP1                        3
-#define IRQ_PXA910_PMIC_INT            4
-#define IRQ_PXA910_RTC_INT             5
-#define IRQ_PXA910_RTC_ALARM           6
-#define IRQ_PXA910_TWSI0               7
-#define IRQ_PXA910_GPU                 8
-#define IRQ_PXA910_KEYPAD              9
-#define IRQ_PXA910_ROTARY              10
-#define IRQ_PXA910_TRACKBALL           11
-#define IRQ_PXA910_ONEWIRE             12
-#define IRQ_PXA910_AP1_TIMER1          13
-#define IRQ_PXA910_AP1_TIMER2          14
-#define IRQ_PXA910_AP1_TIMER3          15
-#define IRQ_PXA910_IPC_AP0             16
-#define IRQ_PXA910_IPC_AP1             17
-#define IRQ_PXA910_IPC_AP2             18
-#define IRQ_PXA910_IPC_AP3             19
-#define IRQ_PXA910_IPC_AP4             20
-#define IRQ_PXA910_IPC_CP0             21
-#define IRQ_PXA910_IPC_CP1             22
-#define IRQ_PXA910_IPC_CP2             23
-#define IRQ_PXA910_IPC_CP3             24
-#define IRQ_PXA910_IPC_CP4             25
-#define IRQ_PXA910_L2_DDR              26
-#define IRQ_PXA910_UART2               27
-#define IRQ_PXA910_UART3               28
-#define IRQ_PXA910_AP2_TIMER1          29
-#define IRQ_PXA910_AP2_TIMER2          30
-#define IRQ_PXA910_CP2_TIMER1          31
-#define IRQ_PXA910_CP2_TIMER2          32
-#define IRQ_PXA910_CP2_TIMER3          33
-#define IRQ_PXA910_GSSP                        34
-#define IRQ_PXA910_CP2_WDT             35
-#define IRQ_PXA910_MAIN_PMU            36
-#define IRQ_PXA910_CP_FREQ_CHG         37
-#define IRQ_PXA910_AP_FREQ_CHG         38
-#define IRQ_PXA910_MMC                 39
-#define IRQ_PXA910_AEU                 40
-#define IRQ_PXA910_LCD                 41
-#define IRQ_PXA910_CCIC                        42
-#define IRQ_PXA910_IRE                 43
-#define IRQ_PXA910_USB1                        44
-#define IRQ_PXA910_NAND                        45
-#define IRQ_PXA910_HIFI_DMA            46
-#define IRQ_PXA910_DMA_INT0            47
-#define IRQ_PXA910_DMA_INT1            48
-#define IRQ_PXA910_AP_GPIO             49
-#define IRQ_PXA910_AP2_TIMER3          50
-#define IRQ_PXA910_USB2                        51
-#define IRQ_PXA910_TWSI1               54
-#define IRQ_PXA910_CP_GPIO             55
-#define IRQ_PXA910_UART1               59      /* Slow UART */
-#define IRQ_PXA910_AP_PMU              60
-#define IRQ_PXA910_SM_INT              63      /* from PinMux */
-
-/*
- * Interrupt numbers for MMP2
- */
-#define IRQ_MMP2_NONE                  (-1)
-#define IRQ_MMP2_SSP1                  0
-#define IRQ_MMP2_SSP2                  1
-#define IRQ_MMP2_SSPA1                 2
-#define IRQ_MMP2_SSPA2                 3
-#define IRQ_MMP2_PMIC_MUX              4       /* PMIC & Charger */
-#define IRQ_MMP2_RTC_MUX               5
-#define IRQ_MMP2_TWSI1                 7
-#define IRQ_MMP2_GPU                   8
-#define IRQ_MMP2_KEYPAD_MUX            9
-#define IRQ_MMP2_ROTARY                        10
-#define IRQ_MMP2_TRACKBALL             11
-#define IRQ_MMP2_ONEWIRE               12
-#define IRQ_MMP2_TIMER1                        13
-#define IRQ_MMP2_TIMER2                        14
-#define IRQ_MMP2_TIMER3                        15
-#define IRQ_MMP2_RIPC                  16
-#define IRQ_MMP2_TWSI_MUX              17      /* TWSI2 ~ TWSI6 */
-#define IRQ_MMP2_HDMI                  19
-#define IRQ_MMP2_SSP3                  20
-#define IRQ_MMP2_SSP4                  21
-#define IRQ_MMP2_USB_HS1               22
-#define IRQ_MMP2_USB_HS2               23
-#define IRQ_MMP2_UART3                 24
-#define IRQ_MMP2_UART1                 27
-#define IRQ_MMP2_UART2                 28
-#define IRQ_MMP2_MIPI_DSI              29
-#define IRQ_MMP2_CI2                   30
-#define IRQ_MMP2_PMU_TIMER1            31
-#define IRQ_MMP2_PMU_TIMER2            32
-#define IRQ_MMP2_PMU_TIMER3            33
-#define IRQ_MMP2_USB_FS                        34
-#define IRQ_MMP2_MISC_MUX              35
-#define IRQ_MMP2_WDT1                  36
-#define IRQ_MMP2_NAND_DMA              37
-#define IRQ_MMP2_USIM                  38
-#define IRQ_MMP2_MMC                   39
-#define IRQ_MMP2_WTM                   40
-#define IRQ_MMP2_LCD                   41
-#define IRQ_MMP2_CI                    42
-#define IRQ_MMP2_IRE                   43
-#define IRQ_MMP2_USB_OTG               44
-#define IRQ_MMP2_NAND                  45
-#define IRQ_MMP2_UART4                 46
-#define IRQ_MMP2_DMA_FIQ               47
-#define IRQ_MMP2_DMA_RIQ               48
-#define IRQ_MMP2_GPIO                  49
-#define IRQ_MMP2_MIPI_HSI1_MUX         51
-#define IRQ_MMP2_MMC2                  52
-#define IRQ_MMP2_MMC3                  53
-#define IRQ_MMP2_MMC4                  54
-#define IRQ_MMP2_MIPI_HSI0_MUX         55
-#define IRQ_MMP2_MSP                   58
-#define IRQ_MMP2_MIPI_SLIM_DMA         59
-#define IRQ_MMP2_PJ4_FREQ_CHG          60
-#define IRQ_MMP2_MIPI_SLIM             62
-#define IRQ_MMP2_SM                    63
-
-#define IRQ_MMP2_MUX_BASE              64
-
-/* secondary interrupt of INT #4 */
-#define IRQ_MMP2_PMIC_BASE             (IRQ_MMP2_MUX_BASE)
-#define IRQ_MMP2_CHARGER               (IRQ_MMP2_PMIC_BASE + 0)
-#define IRQ_MMP2_PMIC                  (IRQ_MMP2_PMIC_BASE + 1)
-
-/* secondary interrupt of INT #5 */
-#define IRQ_MMP2_RTC_BASE              (IRQ_MMP2_PMIC_BASE + 2)
-#define IRQ_MMP2_RTC_ALARM             (IRQ_MMP2_RTC_BASE + 0)
-#define IRQ_MMP2_RTC                   (IRQ_MMP2_RTC_BASE + 1)
-
-/* secondary interrupt of INT #9 */
-#define IRQ_MMP2_KEYPAD_BASE           (IRQ_MMP2_RTC_BASE + 2)
-#define IRQ_MMP2_KPC                   (IRQ_MMP2_KEYPAD_BASE + 0)
-#define IRQ_MMP2_ROTORY                        (IRQ_MMP2_KEYPAD_BASE + 1)
-#define IRQ_MMP2_TBALL                 (IRQ_MMP2_KEYPAD_BASE + 2)
-
-/* secondary interrupt of INT #17 */
-#define IRQ_MMP2_TWSI_BASE             (IRQ_MMP2_KEYPAD_BASE + 3)
-#define IRQ_MMP2_TWSI2                 (IRQ_MMP2_TWSI_BASE + 0)
-#define IRQ_MMP2_TWSI3                 (IRQ_MMP2_TWSI_BASE + 1)
-#define IRQ_MMP2_TWSI4                 (IRQ_MMP2_TWSI_BASE + 2)
-#define IRQ_MMP2_TWSI5                 (IRQ_MMP2_TWSI_BASE + 3)
-#define IRQ_MMP2_TWSI6                 (IRQ_MMP2_TWSI_BASE + 4)
-
-/* secondary interrupt of INT #35 */
-#define IRQ_MMP2_MISC_BASE             (IRQ_MMP2_TWSI_BASE + 5)
-#define IRQ_MMP2_PERF                  (IRQ_MMP2_MISC_BASE + 0)
-#define IRQ_MMP2_L2_PA_ECC             (IRQ_MMP2_MISC_BASE + 1)
-#define IRQ_MMP2_L2_ECC                        (IRQ_MMP2_MISC_BASE + 2)
-#define IRQ_MMP2_L2_UECC               (IRQ_MMP2_MISC_BASE + 3)
-#define IRQ_MMP2_DDR                   (IRQ_MMP2_MISC_BASE + 4)
-#define IRQ_MMP2_FAB0_TIMEOUT          (IRQ_MMP2_MISC_BASE + 5)
-#define IRQ_MMP2_FAB1_TIMEOUT          (IRQ_MMP2_MISC_BASE + 6)
-#define IRQ_MMP2_FAB2_TIMEOUT          (IRQ_MMP2_MISC_BASE + 7)
-#define IRQ_MMP2_THERMAL               (IRQ_MMP2_MISC_BASE + 9)
-#define IRQ_MMP2_MAIN_PMU              (IRQ_MMP2_MISC_BASE + 10)
-#define IRQ_MMP2_WDT2                  (IRQ_MMP2_MISC_BASE + 11)
-#define IRQ_MMP2_CORESIGHT             (IRQ_MMP2_MISC_BASE + 12)
-#define IRQ_MMP2_COMMTX                        (IRQ_MMP2_MISC_BASE + 13)
-#define IRQ_MMP2_COMMRX                        (IRQ_MMP2_MISC_BASE + 14)
-
-/* secondary interrupt of INT #51 */
-#define IRQ_MMP2_MIPI_HSI1_BASE                (IRQ_MMP2_MISC_BASE + 15)
-#define IRQ_MMP2_HSI1_CAWAKE           (IRQ_MMP2_MIPI_HSI1_BASE + 0)
-#define IRQ_MMP2_MIPI_HSI_INT1         (IRQ_MMP2_MIPI_HSI1_BASE + 1)
-
-/* secondary interrupt of INT #55 */
-#define IRQ_MMP2_MIPI_HSI0_BASE                (IRQ_MMP2_MIPI_HSI1_BASE + 2)
-#define IRQ_MMP2_HSI0_CAWAKE           (IRQ_MMP2_MIPI_HSI0_BASE + 0)
-#define IRQ_MMP2_MIPI_HSI_INT0         (IRQ_MMP2_MIPI_HSI0_BASE + 1)
-
-#define IRQ_MMP2_MUX_END               (IRQ_MMP2_MIPI_HSI0_BASE + 2)
-
-#define IRQ_GPIO_START                 128
-#define MMP_NR_BUILTIN_GPIO            192
-#define MMP_GPIO_TO_IRQ(gpio)          (IRQ_GPIO_START + (gpio))
-
-#define IRQ_BOARD_START                        (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
-#define MMP_NR_IRQS                    IRQ_BOARD_START
-
-#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
deleted file mode 100644 (file)
index 4ad3862..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-#ifndef __ASM_MACH_MFP_MMP2_H
-#define __ASM_MACH_MFP_MMP2_H
-
-#include <mach/mfp.h>
-
-#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
-#define MFP_DRIVE_SLOW         (0x2 << 13)
-#define MFP_DRIVE_MEDIUM       (0x4 << 13)
-#define MFP_DRIVE_FAST         (0x6 << 13)
-
-/* GPIO */
-#define GPIO0_GPIO     MFP_CFG(GPIO0, AF0)
-#define GPIO1_GPIO     MFP_CFG(GPIO1, AF0)
-#define GPIO2_GPIO     MFP_CFG(GPIO2, AF0)
-#define GPIO3_GPIO     MFP_CFG(GPIO3, AF0)
-#define GPIO4_GPIO     MFP_CFG(GPIO4, AF0)
-#define GPIO5_GPIO     MFP_CFG(GPIO5, AF0)
-#define GPIO6_GPIO     MFP_CFG(GPIO6, AF0)
-#define GPIO7_GPIO     MFP_CFG(GPIO7, AF0)
-#define GPIO8_GPIO     MFP_CFG(GPIO8, AF0)
-#define GPIO9_GPIO     MFP_CFG(GPIO9, AF0)
-#define GPIO10_GPIO    MFP_CFG(GPIO10, AF0)
-#define GPIO11_GPIO    MFP_CFG(GPIO11, AF0)
-#define GPIO12_GPIO    MFP_CFG(GPIO12, AF0)
-#define GPIO13_GPIO    MFP_CFG(GPIO13, AF0)
-#define GPIO14_GPIO    MFP_CFG(GPIO14, AF0)
-#define GPIO15_GPIO    MFP_CFG(GPIO15, AF0)
-#define GPIO16_GPIO    MFP_CFG(GPIO16, AF0)
-#define GPIO17_GPIO    MFP_CFG(GPIO17, AF0)
-#define GPIO18_GPIO    MFP_CFG(GPIO18, AF0)
-#define GPIO19_GPIO    MFP_CFG(GPIO19, AF0)
-#define GPIO20_GPIO    MFP_CFG(GPIO20, AF0)
-#define GPIO21_GPIO    MFP_CFG(GPIO21, AF0)
-#define GPIO22_GPIO    MFP_CFG(GPIO22, AF0)
-#define GPIO23_GPIO    MFP_CFG(GPIO23, AF0)
-#define GPIO24_GPIO    MFP_CFG(GPIO24, AF0)
-#define GPIO25_GPIO    MFP_CFG(GPIO25, AF0)
-#define GPIO26_GPIO    MFP_CFG(GPIO26, AF0)
-#define GPIO27_GPIO    MFP_CFG(GPIO27, AF0)
-#define GPIO28_GPIO    MFP_CFG(GPIO28, AF0)
-#define GPIO29_GPIO    MFP_CFG(GPIO29, AF0)
-#define GPIO30_GPIO    MFP_CFG(GPIO30, AF0)
-#define GPIO31_GPIO    MFP_CFG(GPIO31, AF0)
-#define GPIO32_GPIO    MFP_CFG(GPIO32, AF0)
-#define GPIO33_GPIO    MFP_CFG(GPIO33, AF0)
-#define GPIO34_GPIO    MFP_CFG(GPIO34, AF0)
-#define GPIO35_GPIO    MFP_CFG(GPIO35, AF0)
-#define GPIO36_GPIO    MFP_CFG(GPIO36, AF0)
-#define GPIO37_GPIO    MFP_CFG(GPIO37, AF0)
-#define GPIO38_GPIO    MFP_CFG(GPIO38, AF0)
-#define GPIO39_GPIO    MFP_CFG(GPIO39, AF0)
-#define GPIO40_GPIO    MFP_CFG(GPIO40, AF0)
-#define GPIO41_GPIO    MFP_CFG(GPIO41, AF0)
-#define GPIO42_GPIO    MFP_CFG(GPIO42, AF0)
-#define GPIO43_GPIO    MFP_CFG(GPIO43, AF0)
-#define GPIO44_GPIO    MFP_CFG(GPIO44, AF0)
-#define GPIO45_GPIO    MFP_CFG(GPIO45, AF0)
-#define GPIO46_GPIO    MFP_CFG(GPIO46, AF0)
-#define GPIO47_GPIO    MFP_CFG(GPIO47, AF0)
-#define GPIO48_GPIO    MFP_CFG(GPIO48, AF0)
-#define GPIO49_GPIO    MFP_CFG(GPIO49, AF0)
-#define GPIO50_GPIO    MFP_CFG(GPIO50, AF0)
-#define GPIO51_GPIO    MFP_CFG(GPIO51, AF0)
-#define GPIO52_GPIO    MFP_CFG(GPIO52, AF0)
-#define GPIO53_GPIO    MFP_CFG(GPIO53, AF0)
-#define GPIO54_GPIO    MFP_CFG(GPIO54, AF0)
-#define GPIO55_GPIO    MFP_CFG(GPIO55, AF0)
-#define GPIO56_GPIO    MFP_CFG(GPIO56, AF0)
-#define GPIO57_GPIO    MFP_CFG(GPIO57, AF0)
-#define GPIO58_GPIO    MFP_CFG(GPIO58, AF0)
-#define GPIO59_GPIO    MFP_CFG(GPIO59, AF0)
-#define GPIO60_GPIO    MFP_CFG(GPIO60, AF0)
-#define GPIO61_GPIO    MFP_CFG(GPIO61, AF0)
-#define GPIO62_GPIO    MFP_CFG(GPIO62, AF0)
-#define GPIO63_GPIO    MFP_CFG(GPIO63, AF0)
-#define GPIO64_GPIO    MFP_CFG(GPIO64, AF0)
-#define GPIO65_GPIO    MFP_CFG(GPIO65, AF0)
-#define GPIO66_GPIO    MFP_CFG(GPIO66, AF0)
-#define GPIO67_GPIO    MFP_CFG(GPIO67, AF0)
-#define GPIO68_GPIO    MFP_CFG(GPIO68, AF0)
-#define GPIO69_GPIO    MFP_CFG(GPIO69, AF0)
-#define GPIO70_GPIO    MFP_CFG(GPIO70, AF0)
-#define GPIO71_GPIO    MFP_CFG(GPIO71, AF0)
-#define GPIO72_GPIO    MFP_CFG(GPIO72, AF0)
-#define GPIO73_GPIO    MFP_CFG(GPIO73, AF0)
-#define GPIO74_GPIO    MFP_CFG(GPIO74, AF0)
-#define GPIO75_GPIO    MFP_CFG(GPIO75, AF0)
-#define GPIO76_GPIO    MFP_CFG(GPIO76, AF0)
-#define GPIO77_GPIO    MFP_CFG(GPIO77, AF0)
-#define GPIO78_GPIO    MFP_CFG(GPIO78, AF0)
-#define GPIO79_GPIO    MFP_CFG(GPIO79, AF0)
-#define GPIO80_GPIO    MFP_CFG(GPIO80, AF0)
-#define GPIO81_GPIO    MFP_CFG(GPIO81, AF0)
-#define GPIO82_GPIO    MFP_CFG(GPIO82, AF0)
-#define GPIO83_GPIO    MFP_CFG(GPIO83, AF0)
-#define GPIO84_GPIO    MFP_CFG(GPIO84, AF0)
-#define GPIO85_GPIO    MFP_CFG(GPIO85, AF0)
-#define GPIO86_GPIO    MFP_CFG(GPIO86, AF0)
-#define GPIO87_GPIO    MFP_CFG(GPIO87, AF0)
-#define GPIO88_GPIO    MFP_CFG(GPIO88, AF0)
-#define GPIO89_GPIO    MFP_CFG(GPIO89, AF0)
-#define GPIO90_GPIO    MFP_CFG(GPIO90, AF0)
-#define GPIO91_GPIO    MFP_CFG(GPIO91, AF0)
-#define GPIO92_GPIO    MFP_CFG(GPIO92, AF0)
-#define GPIO93_GPIO    MFP_CFG(GPIO93, AF0)
-#define GPIO94_GPIO    MFP_CFG(GPIO94, AF0)
-#define GPIO95_GPIO    MFP_CFG(GPIO95, AF0)
-#define GPIO96_GPIO    MFP_CFG(GPIO96, AF0)
-#define GPIO97_GPIO    MFP_CFG(GPIO97, AF0)
-#define GPIO98_GPIO    MFP_CFG(GPIO98, AF0)
-#define GPIO99_GPIO    MFP_CFG(GPIO99, AF0)
-#define GPIO100_GPIO   MFP_CFG(GPIO100, AF0)
-#define GPIO101_GPIO   MFP_CFG(GPIO101, AF0)
-#define GPIO102_GPIO   MFP_CFG(GPIO102, AF1)
-#define GPIO103_GPIO   MFP_CFG(GPIO103, AF1)
-#define GPIO104_GPIO   MFP_CFG(GPIO104, AF1)
-#define GPIO105_GPIO   MFP_CFG(GPIO105, AF1)
-#define GPIO106_GPIO   MFP_CFG(GPIO106, AF1)
-#define GPIO107_GPIO   MFP_CFG(GPIO107, AF1)
-#define GPIO108_GPIO   MFP_CFG(GPIO108, AF1)
-#define GPIO109_GPIO   MFP_CFG(GPIO109, AF1)
-#define GPIO110_GPIO   MFP_CFG(GPIO110, AF1)
-#define GPIO111_GPIO   MFP_CFG(GPIO111, AF1)
-#define GPIO112_GPIO   MFP_CFG(GPIO112, AF1)
-#define GPIO113_GPIO   MFP_CFG(GPIO113, AF1)
-#define GPIO114_GPIO   MFP_CFG(GPIO114, AF0)
-#define GPIO115_GPIO   MFP_CFG(GPIO115, AF0)
-#define GPIO116_GPIO   MFP_CFG(GPIO116, AF0)
-#define GPIO117_GPIO   MFP_CFG(GPIO117, AF0)
-#define GPIO118_GPIO   MFP_CFG(GPIO118, AF0)
-#define GPIO119_GPIO   MFP_CFG(GPIO119, AF0)
-#define GPIO120_GPIO   MFP_CFG(GPIO120, AF0)
-#define GPIO121_GPIO   MFP_CFG(GPIO121, AF0)
-#define GPIO122_GPIO   MFP_CFG(GPIO122, AF0)
-#define GPIO123_GPIO   MFP_CFG(GPIO123, AF0)
-#define GPIO124_GPIO   MFP_CFG(GPIO124, AF0)
-#define GPIO125_GPIO   MFP_CFG(GPIO125, AF0)
-#define GPIO126_GPIO   MFP_CFG(GPIO126, AF0)
-#define GPIO127_GPIO   MFP_CFG(GPIO127, AF0)
-#define GPIO128_GPIO   MFP_CFG(GPIO128, AF0)
-#define GPIO129_GPIO   MFP_CFG(GPIO129, AF0)
-#define GPIO130_GPIO   MFP_CFG(GPIO130, AF0)
-#define GPIO131_GPIO   MFP_CFG(GPIO131, AF0)
-#define GPIO132_GPIO   MFP_CFG(GPIO132, AF0)
-#define GPIO133_GPIO   MFP_CFG(GPIO133, AF0)
-#define GPIO134_GPIO   MFP_CFG(GPIO134, AF0)
-#define GPIO135_GPIO   MFP_CFG(GPIO135, AF0)
-#define GPIO136_GPIO   MFP_CFG(GPIO136, AF0)
-#define GPIO137_GPIO   MFP_CFG(GPIO137, AF0)
-#define GPIO138_GPIO   MFP_CFG(GPIO138, AF0)
-#define GPIO139_GPIO   MFP_CFG(GPIO139, AF0)
-#define GPIO140_GPIO   MFP_CFG(GPIO140, AF0)
-#define GPIO141_GPIO   MFP_CFG(GPIO141, AF0)
-#define GPIO142_GPIO   MFP_CFG(GPIO142, AF1)
-#define GPIO143_GPIO   MFP_CFG(GPIO143, AF1)
-#define GPIO144_GPIO   MFP_CFG(GPIO144, AF1)
-#define GPIO145_GPIO   MFP_CFG(GPIO145, AF1)
-#define GPIO146_GPIO   MFP_CFG(GPIO146, AF1)
-#define GPIO147_GPIO   MFP_CFG(GPIO147, AF1)
-#define GPIO148_GPIO   MFP_CFG(GPIO148, AF1)
-#define GPIO149_GPIO   MFP_CFG(GPIO149, AF1)
-#define GPIO150_GPIO   MFP_CFG(GPIO150, AF1)
-#define GPIO151_GPIO   MFP_CFG(GPIO151, AF1)
-#define GPIO152_GPIO   MFP_CFG(GPIO152, AF1)
-#define GPIO153_GPIO   MFP_CFG(GPIO153, AF1)
-#define GPIO154_GPIO   MFP_CFG(GPIO154, AF1)
-#define GPIO155_GPIO   MFP_CFG(GPIO155, AF1)
-#define GPIO156_GPIO   MFP_CFG(GPIO156, AF1)
-#define GPIO157_GPIO   MFP_CFG(GPIO157, AF1)
-#define GPIO158_GPIO   MFP_CFG(GPIO158, AF1)
-#define GPIO159_GPIO   MFP_CFG(GPIO159, AF1)
-#define GPIO160_GPIO   MFP_CFG(GPIO160, AF1)
-#define GPIO161_GPIO   MFP_CFG(GPIO161, AF1)
-#define GPIO162_GPIO   MFP_CFG(GPIO162, AF1)
-#define GPIO163_GPIO   MFP_CFG(GPIO163, AF1)
-#define GPIO164_GPIO   MFP_CFG(GPIO164, AF1)
-#define GPIO165_GPIO   MFP_CFG(GPIO165, AF1)
-#define GPIO166_GPIO   MFP_CFG(GPIO166, AF1)
-#define GPIO167_GPIO   MFP_CFG(GPIO167, AF1)
-#define GPIO168_GPIO   MFP_CFG(GPIO168, AF1)
-
-/* DFI */
-#define GPIO108_DFI_D15                MFP_CFG(GPIO108, AF0)
-#define GPIO109_DFI_D14                MFP_CFG(GPIO109, AF0)
-#define GPIO110_DFI_D13                MFP_CFG(GPIO110, AF0)
-#define GPIO161_DFI_D12                MFP_CFG(GPIO161, AF0)
-#define GPIO162_DFI_D11                MFP_CFG(GPIO162, AF0)
-#define GPIO163_DFI_D10                MFP_CFG(GPIO163, AF0)
-#define GPIO164_DFI_D9         MFP_CFG(GPIO164, AF0)
-#define GPIO111_DFI_D8         MFP_CFG(GPIO111, AF0)
-#define GPIO104_DFI_D7         MFP_CFG(GPIO104, AF0)
-#define GPIO105_DFI_D6         MFP_CFG(GPIO105, AF0)
-#define GPIO106_DFI_D5         MFP_CFG(GPIO106, AF0)
-#define GPIO107_DFI_D4         MFP_CFG(GPIO107, AF0)
-#define GPIO165_DFI_D3         MFP_CFG(GPIO165, AF0)
-#define GPIO166_DFI_D2         MFP_CFG(GPIO166, AF0)
-#define GPIO167_DFI_D1         MFP_CFG(GPIO167, AF0)
-#define GPIO168_DFI_D0         MFP_CFG(GPIO168, AF0)
-#define GPIO143_ND_nCS0                MFP_CFG(GPIO143, AF0)
-#define GPIO144_ND_nCS1                MFP_CFG(GPIO144, AF0)
-#define GPIO147_ND_nWE         MFP_CFG(GPIO147, AF0)
-#define GPIO148_ND_nRE         MFP_CFG(GPIO148, AF0)
-#define GPIO150_ND_ALE         MFP_CFG(GPIO150, AF0)
-#define GPIO149_ND_CLE         MFP_CFG(GPIO149, AF0)
-#define GPIO112_ND_RDY0                MFP_CFG(GPIO112, AF0)
-#define GPIO160_ND_RDY1                MFP_CFG(GPIO160, AF0)
-
-/* Static Memory Controller */
-#define GPIO145_SMC_nCS0       MFP_CFG(GPIO145, AF0)
-#define GPIO146_SMC_nCS1       MFP_CFG(GPIO146, AF0)
-#define GPIO152_SMC_BE0                MFP_CFG(GPIO152, AF0)
-#define GPIO153_SMC_BE1                MFP_CFG(GPIO153, AF0)
-#define GPIO154_SMC_IRQ                MFP_CFG(GPIO154, AF0)
-#define GPIO113_SMC_RDY                MFP_CFG(GPIO113, AF0)
-#define GPIO151_SMC_SCLK       MFP_CFG(GPIO151, AF0)
-
-/* Ethernet */
-#define GPIO155_SM_ADVMUX      MFP_CFG(GPIO155, AF2)
-
-/* UART1 */
-#define GPIO45_UART1_RXD       MFP_CFG(GPIO45, AF1)
-#define GPIO46_UART1_TXD       MFP_CFG(GPIO46, AF1)
-#define GPIO29_UART1_RXD       MFP_CFG(GPIO29, AF1)
-#define GPIO30_UART1_TXD       MFP_CFG(GPIO30, AF1)
-#define GPIO31_UART1_CTS       MFP_CFG(GPIO31, AF1)
-#define GPIO32_UART1_RTS       MFP_CFG(GPIO32, AF1)
-
-/* UART2 */
-#define GPIO47_UART2_RXD       MFP_CFG(GPIO47, AF1)
-#define GPIO48_UART2_TXD       MFP_CFG(GPIO48, AF1)
-#define GPIO49_UART2_CTS       MFP_CFG(GPIO49, AF1)
-#define GPIO50_UART2_RTS       MFP_CFG(GPIO50, AF1)
-
-/* UART3 */
-#define GPIO51_UART3_RXD       MFP_CFG(GPIO51, AF1)
-#define GPIO52_UART3_TXD       MFP_CFG(GPIO52, AF1)
-#define GPIO53_UART3_CTS       MFP_CFG(GPIO53, AF1)
-#define GPIO54_UART3_RTS       MFP_CFG(GPIO54, AF1)
-
-/* MMC1 */
-#define GPIO124_MMC1_DAT7      MFP_CFG_DRV(GPIO124, AF1, FAST)
-#define GPIO125_MMC1_DAT6      MFP_CFG_DRV(GPIO125, AF1, FAST)
-#define GPIO129_MMC1_DAT5      MFP_CFG_DRV(GPIO129, AF1, FAST)
-#define GPIO130_MMC1_DAT4      MFP_CFG_DRV(GPIO130, AF1, FAST)
-#define GPIO131_MMC1_DAT3      MFP_CFG_DRV(GPIO131, AF1, FAST)
-#define GPIO132_MMC1_DAT2      MFP_CFG_DRV(GPIO132, AF1, FAST)
-#define GPIO133_MMC1_DAT1      MFP_CFG_DRV(GPIO133, AF1, FAST)
-#define GPIO134_MMC1_DAT0      MFP_CFG_DRV(GPIO134, AF1, FAST)
-#define GPIO136_MMC1_CMD       MFP_CFG_DRV(GPIO136, AF1, FAST)
-#define GPIO139_MMC1_CLK       MFP_CFG_DRV(GPIO139, AF1, FAST)
-#define GPIO140_MMC1_CD                MFP_CFG_DRV(GPIO140, AF1, FAST)
-#define GPIO141_MMC1_WP                MFP_CFG_DRV(GPIO141, AF1, FAST)
-
-/*MMC2*/
-#define GPIO37_MMC2_DAT3       MFP_CFG_DRV(GPIO37, AF1, FAST)
-#define GPIO38_MMC2_DAT2       MFP_CFG_DRV(GPIO38, AF1, FAST)
-#define GPIO39_MMC2_DAT1       MFP_CFG_DRV(GPIO39, AF1, FAST)
-#define GPIO40_MMC2_DAT0       MFP_CFG_DRV(GPIO40, AF1, FAST)
-#define GPIO41_MMC2_CMD                MFP_CFG_DRV(GPIO41, AF1, FAST)
-#define GPIO42_MMC2_CLK                MFP_CFG_DRV(GPIO42, AF1, FAST)
-
-/*MMC3*/
-#define GPIO165_MMC3_DAT7      MFP_CFG_DRV(GPIO165, AF2, FAST)
-#define GPIO162_MMC3_DAT6      MFP_CFG_DRV(GPIO162, AF2, FAST)
-#define GPIO166_MMC3_DAT5      MFP_CFG_DRV(GPIO166, AF2, FAST)
-#define GPIO163_MMC3_DAT4      MFP_CFG_DRV(GPIO163, AF2, FAST)
-#define GPIO167_MMC3_DAT3      MFP_CFG_DRV(GPIO167, AF2, FAST)
-#define GPIO164_MMC3_DAT2      MFP_CFG_DRV(GPIO164, AF2, FAST)
-#define GPIO168_MMC3_DAT1      MFP_CFG_DRV(GPIO168, AF2, FAST)
-#define GPIO111_MMC3_DAT0      MFP_CFG_DRV(GPIO111, AF2, FAST)
-#define GPIO112_MMC3_CMD       MFP_CFG_DRV(GPIO112, AF2, FAST)
-#define GPIO151_MMC3_CLK       MFP_CFG_DRV(GPIO151, AF2, FAST)
-
-/* LCD */
-#define GPIO74_LCD_FCLK                MFP_CFG_DRV(GPIO74, AF1, FAST)
-#define GPIO75_LCD_LCLK                MFP_CFG_DRV(GPIO75, AF1, FAST)
-#define GPIO76_LCD_PCLK                MFP_CFG_DRV(GPIO76, AF1, FAST)
-#define GPIO77_LCD_DENA                MFP_CFG_DRV(GPIO77, AF1, FAST)
-#define GPIO78_LCD_DD0         MFP_CFG_DRV(GPIO78, AF1, FAST)
-#define GPIO79_LCD_DD1         MFP_CFG_DRV(GPIO79, AF1, FAST)
-#define GPIO80_LCD_DD2         MFP_CFG_DRV(GPIO80, AF1, FAST)
-#define GPIO81_LCD_DD3         MFP_CFG_DRV(GPIO81, AF1, FAST)
-#define GPIO82_LCD_DD4         MFP_CFG_DRV(GPIO82, AF1, FAST)
-#define GPIO83_LCD_DD5         MFP_CFG_DRV(GPIO83, AF1, FAST)
-#define GPIO84_LCD_DD6         MFP_CFG_DRV(GPIO84, AF1, FAST)
-#define GPIO85_LCD_DD7         MFP_CFG_DRV(GPIO85, AF1, FAST)
-#define GPIO86_LCD_DD8         MFP_CFG_DRV(GPIO86, AF1, FAST)
-#define GPIO87_LCD_DD9         MFP_CFG_DRV(GPIO87, AF1, FAST)
-#define GPIO88_LCD_DD10                MFP_CFG_DRV(GPIO88, AF1, FAST)
-#define GPIO89_LCD_DD11                MFP_CFG_DRV(GPIO89, AF1, FAST)
-#define GPIO90_LCD_DD12                MFP_CFG_DRV(GPIO90, AF1, FAST)
-#define GPIO91_LCD_DD13                MFP_CFG_DRV(GPIO91, AF1, FAST)
-#define GPIO92_LCD_DD14                MFP_CFG_DRV(GPIO92, AF1, FAST)
-#define GPIO93_LCD_DD15                MFP_CFG_DRV(GPIO93, AF1, FAST)
-#define GPIO94_LCD_DD16                MFP_CFG_DRV(GPIO94, AF1, FAST)
-#define GPIO95_LCD_DD17                MFP_CFG_DRV(GPIO95, AF1, FAST)
-#define GPIO96_LCD_DD18                MFP_CFG_DRV(GPIO96, AF1, FAST)
-#define GPIO97_LCD_DD19                MFP_CFG_DRV(GPIO97, AF1, FAST)
-#define GPIO98_LCD_DD20                MFP_CFG_DRV(GPIO98, AF1, FAST)
-#define GPIO99_LCD_DD21                MFP_CFG_DRV(GPIO99, AF1, FAST)
-#define GPIO100_LCD_DD22       MFP_CFG_DRV(GPIO100, AF1, FAST)
-#define GPIO101_LCD_DD23       MFP_CFG_DRV(GPIO101, AF1, FAST)
-#define GPIO94_SPI_DCLK                MFP_CFG_DRV(GPIO94, AF3, FAST)
-#define GPIO95_SPI_CS0         MFP_CFG_DRV(GPIO95, AF3, FAST)
-#define GPIO96_SPI_DIN         MFP_CFG_DRV(GPIO96, AF3, FAST)
-#define GPIO97_SPI_DOUT                MFP_CFG_DRV(GPIO97, AF3, FAST)
-#define GPIO98_LCD_RST         MFP_CFG_DRV(GPIO98, AF0, FAST)
-
-#define GPIO114_MN_CLK_OUT     MFP_CFG_DRV(GPIO114, AF1, FAST)
-
-/*LCD TV path*/
-#define GPIO124_LCD_DD24       MFP_CFG_DRV(GPIO124, AF2, FAST)
-#define GPIO125_LCD_DD25       MFP_CFG_DRV(GPIO125, AF2, FAST)
-#define GPIO126_LCD_DD33       MFP_CFG_DRV(GPIO126, AF2, FAST)
-#define GPIO127_LCD_DD26       MFP_CFG_DRV(GPIO127, AF2, FAST)
-#define GPIO128_LCD_DD27       MFP_CFG_DRV(GPIO128, AF2, FAST)
-#define GPIO129_LCD_DD28       MFP_CFG_DRV(GPIO129, AF2, FAST)
-#define GPIO130_LCD_DD29       MFP_CFG_DRV(GPIO130, AF2, FAST)
-#define GPIO135_LCD_DD30       MFP_CFG_DRV(GPIO135, AF2, FAST)
-#define GPIO137_LCD_DD31       MFP_CFG_DRV(GPIO137, AF2, FAST)
-#define GPIO138_LCD_DD32       MFP_CFG_DRV(GPIO138, AF2, FAST)
-#define GPIO140_LCD_DD34       MFP_CFG_DRV(GPIO140, AF2, FAST)
-#define GPIO141_LCD_DD35       MFP_CFG_DRV(GPIO141, AF2, FAST)
-
-/* I2C */
-#define GPIO43_TWSI2_SCL       MFP_CFG_DRV(GPIO43, AF1, SLOW)
-#define GPIO44_TWSI2_SDA       MFP_CFG_DRV(GPIO44, AF1, SLOW)
-#define GPIO71_TWSI3_SCL       MFP_CFG_DRV(GPIO71, AF1, SLOW)
-#define GPIO72_TWSI3_SDA       MFP_CFG_DRV(GPIO72, AF1, SLOW)
-#define TWSI4_SCL              MFP_CFG_DRV(TWSI4_SCL, AF0, SLOW)
-#define TWSI4_SDA              MFP_CFG_DRV(TWSI4_SDA, AF0, SLOW)
-#define GPIO99_TWSI5_SCL       MFP_CFG_DRV(GPIO99, AF4, SLOW)
-#define GPIO100_TWSI5_SDA      MFP_CFG_DRV(GPIO100, AF4, SLOW)
-#define GPIO97_TWSI6_SCL       MFP_CFG_DRV(GPIO97, AF2, SLOW)
-#define GPIO98_TWSI6_SDA       MFP_CFG_DRV(GPIO98, AF2, SLOW)
-
-/* SSPA1 */
-#define GPIO24_I2S_SYSCLK      MFP_CFG(GPIO24, AF1)
-#define GPIO25_I2S_BITCLK      MFP_CFG(GPIO25, AF1)
-#define GPIO26_I2S_SYNC                MFP_CFG(GPIO26, AF1)
-#define GPIO27_I2S_DATA_OUT    MFP_CFG(GPIO27, AF1)
-#define GPIO28_I2S_SDATA_IN    MFP_CFG(GPIO28, AF1)
-#define GPIO114_I2S_MCLK       MFP_CFG(GPIO114, AF1)
-
-/* SSPA2 */
-#define GPIO33_SSPA2_CLK       MFP_CFG(GPIO33, AF1)
-#define GPIO34_SSPA2_FRM       MFP_CFG(GPIO34, AF1)
-#define GPIO35_SSPA2_TXD       MFP_CFG(GPIO35, AF1)
-#define GPIO36_SSPA2_RXD       MFP_CFG(GPIO36, AF1)
-
-/* Keypad */
-#define GPIO00_KP_MKIN0                MFP_CFG(GPIO0, AF1)
-#define GPIO01_KP_MKOUT0       MFP_CFG(GPIO1, AF1)
-#define GPIO02_KP_MKIN1                MFP_CFG(GPIO2, AF1)
-#define GPIO03_KP_MKOUT1       MFP_CFG(GPIO3, AF1)
-#define GPIO04_KP_MKIN2                MFP_CFG(GPIO4, AF1)
-#define GPIO05_KP_MKOUT2       MFP_CFG(GPIO5, AF1)
-#define GPIO06_KP_MKIN3                MFP_CFG(GPIO6, AF1)
-#define GPIO07_KP_MKOUT3       MFP_CFG(GPIO7, AF1)
-#define GPIO08_KP_MKIN4                MFP_CFG(GPIO8, AF1)
-#define GPIO09_KP_MKOUT4       MFP_CFG(GPIO9, AF1)
-#define GPIO10_KP_MKIN5                MFP_CFG(GPIO10, AF1)
-#define GPIO11_KP_MKOUT5       MFP_CFG(GPIO11, AF1)
-#define GPIO12_KP_MKIN6                MFP_CFG(GPIO12, AF1)
-#define GPIO13_KP_MKOUT6       MFP_CFG(GPIO13, AF1)
-#define GPIO14_KP_MKIN7                MFP_CFG(GPIO14, AF1)
-#define GPIO15_KP_MKOUT7       MFP_CFG(GPIO15, AF1)
-#define GPIO16_KP_DKIN0                MFP_CFG(GPIO16, AF1)
-#define GPIO17_KP_DKIN1                MFP_CFG(GPIO17, AF1)
-#define GPIO18_KP_DKIN2                MFP_CFG(GPIO18, AF1)
-#define GPIO19_KP_DKIN3                MFP_CFG(GPIO19, AF1)
-#define GPIO20_KP_DKIN4                MFP_CFG(GPIO20, AF1)
-#define GPIO21_KP_DKIN5                MFP_CFG(GPIO21, AF1)
-#define GPIO22_KP_DKIN6                MFP_CFG(GPIO22, AF1)
-#define GPIO23_KP_DKIN7                MFP_CFG(GPIO23, AF1)
-
-/* CAMERA */
-#define GPIO59_CCIC_IN7                MFP_CFG_DRV(GPIO59, AF1, FAST)
-#define GPIO60_CCIC_IN6                MFP_CFG_DRV(GPIO60, AF1, FAST)
-#define GPIO61_CCIC_IN5                MFP_CFG_DRV(GPIO61, AF1, FAST)
-#define GPIO62_CCIC_IN4                MFP_CFG_DRV(GPIO62, AF1, FAST)
-#define GPIO63_CCIC_IN3                MFP_CFG_DRV(GPIO63, AF1, FAST)
-#define GPIO64_CCIC_IN2                MFP_CFG_DRV(GPIO64, AF1, FAST)
-#define GPIO65_CCIC_IN1                MFP_CFG_DRV(GPIO65, AF1, FAST)
-#define GPIO66_CCIC_IN0                MFP_CFG_DRV(GPIO66, AF1, FAST)
-#define GPIO67_CAM_HSYNC       MFP_CFG_DRV(GPIO67, AF1, FAST)
-#define GPIO68_CAM_VSYNC       MFP_CFG_DRV(GPIO68, AF1, FAST)
-#define GPIO69_CAM_MCLK                MFP_CFG_DRV(GPIO69, AF1, FAST)
-#define GPIO70_CAM_PCLK                MFP_CFG_DRV(GPIO70, AF1, FAST)
-
-/* PMIC */
-#define PMIC_PMIC_INT          MFP_CFG(PMIC_INT, AF0)
-
-#endif /* __ASM_MACH_MFP_MMP2_H */
-
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
deleted file mode 100644 (file)
index 92aaa3c..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-#ifndef __ASM_MACH_MFP_PXA168_H
-#define __ASM_MACH_MFP_PXA168_H
-
-#include <mach/mfp.h>
-
-#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
-#define MFP_DRIVE_SLOW         (0x1 << 13)
-#define MFP_DRIVE_MEDIUM       (0x2 << 13)
-#define MFP_DRIVE_FAST         (0x3 << 13)
-
-#undef MFP_CFG
-#undef MFP_CFG_DRV
-
-#define MFP_CFG(pin, af)               \
-       (MFP_LPM_INPUT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
-
-#define MFP_CFG_DRV(pin, af, drv)      \
-       (MFP_LPM_INPUT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
-
-/* GPIO */
-#define GPIO0_GPIO             MFP_CFG(GPIO0, AF5)
-#define GPIO1_GPIO             MFP_CFG(GPIO1, AF5)
-#define GPIO2_GPIO             MFP_CFG(GPIO2, AF5)
-#define GPIO3_GPIO             MFP_CFG(GPIO3, AF5)
-#define GPIO4_GPIO             MFP_CFG(GPIO4, AF5)
-#define GPIO5_GPIO             MFP_CFG(GPIO5, AF5)
-#define GPIO6_GPIO             MFP_CFG(GPIO6, AF5)
-#define GPIO7_GPIO             MFP_CFG(GPIO7, AF5)
-#define GPIO8_GPIO             MFP_CFG(GPIO8, AF5)
-#define GPIO9_GPIO             MFP_CFG(GPIO9, AF5)
-#define GPIO10_GPIO            MFP_CFG(GPIO10, AF5)
-#define GPIO11_GPIO            MFP_CFG(GPIO11, AF5)
-#define GPIO12_GPIO            MFP_CFG(GPIO12, AF5)
-#define GPIO13_GPIO            MFP_CFG(GPIO13, AF5)
-#define GPIO14_GPIO            MFP_CFG(GPIO14, AF5)
-#define GPIO15_GPIO            MFP_CFG(GPIO15, AF5)
-#define GPIO16_GPIO            MFP_CFG(GPIO16, AF0)
-#define GPIO17_GPIO            MFP_CFG(GPIO17, AF5)
-#define GPIO18_GPIO            MFP_CFG(GPIO18, AF0)
-#define GPIO19_GPIO            MFP_CFG(GPIO19, AF5)
-#define GPIO20_GPIO            MFP_CFG(GPIO20, AF0)
-#define GPIO21_GPIO            MFP_CFG(GPIO21, AF5)
-#define GPIO22_GPIO            MFP_CFG(GPIO22, AF5)
-#define GPIO23_GPIO            MFP_CFG(GPIO23, AF5)
-#define GPIO24_GPIO            MFP_CFG(GPIO24, AF5)
-#define GPIO25_GPIO            MFP_CFG(GPIO25, AF5)
-#define GPIO26_GPIO            MFP_CFG(GPIO26, AF0)
-#define GPIO27_GPIO            MFP_CFG(GPIO27, AF5)
-#define GPIO28_GPIO            MFP_CFG(GPIO28, AF5)
-#define GPIO29_GPIO            MFP_CFG(GPIO29, AF5)
-#define GPIO30_GPIO            MFP_CFG(GPIO30, AF5)
-#define GPIO31_GPIO            MFP_CFG(GPIO31, AF5)
-#define GPIO32_GPIO            MFP_CFG(GPIO32, AF5)
-#define GPIO33_GPIO            MFP_CFG(GPIO33, AF5)
-#define GPIO34_GPIO            MFP_CFG(GPIO34, AF0)
-#define GPIO35_GPIO            MFP_CFG(GPIO35, AF0)
-#define GPIO36_GPIO            MFP_CFG(GPIO36, AF0)
-#define GPIO37_GPIO            MFP_CFG(GPIO37, AF0)
-#define GPIO38_GPIO            MFP_CFG(GPIO38, AF0)
-#define GPIO39_GPIO            MFP_CFG(GPIO39, AF0)
-#define GPIO40_GPIO            MFP_CFG(GPIO40, AF0)
-#define GPIO41_GPIO            MFP_CFG(GPIO41, AF0)
-#define GPIO42_GPIO            MFP_CFG(GPIO42, AF0)
-#define GPIO43_GPIO            MFP_CFG(GPIO43, AF0)
-#define GPIO44_GPIO            MFP_CFG(GPIO44, AF0)
-#define GPIO45_GPIO            MFP_CFG(GPIO45, AF0)
-#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
-#define GPIO47_GPIO            MFP_CFG(GPIO47, AF0)
-#define GPIO48_GPIO            MFP_CFG(GPIO48, AF0)
-#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
-#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
-#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
-#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
-#define GPIO53_GPIO            MFP_CFG(GPIO53, AF0)
-#define GPIO54_GPIO            MFP_CFG(GPIO54, AF0)
-#define GPIO55_GPIO            MFP_CFG(GPIO55, AF0)
-#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
-#define GPIO57_GPIO            MFP_CFG(GPIO57, AF0)
-#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
-#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
-#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
-#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
-#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
-#define GPIO63_GPIO            MFP_CFG(GPIO63, AF0)
-#define GPIO64_GPIO            MFP_CFG(GPIO64, AF0)
-#define GPIO65_GPIO            MFP_CFG(GPIO65, AF0)
-#define GPIO66_GPIO            MFP_CFG(GPIO66, AF0)
-#define GPIO67_GPIO            MFP_CFG(GPIO67, AF0)
-#define GPIO68_GPIO            MFP_CFG(GPIO68, AF0)
-#define GPIO69_GPIO            MFP_CFG(GPIO69, AF0)
-#define GPIO70_GPIO            MFP_CFG(GPIO70, AF0)
-#define GPIO71_GPIO            MFP_CFG(GPIO71, AF0)
-#define GPIO72_GPIO            MFP_CFG(GPIO72, AF0)
-#define GPIO73_GPIO            MFP_CFG(GPIO73, AF0)
-#define GPIO74_GPIO            MFP_CFG(GPIO74, AF0)
-#define GPIO75_GPIO            MFP_CFG(GPIO75, AF0)
-#define GPIO76_GPIO            MFP_CFG(GPIO76, AF0)
-#define GPIO77_GPIO            MFP_CFG(GPIO77, AF0)
-#define GPIO78_GPIO            MFP_CFG(GPIO78, AF0)
-#define GPIO79_GPIO            MFP_CFG(GPIO79, AF0)
-#define GPIO80_GPIO            MFP_CFG(GPIO80, AF0)
-#define GPIO81_GPIO            MFP_CFG(GPIO81, AF0)
-#define GPIO82_GPIO            MFP_CFG(GPIO82, AF0)
-#define GPIO83_GPIO            MFP_CFG(GPIO83, AF0)
-#define GPIO84_GPIO            MFP_CFG(GPIO84, AF0)
-#define GPIO85_GPIO            MFP_CFG(GPIO85, AF0)
-#define GPIO86_GPIO            MFP_CFG(GPIO86, AF0)
-#define GPIO87_GPIO            MFP_CFG(GPIO87, AF0)
-#define GPIO88_GPIO            MFP_CFG(GPIO88, AF0)
-#define GPIO89_GPIO            MFP_CFG(GPIO89, AF0)
-#define GPIO90_GPIO            MFP_CFG(GPIO90, AF0)
-#define GPIO91_GPIO            MFP_CFG(GPIO91, AF0)
-#define GPIO92_GPIO            MFP_CFG(GPIO92, AF0)
-#define GPIO93_GPIO            MFP_CFG(GPIO93, AF0)
-#define GPIO94_GPIO            MFP_CFG(GPIO94, AF0)
-#define GPIO95_GPIO            MFP_CFG(GPIO95, AF0)
-#define GPIO96_GPIO            MFP_CFG(GPIO96, AF0)
-#define GPIO97_GPIO            MFP_CFG(GPIO97, AF0)
-#define GPIO98_GPIO            MFP_CFG(GPIO98, AF0)
-#define GPIO99_GPIO            MFP_CFG(GPIO99, AF0)
-#define GPIO100_GPIO           MFP_CFG(GPIO100, AF0)
-#define GPIO101_GPIO           MFP_CFG(GPIO101, AF0)
-#define GPIO102_GPIO           MFP_CFG(GPIO102, AF0)
-#define GPIO103_GPIO           MFP_CFG(GPIO103, AF0)
-#define GPIO104_GPIO           MFP_CFG(GPIO104, AF0)
-#define GPIO105_GPIO           MFP_CFG(GPIO105, AF0)
-#define GPIO106_GPIO           MFP_CFG(GPIO106, AF0)
-#define GPIO107_GPIO           MFP_CFG(GPIO107, AF0)
-#define GPIO108_GPIO           MFP_CFG(GPIO108, AF0)
-#define GPIO109_GPIO           MFP_CFG(GPIO109, AF0)
-#define GPIO110_GPIO           MFP_CFG(GPIO110, AF0)
-#define GPIO111_GPIO           MFP_CFG(GPIO111, AF0)
-#define GPIO112_GPIO           MFP_CFG(GPIO112, AF0)
-#define GPIO113_GPIO           MFP_CFG(GPIO113, AF0)
-#define GPIO114_GPIO           MFP_CFG(GPIO114, AF0)
-#define GPIO115_GPIO           MFP_CFG(GPIO115, AF0)
-#define GPIO116_GPIO           MFP_CFG(GPIO116, AF0)
-#define GPIO117_GPIO           MFP_CFG(GPIO117, AF0)
-#define GPIO118_GPIO           MFP_CFG(GPIO118, AF0)
-#define GPIO119_GPIO           MFP_CFG(GPIO119, AF0)
-#define GPIO120_GPIO           MFP_CFG(GPIO120, AF0)
-#define GPIO121_GPIO           MFP_CFG(GPIO121, AF0)
-#define GPIO122_GPIO           MFP_CFG(GPIO122, AF0)
-
-/* DFI */
-#define GPIO0_DFI_D15          MFP_CFG(GPIO0, AF0)
-#define GPIO1_DFI_D14          MFP_CFG(GPIO1, AF0)
-#define GPIO2_DFI_D13          MFP_CFG(GPIO2, AF0)
-#define GPIO3_DFI_D12          MFP_CFG(GPIO3, AF0)
-#define GPIO4_DFI_D11          MFP_CFG(GPIO4, AF0)
-#define GPIO5_DFI_D10          MFP_CFG(GPIO5, AF0)
-#define GPIO6_DFI_D9           MFP_CFG(GPIO6, AF0)
-#define GPIO7_DFI_D8           MFP_CFG(GPIO7, AF0)
-#define GPIO8_DFI_D7           MFP_CFG(GPIO8, AF0)
-#define GPIO9_DFI_D6           MFP_CFG(GPIO9, AF0)
-#define GPIO10_DFI_D5          MFP_CFG(GPIO10, AF0)
-#define GPIO11_DFI_D4          MFP_CFG(GPIO11, AF0)
-#define GPIO12_DFI_D3          MFP_CFG(GPIO12, AF0)
-#define GPIO13_DFI_D2          MFP_CFG(GPIO13, AF0)
-#define GPIO14_DFI_D1          MFP_CFG(GPIO14, AF0)
-#define GPIO15_DFI_D0          MFP_CFG(GPIO15, AF0)
-
-#define GPIO30_DFI_ADDR0       MFP_CFG(GPIO30, AF0)
-#define GPIO31_DFI_ADDR1       MFP_CFG(GPIO31, AF0)
-#define GPIO32_DFI_ADDR2       MFP_CFG(GPIO32, AF0)
-#define GPIO33_DFI_ADDR3       MFP_CFG(GPIO33, AF0)
-
-/* NAND */
-#define GPIO16_ND_nCS0         MFP_CFG(GPIO16, AF1)
-#define GPIO17_ND_nWE          MFP_CFG(GPIO17, AF0)
-#define GPIO21_ND_ALE          MFP_CFG(GPIO21, AF0)
-#define GPIO22_ND_CLE          MFP_CFG(GPIO22, AF0)
-#define GPIO24_ND_nRE          MFP_CFG(GPIO24, AF0)
-#define GPIO26_ND_RnB1         MFP_CFG(GPIO26, AF1)
-#define GPIO27_ND_RnB2         MFP_CFG(GPIO27, AF1)
-
-/* Static Memory Controller */
-#define GPIO18_SMC_nCS0                MFP_CFG(GPIO18, AF3)
-#define GPIO18_SMC_nCS1                MFP_CFG(GPIO18, AF2)
-#define GPIO16_SMC_nCS0                MFP_CFG(GPIO16, AF2)
-#define GPIO16_SMC_nCS1                MFP_CFG(GPIO16, AF3)
-#define GPIO19_SMC_nCS0                MFP_CFG(GPIO19, AF0)
-#define GPIO20_SMC_nCS1                MFP_CFG(GPIO20, AF2)
-#define GPIO23_SMC_nLUA                MFP_CFG(GPIO23, AF0)
-#define GPIO25_SMC_nLLA                MFP_CFG(GPIO25, AF0)
-#define GPIO27_SMC_IRQ         MFP_CFG(GPIO27, AF0)
-#define GPIO28_SMC_RDY         MFP_CFG(GPIO28, AF0)
-#define GPIO29_SMC_SCLK                MFP_CFG(GPIO29, AF0)
-#define GPIO34_SMC_nCS1                MFP_CFG(GPIO34, AF2)
-#define GPIO35_SMC_BE1         MFP_CFG(GPIO35, AF2)
-#define GPIO36_SMC_BE2         MFP_CFG(GPIO36, AF2)
-
-/* Compact Flash */
-#define GPIO19_CF_nCE1         MFP_CFG(GPIO19, AF3)
-#define GPIO20_CF_nCE2         MFP_CFG(GPIO20, AF3)
-#define GPIO23_CF_nALE         MFP_CFG(GPIO23, AF3)
-#define GPIO25_CF_nRESET       MFP_CFG(GPIO25, AF3)
-#define GPIO28_CF_RDY          MFP_CFG(GPIO28, AF3)
-#define GPIO29_CF_STSCH                MFP_CFG(GPIO29, AF3)
-#define GPIO30_CF_nREG         MFP_CFG(GPIO30, AF3)
-#define GPIO31_CF_nIOIS16      MFP_CFG(GPIO31, AF3)
-#define GPIO32_CF_nCD1         MFP_CFG(GPIO32, AF3)
-#define GPIO33_CF_nCD2         MFP_CFG(GPIO33, AF3)
-
-/* UART */
-#define GPIO8_UART3_TXD                MFP_CFG(GPIO8, AF2)
-#define GPIO9_UART3_RXD                MFP_CFG(GPIO9, AF2)
-#define GPIO1O_UART3_CTS       MFP_CFG(GPIO10, AF2)
-#define GPIO11_UART3_RTS       MFP_CFG(GPIO11, AF2)
-#define GPIO88_UART2_TXD       MFP_CFG(GPIO88, AF2)
-#define GPIO89_UART2_RXD       MFP_CFG(GPIO89, AF2)
-#define GPIO107_UART1_TXD      MFP_CFG_DRV(GPIO107, AF1, FAST)
-#define GPIO107_UART1_RXD      MFP_CFG_DRV(GPIO107, AF2, FAST)
-#define GPIO108_UART1_RXD      MFP_CFG_DRV(GPIO108, AF1, FAST)
-#define GPIO108_UART1_TXD      MFP_CFG_DRV(GPIO108, AF2, FAST)
-#define GPIO109_UART1_CTS      MFP_CFG(GPIO109, AF1)
-#define GPIO109_UART1_RTS      MFP_CFG(GPIO109, AF2)
-#define GPIO110_UART1_RTS      MFP_CFG(GPIO110, AF1)
-#define GPIO110_UART1_CTS      MFP_CFG(GPIO110, AF2)
-#define GPIO111_UART1_RI       MFP_CFG(GPIO111, AF1)
-#define GPIO111_UART1_DSR      MFP_CFG(GPIO111, AF2)
-#define GPIO112_UART1_DTR      MFP_CFG(GPIO111, AF1)
-#define GPIO112_UART1_DCD      MFP_CFG(GPIO112, AF2)
-
-/* MMC1 */
-#define GPIO37_MMC1_DAT7       MFP_CFG(GPIO37, AF1)
-#define GPIO38_MMC1_DAT6       MFP_CFG(GPIO38, AF1)
-#define GPIO54_MMC1_DAT5       MFP_CFG(GPIO54, AF1)
-#define GPIO48_MMC1_DAT4       MFP_CFG(GPIO48, AF1)
-#define GPIO51_MMC1_DAT3       MFP_CFG(GPIO51, AF1)
-#define GPIO52_MMC1_DAT2       MFP_CFG(GPIO52, AF1)
-#define GPIO40_MMC1_DAT1       MFP_CFG(GPIO40, AF1)
-#define GPIO41_MMC1_DAT0       MFP_CFG(GPIO41, AF1)
-#define GPIO49_MMC1_CMD                MFP_CFG(GPIO49, AF1)
-#define GPIO43_MMC1_CLK                MFP_CFG(GPIO43, AF1)
-#define GPIO53_MMC1_CD         MFP_CFG(GPIO53, AF1)
-#define GPIO46_MMC1_WP         MFP_CFG(GPIO46, AF1)
-
-/* MMC2 */
-#define        GPIO28_MMC2_CMD         MFP_CFG_DRV(GPIO28, AF6, FAST)
-#define        GPIO29_MMC2_CLK         MFP_CFG_DRV(GPIO29, AF6, FAST)
-#define        GPIO30_MMC2_DAT0        MFP_CFG_DRV(GPIO30, AF6, FAST)
-#define        GPIO31_MMC2_DAT1        MFP_CFG_DRV(GPIO31, AF6, FAST)
-#define        GPIO32_MMC2_DAT2        MFP_CFG_DRV(GPIO32, AF6, FAST)
-#define        GPIO33_MMC2_DAT3        MFP_CFG_DRV(GPIO33, AF6, FAST)
-
-/* MMC4 */
-#define GPIO125_MMC4_DAT3       MFP_CFG_DRV(GPIO125, AF7, FAST)
-#define GPIO126_MMC4_DAT2       MFP_CFG_DRV(GPIO126, AF7, FAST)
-#define GPIO127_MMC4_DAT1       MFP_CFG_DRV(GPIO127, AF7, FAST)
-#define GPIO0_2_MMC4_DAT0       MFP_CFG_DRV(GPIO0_2, AF7, FAST)
-#define GPIO1_2_MMC4_CMD        MFP_CFG_DRV(GPIO1_2, AF7, FAST)
-#define GPIO2_2_MMC4_CLK        MFP_CFG_DRV(GPIO2_2, AF7, FAST)
-
-/* LCD */
-#define GPIO84_LCD_CS          MFP_CFG(GPIO84, AF1)
-#define GPIO60_LCD_DD0         MFP_CFG(GPIO60, AF1)
-#define GPIO61_LCD_DD1         MFP_CFG(GPIO61, AF1)
-#define GPIO70_LCD_DD10                MFP_CFG(GPIO70, AF1)
-#define GPIO71_LCD_DD11                MFP_CFG(GPIO71, AF1)
-#define GPIO72_LCD_DD12                MFP_CFG(GPIO72, AF1)
-#define GPIO73_LCD_DD13                MFP_CFG(GPIO73, AF1)
-#define GPIO74_LCD_DD14                MFP_CFG(GPIO74, AF1)
-#define GPIO75_LCD_DD15                MFP_CFG(GPIO75, AF1)
-#define GPIO76_LCD_DD16                MFP_CFG(GPIO76, AF1)
-#define GPIO77_LCD_DD17                MFP_CFG(GPIO77, AF1)
-#define GPIO78_LCD_DD18                MFP_CFG(GPIO78, AF1)
-#define GPIO79_LCD_DD19                MFP_CFG(GPIO79, AF1)
-#define GPIO62_LCD_DD2         MFP_CFG(GPIO62, AF1)
-#define GPIO80_LCD_DD20                MFP_CFG(GPIO80, AF1)
-#define GPIO81_LCD_DD21                MFP_CFG(GPIO81, AF1)
-#define GPIO82_LCD_DD22                MFP_CFG(GPIO82, AF1)
-#define GPIO83_LCD_DD23                MFP_CFG(GPIO83, AF1)
-#define GPIO63_LCD_DD3         MFP_CFG(GPIO63, AF1)
-#define GPIO64_LCD_DD4         MFP_CFG(GPIO64, AF1)
-#define GPIO65_LCD_DD5         MFP_CFG(GPIO65, AF1)
-#define GPIO66_LCD_DD6         MFP_CFG(GPIO66, AF1)
-#define GPIO67_LCD_DD7         MFP_CFG(GPIO67, AF1)
-#define GPIO68_LCD_DD8         MFP_CFG(GPIO68, AF1)
-#define GPIO69_LCD_DD9         MFP_CFG(GPIO69, AF1)
-#define GPIO59_LCD_DENA_BIAS   MFP_CFG(GPIO59, AF1)
-#define GPIO56_LCD_FCLK_RD     MFP_CFG(GPIO56, AF1)
-#define GPIO57_LCD_LCLK_A0     MFP_CFG(GPIO57, AF1)
-#define GPIO58_LCD_PCLK_WR     MFP_CFG(GPIO58, AF1)
-#define GPIO85_LCD_VSYNC       MFP_CFG(GPIO85, AF1)
-
-/* I2C */
-#define GPIO105_CI2C_SDA       MFP_CFG(GPIO105, AF1)
-#define GPIO106_CI2C_SCL       MFP_CFG(GPIO106, AF1)
-
-/* I2S */
-#define GPIO113_I2S_MCLK       MFP_CFG(GPIO113, AF6)
-#define GPIO114_I2S_FRM                MFP_CFG(GPIO114, AF1)
-#define GPIO115_I2S_BCLK       MFP_CFG(GPIO115, AF1)
-#define GPIO116_I2S_RXD                MFP_CFG(GPIO116, AF2)
-#define GPIO116_I2S_TXD         MFP_CFG(GPIO116, AF1)
-#define GPIO117_I2S_TXD                MFP_CFG(GPIO117, AF2)
-
-/* PWM */
-#define GPIO96_PWM3_OUT                MFP_CFG(GPIO96, AF1)
-#define GPIO97_PWM2_OUT                MFP_CFG(GPIO97, AF1)
-#define GPIO98_PWM1_OUT                MFP_CFG(GPIO98, AF1)
-#define GPIO104_PWM4_OUT       MFP_CFG(GPIO104, AF1)
-#define GPIO106_PWM2_OUT       MFP_CFG(GPIO106, AF2)
-#define GPIO74_PWM4_OUT                MFP_CFG(GPIO74, AF2)
-#define GPIO75_PWM3_OUT                MFP_CFG(GPIO75, AF2)
-#define GPIO76_PWM2_OUT                MFP_CFG(GPIO76, AF2)
-#define GPIO77_PWM1_OUT                MFP_CFG(GPIO77, AF2)
-#define GPIO82_PWM4_OUT                MFP_CFG(GPIO82, AF2)
-#define GPIO83_PWM3_OUT                MFP_CFG(GPIO83, AF2)
-#define GPIO84_PWM2_OUT                MFP_CFG(GPIO84, AF2)
-#define GPIO85_PWM1_OUT                MFP_CFG(GPIO85, AF2)
-#define GPIO84_PWM1_OUT                MFP_CFG(GPIO84, AF4)
-#define GPIO122_PWM3_OUT       MFP_CFG(GPIO122, AF3)
-#define GPIO123_PWM1_OUT       MFP_CFG(GPIO123, AF1)
-#define GPIO124_PWM2_OUT       MFP_CFG(GPIO124, AF1)
-#define GPIO125_PWM3_OUT       MFP_CFG(GPIO125, AF1)
-#define GPIO126_PWM4_OUT       MFP_CFG(GPIO126, AF1)
-#define GPIO86_PWM1_OUT                MFP_CFG(GPIO86, AF2)
-#define GPIO86_PWM2_OUT                MFP_CFG(GPIO86, AF3)
-
-/* Keypad */
-#define GPIO109_KP_MKIN1        MFP_CFG(GPIO109, AF7)
-#define GPIO110_KP_MKIN0        MFP_CFG(GPIO110, AF7)
-#define GPIO111_KP_MKOUT7       MFP_CFG(GPIO111, AF7)
-#define GPIO112_KP_MKOUT6       MFP_CFG(GPIO112, AF7)
-#define GPIO121_KP_MKIN4        MFP_CFG(GPIO121, AF7)
-
-/* Fast Ethernet */
-#define GPIO86_TX_CLK          MFP_CFG(GPIO86, AF5)
-#define GPIO87_TX_EN           MFP_CFG(GPIO87, AF5)
-#define GPIO88_TX_DQ3          MFP_CFG(GPIO88, AF5)
-#define GPIO89_TX_DQ2          MFP_CFG(GPIO89, AF5)
-#define GPIO90_TX_DQ1          MFP_CFG(GPIO90, AF5)
-#define GPIO91_TX_DQ0          MFP_CFG(GPIO91, AF5)
-#define GPIO92_MII_CRS         MFP_CFG(GPIO92, AF5)
-#define GPIO93_MII_COL         MFP_CFG(GPIO93, AF5)
-#define GPIO94_RX_CLK          MFP_CFG(GPIO94, AF5)
-#define GPIO95_RX_ER           MFP_CFG(GPIO95, AF5)
-#define GPIO96_RX_DQ3          MFP_CFG(GPIO96, AF5)
-#define GPIO97_RX_DQ2          MFP_CFG(GPIO97, AF5)
-#define GPIO98_RX_DQ1          MFP_CFG(GPIO98, AF5)
-#define GPIO99_RX_DQ0          MFP_CFG(GPIO99, AF5)
-#define GPIO100_MII_MDC                MFP_CFG(GPIO100, AF5)
-#define GPIO101_MII_MDIO       MFP_CFG(GPIO101, AF5)
-#define GPIO103_RX_DV          MFP_CFG(GPIO103, AF5)
-
-/* SSP2 */
-#define GPIO107_SSP2_RXD       MFP_CFG(GPIO107, AF4)
-#define GPIO108_SSP2_TXD       MFP_CFG(GPIO108, AF4)
-#define GPIO111_SSP2_CLK       MFP_CFG(GPIO111, AF4)
-#define GPIO112_SSP2_FRM       MFP_CFG(GPIO112, AF4)
-
-#endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
deleted file mode 100644 (file)
index 8c78f2b..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-#ifndef __ASM_MACH_MFP_PXA910_H
-#define __ASM_MACH_MFP_PXA910_H
-
-#include <mach/mfp.h>
-
-#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
-#define MFP_DRIVE_SLOW         (0x2 << 13)
-#define MFP_DRIVE_MEDIUM       (0x4 << 13)
-#define MFP_DRIVE_FAST         (0x6 << 13)
-
-/* UART2 */
-#define GPIO47_UART2_RXD       MFP_CFG(GPIO47, AF6)
-#define GPIO48_UART2_TXD       MFP_CFG(GPIO48, AF6)
-
-/* UART3 */
-#define GPIO31_UART3_RXD       MFP_CFG(GPIO31, AF4)
-#define GPIO32_UART3_TXD       MFP_CFG(GPIO32, AF4)
-
-/*IRDA*/
-#define GPIO51_IRDA_SHDN       MFP_CFG(GPIO51, AF0)
-
-/* SMC */
-#define SM_nCS0_nCS0           MFP_CFG(SM_nCS0, AF0)
-#define SM_ADV_SM_ADV          MFP_CFG(SM_ADV, AF0)
-#define SM_SCLK_SM_SCLK                MFP_CFG(SM_SCLK, AF0)
-#define SM_BE0_SM_BE0          MFP_CFG(SM_BE0, AF1)
-#define SM_BE1_SM_BE1          MFP_CFG(SM_BE1, AF1)
-
-/* I2C */
-#define GPIO53_CI2C_SCL                MFP_CFG(GPIO53, AF2)
-#define GPIO54_CI2C_SDA                MFP_CFG(GPIO54, AF2)
-
-/* SSP1 (I2S) */
-#define GPIO24_SSP1_SDATA_IN   MFP_CFG_DRV(GPIO24, AF1, MEDIUM)
-#define GPIO21_SSP1_BITCLK     MFP_CFG_DRV(GPIO21, AF1, MEDIUM)
-#define GPIO20_SSP1_SYSCLK     MFP_CFG_DRV(GPIO20, AF1, MEDIUM)
-#define GPIO22_SSP1_SYNC       MFP_CFG_DRV(GPIO22, AF1, MEDIUM)
-#define GPIO23_SSP1_DATA_OUT   MFP_CFG_DRV(GPIO23, AF1, MEDIUM)
-#define GPIO124_MN_CLK_OUT     MFP_CFG_DRV(GPIO124, AF1, MEDIUM)
-#define GPIO123_CLK_REQ                MFP_CFG_DRV(GPIO123, AF0, MEDIUM)
-
-/* DFI */
-#define DF_IO0_ND_IO0          MFP_CFG(DF_IO0, AF0)
-#define DF_IO1_ND_IO1          MFP_CFG(DF_IO1, AF0)
-#define DF_IO2_ND_IO2          MFP_CFG(DF_IO2, AF0)
-#define DF_IO3_ND_IO3          MFP_CFG(DF_IO3, AF0)
-#define DF_IO4_ND_IO4          MFP_CFG(DF_IO4, AF0)
-#define DF_IO5_ND_IO5          MFP_CFG(DF_IO5, AF0)
-#define DF_IO6_ND_IO6          MFP_CFG(DF_IO6, AF0)
-#define DF_IO7_ND_IO7          MFP_CFG(DF_IO7, AF0)
-#define DF_IO8_ND_IO8          MFP_CFG(DF_IO8, AF0)
-#define DF_IO9_ND_IO9          MFP_CFG(DF_IO9, AF0)
-#define DF_IO10_ND_IO10                MFP_CFG(DF_IO10, AF0)
-#define DF_IO11_ND_IO11                MFP_CFG(DF_IO11, AF0)
-#define DF_IO12_ND_IO12                MFP_CFG(DF_IO12, AF0)
-#define DF_IO13_ND_IO13                MFP_CFG(DF_IO13, AF0)
-#define DF_IO14_ND_IO14                MFP_CFG(DF_IO14, AF0)
-#define DF_IO15_ND_IO15                MFP_CFG(DF_IO15, AF0)
-#define DF_nCS0_SM_nCS2_nCS0   MFP_CFG(DF_nCS0_SM_nCS2, AF0)
-#define DF_ALE_SM_WEn_ND_ALE   MFP_CFG(DF_ALE_SM_WEn, AF1)
-#define DF_CLE_SM_OEn_ND_CLE   MFP_CFG(DF_CLE_SM_OEn, AF0)
-#define DF_WEn_DF_WEn          MFP_CFG(DF_WEn, AF1)
-#define DF_REn_DF_REn          MFP_CFG(DF_REn, AF1)
-#define DF_RDY0_DF_RDY0                MFP_CFG(DF_RDY0, AF0)
-
-/*keypad*/
-#define GPIO00_KP_MKIN0                MFP_CFG(GPIO0, AF1)
-#define GPIO01_KP_MKOUT0       MFP_CFG(GPIO1, AF1)
-#define GPIO02_KP_MKIN1                MFP_CFG(GPIO2, AF1)
-#define GPIO03_KP_MKOUT1       MFP_CFG(GPIO3, AF1)
-#define GPIO04_KP_MKIN2                MFP_CFG(GPIO4, AF1)
-#define GPIO05_KP_MKOUT2       MFP_CFG(GPIO5, AF1)
-#define GPIO06_KP_MKIN3                MFP_CFG(GPIO6, AF1)
-#define GPIO07_KP_MKOUT3       MFP_CFG(GPIO7, AF1)
-#define GPIO08_KP_MKIN4                MFP_CFG(GPIO8, AF1)
-#define GPIO09_KP_MKOUT4       MFP_CFG(GPIO9, AF1)
-#define GPIO10_KP_MKIN5                MFP_CFG(GPIO10, AF1)
-#define GPIO11_KP_MKOUT5       MFP_CFG(GPIO11, AF1)
-#define GPIO12_KP_MKIN6                MFP_CFG(GPIO12, AF1)
-#define GPIO13_KP_MKOUT6       MFP_CFG(GPIO13, AF1)
-#define GPIO14_KP_MKIN7                MFP_CFG(GPIO14, AF1)
-#define GPIO15_KP_MKOUT7       MFP_CFG(GPIO15, AF1)
-#define GPIO16_KP_DKIN0                MFP_CFG(GPIO16, AF1)
-#define GPIO17_KP_DKIN1                MFP_CFG(GPIO17, AF1)
-#define GPIO18_KP_DKIN2                MFP_CFG(GPIO18, AF1)
-#define GPIO19_KP_DKIN3                MFP_CFG(GPIO19, AF1)
-
-/* LCD */
-#define GPIO81_LCD_FCLK                MFP_CFG(GPIO81, AF1)
-#define GPIO82_LCD_LCLK                MFP_CFG(GPIO82, AF1)
-#define GPIO83_LCD_PCLK                MFP_CFG(GPIO83, AF1)
-#define GPIO84_LCD_DENA                MFP_CFG(GPIO84, AF1)
-#define GPIO85_LCD_DD0         MFP_CFG(GPIO85, AF1)
-#define GPIO86_LCD_DD1         MFP_CFG(GPIO86, AF1)
-#define GPIO87_LCD_DD2         MFP_CFG(GPIO87, AF1)
-#define GPIO88_LCD_DD3         MFP_CFG(GPIO88, AF1)
-#define GPIO89_LCD_DD4         MFP_CFG(GPIO89, AF1)
-#define GPIO90_LCD_DD5         MFP_CFG(GPIO90, AF1)
-#define GPIO91_LCD_DD6         MFP_CFG(GPIO91, AF1)
-#define GPIO92_LCD_DD7         MFP_CFG(GPIO92, AF1)
-#define GPIO93_LCD_DD8         MFP_CFG(GPIO93, AF1)
-#define GPIO94_LCD_DD9         MFP_CFG(GPIO94, AF1)
-#define GPIO95_LCD_DD10                MFP_CFG(GPIO95, AF1)
-#define GPIO96_LCD_DD11                MFP_CFG(GPIO96, AF1)
-#define GPIO97_LCD_DD12                MFP_CFG(GPIO97, AF1)
-#define GPIO98_LCD_DD13                MFP_CFG(GPIO98, AF1)
-#define GPIO100_LCD_DD14       MFP_CFG(GPIO100, AF1)
-#define GPIO101_LCD_DD15       MFP_CFG(GPIO101, AF1)
-#define GPIO102_LCD_DD16       MFP_CFG(GPIO102, AF1)
-#define GPIO103_LCD_DD17       MFP_CFG(GPIO103, AF1)
-#define GPIO104_LCD_DD18       MFP_CFG(GPIO104, AF1)
-#define GPIO105_LCD_DD19       MFP_CFG(GPIO105, AF1)
-#define GPIO106_LCD_DD20       MFP_CFG(GPIO106, AF1)
-#define GPIO107_LCD_DD21       MFP_CFG(GPIO107, AF1)
-#define GPIO108_LCD_DD22       MFP_CFG(GPIO108, AF1)
-#define GPIO109_LCD_DD23       MFP_CFG(GPIO109, AF1)
-
-#define GPIO104_LCD_SPIDOUT    MFP_CFG(GPIO104, AF3)
-#define GPIO105_LCD_SPIDIN     MFP_CFG(GPIO105, AF3)
-#define GPIO107_LCD_CS1        MFP_CFG(GPIO107, AF3)
-#define GPIO108_LCD_DCLK       MFP_CFG(GPIO108, AF3)
-
-#define GPIO106_LCD_RESET      MFP_CFG(GPIO106, AF0)
-
-/*smart panel*/
-#define GPIO82_LCD_A0          MFP_CFG(GPIO82, AF0)
-#define GPIO83_LCD_WR          MFP_CFG(GPIO83, AF0)
-#define GPIO103_LCD_CS         MFP_CFG(GPIO103, AF0)
-
-/*1wire*/
-#define GPIO106_1WIRE          MFP_CFG(GPIO106, AF3)
-
-/*CCIC*/
-#define GPIO67_CCIC_IN7                MFP_CFG_DRV(GPIO67, AF1, MEDIUM)
-#define GPIO68_CCIC_IN6                MFP_CFG_DRV(GPIO68, AF1, MEDIUM)
-#define GPIO69_CCIC_IN5                MFP_CFG_DRV(GPIO69, AF1, MEDIUM)
-#define GPIO70_CCIC_IN4                MFP_CFG_DRV(GPIO70, AF1, MEDIUM)
-#define GPIO71_CCIC_IN3                MFP_CFG_DRV(GPIO71, AF1, MEDIUM)
-#define GPIO72_CCIC_IN2                MFP_CFG_DRV(GPIO72, AF1, MEDIUM)
-#define GPIO73_CCIC_IN1                MFP_CFG_DRV(GPIO73, AF1, MEDIUM)
-#define GPIO74_CCIC_IN0                MFP_CFG_DRV(GPIO74, AF1, MEDIUM)
-#define GPIO75_CAM_HSYNC       MFP_CFG_DRV(GPIO75, AF1, MEDIUM)
-#define GPIO76_CAM_VSYNC       MFP_CFG_DRV(GPIO76, AF1, MEDIUM)
-#define GPIO77_CAM_MCLK                MFP_CFG_DRV(GPIO77, AF1, MEDIUM)
-#define GPIO78_CAM_PCLK                MFP_CFG_DRV(GPIO78, AF1, MEDIUM)
-
-/* MMC1 */
-#define MMC1_DAT7_MMC1_DAT7    MFP_CFG_DRV(MMC1_DAT7, AF0, MEDIUM)
-#define MMC1_DAT6_MMC1_DAT6    MFP_CFG_DRV(MMC1_DAT6, AF0, MEDIUM)
-#define MMC1_DAT5_MMC1_DAT5    MFP_CFG_DRV(MMC1_DAT5, AF0, MEDIUM)
-#define MMC1_DAT4_MMC1_DAT4    MFP_CFG_DRV(MMC1_DAT4, AF0, MEDIUM)
-#define MMC1_DAT3_MMC1_DAT3    MFP_CFG_DRV(MMC1_DAT3, AF0, MEDIUM)
-#define MMC1_DAT2_MMC1_DAT2    MFP_CFG_DRV(MMC1_DAT2, AF0, MEDIUM)
-#define MMC1_DAT1_MMC1_DAT1    MFP_CFG_DRV(MMC1_DAT1, AF0, MEDIUM)
-#define MMC1_DAT0_MMC1_DAT0    MFP_CFG_DRV(MMC1_DAT0, AF0, MEDIUM)
-#define MMC1_CMD_MMC1_CMD      MFP_CFG_DRV(MMC1_CMD, AF0, MEDIUM)
-#define MMC1_CLK_MMC1_CLK      MFP_CFG_DRV(MMC1_CLK, AF0, MEDIUM)
-#define MMC1_CD_MMC1_CD                MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
-#define MMC1_WP_MMC1_WP                MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
-
-/* PWM */
-#define GPIO27_PWM3_AF2                MFP_CFG(GPIO27, AF2)
-#define GPIO51_PWM2_OUT                MFP_CFG(GPIO51, AF2)
-#define GPIO117_PWM1_OUT       MFP_CFG(GPIO117, AF2)
-#define GPIO118_PWM2_OUT       MFP_CFG(GPIO118, AF2)
-#define GPIO119_PWM3_OUT       MFP_CFG(GPIO119, AF2)
-#define GPIO120_PWM4_OUT       MFP_CFG(GPIO120, AF2)
-
-#endif /* __ASM_MACH MFP_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp.h b/arch/arm/mach-mmp/include/mach/mfp.h
deleted file mode 100644 (file)
index 62e510e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __ASM_MACH_MFP_H
-#define __ASM_MACH_MFP_H
-
-#include <plat/mfp.h>
-
-/*
- * NOTE: the MFPR register bit definitions on PXA168 processor lines are a
- * bit different from those on PXA3xx.  Bit [7:10] are now reserved, which
- * were SLEEP_OE_N, SLEEP_DATA, SLEEP_SEL and the LSB of DRIVE bits.
- *
- * To cope with this difference and re-use the pxa3xx mfp code as much as
- * possible, we make the following compromise:
- *
- * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT)
- * 2. DRIVE strength definitions redefined to include the reserved bit
- *    - the reserved bit differs between pxa168 and pxa910, and the
- *      MFP_DRIVE_* macros are individually defined in mfp-pxa{168,910}.h
- * 3. Override MFP_CFG() and MFP_CFG_DRV()
- * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X()
- */
-
-#undef MFP_CFG
-#undef MFP_CFG_DRV
-#undef MFP_CFG_LPM
-#undef MFP_CFG_X
-#undef MFP_CFG_DEFAULT
-
-#define MFP_CFG(pin, af)               \
-       (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
-
-#define MFP_CFG_DRV(pin, af, drv)      \
-       (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
-
-#endif /* __ASM_MACH_MFP_H */
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
deleted file mode 100644 (file)
index 0764f4e..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef __ASM_MACH_MMP2_H
-#define __ASM_MACH_MMP2_H
-
-#include <linux/platform_data/pxa_sdhci.h>
-
-extern void mmp2_timer_init(void);
-extern void __init mmp2_init_icu(void);
-extern void __init mmp2_init_irq(void);
-extern void mmp2_clear_pmic_int(void);
-
-#include <linux/i2c.h>
-#include <linux/i2c/pxa-i2c.h>
-#include <mach/devices.h>
-#include <linux/platform_data/dma-mmp_tdma.h>
-
-extern struct pxa_device_desc mmp2_device_uart1;
-extern struct pxa_device_desc mmp2_device_uart2;
-extern struct pxa_device_desc mmp2_device_uart3;
-extern struct pxa_device_desc mmp2_device_uart4;
-extern struct pxa_device_desc mmp2_device_twsi1;
-extern struct pxa_device_desc mmp2_device_twsi2;
-extern struct pxa_device_desc mmp2_device_twsi3;
-extern struct pxa_device_desc mmp2_device_twsi4;
-extern struct pxa_device_desc mmp2_device_twsi5;
-extern struct pxa_device_desc mmp2_device_twsi6;
-extern struct pxa_device_desc mmp2_device_sdh0;
-extern struct pxa_device_desc mmp2_device_sdh1;
-extern struct pxa_device_desc mmp2_device_sdh2;
-extern struct pxa_device_desc mmp2_device_sdh3;
-extern struct pxa_device_desc mmp2_device_asram;
-extern struct pxa_device_desc mmp2_device_isram;
-
-extern struct platform_device mmp2_device_gpio;
-
-static inline int mmp2_add_uart(int id)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 1: d = &mmp2_device_uart1; break;
-       case 2: d = &mmp2_device_uart2; break;
-       case 3: d = &mmp2_device_uart3; break;
-       case 4: d = &mmp2_device_uart4; break;
-       default:
-               return -EINVAL;
-       }
-
-       return pxa_register_device(d, NULL, 0);
-}
-
-static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
-                                 struct i2c_board_info *info, unsigned size)
-{
-       struct pxa_device_desc *d = NULL;
-       int ret;
-
-       switch (id) {
-       case 1: d = &mmp2_device_twsi1; break;
-       case 2: d = &mmp2_device_twsi2; break;
-       case 3: d = &mmp2_device_twsi3; break;
-       case 4: d = &mmp2_device_twsi4; break;
-       case 5: d = &mmp2_device_twsi5; break;
-       case 6: d = &mmp2_device_twsi6; break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = i2c_register_board_info(id - 1, info, size);
-       if (ret)
-               return ret;
-
-       return pxa_register_device(d, data, sizeof(*data));
-}
-
-static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 0: d = &mmp2_device_sdh0; break;
-       case 1: d = &mmp2_device_sdh1; break;
-       case 2: d = &mmp2_device_sdh2; break;
-       case 3: d = &mmp2_device_sdh3; break;
-       default:
-               return -EINVAL;
-       }
-
-       return pxa_register_device(d, data, sizeof(*data));
-}
-
-static inline int mmp2_add_asram(struct sram_platdata *data)
-{
-       return pxa_register_device(&mmp2_device_asram, data, sizeof(*data));
-}
-
-static inline int mmp2_add_isram(struct sram_platdata *data)
-{
-       return pxa_register_device(&mmp2_device_isram, data, sizeof(*data));
-}
-
-#endif /* __ASM_MACH_MMP2_H */
-
diff --git a/arch/arm/mach-mmp/include/mach/pm-mmp2.h b/arch/arm/mach-mmp/include/mach/pm-mmp2.h
deleted file mode 100644 (file)
index 98bd66c..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * MMP2 Power Management Routines
- *
- * This software program is licensed subject to the GNU General Public License
- * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
- *
- * (C) Copyright 2010 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#ifndef __MMP2_PM_H__
-#define __MMP2_PM_H__
-
-#include <mach/addr-map.h>
-
-#define APMU_PJ_IDLE_CFG                       APMU_REG(0x018)
-#define APMU_PJ_IDLE_CFG_PJ_IDLE               (1 << 1)
-#define APMU_PJ_IDLE_CFG_PJ_PWRDWN             (1 << 5)
-#define APMU_PJ_IDLE_CFG_PWR_SW(x)             ((x) << 16)
-#define APMU_PJ_IDLE_CFG_L2_PWR_SW             (1 << 19)
-#define APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK   (3 << 28)
-
-#define APMU_SRAM_PWR_DWN                      APMU_REG(0x08c)
-
-#define MPMU_SCCR                              MPMU_REG(0x038)
-#define MPMU_PCR_PJ                            MPMU_REG(0x1000)
-#define MPMU_PCR_PJ_AXISD                      (1 << 31)
-#define MPMU_PCR_PJ_SLPEN                      (1 << 29)
-#define MPMU_PCR_PJ_SPSD                       (1 << 28)
-#define MPMU_PCR_PJ_DDRCORSD                   (1 << 27)
-#define MPMU_PCR_PJ_APBSD                      (1 << 26)
-#define MPMU_PCR_PJ_INTCLR                     (1 << 24)
-#define MPMU_PCR_PJ_SLPWP0                     (1 << 23)
-#define MPMU_PCR_PJ_SLPWP1                     (1 << 22)
-#define MPMU_PCR_PJ_SLPWP2                     (1 << 21)
-#define MPMU_PCR_PJ_SLPWP3                     (1 << 20)
-#define MPMU_PCR_PJ_VCTCXOSD                   (1 << 19)
-#define MPMU_PCR_PJ_SLPWP4                     (1 << 18)
-#define MPMU_PCR_PJ_SLPWP5                     (1 << 17)
-#define MPMU_PCR_PJ_SLPWP6                     (1 << 16)
-#define MPMU_PCR_PJ_SLPWP7                     (1 << 15)
-
-#define MPMU_PLL2_CTRL1                                MPMU_REG(0x0414)
-#define MPMU_CGR_PJ                            MPMU_REG(0x1024)
-#define MPMU_WUCRM_PJ                          MPMU_REG(0x104c)
-#define MPMU_WUCRM_PJ_WAKEUP(x)                        (1 << (x))
-#define MPMU_WUCRM_PJ_RTC_ALARM                        (1 << 17)
-
-enum {
-       POWER_MODE_ACTIVE = 0,
-       POWER_MODE_CORE_INTIDLE,
-       POWER_MODE_CORE_EXTIDLE,
-       POWER_MODE_APPS_IDLE,
-       POWER_MODE_APPS_SLEEP,
-       POWER_MODE_CHIP_SLEEP,
-       POWER_MODE_SYS_SLEEP,
-};
-
-extern void mmp2_pm_enter_lowpower_mode(int state);
-extern int mmp2_set_wake(struct irq_data *d, unsigned int on);
-#endif
diff --git a/arch/arm/mach-mmp/include/mach/pm-pxa910.h b/arch/arm/mach-mmp/include/mach/pm-pxa910.h
deleted file mode 100644 (file)
index 8cac8ab..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * PXA910 Power Management Routines
- *
- * This software program is licensed subject to the GNU General Public License
- * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
- *
- * (C) Copyright 2009 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#ifndef __PXA910_PM_H__
-#define __PXA910_PM_H__
-
-#define APMU_MOH_IDLE_CFG                      APMU_REG(0x0018)
-#define APMU_MOH_IDLE_CFG_MOH_IDLE             (1 << 1)
-#define APMU_MOH_IDLE_CFG_MOH_PWRDWN           (1 << 5)
-#define APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN      (1 << 6)
-#define APMU_MOH_IDLE_CFG_MOH_PWR_SW(x)                (((x) & 0x3) << 16)
-#define APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(x)     (((x) & 0x3) << 18)
-#define APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ    (1 << 21)
-#define APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN       (1 << 20)
-
-#define APMU_SQU_CLK_GATE_CTRL                 APMU_REG(0x001c)
-#define APMU_MC_HW_SLP_TYPE                    APMU_REG(0x00b0)
-
-#define MPMU_FCCR                              MPMU_REG(0x0008)
-#define MPMU_APCR                              MPMU_REG(0x1000)
-#define MPMU_APCR_AXISD                                (1 << 31)
-#define MPMU_APCR_DSPSD                                (1 << 30)
-#define MPMU_APCR_SLPEN                                (1 << 29)
-#define MPMU_APCR_DTCMSD                       (1 << 28)
-#define MPMU_APCR_DDRCORSD                     (1 << 27)
-#define MPMU_APCR_APBSD                                (1 << 26)
-#define MPMU_APCR_BBSD                         (1 << 25)
-#define MPMU_APCR_SLPWP0                       (1 << 23)
-#define MPMU_APCR_SLPWP1                       (1 << 22)
-#define MPMU_APCR_SLPWP2                       (1 << 21)
-#define MPMU_APCR_SLPWP3                       (1 << 20)
-#define MPMU_APCR_VCTCXOSD                     (1 << 19)
-#define MPMU_APCR_SLPWP4                       (1 << 18)
-#define MPMU_APCR_SLPWP5                       (1 << 17)
-#define MPMU_APCR_SLPWP6                       (1 << 16)
-#define MPMU_APCR_SLPWP7                       (1 << 15)
-#define MPMU_APCR_MSASLPEN                     (1 << 14)
-#define MPMU_APCR_STBYEN                       (1 << 13)
-
-#define MPMU_AWUCRM                            MPMU_REG(0x104c)
-#define MPMU_AWUCRM_AP_ASYNC_INT               (1 << 25)
-#define MPMU_AWUCRM_AP_FULL_IDLE               (1 << 24)
-#define MPMU_AWUCRM_SDH1                       (1 << 23)
-#define MPMU_AWUCRM_SDH2                       (1 << 22)
-#define MPMU_AWUCRM_KEYPRESS                   (1 << 21)
-#define MPMU_AWUCRM_TRACKBALL                  (1 << 20)
-#define MPMU_AWUCRM_NEWROTARY                  (1 << 19)
-#define MPMU_AWUCRM_RTC_ALARM                  (1 << 17)
-#define MPMU_AWUCRM_AP2_TIMER_3                        (1 << 13)
-#define MPMU_AWUCRM_AP2_TIMER_2                        (1 << 12)
-#define MPMU_AWUCRM_AP2_TIMER_1                        (1 << 11)
-#define MPMU_AWUCRM_AP1_TIMER_3                        (1 << 10)
-#define MPMU_AWUCRM_AP1_TIMER_2                        (1 << 9)
-#define MPMU_AWUCRM_AP1_TIMER_1                        (1 << 8)
-#define MPMU_AWUCRM_WAKEUP(x)                  (1 << ((x) & 0x7))
-
-enum {
-       POWER_MODE_ACTIVE = 0,
-       POWER_MODE_CORE_INTIDLE,
-       POWER_MODE_CORE_EXTIDLE,
-       POWER_MODE_APPS_IDLE,
-       POWER_MODE_APPS_SLEEP,
-       POWER_MODE_SYS_SLEEP,
-       POWER_MODE_HIBERNATE,
-       POWER_MODE_UDR,
-};
-
-extern int pxa910_set_wake(struct irq_data *data, unsigned int on);
-
-#endif
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
deleted file mode 100644 (file)
index a83ba7c..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-#ifndef __ASM_MACH_PXA168_H
-#define __ASM_MACH_PXA168_H
-
-#include <linux/reboot.h>
-
-extern void pxa168_timer_init(void);
-extern void __init icu_init_irq(void);
-extern void __init pxa168_init_irq(void);
-extern void pxa168_restart(enum reboot_mode, const char *);
-extern void pxa168_clear_keypad_wakeup(void);
-
-#include <linux/i2c.h>
-#include <linux/i2c/pxa-i2c.h>
-#include <mach/devices.h>
-#include <linux/platform_data/mtd-nand-pxa3xx.h>
-#include <video/pxa168fb.h>
-#include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/cputype.h>
-#include <linux/pxa168_eth.h>
-#include <linux/platform_data/mv_usb.h>
-
-extern struct pxa_device_desc pxa168_device_uart1;
-extern struct pxa_device_desc pxa168_device_uart2;
-extern struct pxa_device_desc pxa168_device_uart3;
-extern struct pxa_device_desc pxa168_device_twsi0;
-extern struct pxa_device_desc pxa168_device_twsi1;
-extern struct pxa_device_desc pxa168_device_pwm1;
-extern struct pxa_device_desc pxa168_device_pwm2;
-extern struct pxa_device_desc pxa168_device_pwm3;
-extern struct pxa_device_desc pxa168_device_pwm4;
-extern struct pxa_device_desc pxa168_device_ssp1;
-extern struct pxa_device_desc pxa168_device_ssp2;
-extern struct pxa_device_desc pxa168_device_ssp3;
-extern struct pxa_device_desc pxa168_device_ssp4;
-extern struct pxa_device_desc pxa168_device_ssp5;
-extern struct pxa_device_desc pxa168_device_nand;
-extern struct pxa_device_desc pxa168_device_fb;
-extern struct pxa_device_desc pxa168_device_keypad;
-extern struct pxa_device_desc pxa168_device_eth;
-
-/* pdata can be NULL */
-extern int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata);
-
-
-extern struct platform_device pxa168_device_gpio;
-
-static inline int pxa168_add_uart(int id)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 1: d = &pxa168_device_uart1; break;
-       case 2: d = &pxa168_device_uart2; break;
-       case 3: d = &pxa168_device_uart3; break;
-       }
-
-       if (d == NULL)
-               return -EINVAL;
-
-       return pxa_register_device(d, NULL, 0);
-}
-
-static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data,
-                                 struct i2c_board_info *info, unsigned size)
-{
-       struct pxa_device_desc *d = NULL;
-       int ret;
-
-       switch (id) {
-       case 0: d = &pxa168_device_twsi0; break;
-       case 1: d = &pxa168_device_twsi1; break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = i2c_register_board_info(id, info, size);
-       if (ret)
-               return ret;
-
-       return pxa_register_device(d, data, sizeof(*data));
-}
-
-static inline int pxa168_add_pwm(int id)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 1: d = &pxa168_device_pwm1; break;
-       case 2: d = &pxa168_device_pwm2; break;
-       case 3: d = &pxa168_device_pwm3; break;
-       case 4: d = &pxa168_device_pwm4; break;
-       default:
-               return -EINVAL;
-       }
-
-       return pxa_register_device(d, NULL, 0);
-}
-
-static inline int pxa168_add_ssp(int id)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 1: d = &pxa168_device_ssp1; break;
-       case 2: d = &pxa168_device_ssp2; break;
-       case 3: d = &pxa168_device_ssp3; break;
-       case 4: d = &pxa168_device_ssp4; break;
-       case 5: d = &pxa168_device_ssp5; break;
-       default:
-               return -EINVAL;
-       }
-       return pxa_register_device(d, NULL, 0);
-}
-
-static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
-{
-       return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
-}
-
-static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi)
-{
-       return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi));
-}
-
-static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
-{
-       if (cpu_is_pxa168())
-               data->clear_wakeup_event = pxa168_clear_keypad_wakeup;
-
-       return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
-}
-
-static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data)
-{
-       return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
-}
-#endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
deleted file mode 100644 (file)
index 9225320..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef __ASM_MACH_PXA910_H
-#define __ASM_MACH_PXA910_H
-
-extern void pxa910_timer_init(void);
-extern void __init icu_init_irq(void);
-extern void __init pxa910_init_irq(void);
-
-#include <linux/i2c.h>
-#include <linux/i2c/pxa-i2c.h>
-#include <mach/devices.h>
-#include <linux/platform_data/mtd-nand-pxa3xx.h>
-#include <video/mmp_disp.h>
-
-extern struct pxa_device_desc pxa910_device_uart1;
-extern struct pxa_device_desc pxa910_device_uart2;
-extern struct pxa_device_desc pxa910_device_twsi0;
-extern struct pxa_device_desc pxa910_device_twsi1;
-extern struct pxa_device_desc pxa910_device_pwm1;
-extern struct pxa_device_desc pxa910_device_pwm2;
-extern struct pxa_device_desc pxa910_device_pwm3;
-extern struct pxa_device_desc pxa910_device_pwm4;
-extern struct pxa_device_desc pxa910_device_nand;
-extern struct platform_device pxa168_device_u2o;
-extern struct platform_device pxa168_device_u2ootg;
-extern struct platform_device pxa168_device_u2oehci;
-extern struct pxa_device_desc pxa910_device_disp;
-extern struct pxa_device_desc pxa910_device_fb;
-extern struct pxa_device_desc pxa910_device_panel;
-extern struct platform_device pxa910_device_gpio;
-extern struct platform_device pxa910_device_rtc;
-
-static inline int pxa910_add_uart(int id)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 1: d = &pxa910_device_uart1; break;
-       case 2: d = &pxa910_device_uart2; break;
-       }
-
-       if (d == NULL)
-               return -EINVAL;
-
-       return pxa_register_device(d, NULL, 0);
-}
-
-static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data,
-                                 struct i2c_board_info *info, unsigned size)
-{
-       struct pxa_device_desc *d = NULL;
-       int ret;
-
-       switch (id) {
-       case 0: d = &pxa910_device_twsi0; break;
-       case 1: d = &pxa910_device_twsi1; break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = i2c_register_board_info(id, info, size);
-       if (ret)
-               return ret;
-
-       return pxa_register_device(d, data, sizeof(*data));
-}
-
-static inline int pxa910_add_pwm(int id)
-{
-       struct pxa_device_desc *d = NULL;
-
-       switch (id) {
-       case 1: d = &pxa910_device_pwm1; break;
-       case 2: d = &pxa910_device_pwm2; break;
-       case 3: d = &pxa910_device_pwm3; break;
-       case 4: d = &pxa910_device_pwm4; break;
-       default:
-               return -EINVAL;
-       }
-
-       return pxa_register_device(d, NULL, 0);
-}
-
-static inline int pxa910_add_nand(struct pxa3xx_nand_platform_data *info)
-{
-       return pxa_register_device(&pxa910_device_nand, info, sizeof(*info));
-}
-#endif /* __ASM_MACH_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
deleted file mode 100644 (file)
index ddc812f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-apbc.h
- *
- *   Application Peripheral Bus Clock Unit
- *
- * 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_MACH_REGS_APBC_H
-#define __ASM_MACH_REGS_APBC_H
-
-#include <mach/addr-map.h>
-
-/* Common APB clock register bit definitions */
-#define APBC_APBCLK    (1 << 0)  /* APB Bus Clock Enable */
-#define APBC_FNCLK     (1 << 1)  /* Functional Clock Enable */
-#define APBC_RST       (1 << 2)  /* Reset Generation */
-
-/* Functional Clock Selection Mask */
-#define APBC_FNCLKSEL(x)       (((x) & 0xf) << 4)
-
-#endif /* __ASM_MACH_REGS_APBC_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
deleted file mode 100644 (file)
index 93c8d0e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-apmu.h
- *
- *   Application Subsystem Power Management Unit
- *
- * 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_MACH_REGS_APMU_H
-#define __ASM_MACH_REGS_APMU_H
-
-#include <mach/addr-map.h>
-
-#define APMU_FNCLK_EN  (1 << 4)
-#define APMU_AXICLK_EN (1 << 3)
-#define APMU_FNRST_DIS (1 << 1)
-#define APMU_AXIRST_DIS        (1 << 0)
-
-/* Wake Clear Register */
-#define APMU_WAKE_CLR  APMU_REG(0x07c)
-
-#define APMU_PXA168_KP_WAKE_CLR                (1 << 7)
-#define APMU_PXA168_CFI_WAKE_CLR       (1 << 6)
-#define APMU_PXA168_XD_WAKE_CLR                (1 << 5)
-#define APMU_PXA168_MSP_WAKE_CLR       (1 << 4)
-#define APMU_PXA168_SD4_WAKE_CLR       (1 << 3)
-#define APMU_PXA168_SD3_WAKE_CLR       (1 << 2)
-#define APMU_PXA168_SD2_WAKE_CLR       (1 << 1)
-#define APMU_PXA168_SD1_WAKE_CLR       (1 << 0)
-
-#endif /* __ASM_MACH_REGS_APMU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-icu.h b/arch/arm/mach-mmp/include/mach/regs-icu.h
deleted file mode 100644 (file)
index f882d91..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-icu.h
- *
- *   Interrupt Control Unit
- *
- * 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_MACH_ICU_H
-#define __ASM_MACH_ICU_H
-
-#include <mach/addr-map.h>
-
-#define ICU_VIRT_BASE  (AXI_VIRT_BASE + 0x82000)
-#define ICU_REG(x)     (ICU_VIRT_BASE + (x))
-
-#define ICU_INT_CONF(n)                ICU_REG((n) << 2)
-#define ICU_INT_CONF_MASK      (0xf)
-
-/************ PXA168/PXA910 (MMP) *********************/
-#define ICU_INT_CONF_AP_INT    (1 << 6)
-#define ICU_INT_CONF_CP_INT    (1 << 5)
-#define ICU_INT_CONF_IRQ       (1 << 4)
-
-#define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108)  /* AP FIQ Selected Interrupt */
-#define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C)  /* AP IRQ Selected Interrupt */
-#define ICU_AP_GBL_IRQ_MSK     ICU_REG(0x114)  /* AP Global Interrupt Mask */
-#define ICU_INT_STATUS_0       ICU_REG(0x128)  /* Interrupt Stuats 0 */
-#define ICU_INT_STATUS_1       ICU_REG(0x12C)  /* Interrupt Status 1 */
-
-/************************** MMP2 ***********************/
-
-/*
- * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
- * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
- */
-#define ICU_INT_ROUTE_SP_IRQ           (1 << 4)
-#define ICU_INT_ROUTE_PJ4_IRQ          (1 << 5)
-#define ICU_INT_ROUTE_PJ4_FIQ          (1 << 6)
-
-#define MMP2_ICU_PJ4_IRQ_STATUS0       ICU_REG(0x138)
-#define MMP2_ICU_PJ4_IRQ_STATUS1       ICU_REG(0x13c)
-#define MMP2_ICU_PJ4_FIQ_STATUS0       ICU_REG(0x140)
-#define MMP2_ICU_PJ4_FIQ_STATUS1       ICU_REG(0x144)
-
-#define MMP2_ICU_INT4_STATUS           ICU_REG(0x150)
-#define MMP2_ICU_INT5_STATUS           ICU_REG(0x154)
-#define MMP2_ICU_INT17_STATUS          ICU_REG(0x158)
-#define MMP2_ICU_INT35_STATUS          ICU_REG(0x15c)
-#define MMP2_ICU_INT51_STATUS          ICU_REG(0x160)
-
-#define MMP2_ICU_INT4_MASK             ICU_REG(0x168)
-#define MMP2_ICU_INT5_MASK             ICU_REG(0x16C)
-#define MMP2_ICU_INT17_MASK            ICU_REG(0x170)
-#define MMP2_ICU_INT35_MASK            ICU_REG(0x174)
-#define MMP2_ICU_INT51_MASK            ICU_REG(0x178)
-
-#define MMP2_ICU_SP_IRQ_SEL            ICU_REG(0x100)
-#define MMP2_ICU_PJ4_IRQ_SEL           ICU_REG(0x104)
-#define MMP2_ICU_PJ4_FIQ_SEL           ICU_REG(0x108)
-
-#define MMP2_ICU_INVERT                        ICU_REG(0x164)
-
-#define MMP2_ICU_INV_PMIC              (1 << 0)
-#define MMP2_ICU_INV_PERF              (1 << 1)
-#define MMP2_ICU_INV_COMMTX            (1 << 2)
-#define MMP2_ICU_INV_COMMRX            (1 << 3)
-
-#endif /* __ASM_MACH_ICU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h
deleted file mode 100644 (file)
index e484d40..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-smc.h
- *
- *  Static Memory Controller Registers
- *
- * 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_MACH_REGS_SMC_H
-#define __ASM_MACH_REGS_SMC_H
-
-#include <mach/addr-map.h>
-
-#define SMC_VIRT_BASE          (AXI_VIRT_BASE + 0x83800)
-#define SMC_REG(x)             (SMC_VIRT_BASE + (x))
-
-#define SMC_MSC0               SMC_REG(0x0020)
-#define SMC_MSC1               SMC_REG(0x0024)
-#define SMC_SXCNFG0            SMC_REG(0x0030)
-#define SMC_SXCNFG1            SMC_REG(0x0034)
-#define SMC_MEMCLKCFG          SMC_REG(0x0068)
-#define SMC_CSDFICFG0          SMC_REG(0x0090)
-#define SMC_CSDFICFG1          SMC_REG(0x0094)
-#define SMC_CLK_RET_DEL                SMC_REG(0x00b0)
-#define SMC_ADV_RET_DEL                SMC_REG(0x00b4)
-#define SMC_CSADRMAP0          SMC_REG(0x00c0)
-#define SMC_CSADRMAP1          SMC_REG(0x00c4)
-#define SMC_WE_AP0             SMC_REG(0x00e0)
-#define SMC_WE_AP1             SMC_REG(0x00e4)
-#define SMC_OE_AP0             SMC_REG(0x00f0)
-#define SMC_OE_AP1             SMC_REG(0x00f4)
-#define SMC_ADV_AP0            SMC_REG(0x0100)
-#define SMC_ADV_AP1            SMC_REG(0x0104)
-
-#endif /* __ASM_MACH_REGS_SMC_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-timers.h b/arch/arm/mach-mmp/include/mach/regs-timers.h
deleted file mode 100644 (file)
index 45589fe..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-timers.h
- *
- *   Timers Module
- *
- * 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_MACH_REGS_TIMERS_H
-#define __ASM_MACH_REGS_TIMERS_H
-
-#include <mach/addr-map.h>
-
-#define TIMERS1_VIRT_BASE      (APB_VIRT_BASE + 0x14000)
-#define TIMERS2_VIRT_BASE      (APB_VIRT_BASE + 0x16000)
-
-#define TMR_CCR                (0x0000)
-#define TMR_TN_MM(n, m)        (0x0004 + ((n) << 3) + (((n) + (m)) << 2))
-#define TMR_CR(n)      (0x0028 + ((n) << 2))
-#define TMR_SR(n)      (0x0034 + ((n) << 2))
-#define TMR_IER(n)     (0x0040 + ((n) << 2))
-#define TMR_PLVR(n)    (0x004c + ((n) << 2))
-#define TMR_PLCR(n)    (0x0058 + ((n) << 2))
-#define TMR_WMER       (0x0064)
-#define TMR_WMR                (0x0068)
-#define TMR_WVR                (0x006c)
-#define TMR_WSR                (0x0070)
-#define TMR_ICR(n)     (0x0074 + ((n) << 2))
-#define TMR_WICR       (0x0080)
-#define TMR_CER                (0x0084)
-#define TMR_CMR                (0x0088)
-#define TMR_ILR(n)     (0x008c + ((n) << 2))
-#define TMR_WCR                (0x0098)
-#define TMR_WFAR       (0x009c)
-#define TMR_WSAR       (0x00A0)
-#define TMR_CVWR(n)    (0x00A4 + ((n) << 2))
-
-#define TMR_CCR_CS_0(x)        (((x) & 0x3) << 0)
-#define TMR_CCR_CS_1(x)        (((x) & 0x7) << 2)
-#define TMR_CCR_CS_2(x)        (((x) & 0x3) << 5)
-
-#endif /* __ASM_MACH_REGS_TIMERS_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-usb.h b/arch/arm/mach-mmp/include/mach/regs-usb.h
deleted file mode 100644 (file)
index b047bf4..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __ASM_ARCH_REGS_USB_H
-#define __ASM_ARCH_REGS_USB_H
-
-#define PXA168_U2O_REGBASE     (0xd4208000)
-#define PXA168_U2O_PHYBASE     (0xd4207000)
-
-#define PXA168_U2H_REGBASE      (0xd4209000)
-#define PXA168_U2H_PHYBASE      (0xd4206000)
-
-#define MMP3_HSIC1_REGBASE     (0xf0001000)
-#define MMP3_HSIC1_PHYBASE     (0xf0001800)
-
-#define MMP3_HSIC2_REGBASE     (0xf0002000)
-#define MMP3_HSIC2_PHYBASE     (0xf0002800)
-
-#define MMP3_FSIC_REGBASE      (0xf0003000)
-#define MMP3_FSIC_PHYBASE      (0xf0003800)
-
-
-#define USB_REG_RANGE          (0x1ff)
-#define USB_PHY_RANGE          (0xff)
-
-/* registers */
-#define U2x_CAPREGS_OFFSET       0x100
-
-/* phy regs */
-#define UTMI_REVISION          0x0
-#define UTMI_CTRL              0x4
-#define UTMI_PLL               0x8
-#define UTMI_TX                        0xc
-#define UTMI_RX                        0x10
-#define UTMI_IVREF             0x14
-#define UTMI_T0                        0x18
-#define UTMI_T1                        0x1c
-#define UTMI_T2                        0x20
-#define UTMI_T3                        0x24
-#define UTMI_T4                        0x28
-#define UTMI_T5                        0x2c
-#define UTMI_RESERVE           0x30
-#define UTMI_USB_INT           0x34
-#define UTMI_DBG_CTL           0x38
-#define UTMI_OTG_ADDON         0x3c
-
-/* For UTMICTRL Register */
-#define UTMI_CTRL_USB_CLK_EN                    (1 << 31)
-/* pxa168 */
-#define UTMI_CTRL_SUSPEND_SET1                  (1 << 30)
-#define UTMI_CTRL_SUSPEND_SET2                  (1 << 29)
-#define UTMI_CTRL_RXBUF_PDWN                    (1 << 24)
-#define UTMI_CTRL_TXBUF_PDWN                    (1 << 11)
-
-#define UTMI_CTRL_INPKT_DELAY_SHIFT             30
-#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT                28
-#define UTMI_CTRL_PU_REF_SHIFT                 20
-#define UTMI_CTRL_ARC_PULLDN_SHIFT              12
-#define UTMI_CTRL_PLL_PWR_UP_SHIFT              1
-#define UTMI_CTRL_PWR_UP_SHIFT                  0
-
-/* For UTMI_PLL Register */
-#define UTMI_PLL_PLLCALI12_SHIFT               29
-#define UTMI_PLL_PLLCALI12_MASK                        (0x3 << 29)
-
-#define UTMI_PLL_PLLVDD18_SHIFT                        27
-#define UTMI_PLL_PLLVDD18_MASK                 (0x3 << 27)
-
-#define UTMI_PLL_PLLVDD12_SHIFT                        25
-#define UTMI_PLL_PLLVDD12_MASK                 (0x3 << 25)
-
-#define UTMI_PLL_CLK_BLK_EN_SHIFT               24
-#define CLK_BLK_EN                              (0x1 << 24)
-#define PLL_READY                               (0x1 << 23)
-#define KVCO_EXT                                (0x1 << 22)
-#define VCOCAL_START                            (0x1 << 21)
-
-#define UTMI_PLL_KVCO_SHIFT                    15
-#define UTMI_PLL_KVCO_MASK                      (0x7 << 15)
-
-#define UTMI_PLL_ICP_SHIFT                     12
-#define UTMI_PLL_ICP_MASK                       (0x7 << 12)
-
-#define UTMI_PLL_FBDIV_SHIFT                    4
-#define UTMI_PLL_FBDIV_MASK                     (0xFF << 4)
-
-#define UTMI_PLL_REFDIV_SHIFT                   0
-#define UTMI_PLL_REFDIV_MASK                    (0xF << 0)
-
-/* For UTMI_TX Register */
-#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT          27
-#define UTMI_TX_REG_EXT_FS_RCAL_MASK           (0xf << 27)
-
-#define UTMI_TX_REG_EXT_FS_RCAL_EN_SHIFT       26
-#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK                (0x1 << 26)
-
-#define UTMI_TX_TXVDD12_SHIFT                   22
-#define UTMI_TX_TXVDD12_MASK                    (0x3 << 22)
-
-#define UTMI_TX_CK60_PHSEL_SHIFT                17
-#define UTMI_TX_CK60_PHSEL_MASK                 (0xf << 17)
-
-#define UTMI_TX_IMPCAL_VTH_SHIFT                14
-#define UTMI_TX_IMPCAL_VTH_MASK                 (0x7 << 14)
-
-#define REG_RCAL_START                          (0x1 << 12)
-
-#define UTMI_TX_LOW_VDD_EN_SHIFT                11
-
-#define UTMI_TX_AMP_SHIFT                      0
-#define UTMI_TX_AMP_MASK                       (0x7 << 0)
-
-/* For UTMI_RX Register */
-#define UTMI_REG_SQ_LENGTH_SHIFT                15
-#define UTMI_REG_SQ_LENGTH_MASK                 (0x3 << 15)
-
-#define UTMI_RX_SQ_THRESH_SHIFT                 4
-#define UTMI_RX_SQ_THRESH_MASK                  (0xf << 4)
-
-#define UTMI_OTG_ADDON_OTG_ON                  (1 << 0)
-
-/* For MMP3 USB Phy */
-#define USB2_PLL_REG0          0x4
-#define USB2_PLL_REG1          0x8
-#define USB2_TX_REG0           0x10
-#define USB2_TX_REG1           0x14
-#define USB2_TX_REG2           0x18
-#define USB2_RX_REG0           0x20
-#define USB2_RX_REG1           0x24
-#define USB2_RX_REG2           0x28
-#define USB2_ANA_REG0          0x30
-#define USB2_ANA_REG1          0x34
-#define USB2_ANA_REG2          0x38
-#define USB2_DIG_REG0          0x3C
-#define USB2_DIG_REG1          0x40
-#define USB2_DIG_REG2          0x44
-#define USB2_DIG_REG3          0x48
-#define USB2_TEST_REG0         0x4C
-#define USB2_TEST_REG1         0x50
-#define USB2_TEST_REG2         0x54
-#define USB2_CHARGER_REG0      0x58
-#define USB2_OTG_REG0          0x5C
-#define USB2_PHY_MON0          0x60
-#define USB2_RESETVE_REG0      0x64
-#define USB2_ICID_REG0         0x78
-#define USB2_ICID_REG1         0x7C
-
-/* USB2_PLL_REG0 */
-/* This is for Ax stepping */
-#define USB2_PLL_FBDIV_SHIFT_MMP3              0
-#define USB2_PLL_FBDIV_MASK_MMP3               (0xFF << 0)
-
-#define USB2_PLL_REFDIV_SHIFT_MMP3             8
-#define USB2_PLL_REFDIV_MASK_MMP3              (0xF << 8)
-
-#define USB2_PLL_VDD12_SHIFT_MMP3              12
-#define USB2_PLL_VDD18_SHIFT_MMP3              14
-
-/* This is for B0 stepping */
-#define USB2_PLL_FBDIV_SHIFT_MMP3_B0           0
-#define USB2_PLL_REFDIV_SHIFT_MMP3_B0          9
-#define USB2_PLL_VDD18_SHIFT_MMP3_B0           14
-#define USB2_PLL_FBDIV_MASK_MMP3_B0            0x01FF
-#define USB2_PLL_REFDIV_MASK_MMP3_B0           0x3E00
-
-#define USB2_PLL_CAL12_SHIFT_MMP3              0
-#define USB2_PLL_CALI12_MASK_MMP3              (0x3 << 0)
-
-#define USB2_PLL_VCOCAL_START_SHIFT_MMP3       2
-
-#define USB2_PLL_KVCO_SHIFT_MMP3               4
-#define USB2_PLL_KVCO_MASK_MMP3                        (0x7<<4)
-
-#define USB2_PLL_ICP_SHIFT_MMP3                        8
-#define USB2_PLL_ICP_MASK_MMP3                 (0x7<<8)
-
-#define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3                12
-
-#define USB2_PLL_PU_PLL_SHIFT_MMP3             13
-#define USB2_PLL_PU_PLL_MASK                   (0x1 << 13)
-
-#define USB2_PLL_READY_MASK_MMP3               (0x1 << 15)
-
-/* USB2_TX_REG0 */
-#define USB2_TX_IMPCAL_VTH_SHIFT_MMP3          8
-#define USB2_TX_IMPCAL_VTH_MASK_MMP3           (0x7 << 8)
-
-#define USB2_TX_RCAL_START_SHIFT_MMP3          13
-
-/* USB2_TX_REG1 */
-#define USB2_TX_CK60_PHSEL_SHIFT_MMP3          0
-#define USB2_TX_CK60_PHSEL_MASK_MMP3           (0xf << 0)
-
-#define USB2_TX_AMP_SHIFT_MMP3                 4
-#define USB2_TX_AMP_MASK_MMP3                  (0x7 << 4)
-
-#define USB2_TX_VDD12_SHIFT_MMP3               8
-#define USB2_TX_VDD12_MASK_MMP3                        (0x3 << 8)
-
-/* USB2_TX_REG2 */
-#define USB2_TX_DRV_SLEWRATE_SHIFT             10
-
-/* USB2_RX_REG0 */
-#define USB2_RX_SQ_THRESH_SHIFT_MMP3           4
-#define USB2_RX_SQ_THRESH_MASK_MMP3            (0xf << 4)
-
-#define USB2_RX_SQ_LENGTH_SHIFT_MMP3           10
-#define USB2_RX_SQ_LENGTH_MASK_MMP3            (0x3 << 10)
-
-/* USB2_ANA_REG1*/
-#define USB2_ANA_PU_ANA_SHIFT_MMP3             14
-
-/* USB2_OTG_REG0 */
-#define USB2_OTG_PU_OTG_SHIFT_MMP3             3
-
-/* fsic registers */
-#define FSIC_MISC                      0x4
-#define FSIC_INT                       0x28
-#define FSIC_CTRL                      0x30
-
-/* HSIC registers */
-#define HSIC_PAD_CTRL                  0x4
-
-#define HSIC_CTRL                      0x8
-#define HSIC_CTRL_HSIC_ENABLE          (1<<7)
-#define HSIC_CTRL_PLL_BYPASS           (1<<4)
-
-#define TEST_GRP_0                     0xc
-#define TEST_GRP_1                     0x10
-
-#define HSIC_INT                       0x14
-#define HSIC_INT_READY_INT_EN          (1<<10)
-#define HSIC_INT_CONNECT_INT_EN                (1<<9)
-#define HSIC_INT_CORE_INT_EN           (1<<8)
-#define HSIC_INT_HS_READY              (1<<2)
-#define HSIC_INT_CONNECT               (1<<1)
-#define HSIC_INT_CORE                  (1<<0)
-
-#define HSIC_CONFIG                    0x18
-#define USBHSIC_CTRL                   0x20
-
-#define HSIC_USB_CTRL                  0x28
-#define HSIC_USB_CTRL_CLKEN            1
-#define        HSIC_USB_CLK_PHY                0x0
-#define HSIC_USB_CLK_PMU               0x1
-
-#endif /* __ASM_ARCH_PXA_U2O_H */
diff --git a/arch/arm/mach-mmp/include/mach/teton_bga.h b/arch/arm/mach-mmp/include/mach/teton_bga.h
deleted file mode 100644 (file)
index 61a539b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  linux/arch/arm/mach-mmp/include/mach/teton_bga.h
- *
- *  Support for the Marvell PXA168 Teton BGA Development Platform.
- *
- *  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
- *  publishhed by the Free Software Foundation.
- */
-#ifndef __ASM_MACH_TETON_BGA_H
-#define __ASM_MACH_TETON_BGA_H
-
-/* GPIOs */
-#define MMC_PWENA_GPIO         27
-#define USBHPENB_GPIO          55
-#define RTC_INT_GPIO           78
-#define LCD_VBLK_EN_GPIO       79
-#define LCD_DVDD_EN_GPIO       80
-#define RST_WIFI_GPIO          81
-#define CF_PWEN_GPIO           82
-#define USB_OC_GPIO            83
-#define PWM_GPIO               84
-#define USBHPENA_GPIO          85
-#define TS_INT_GPIO            86
-#define CIR_GPIO               108
-
-#endif /* __ASM_MACH_TETON_BGA_H */
diff --git a/arch/arm/mach-mmp/include/mach/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h
deleted file mode 100644 (file)
index 8890fa8..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * arch/arm/mach-mmp/include/mach/uncompress.h
- *
- * 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 <mach/addr-map.h>
-#include <asm/mach-types.h>
-
-#define UART1_BASE     (APB_PHYS_BASE + 0x36000)
-#define UART2_BASE     (APB_PHYS_BASE + 0x17000)
-#define UART3_BASE     (APB_PHYS_BASE + 0x18000)
-
-volatile unsigned long *UART;
-
-static inline void putc(char c)
-{
-       /* UART enabled? */
-       if (!(UART[UART_IER] & UART_IER_UUE))
-               return;
-
-       while (!(UART[UART_LSR] & UART_LSR_THRE))
-               barrier();
-
-       UART[UART_TX] = c;
-}
-
-/*
- * This does not append a newline
- */
-static inline void flush(void)
-{
-}
-
-static inline void arch_decomp_setup(void)
-{
-       /* default to UART2 */
-       UART = (unsigned long *)UART2_BASE;
-
-       if (machine_is_avengers_lite())
-               UART = (unsigned long *)UART3_BASE;
-}
diff --git a/arch/arm/mach-mmp/irqs.h b/arch/arm/mach-mmp/irqs.h
new file mode 100644 (file)
index 0000000..fb492a5
--- /dev/null
@@ -0,0 +1,239 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+/*
+ * Interrupt numbers for PXA168
+ */
+#define IRQ_PXA168_NONE                        (-1)
+#define IRQ_PXA168_SSP4                        0
+#define IRQ_PXA168_SSP3                        1
+#define IRQ_PXA168_SSP2                        2
+#define IRQ_PXA168_SSP1                        3
+#define IRQ_PXA168_PMIC_INT            4
+#define IRQ_PXA168_RTC_INT             5
+#define IRQ_PXA168_RTC_ALARM           6
+#define IRQ_PXA168_TWSI0               7
+#define IRQ_PXA168_GPU                 8
+#define IRQ_PXA168_KEYPAD              9
+#define IRQ_PXA168_ONEWIRE             12
+#define IRQ_PXA168_TIMER1              13
+#define IRQ_PXA168_TIMER2              14
+#define IRQ_PXA168_TIMER3              15
+#define IRQ_PXA168_CMU                 16
+#define IRQ_PXA168_SSP5                        17
+#define IRQ_PXA168_MSP_WAKEUP          19
+#define IRQ_PXA168_CF_WAKEUP           20
+#define IRQ_PXA168_XD_WAKEUP           21
+#define IRQ_PXA168_MFU                 22
+#define IRQ_PXA168_MSP                 23
+#define IRQ_PXA168_CF                  24
+#define IRQ_PXA168_XD                  25
+#define IRQ_PXA168_DDR_INT             26
+#define IRQ_PXA168_UART1               27
+#define IRQ_PXA168_UART2               28
+#define IRQ_PXA168_UART3               29
+#define IRQ_PXA168_WDT                 35
+#define IRQ_PXA168_MAIN_PMU            36
+#define IRQ_PXA168_FRQ_CHANGE          38
+#define IRQ_PXA168_SDH1                        39
+#define IRQ_PXA168_SDH2                        40
+#define IRQ_PXA168_LCD                 41
+#define IRQ_PXA168_CI                  42
+#define IRQ_PXA168_USB1                        44
+#define IRQ_PXA168_NAND                        45
+#define IRQ_PXA168_HIFI_DMA            46
+#define IRQ_PXA168_DMA_INT0            47
+#define IRQ_PXA168_DMA_INT1            48
+#define IRQ_PXA168_GPIOX               49
+#define IRQ_PXA168_USB2                        51
+#define IRQ_PXA168_AC97                        57
+#define IRQ_PXA168_TWSI1               58
+#define IRQ_PXA168_AP_PMU              60
+#define IRQ_PXA168_SM_INT              63
+
+/*
+ * Interrupt numbers for PXA910
+ */
+#define IRQ_PXA910_NONE                        (-1)
+#define IRQ_PXA910_AIRQ                        0
+#define IRQ_PXA910_SSP3                        1
+#define IRQ_PXA910_SSP2                        2
+#define IRQ_PXA910_SSP1                        3
+#define IRQ_PXA910_PMIC_INT            4
+#define IRQ_PXA910_RTC_INT             5
+#define IRQ_PXA910_RTC_ALARM           6
+#define IRQ_PXA910_TWSI0               7
+#define IRQ_PXA910_GPU                 8
+#define IRQ_PXA910_KEYPAD              9
+#define IRQ_PXA910_ROTARY              10
+#define IRQ_PXA910_TRACKBALL           11
+#define IRQ_PXA910_ONEWIRE             12
+#define IRQ_PXA910_AP1_TIMER1          13
+#define IRQ_PXA910_AP1_TIMER2          14
+#define IRQ_PXA910_AP1_TIMER3          15
+#define IRQ_PXA910_IPC_AP0             16
+#define IRQ_PXA910_IPC_AP1             17
+#define IRQ_PXA910_IPC_AP2             18
+#define IRQ_PXA910_IPC_AP3             19
+#define IRQ_PXA910_IPC_AP4             20
+#define IRQ_PXA910_IPC_CP0             21
+#define IRQ_PXA910_IPC_CP1             22
+#define IRQ_PXA910_IPC_CP2             23
+#define IRQ_PXA910_IPC_CP3             24
+#define IRQ_PXA910_IPC_CP4             25
+#define IRQ_PXA910_L2_DDR              26
+#define IRQ_PXA910_UART2               27
+#define IRQ_PXA910_UART3               28
+#define IRQ_PXA910_AP2_TIMER1          29
+#define IRQ_PXA910_AP2_TIMER2          30
+#define IRQ_PXA910_CP2_TIMER1          31
+#define IRQ_PXA910_CP2_TIMER2          32
+#define IRQ_PXA910_CP2_TIMER3          33
+#define IRQ_PXA910_GSSP                        34
+#define IRQ_PXA910_CP2_WDT             35
+#define IRQ_PXA910_MAIN_PMU            36
+#define IRQ_PXA910_CP_FREQ_CHG         37
+#define IRQ_PXA910_AP_FREQ_CHG         38
+#define IRQ_PXA910_MMC                 39
+#define IRQ_PXA910_AEU                 40
+#define IRQ_PXA910_LCD                 41
+#define IRQ_PXA910_CCIC                        42
+#define IRQ_PXA910_IRE                 43
+#define IRQ_PXA910_USB1                        44
+#define IRQ_PXA910_NAND                        45
+#define IRQ_PXA910_HIFI_DMA            46
+#define IRQ_PXA910_DMA_INT0            47
+#define IRQ_PXA910_DMA_INT1            48
+#define IRQ_PXA910_AP_GPIO             49
+#define IRQ_PXA910_AP2_TIMER3          50
+#define IRQ_PXA910_USB2                        51
+#define IRQ_PXA910_TWSI1               54
+#define IRQ_PXA910_CP_GPIO             55
+#define IRQ_PXA910_UART1               59      /* Slow UART */
+#define IRQ_PXA910_AP_PMU              60
+#define IRQ_PXA910_SM_INT              63      /* from PinMux */
+
+/*
+ * Interrupt numbers for MMP2
+ */
+#define IRQ_MMP2_NONE                  (-1)
+#define IRQ_MMP2_SSP1                  0
+#define IRQ_MMP2_SSP2                  1
+#define IRQ_MMP2_SSPA1                 2
+#define IRQ_MMP2_SSPA2                 3
+#define IRQ_MMP2_PMIC_MUX              4       /* PMIC & Charger */
+#define IRQ_MMP2_RTC_MUX               5
+#define IRQ_MMP2_TWSI1                 7
+#define IRQ_MMP2_GPU                   8
+#define IRQ_MMP2_KEYPAD_MUX            9
+#define IRQ_MMP2_ROTARY                        10
+#define IRQ_MMP2_TRACKBALL             11
+#define IRQ_MMP2_ONEWIRE               12
+#define IRQ_MMP2_TIMER1                        13
+#define IRQ_MMP2_TIMER2                        14
+#define IRQ_MMP2_TIMER3                        15
+#define IRQ_MMP2_RIPC                  16
+#define IRQ_MMP2_TWSI_MUX              17      /* TWSI2 ~ TWSI6 */
+#define IRQ_MMP2_HDMI                  19
+#define IRQ_MMP2_SSP3                  20
+#define IRQ_MMP2_SSP4                  21
+#define IRQ_MMP2_USB_HS1               22
+#define IRQ_MMP2_USB_HS2               23
+#define IRQ_MMP2_UART3                 24
+#define IRQ_MMP2_UART1                 27
+#define IRQ_MMP2_UART2                 28
+#define IRQ_MMP2_MIPI_DSI              29
+#define IRQ_MMP2_CI2                   30
+#define IRQ_MMP2_PMU_TIMER1            31
+#define IRQ_MMP2_PMU_TIMER2            32
+#define IRQ_MMP2_PMU_TIMER3            33
+#define IRQ_MMP2_USB_FS                        34
+#define IRQ_MMP2_MISC_MUX              35
+#define IRQ_MMP2_WDT1                  36
+#define IRQ_MMP2_NAND_DMA              37
+#define IRQ_MMP2_USIM                  38
+#define IRQ_MMP2_MMC                   39
+#define IRQ_MMP2_WTM                   40
+#define IRQ_MMP2_LCD                   41
+#define IRQ_MMP2_CI                    42
+#define IRQ_MMP2_IRE                   43
+#define IRQ_MMP2_USB_OTG               44
+#define IRQ_MMP2_NAND                  45
+#define IRQ_MMP2_UART4                 46
+#define IRQ_MMP2_DMA_FIQ               47
+#define IRQ_MMP2_DMA_RIQ               48
+#define IRQ_MMP2_GPIO                  49
+#define IRQ_MMP2_MIPI_HSI1_MUX         51
+#define IRQ_MMP2_MMC2                  52
+#define IRQ_MMP2_MMC3                  53
+#define IRQ_MMP2_MMC4                  54
+#define IRQ_MMP2_MIPI_HSI0_MUX         55
+#define IRQ_MMP2_MSP                   58
+#define IRQ_MMP2_MIPI_SLIM_DMA         59
+#define IRQ_MMP2_PJ4_FREQ_CHG          60
+#define IRQ_MMP2_MIPI_SLIM             62
+#define IRQ_MMP2_SM                    63
+
+#define IRQ_MMP2_MUX_BASE              64
+
+/* secondary interrupt of INT #4 */
+#define IRQ_MMP2_PMIC_BASE             (IRQ_MMP2_MUX_BASE)
+#define IRQ_MMP2_CHARGER               (IRQ_MMP2_PMIC_BASE + 0)
+#define IRQ_MMP2_PMIC                  (IRQ_MMP2_PMIC_BASE + 1)
+
+/* secondary interrupt of INT #5 */
+#define IRQ_MMP2_RTC_BASE              (IRQ_MMP2_PMIC_BASE + 2)
+#define IRQ_MMP2_RTC_ALARM             (IRQ_MMP2_RTC_BASE + 0)
+#define IRQ_MMP2_RTC                   (IRQ_MMP2_RTC_BASE + 1)
+
+/* secondary interrupt of INT #9 */
+#define IRQ_MMP2_KEYPAD_BASE           (IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_KPC                   (IRQ_MMP2_KEYPAD_BASE + 0)
+#define IRQ_MMP2_ROTORY                        (IRQ_MMP2_KEYPAD_BASE + 1)
+#define IRQ_MMP2_TBALL                 (IRQ_MMP2_KEYPAD_BASE + 2)
+
+/* secondary interrupt of INT #17 */
+#define IRQ_MMP2_TWSI_BASE             (IRQ_MMP2_KEYPAD_BASE + 3)
+#define IRQ_MMP2_TWSI2                 (IRQ_MMP2_TWSI_BASE + 0)
+#define IRQ_MMP2_TWSI3                 (IRQ_MMP2_TWSI_BASE + 1)
+#define IRQ_MMP2_TWSI4                 (IRQ_MMP2_TWSI_BASE + 2)
+#define IRQ_MMP2_TWSI5                 (IRQ_MMP2_TWSI_BASE + 3)
+#define IRQ_MMP2_TWSI6                 (IRQ_MMP2_TWSI_BASE + 4)
+
+/* secondary interrupt of INT #35 */
+#define IRQ_MMP2_MISC_BASE             (IRQ_MMP2_TWSI_BASE + 5)
+#define IRQ_MMP2_PERF                  (IRQ_MMP2_MISC_BASE + 0)
+#define IRQ_MMP2_L2_PA_ECC             (IRQ_MMP2_MISC_BASE + 1)
+#define IRQ_MMP2_L2_ECC                        (IRQ_MMP2_MISC_BASE + 2)
+#define IRQ_MMP2_L2_UECC               (IRQ_MMP2_MISC_BASE + 3)
+#define IRQ_MMP2_DDR                   (IRQ_MMP2_MISC_BASE + 4)
+#define IRQ_MMP2_FAB0_TIMEOUT          (IRQ_MMP2_MISC_BASE + 5)
+#define IRQ_MMP2_FAB1_TIMEOUT          (IRQ_MMP2_MISC_BASE + 6)
+#define IRQ_MMP2_FAB2_TIMEOUT          (IRQ_MMP2_MISC_BASE + 7)
+#define IRQ_MMP2_THERMAL               (IRQ_MMP2_MISC_BASE + 9)
+#define IRQ_MMP2_MAIN_PMU              (IRQ_MMP2_MISC_BASE + 10)
+#define IRQ_MMP2_WDT2                  (IRQ_MMP2_MISC_BASE + 11)
+#define IRQ_MMP2_CORESIGHT             (IRQ_MMP2_MISC_BASE + 12)
+#define IRQ_MMP2_COMMTX                        (IRQ_MMP2_MISC_BASE + 13)
+#define IRQ_MMP2_COMMRX                        (IRQ_MMP2_MISC_BASE + 14)
+
+/* secondary interrupt of INT #51 */
+#define IRQ_MMP2_MIPI_HSI1_BASE                (IRQ_MMP2_MISC_BASE + 15)
+#define IRQ_MMP2_HSI1_CAWAKE           (IRQ_MMP2_MIPI_HSI1_BASE + 0)
+#define IRQ_MMP2_MIPI_HSI_INT1         (IRQ_MMP2_MIPI_HSI1_BASE + 1)
+
+/* secondary interrupt of INT #55 */
+#define IRQ_MMP2_MIPI_HSI0_BASE                (IRQ_MMP2_MIPI_HSI1_BASE + 2)
+#define IRQ_MMP2_HSI0_CAWAKE           (IRQ_MMP2_MIPI_HSI0_BASE + 0)
+#define IRQ_MMP2_MIPI_HSI_INT0         (IRQ_MMP2_MIPI_HSI0_BASE + 1)
+
+#define IRQ_MMP2_MUX_END               (IRQ_MMP2_MIPI_HSI0_BASE + 2)
+
+#define IRQ_GPIO_START                 128
+#define MMP_NR_BUILTIN_GPIO            192
+#define MMP_GPIO_TO_IRQ(gpio)          (IRQ_GPIO_START + (gpio))
+
+#define IRQ_BOARD_START                        (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
+#define MMP_NR_IRQS                    IRQ_BOARD_START
+
+#endif /* __ASM_MACH_IRQS_H */
index 0e9e5c0..5dbb753 100644 (file)
 #include <linux/mfd/max8925.h>
 #include <linux/interrupt.h>
 
-#include <mach/irqs.h>
+#include "irqs.h"
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-mmp2.h>
-#include <mach/mmp2.h>
+#include "addr-map.h"
+#include "mfp-mmp2.h"
+#include "mmp2.h"
 
 #include "common.h"
 
diff --git a/arch/arm/mach-mmp/mfp-mmp2.h b/arch/arm/mach-mmp/mfp-mmp2.h
new file mode 100644 (file)
index 0000000..b274434
--- /dev/null
@@ -0,0 +1,395 @@
+#ifndef __ASM_MACH_MFP_MMP2_H
+#define __ASM_MACH_MFP_MMP2_H
+
+#include "mfp.h"
+
+#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
+#define MFP_DRIVE_SLOW         (0x2 << 13)
+#define MFP_DRIVE_MEDIUM       (0x4 << 13)
+#define MFP_DRIVE_FAST         (0x6 << 13)
+
+/* GPIO */
+#define GPIO0_GPIO     MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO     MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO     MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO     MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO     MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO     MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO     MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO     MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO     MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO     MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO    MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO    MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO    MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO    MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO    MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO    MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO    MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO    MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO    MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO    MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO    MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO    MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO    MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO    MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO    MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO    MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO    MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO    MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO    MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO    MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO    MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO    MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO    MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO    MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO    MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO    MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO    MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO    MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO    MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO    MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO    MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO    MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO    MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO    MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO    MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO    MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO    MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO    MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO    MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO    MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO    MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO    MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO    MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO    MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO    MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO    MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO    MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO    MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO    MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO    MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO    MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO    MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO    MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO    MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO    MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO    MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO    MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO    MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO    MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO    MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO    MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO    MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO    MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO    MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO    MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO    MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO    MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO    MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO    MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO    MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO    MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO    MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO    MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO    MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO    MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO    MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO    MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO    MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO    MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO    MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO    MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO    MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO    MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO    MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO    MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO    MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO    MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO    MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO    MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO    MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO   MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO   MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO   MFP_CFG(GPIO102, AF1)
+#define GPIO103_GPIO   MFP_CFG(GPIO103, AF1)
+#define GPIO104_GPIO   MFP_CFG(GPIO104, AF1)
+#define GPIO105_GPIO   MFP_CFG(GPIO105, AF1)
+#define GPIO106_GPIO   MFP_CFG(GPIO106, AF1)
+#define GPIO107_GPIO   MFP_CFG(GPIO107, AF1)
+#define GPIO108_GPIO   MFP_CFG(GPIO108, AF1)
+#define GPIO109_GPIO   MFP_CFG(GPIO109, AF1)
+#define GPIO110_GPIO   MFP_CFG(GPIO110, AF1)
+#define GPIO111_GPIO   MFP_CFG(GPIO111, AF1)
+#define GPIO112_GPIO   MFP_CFG(GPIO112, AF1)
+#define GPIO113_GPIO   MFP_CFG(GPIO113, AF1)
+#define GPIO114_GPIO   MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO   MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO   MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO   MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO   MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO   MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO   MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO   MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO   MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO   MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO   MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO   MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO   MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO   MFP_CFG(GPIO127, AF0)
+#define GPIO128_GPIO   MFP_CFG(GPIO128, AF0)
+#define GPIO129_GPIO   MFP_CFG(GPIO129, AF0)
+#define GPIO130_GPIO   MFP_CFG(GPIO130, AF0)
+#define GPIO131_GPIO   MFP_CFG(GPIO131, AF0)
+#define GPIO132_GPIO   MFP_CFG(GPIO132, AF0)
+#define GPIO133_GPIO   MFP_CFG(GPIO133, AF0)
+#define GPIO134_GPIO   MFP_CFG(GPIO134, AF0)
+#define GPIO135_GPIO   MFP_CFG(GPIO135, AF0)
+#define GPIO136_GPIO   MFP_CFG(GPIO136, AF0)
+#define GPIO137_GPIO   MFP_CFG(GPIO137, AF0)
+#define GPIO138_GPIO   MFP_CFG(GPIO138, AF0)
+#define GPIO139_GPIO   MFP_CFG(GPIO139, AF0)
+#define GPIO140_GPIO   MFP_CFG(GPIO140, AF0)
+#define GPIO141_GPIO   MFP_CFG(GPIO141, AF0)
+#define GPIO142_GPIO   MFP_CFG(GPIO142, AF1)
+#define GPIO143_GPIO   MFP_CFG(GPIO143, AF1)
+#define GPIO144_GPIO   MFP_CFG(GPIO144, AF1)
+#define GPIO145_GPIO   MFP_CFG(GPIO145, AF1)
+#define GPIO146_GPIO   MFP_CFG(GPIO146, AF1)
+#define GPIO147_GPIO   MFP_CFG(GPIO147, AF1)
+#define GPIO148_GPIO   MFP_CFG(GPIO148, AF1)
+#define GPIO149_GPIO   MFP_CFG(GPIO149, AF1)
+#define GPIO150_GPIO   MFP_CFG(GPIO150, AF1)
+#define GPIO151_GPIO   MFP_CFG(GPIO151, AF1)
+#define GPIO152_GPIO   MFP_CFG(GPIO152, AF1)
+#define GPIO153_GPIO   MFP_CFG(GPIO153, AF1)
+#define GPIO154_GPIO   MFP_CFG(GPIO154, AF1)
+#define GPIO155_GPIO   MFP_CFG(GPIO155, AF1)
+#define GPIO156_GPIO   MFP_CFG(GPIO156, AF1)
+#define GPIO157_GPIO   MFP_CFG(GPIO157, AF1)
+#define GPIO158_GPIO   MFP_CFG(GPIO158, AF1)
+#define GPIO159_GPIO   MFP_CFG(GPIO159, AF1)
+#define GPIO160_GPIO   MFP_CFG(GPIO160, AF1)
+#define GPIO161_GPIO   MFP_CFG(GPIO161, AF1)
+#define GPIO162_GPIO   MFP_CFG(GPIO162, AF1)
+#define GPIO163_GPIO   MFP_CFG(GPIO163, AF1)
+#define GPIO164_GPIO   MFP_CFG(GPIO164, AF1)
+#define GPIO165_GPIO   MFP_CFG(GPIO165, AF1)
+#define GPIO166_GPIO   MFP_CFG(GPIO166, AF1)
+#define GPIO167_GPIO   MFP_CFG(GPIO167, AF1)
+#define GPIO168_GPIO   MFP_CFG(GPIO168, AF1)
+
+/* DFI */
+#define GPIO108_DFI_D15                MFP_CFG(GPIO108, AF0)
+#define GPIO109_DFI_D14                MFP_CFG(GPIO109, AF0)
+#define GPIO110_DFI_D13                MFP_CFG(GPIO110, AF0)
+#define GPIO161_DFI_D12                MFP_CFG(GPIO161, AF0)
+#define GPIO162_DFI_D11                MFP_CFG(GPIO162, AF0)
+#define GPIO163_DFI_D10                MFP_CFG(GPIO163, AF0)
+#define GPIO164_DFI_D9         MFP_CFG(GPIO164, AF0)
+#define GPIO111_DFI_D8         MFP_CFG(GPIO111, AF0)
+#define GPIO104_DFI_D7         MFP_CFG(GPIO104, AF0)
+#define GPIO105_DFI_D6         MFP_CFG(GPIO105, AF0)
+#define GPIO106_DFI_D5         MFP_CFG(GPIO106, AF0)
+#define GPIO107_DFI_D4         MFP_CFG(GPIO107, AF0)
+#define GPIO165_DFI_D3         MFP_CFG(GPIO165, AF0)
+#define GPIO166_DFI_D2         MFP_CFG(GPIO166, AF0)
+#define GPIO167_DFI_D1         MFP_CFG(GPIO167, AF0)
+#define GPIO168_DFI_D0         MFP_CFG(GPIO168, AF0)
+#define GPIO143_ND_nCS0                MFP_CFG(GPIO143, AF0)
+#define GPIO144_ND_nCS1                MFP_CFG(GPIO144, AF0)
+#define GPIO147_ND_nWE         MFP_CFG(GPIO147, AF0)
+#define GPIO148_ND_nRE         MFP_CFG(GPIO148, AF0)
+#define GPIO150_ND_ALE         MFP_CFG(GPIO150, AF0)
+#define GPIO149_ND_CLE         MFP_CFG(GPIO149, AF0)
+#define GPIO112_ND_RDY0                MFP_CFG(GPIO112, AF0)
+#define GPIO160_ND_RDY1                MFP_CFG(GPIO160, AF0)
+
+/* Static Memory Controller */
+#define GPIO145_SMC_nCS0       MFP_CFG(GPIO145, AF0)
+#define GPIO146_SMC_nCS1       MFP_CFG(GPIO146, AF0)
+#define GPIO152_SMC_BE0                MFP_CFG(GPIO152, AF0)
+#define GPIO153_SMC_BE1                MFP_CFG(GPIO153, AF0)
+#define GPIO154_SMC_IRQ                MFP_CFG(GPIO154, AF0)
+#define GPIO113_SMC_RDY                MFP_CFG(GPIO113, AF0)
+#define GPIO151_SMC_SCLK       MFP_CFG(GPIO151, AF0)
+
+/* Ethernet */
+#define GPIO155_SM_ADVMUX      MFP_CFG(GPIO155, AF2)
+
+/* UART1 */
+#define GPIO45_UART1_RXD       MFP_CFG(GPIO45, AF1)
+#define GPIO46_UART1_TXD       MFP_CFG(GPIO46, AF1)
+#define GPIO29_UART1_RXD       MFP_CFG(GPIO29, AF1)
+#define GPIO30_UART1_TXD       MFP_CFG(GPIO30, AF1)
+#define GPIO31_UART1_CTS       MFP_CFG(GPIO31, AF1)
+#define GPIO32_UART1_RTS       MFP_CFG(GPIO32, AF1)
+
+/* UART2 */
+#define GPIO47_UART2_RXD       MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART2_TXD       MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART2_CTS       MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART2_RTS       MFP_CFG(GPIO50, AF1)
+
+/* UART3 */
+#define GPIO51_UART3_RXD       MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART3_TXD       MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART3_CTS       MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART3_RTS       MFP_CFG(GPIO54, AF1)
+
+/* MMC1 */
+#define GPIO124_MMC1_DAT7      MFP_CFG_DRV(GPIO124, AF1, FAST)
+#define GPIO125_MMC1_DAT6      MFP_CFG_DRV(GPIO125, AF1, FAST)
+#define GPIO129_MMC1_DAT5      MFP_CFG_DRV(GPIO129, AF1, FAST)
+#define GPIO130_MMC1_DAT4      MFP_CFG_DRV(GPIO130, AF1, FAST)
+#define GPIO131_MMC1_DAT3      MFP_CFG_DRV(GPIO131, AF1, FAST)
+#define GPIO132_MMC1_DAT2      MFP_CFG_DRV(GPIO132, AF1, FAST)
+#define GPIO133_MMC1_DAT1      MFP_CFG_DRV(GPIO133, AF1, FAST)
+#define GPIO134_MMC1_DAT0      MFP_CFG_DRV(GPIO134, AF1, FAST)
+#define GPIO136_MMC1_CMD       MFP_CFG_DRV(GPIO136, AF1, FAST)
+#define GPIO139_MMC1_CLK       MFP_CFG_DRV(GPIO139, AF1, FAST)
+#define GPIO140_MMC1_CD                MFP_CFG_DRV(GPIO140, AF1, FAST)
+#define GPIO141_MMC1_WP                MFP_CFG_DRV(GPIO141, AF1, FAST)
+
+/*MMC2*/
+#define GPIO37_MMC2_DAT3       MFP_CFG_DRV(GPIO37, AF1, FAST)
+#define GPIO38_MMC2_DAT2       MFP_CFG_DRV(GPIO38, AF1, FAST)
+#define GPIO39_MMC2_DAT1       MFP_CFG_DRV(GPIO39, AF1, FAST)
+#define GPIO40_MMC2_DAT0       MFP_CFG_DRV(GPIO40, AF1, FAST)
+#define GPIO41_MMC2_CMD                MFP_CFG_DRV(GPIO41, AF1, FAST)
+#define GPIO42_MMC2_CLK                MFP_CFG_DRV(GPIO42, AF1, FAST)
+
+/*MMC3*/
+#define GPIO165_MMC3_DAT7      MFP_CFG_DRV(GPIO165, AF2, FAST)
+#define GPIO162_MMC3_DAT6      MFP_CFG_DRV(GPIO162, AF2, FAST)
+#define GPIO166_MMC3_DAT5      MFP_CFG_DRV(GPIO166, AF2, FAST)
+#define GPIO163_MMC3_DAT4      MFP_CFG_DRV(GPIO163, AF2, FAST)
+#define GPIO167_MMC3_DAT3      MFP_CFG_DRV(GPIO167, AF2, FAST)
+#define GPIO164_MMC3_DAT2      MFP_CFG_DRV(GPIO164, AF2, FAST)
+#define GPIO168_MMC3_DAT1      MFP_CFG_DRV(GPIO168, AF2, FAST)
+#define GPIO111_MMC3_DAT0      MFP_CFG_DRV(GPIO111, AF2, FAST)
+#define GPIO112_MMC3_CMD       MFP_CFG_DRV(GPIO112, AF2, FAST)
+#define GPIO151_MMC3_CLK       MFP_CFG_DRV(GPIO151, AF2, FAST)
+
+/* LCD */
+#define GPIO74_LCD_FCLK                MFP_CFG_DRV(GPIO74, AF1, FAST)
+#define GPIO75_LCD_LCLK                MFP_CFG_DRV(GPIO75, AF1, FAST)
+#define GPIO76_LCD_PCLK                MFP_CFG_DRV(GPIO76, AF1, FAST)
+#define GPIO77_LCD_DENA                MFP_CFG_DRV(GPIO77, AF1, FAST)
+#define GPIO78_LCD_DD0         MFP_CFG_DRV(GPIO78, AF1, FAST)
+#define GPIO79_LCD_DD1         MFP_CFG_DRV(GPIO79, AF1, FAST)
+#define GPIO80_LCD_DD2         MFP_CFG_DRV(GPIO80, AF1, FAST)
+#define GPIO81_LCD_DD3         MFP_CFG_DRV(GPIO81, AF1, FAST)
+#define GPIO82_LCD_DD4         MFP_CFG_DRV(GPIO82, AF1, FAST)
+#define GPIO83_LCD_DD5         MFP_CFG_DRV(GPIO83, AF1, FAST)
+#define GPIO84_LCD_DD6         MFP_CFG_DRV(GPIO84, AF1, FAST)
+#define GPIO85_LCD_DD7         MFP_CFG_DRV(GPIO85, AF1, FAST)
+#define GPIO86_LCD_DD8         MFP_CFG_DRV(GPIO86, AF1, FAST)
+#define GPIO87_LCD_DD9         MFP_CFG_DRV(GPIO87, AF1, FAST)
+#define GPIO88_LCD_DD10                MFP_CFG_DRV(GPIO88, AF1, FAST)
+#define GPIO89_LCD_DD11                MFP_CFG_DRV(GPIO89, AF1, FAST)
+#define GPIO90_LCD_DD12                MFP_CFG_DRV(GPIO90, AF1, FAST)
+#define GPIO91_LCD_DD13                MFP_CFG_DRV(GPIO91, AF1, FAST)
+#define GPIO92_LCD_DD14                MFP_CFG_DRV(GPIO92, AF1, FAST)
+#define GPIO93_LCD_DD15                MFP_CFG_DRV(GPIO93, AF1, FAST)
+#define GPIO94_LCD_DD16                MFP_CFG_DRV(GPIO94, AF1, FAST)
+#define GPIO95_LCD_DD17                MFP_CFG_DRV(GPIO95, AF1, FAST)
+#define GPIO96_LCD_DD18                MFP_CFG_DRV(GPIO96, AF1, FAST)
+#define GPIO97_LCD_DD19                MFP_CFG_DRV(GPIO97, AF1, FAST)
+#define GPIO98_LCD_DD20                MFP_CFG_DRV(GPIO98, AF1, FAST)
+#define GPIO99_LCD_DD21                MFP_CFG_DRV(GPIO99, AF1, FAST)
+#define GPIO100_LCD_DD22       MFP_CFG_DRV(GPIO100, AF1, FAST)
+#define GPIO101_LCD_DD23       MFP_CFG_DRV(GPIO101, AF1, FAST)
+#define GPIO94_SPI_DCLK                MFP_CFG_DRV(GPIO94, AF3, FAST)
+#define GPIO95_SPI_CS0         MFP_CFG_DRV(GPIO95, AF3, FAST)
+#define GPIO96_SPI_DIN         MFP_CFG_DRV(GPIO96, AF3, FAST)
+#define GPIO97_SPI_DOUT                MFP_CFG_DRV(GPIO97, AF3, FAST)
+#define GPIO98_LCD_RST         MFP_CFG_DRV(GPIO98, AF0, FAST)
+
+#define GPIO114_MN_CLK_OUT     MFP_CFG_DRV(GPIO114, AF1, FAST)
+
+/*LCD TV path*/
+#define GPIO124_LCD_DD24       MFP_CFG_DRV(GPIO124, AF2, FAST)
+#define GPIO125_LCD_DD25       MFP_CFG_DRV(GPIO125, AF2, FAST)
+#define GPIO126_LCD_DD33       MFP_CFG_DRV(GPIO126, AF2, FAST)
+#define GPIO127_LCD_DD26       MFP_CFG_DRV(GPIO127, AF2, FAST)
+#define GPIO128_LCD_DD27       MFP_CFG_DRV(GPIO128, AF2, FAST)
+#define GPIO129_LCD_DD28       MFP_CFG_DRV(GPIO129, AF2, FAST)
+#define GPIO130_LCD_DD29       MFP_CFG_DRV(GPIO130, AF2, FAST)
+#define GPIO135_LCD_DD30       MFP_CFG_DRV(GPIO135, AF2, FAST)
+#define GPIO137_LCD_DD31       MFP_CFG_DRV(GPIO137, AF2, FAST)
+#define GPIO138_LCD_DD32       MFP_CFG_DRV(GPIO138, AF2, FAST)
+#define GPIO140_LCD_DD34       MFP_CFG_DRV(GPIO140, AF2, FAST)
+#define GPIO141_LCD_DD35       MFP_CFG_DRV(GPIO141, AF2, FAST)
+
+/* I2C */
+#define GPIO43_TWSI2_SCL       MFP_CFG_DRV(GPIO43, AF1, SLOW)
+#define GPIO44_TWSI2_SDA       MFP_CFG_DRV(GPIO44, AF1, SLOW)
+#define GPIO71_TWSI3_SCL       MFP_CFG_DRV(GPIO71, AF1, SLOW)
+#define GPIO72_TWSI3_SDA       MFP_CFG_DRV(GPIO72, AF1, SLOW)
+#define TWSI4_SCL              MFP_CFG_DRV(TWSI4_SCL, AF0, SLOW)
+#define TWSI4_SDA              MFP_CFG_DRV(TWSI4_SDA, AF0, SLOW)
+#define GPIO99_TWSI5_SCL       MFP_CFG_DRV(GPIO99, AF4, SLOW)
+#define GPIO100_TWSI5_SDA      MFP_CFG_DRV(GPIO100, AF4, SLOW)
+#define GPIO97_TWSI6_SCL       MFP_CFG_DRV(GPIO97, AF2, SLOW)
+#define GPIO98_TWSI6_SDA       MFP_CFG_DRV(GPIO98, AF2, SLOW)
+
+/* SSPA1 */
+#define GPIO24_I2S_SYSCLK      MFP_CFG(GPIO24, AF1)
+#define GPIO25_I2S_BITCLK      MFP_CFG(GPIO25, AF1)
+#define GPIO26_I2S_SYNC                MFP_CFG(GPIO26, AF1)
+#define GPIO27_I2S_DATA_OUT    MFP_CFG(GPIO27, AF1)
+#define GPIO28_I2S_SDATA_IN    MFP_CFG(GPIO28, AF1)
+#define GPIO114_I2S_MCLK       MFP_CFG(GPIO114, AF1)
+
+/* SSPA2 */
+#define GPIO33_SSPA2_CLK       MFP_CFG(GPIO33, AF1)
+#define GPIO34_SSPA2_FRM       MFP_CFG(GPIO34, AF1)
+#define GPIO35_SSPA2_TXD       MFP_CFG(GPIO35, AF1)
+#define GPIO36_SSPA2_RXD       MFP_CFG(GPIO36, AF1)
+
+/* Keypad */
+#define GPIO00_KP_MKIN0                MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0       MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1                MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1       MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2                MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2       MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3                MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3       MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4                MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4       MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5                MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5       MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6                MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6       MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7                MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7       MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0                MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1                MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2                MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3                MFP_CFG(GPIO19, AF1)
+#define GPIO20_KP_DKIN4                MFP_CFG(GPIO20, AF1)
+#define GPIO21_KP_DKIN5                MFP_CFG(GPIO21, AF1)
+#define GPIO22_KP_DKIN6                MFP_CFG(GPIO22, AF1)
+#define GPIO23_KP_DKIN7                MFP_CFG(GPIO23, AF1)
+
+/* CAMERA */
+#define GPIO59_CCIC_IN7                MFP_CFG_DRV(GPIO59, AF1, FAST)
+#define GPIO60_CCIC_IN6                MFP_CFG_DRV(GPIO60, AF1, FAST)
+#define GPIO61_CCIC_IN5                MFP_CFG_DRV(GPIO61, AF1, FAST)
+#define GPIO62_CCIC_IN4                MFP_CFG_DRV(GPIO62, AF1, FAST)
+#define GPIO63_CCIC_IN3                MFP_CFG_DRV(GPIO63, AF1, FAST)
+#define GPIO64_CCIC_IN2                MFP_CFG_DRV(GPIO64, AF1, FAST)
+#define GPIO65_CCIC_IN1                MFP_CFG_DRV(GPIO65, AF1, FAST)
+#define GPIO66_CCIC_IN0                MFP_CFG_DRV(GPIO66, AF1, FAST)
+#define GPIO67_CAM_HSYNC       MFP_CFG_DRV(GPIO67, AF1, FAST)
+#define GPIO68_CAM_VSYNC       MFP_CFG_DRV(GPIO68, AF1, FAST)
+#define GPIO69_CAM_MCLK                MFP_CFG_DRV(GPIO69, AF1, FAST)
+#define GPIO70_CAM_PCLK                MFP_CFG_DRV(GPIO70, AF1, FAST)
+
+/* PMIC */
+#define PMIC_PMIC_INT          MFP_CFG(PMIC_INT, AF0)
+
+#endif /* __ASM_MACH_MFP_MMP2_H */
+
diff --git a/arch/arm/mach-mmp/mfp-pxa168.h b/arch/arm/mach-mmp/mfp-pxa168.h
new file mode 100644 (file)
index 0000000..9050d03
--- /dev/null
@@ -0,0 +1,354 @@
+#ifndef __ASM_MACH_MFP_PXA168_H
+#define __ASM_MACH_MFP_PXA168_H
+
+#include "mfp.h"
+
+#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
+#define MFP_DRIVE_SLOW         (0x1 << 13)
+#define MFP_DRIVE_MEDIUM       (0x2 << 13)
+#define MFP_DRIVE_FAST         (0x3 << 13)
+
+#undef MFP_CFG
+#undef MFP_CFG_DRV
+
+#define MFP_CFG(pin, af)               \
+       (MFP_LPM_INPUT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
+
+#define MFP_CFG_DRV(pin, af, drv)      \
+       (MFP_LPM_INPUT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
+
+/* GPIO */
+#define GPIO0_GPIO             MFP_CFG(GPIO0, AF5)
+#define GPIO1_GPIO             MFP_CFG(GPIO1, AF5)
+#define GPIO2_GPIO             MFP_CFG(GPIO2, AF5)
+#define GPIO3_GPIO             MFP_CFG(GPIO3, AF5)
+#define GPIO4_GPIO             MFP_CFG(GPIO4, AF5)
+#define GPIO5_GPIO             MFP_CFG(GPIO5, AF5)
+#define GPIO6_GPIO             MFP_CFG(GPIO6, AF5)
+#define GPIO7_GPIO             MFP_CFG(GPIO7, AF5)
+#define GPIO8_GPIO             MFP_CFG(GPIO8, AF5)
+#define GPIO9_GPIO             MFP_CFG(GPIO9, AF5)
+#define GPIO10_GPIO            MFP_CFG(GPIO10, AF5)
+#define GPIO11_GPIO            MFP_CFG(GPIO11, AF5)
+#define GPIO12_GPIO            MFP_CFG(GPIO12, AF5)
+#define GPIO13_GPIO            MFP_CFG(GPIO13, AF5)
+#define GPIO14_GPIO            MFP_CFG(GPIO14, AF5)
+#define GPIO15_GPIO            MFP_CFG(GPIO15, AF5)
+#define GPIO16_GPIO            MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO            MFP_CFG(GPIO17, AF5)
+#define GPIO18_GPIO            MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO            MFP_CFG(GPIO19, AF5)
+#define GPIO20_GPIO            MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO            MFP_CFG(GPIO21, AF5)
+#define GPIO22_GPIO            MFP_CFG(GPIO22, AF5)
+#define GPIO23_GPIO            MFP_CFG(GPIO23, AF5)
+#define GPIO24_GPIO            MFP_CFG(GPIO24, AF5)
+#define GPIO25_GPIO            MFP_CFG(GPIO25, AF5)
+#define GPIO26_GPIO            MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO            MFP_CFG(GPIO27, AF5)
+#define GPIO28_GPIO            MFP_CFG(GPIO28, AF5)
+#define GPIO29_GPIO            MFP_CFG(GPIO29, AF5)
+#define GPIO30_GPIO            MFP_CFG(GPIO30, AF5)
+#define GPIO31_GPIO            MFP_CFG(GPIO31, AF5)
+#define GPIO32_GPIO            MFP_CFG(GPIO32, AF5)
+#define GPIO33_GPIO            MFP_CFG(GPIO33, AF5)
+#define GPIO34_GPIO            MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO            MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO            MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO            MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO            MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO            MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO            MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO            MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO            MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO            MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO            MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO            MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO            MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO            MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO            MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO            MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO            MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO            MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO            MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO            MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO            MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO            MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO            MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO            MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO            MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO            MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO            MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO            MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO            MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO            MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO            MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO            MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO            MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO            MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO            MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO            MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO            MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO            MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO            MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO            MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO            MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO            MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO            MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO            MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO            MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO            MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO            MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO            MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO            MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO            MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO            MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO            MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO            MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO            MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO            MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO           MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO           MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO           MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO           MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO           MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO           MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO           MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO           MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO           MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO           MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO           MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO           MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO           MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO           MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO           MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO           MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO           MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO           MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO           MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO           MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO           MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO           MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO           MFP_CFG(GPIO122, AF0)
+
+/* DFI */
+#define GPIO0_DFI_D15          MFP_CFG(GPIO0, AF0)
+#define GPIO1_DFI_D14          MFP_CFG(GPIO1, AF0)
+#define GPIO2_DFI_D13          MFP_CFG(GPIO2, AF0)
+#define GPIO3_DFI_D12          MFP_CFG(GPIO3, AF0)
+#define GPIO4_DFI_D11          MFP_CFG(GPIO4, AF0)
+#define GPIO5_DFI_D10          MFP_CFG(GPIO5, AF0)
+#define GPIO6_DFI_D9           MFP_CFG(GPIO6, AF0)
+#define GPIO7_DFI_D8           MFP_CFG(GPIO7, AF0)
+#define GPIO8_DFI_D7           MFP_CFG(GPIO8, AF0)
+#define GPIO9_DFI_D6           MFP_CFG(GPIO9, AF0)
+#define GPIO10_DFI_D5          MFP_CFG(GPIO10, AF0)
+#define GPIO11_DFI_D4          MFP_CFG(GPIO11, AF0)
+#define GPIO12_DFI_D3          MFP_CFG(GPIO12, AF0)
+#define GPIO13_DFI_D2          MFP_CFG(GPIO13, AF0)
+#define GPIO14_DFI_D1          MFP_CFG(GPIO14, AF0)
+#define GPIO15_DFI_D0          MFP_CFG(GPIO15, AF0)
+
+#define GPIO30_DFI_ADDR0       MFP_CFG(GPIO30, AF0)
+#define GPIO31_DFI_ADDR1       MFP_CFG(GPIO31, AF0)
+#define GPIO32_DFI_ADDR2       MFP_CFG(GPIO32, AF0)
+#define GPIO33_DFI_ADDR3       MFP_CFG(GPIO33, AF0)
+
+/* NAND */
+#define GPIO16_ND_nCS0         MFP_CFG(GPIO16, AF1)
+#define GPIO17_ND_nWE          MFP_CFG(GPIO17, AF0)
+#define GPIO21_ND_ALE          MFP_CFG(GPIO21, AF0)
+#define GPIO22_ND_CLE          MFP_CFG(GPIO22, AF0)
+#define GPIO24_ND_nRE          MFP_CFG(GPIO24, AF0)
+#define GPIO26_ND_RnB1         MFP_CFG(GPIO26, AF1)
+#define GPIO27_ND_RnB2         MFP_CFG(GPIO27, AF1)
+
+/* Static Memory Controller */
+#define GPIO18_SMC_nCS0                MFP_CFG(GPIO18, AF3)
+#define GPIO18_SMC_nCS1                MFP_CFG(GPIO18, AF2)
+#define GPIO16_SMC_nCS0                MFP_CFG(GPIO16, AF2)
+#define GPIO16_SMC_nCS1                MFP_CFG(GPIO16, AF3)
+#define GPIO19_SMC_nCS0                MFP_CFG(GPIO19, AF0)
+#define GPIO20_SMC_nCS1                MFP_CFG(GPIO20, AF2)
+#define GPIO23_SMC_nLUA                MFP_CFG(GPIO23, AF0)
+#define GPIO25_SMC_nLLA                MFP_CFG(GPIO25, AF0)
+#define GPIO27_SMC_IRQ         MFP_CFG(GPIO27, AF0)
+#define GPIO28_SMC_RDY         MFP_CFG(GPIO28, AF0)
+#define GPIO29_SMC_SCLK                MFP_CFG(GPIO29, AF0)
+#define GPIO34_SMC_nCS1                MFP_CFG(GPIO34, AF2)
+#define GPIO35_SMC_BE1         MFP_CFG(GPIO35, AF2)
+#define GPIO36_SMC_BE2         MFP_CFG(GPIO36, AF2)
+
+/* Compact Flash */
+#define GPIO19_CF_nCE1         MFP_CFG(GPIO19, AF3)
+#define GPIO20_CF_nCE2         MFP_CFG(GPIO20, AF3)
+#define GPIO23_CF_nALE         MFP_CFG(GPIO23, AF3)
+#define GPIO25_CF_nRESET       MFP_CFG(GPIO25, AF3)
+#define GPIO28_CF_RDY          MFP_CFG(GPIO28, AF3)
+#define GPIO29_CF_STSCH                MFP_CFG(GPIO29, AF3)
+#define GPIO30_CF_nREG         MFP_CFG(GPIO30, AF3)
+#define GPIO31_CF_nIOIS16      MFP_CFG(GPIO31, AF3)
+#define GPIO32_CF_nCD1         MFP_CFG(GPIO32, AF3)
+#define GPIO33_CF_nCD2         MFP_CFG(GPIO33, AF3)
+
+/* UART */
+#define GPIO8_UART3_TXD                MFP_CFG(GPIO8, AF2)
+#define GPIO9_UART3_RXD                MFP_CFG(GPIO9, AF2)
+#define GPIO1O_UART3_CTS       MFP_CFG(GPIO10, AF2)
+#define GPIO11_UART3_RTS       MFP_CFG(GPIO11, AF2)
+#define GPIO88_UART2_TXD       MFP_CFG(GPIO88, AF2)
+#define GPIO89_UART2_RXD       MFP_CFG(GPIO89, AF2)
+#define GPIO107_UART1_TXD      MFP_CFG_DRV(GPIO107, AF1, FAST)
+#define GPIO107_UART1_RXD      MFP_CFG_DRV(GPIO107, AF2, FAST)
+#define GPIO108_UART1_RXD      MFP_CFG_DRV(GPIO108, AF1, FAST)
+#define GPIO108_UART1_TXD      MFP_CFG_DRV(GPIO108, AF2, FAST)
+#define GPIO109_UART1_CTS      MFP_CFG(GPIO109, AF1)
+#define GPIO109_UART1_RTS      MFP_CFG(GPIO109, AF2)
+#define GPIO110_UART1_RTS      MFP_CFG(GPIO110, AF1)
+#define GPIO110_UART1_CTS      MFP_CFG(GPIO110, AF2)
+#define GPIO111_UART1_RI       MFP_CFG(GPIO111, AF1)
+#define GPIO111_UART1_DSR      MFP_CFG(GPIO111, AF2)
+#define GPIO112_UART1_DTR      MFP_CFG(GPIO111, AF1)
+#define GPIO112_UART1_DCD      MFP_CFG(GPIO112, AF2)
+
+/* MMC1 */
+#define GPIO37_MMC1_DAT7       MFP_CFG(GPIO37, AF1)
+#define GPIO38_MMC1_DAT6       MFP_CFG(GPIO38, AF1)
+#define GPIO54_MMC1_DAT5       MFP_CFG(GPIO54, AF1)
+#define GPIO48_MMC1_DAT4       MFP_CFG(GPIO48, AF1)
+#define GPIO51_MMC1_DAT3       MFP_CFG(GPIO51, AF1)
+#define GPIO52_MMC1_DAT2       MFP_CFG(GPIO52, AF1)
+#define GPIO40_MMC1_DAT1       MFP_CFG(GPIO40, AF1)
+#define GPIO41_MMC1_DAT0       MFP_CFG(GPIO41, AF1)
+#define GPIO49_MMC1_CMD                MFP_CFG(GPIO49, AF1)
+#define GPIO43_MMC1_CLK                MFP_CFG(GPIO43, AF1)
+#define GPIO53_MMC1_CD         MFP_CFG(GPIO53, AF1)
+#define GPIO46_MMC1_WP         MFP_CFG(GPIO46, AF1)
+
+/* MMC2 */
+#define        GPIO28_MMC2_CMD         MFP_CFG_DRV(GPIO28, AF6, FAST)
+#define        GPIO29_MMC2_CLK         MFP_CFG_DRV(GPIO29, AF6, FAST)
+#define        GPIO30_MMC2_DAT0        MFP_CFG_DRV(GPIO30, AF6, FAST)
+#define        GPIO31_MMC2_DAT1        MFP_CFG_DRV(GPIO31, AF6, FAST)
+#define        GPIO32_MMC2_DAT2        MFP_CFG_DRV(GPIO32, AF6, FAST)
+#define        GPIO33_MMC2_DAT3        MFP_CFG_DRV(GPIO33, AF6, FAST)
+
+/* MMC4 */
+#define GPIO125_MMC4_DAT3       MFP_CFG_DRV(GPIO125, AF7, FAST)
+#define GPIO126_MMC4_DAT2       MFP_CFG_DRV(GPIO126, AF7, FAST)
+#define GPIO127_MMC4_DAT1       MFP_CFG_DRV(GPIO127, AF7, FAST)
+#define GPIO0_2_MMC4_DAT0       MFP_CFG_DRV(GPIO0_2, AF7, FAST)
+#define GPIO1_2_MMC4_CMD        MFP_CFG_DRV(GPIO1_2, AF7, FAST)
+#define GPIO2_2_MMC4_CLK        MFP_CFG_DRV(GPIO2_2, AF7, FAST)
+
+/* LCD */
+#define GPIO84_LCD_CS          MFP_CFG(GPIO84, AF1)
+#define GPIO60_LCD_DD0         MFP_CFG(GPIO60, AF1)
+#define GPIO61_LCD_DD1         MFP_CFG(GPIO61, AF1)
+#define GPIO70_LCD_DD10                MFP_CFG(GPIO70, AF1)
+#define GPIO71_LCD_DD11                MFP_CFG(GPIO71, AF1)
+#define GPIO72_LCD_DD12                MFP_CFG(GPIO72, AF1)
+#define GPIO73_LCD_DD13                MFP_CFG(GPIO73, AF1)
+#define GPIO74_LCD_DD14                MFP_CFG(GPIO74, AF1)
+#define GPIO75_LCD_DD15                MFP_CFG(GPIO75, AF1)
+#define GPIO76_LCD_DD16                MFP_CFG(GPIO76, AF1)
+#define GPIO77_LCD_DD17                MFP_CFG(GPIO77, AF1)
+#define GPIO78_LCD_DD18                MFP_CFG(GPIO78, AF1)
+#define GPIO79_LCD_DD19                MFP_CFG(GPIO79, AF1)
+#define GPIO62_LCD_DD2         MFP_CFG(GPIO62, AF1)
+#define GPIO80_LCD_DD20                MFP_CFG(GPIO80, AF1)
+#define GPIO81_LCD_DD21                MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_DD22                MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_DD23                MFP_CFG(GPIO83, AF1)
+#define GPIO63_LCD_DD3         MFP_CFG(GPIO63, AF1)
+#define GPIO64_LCD_DD4         MFP_CFG(GPIO64, AF1)
+#define GPIO65_LCD_DD5         MFP_CFG(GPIO65, AF1)
+#define GPIO66_LCD_DD6         MFP_CFG(GPIO66, AF1)
+#define GPIO67_LCD_DD7         MFP_CFG(GPIO67, AF1)
+#define GPIO68_LCD_DD8         MFP_CFG(GPIO68, AF1)
+#define GPIO69_LCD_DD9         MFP_CFG(GPIO69, AF1)
+#define GPIO59_LCD_DENA_BIAS   MFP_CFG(GPIO59, AF1)
+#define GPIO56_LCD_FCLK_RD     MFP_CFG(GPIO56, AF1)
+#define GPIO57_LCD_LCLK_A0     MFP_CFG(GPIO57, AF1)
+#define GPIO58_LCD_PCLK_WR     MFP_CFG(GPIO58, AF1)
+#define GPIO85_LCD_VSYNC       MFP_CFG(GPIO85, AF1)
+
+/* I2C */
+#define GPIO105_CI2C_SDA       MFP_CFG(GPIO105, AF1)
+#define GPIO106_CI2C_SCL       MFP_CFG(GPIO106, AF1)
+
+/* I2S */
+#define GPIO113_I2S_MCLK       MFP_CFG(GPIO113, AF6)
+#define GPIO114_I2S_FRM                MFP_CFG(GPIO114, AF1)
+#define GPIO115_I2S_BCLK       MFP_CFG(GPIO115, AF1)
+#define GPIO116_I2S_RXD                MFP_CFG(GPIO116, AF2)
+#define GPIO116_I2S_TXD         MFP_CFG(GPIO116, AF1)
+#define GPIO117_I2S_TXD                MFP_CFG(GPIO117, AF2)
+
+/* PWM */
+#define GPIO96_PWM3_OUT                MFP_CFG(GPIO96, AF1)
+#define GPIO97_PWM2_OUT                MFP_CFG(GPIO97, AF1)
+#define GPIO98_PWM1_OUT                MFP_CFG(GPIO98, AF1)
+#define GPIO104_PWM4_OUT       MFP_CFG(GPIO104, AF1)
+#define GPIO106_PWM2_OUT       MFP_CFG(GPIO106, AF2)
+#define GPIO74_PWM4_OUT                MFP_CFG(GPIO74, AF2)
+#define GPIO75_PWM3_OUT                MFP_CFG(GPIO75, AF2)
+#define GPIO76_PWM2_OUT                MFP_CFG(GPIO76, AF2)
+#define GPIO77_PWM1_OUT                MFP_CFG(GPIO77, AF2)
+#define GPIO82_PWM4_OUT                MFP_CFG(GPIO82, AF2)
+#define GPIO83_PWM3_OUT                MFP_CFG(GPIO83, AF2)
+#define GPIO84_PWM2_OUT                MFP_CFG(GPIO84, AF2)
+#define GPIO85_PWM1_OUT                MFP_CFG(GPIO85, AF2)
+#define GPIO84_PWM1_OUT                MFP_CFG(GPIO84, AF4)
+#define GPIO122_PWM3_OUT       MFP_CFG(GPIO122, AF3)
+#define GPIO123_PWM1_OUT       MFP_CFG(GPIO123, AF1)
+#define GPIO124_PWM2_OUT       MFP_CFG(GPIO124, AF1)
+#define GPIO125_PWM3_OUT       MFP_CFG(GPIO125, AF1)
+#define GPIO126_PWM4_OUT       MFP_CFG(GPIO126, AF1)
+#define GPIO86_PWM1_OUT                MFP_CFG(GPIO86, AF2)
+#define GPIO86_PWM2_OUT                MFP_CFG(GPIO86, AF3)
+
+/* Keypad */
+#define GPIO109_KP_MKIN1        MFP_CFG(GPIO109, AF7)
+#define GPIO110_KP_MKIN0        MFP_CFG(GPIO110, AF7)
+#define GPIO111_KP_MKOUT7       MFP_CFG(GPIO111, AF7)
+#define GPIO112_KP_MKOUT6       MFP_CFG(GPIO112, AF7)
+#define GPIO121_KP_MKIN4        MFP_CFG(GPIO121, AF7)
+
+/* Fast Ethernet */
+#define GPIO86_TX_CLK          MFP_CFG(GPIO86, AF5)
+#define GPIO87_TX_EN           MFP_CFG(GPIO87, AF5)
+#define GPIO88_TX_DQ3          MFP_CFG(GPIO88, AF5)
+#define GPIO89_TX_DQ2          MFP_CFG(GPIO89, AF5)
+#define GPIO90_TX_DQ1          MFP_CFG(GPIO90, AF5)
+#define GPIO91_TX_DQ0          MFP_CFG(GPIO91, AF5)
+#define GPIO92_MII_CRS         MFP_CFG(GPIO92, AF5)
+#define GPIO93_MII_COL         MFP_CFG(GPIO93, AF5)
+#define GPIO94_RX_CLK          MFP_CFG(GPIO94, AF5)
+#define GPIO95_RX_ER           MFP_CFG(GPIO95, AF5)
+#define GPIO96_RX_DQ3          MFP_CFG(GPIO96, AF5)
+#define GPIO97_RX_DQ2          MFP_CFG(GPIO97, AF5)
+#define GPIO98_RX_DQ1          MFP_CFG(GPIO98, AF5)
+#define GPIO99_RX_DQ0          MFP_CFG(GPIO99, AF5)
+#define GPIO100_MII_MDC                MFP_CFG(GPIO100, AF5)
+#define GPIO101_MII_MDIO       MFP_CFG(GPIO101, AF5)
+#define GPIO103_RX_DV          MFP_CFG(GPIO103, AF5)
+
+/* SSP2 */
+#define GPIO107_SSP2_RXD       MFP_CFG(GPIO107, AF4)
+#define GPIO108_SSP2_TXD       MFP_CFG(GPIO108, AF4)
+#define GPIO111_SSP2_CLK       MFP_CFG(GPIO111, AF4)
+#define GPIO112_SSP2_FRM       MFP_CFG(GPIO112, AF4)
+
+#endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/mfp-pxa910.h b/arch/arm/mach-mmp/mfp-pxa910.h
new file mode 100644 (file)
index 0000000..f06db5c
--- /dev/null
@@ -0,0 +1,169 @@
+#ifndef __ASM_MACH_MFP_PXA910_H
+#define __ASM_MACH_MFP_PXA910_H
+
+#include "mfp.h"
+
+#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
+#define MFP_DRIVE_SLOW         (0x2 << 13)
+#define MFP_DRIVE_MEDIUM       (0x4 << 13)
+#define MFP_DRIVE_FAST         (0x6 << 13)
+
+/* UART2 */
+#define GPIO47_UART2_RXD       MFP_CFG(GPIO47, AF6)
+#define GPIO48_UART2_TXD       MFP_CFG(GPIO48, AF6)
+
+/* UART3 */
+#define GPIO31_UART3_RXD       MFP_CFG(GPIO31, AF4)
+#define GPIO32_UART3_TXD       MFP_CFG(GPIO32, AF4)
+
+/*IRDA*/
+#define GPIO51_IRDA_SHDN       MFP_CFG(GPIO51, AF0)
+
+/* SMC */
+#define SM_nCS0_nCS0           MFP_CFG(SM_nCS0, AF0)
+#define SM_ADV_SM_ADV          MFP_CFG(SM_ADV, AF0)
+#define SM_SCLK_SM_SCLK                MFP_CFG(SM_SCLK, AF0)
+#define SM_BE0_SM_BE0          MFP_CFG(SM_BE0, AF1)
+#define SM_BE1_SM_BE1          MFP_CFG(SM_BE1, AF1)
+
+/* I2C */
+#define GPIO53_CI2C_SCL                MFP_CFG(GPIO53, AF2)
+#define GPIO54_CI2C_SDA                MFP_CFG(GPIO54, AF2)
+
+/* SSP1 (I2S) */
+#define GPIO24_SSP1_SDATA_IN   MFP_CFG_DRV(GPIO24, AF1, MEDIUM)
+#define GPIO21_SSP1_BITCLK     MFP_CFG_DRV(GPIO21, AF1, MEDIUM)
+#define GPIO20_SSP1_SYSCLK     MFP_CFG_DRV(GPIO20, AF1, MEDIUM)
+#define GPIO22_SSP1_SYNC       MFP_CFG_DRV(GPIO22, AF1, MEDIUM)
+#define GPIO23_SSP1_DATA_OUT   MFP_CFG_DRV(GPIO23, AF1, MEDIUM)
+#define GPIO124_MN_CLK_OUT     MFP_CFG_DRV(GPIO124, AF1, MEDIUM)
+#define GPIO123_CLK_REQ                MFP_CFG_DRV(GPIO123, AF0, MEDIUM)
+
+/* DFI */
+#define DF_IO0_ND_IO0          MFP_CFG(DF_IO0, AF0)
+#define DF_IO1_ND_IO1          MFP_CFG(DF_IO1, AF0)
+#define DF_IO2_ND_IO2          MFP_CFG(DF_IO2, AF0)
+#define DF_IO3_ND_IO3          MFP_CFG(DF_IO3, AF0)
+#define DF_IO4_ND_IO4          MFP_CFG(DF_IO4, AF0)
+#define DF_IO5_ND_IO5          MFP_CFG(DF_IO5, AF0)
+#define DF_IO6_ND_IO6          MFP_CFG(DF_IO6, AF0)
+#define DF_IO7_ND_IO7          MFP_CFG(DF_IO7, AF0)
+#define DF_IO8_ND_IO8          MFP_CFG(DF_IO8, AF0)
+#define DF_IO9_ND_IO9          MFP_CFG(DF_IO9, AF0)
+#define DF_IO10_ND_IO10                MFP_CFG(DF_IO10, AF0)
+#define DF_IO11_ND_IO11                MFP_CFG(DF_IO11, AF0)
+#define DF_IO12_ND_IO12                MFP_CFG(DF_IO12, AF0)
+#define DF_IO13_ND_IO13                MFP_CFG(DF_IO13, AF0)
+#define DF_IO14_ND_IO14                MFP_CFG(DF_IO14, AF0)
+#define DF_IO15_ND_IO15                MFP_CFG(DF_IO15, AF0)
+#define DF_nCS0_SM_nCS2_nCS0   MFP_CFG(DF_nCS0_SM_nCS2, AF0)
+#define DF_ALE_SM_WEn_ND_ALE   MFP_CFG(DF_ALE_SM_WEn, AF1)
+#define DF_CLE_SM_OEn_ND_CLE   MFP_CFG(DF_CLE_SM_OEn, AF0)
+#define DF_WEn_DF_WEn          MFP_CFG(DF_WEn, AF1)
+#define DF_REn_DF_REn          MFP_CFG(DF_REn, AF1)
+#define DF_RDY0_DF_RDY0                MFP_CFG(DF_RDY0, AF0)
+
+/*keypad*/
+#define GPIO00_KP_MKIN0                MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0       MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1                MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1       MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2                MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2       MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3                MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3       MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4                MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4       MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5                MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5       MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6                MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6       MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7                MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7       MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0                MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1                MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2                MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3                MFP_CFG(GPIO19, AF1)
+
+/* LCD */
+#define GPIO81_LCD_FCLK                MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_LCLK                MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_PCLK                MFP_CFG(GPIO83, AF1)
+#define GPIO84_LCD_DENA                MFP_CFG(GPIO84, AF1)
+#define GPIO85_LCD_DD0         MFP_CFG(GPIO85, AF1)
+#define GPIO86_LCD_DD1         MFP_CFG(GPIO86, AF1)
+#define GPIO87_LCD_DD2         MFP_CFG(GPIO87, AF1)
+#define GPIO88_LCD_DD3         MFP_CFG(GPIO88, AF1)
+#define GPIO89_LCD_DD4         MFP_CFG(GPIO89, AF1)
+#define GPIO90_LCD_DD5         MFP_CFG(GPIO90, AF1)
+#define GPIO91_LCD_DD6         MFP_CFG(GPIO91, AF1)
+#define GPIO92_LCD_DD7         MFP_CFG(GPIO92, AF1)
+#define GPIO93_LCD_DD8         MFP_CFG(GPIO93, AF1)
+#define GPIO94_LCD_DD9         MFP_CFG(GPIO94, AF1)
+#define GPIO95_LCD_DD10                MFP_CFG(GPIO95, AF1)
+#define GPIO96_LCD_DD11                MFP_CFG(GPIO96, AF1)
+#define GPIO97_LCD_DD12                MFP_CFG(GPIO97, AF1)
+#define GPIO98_LCD_DD13                MFP_CFG(GPIO98, AF1)
+#define GPIO100_LCD_DD14       MFP_CFG(GPIO100, AF1)
+#define GPIO101_LCD_DD15       MFP_CFG(GPIO101, AF1)
+#define GPIO102_LCD_DD16       MFP_CFG(GPIO102, AF1)
+#define GPIO103_LCD_DD17       MFP_CFG(GPIO103, AF1)
+#define GPIO104_LCD_DD18       MFP_CFG(GPIO104, AF1)
+#define GPIO105_LCD_DD19       MFP_CFG(GPIO105, AF1)
+#define GPIO106_LCD_DD20       MFP_CFG(GPIO106, AF1)
+#define GPIO107_LCD_DD21       MFP_CFG(GPIO107, AF1)
+#define GPIO108_LCD_DD22       MFP_CFG(GPIO108, AF1)
+#define GPIO109_LCD_DD23       MFP_CFG(GPIO109, AF1)
+
+#define GPIO104_LCD_SPIDOUT    MFP_CFG(GPIO104, AF3)
+#define GPIO105_LCD_SPIDIN     MFP_CFG(GPIO105, AF3)
+#define GPIO107_LCD_CS1        MFP_CFG(GPIO107, AF3)
+#define GPIO108_LCD_DCLK       MFP_CFG(GPIO108, AF3)
+
+#define GPIO106_LCD_RESET      MFP_CFG(GPIO106, AF0)
+
+/*smart panel*/
+#define GPIO82_LCD_A0          MFP_CFG(GPIO82, AF0)
+#define GPIO83_LCD_WR          MFP_CFG(GPIO83, AF0)
+#define GPIO103_LCD_CS         MFP_CFG(GPIO103, AF0)
+
+/*1wire*/
+#define GPIO106_1WIRE          MFP_CFG(GPIO106, AF3)
+
+/*CCIC*/
+#define GPIO67_CCIC_IN7                MFP_CFG_DRV(GPIO67, AF1, MEDIUM)
+#define GPIO68_CCIC_IN6                MFP_CFG_DRV(GPIO68, AF1, MEDIUM)
+#define GPIO69_CCIC_IN5                MFP_CFG_DRV(GPIO69, AF1, MEDIUM)
+#define GPIO70_CCIC_IN4                MFP_CFG_DRV(GPIO70, AF1, MEDIUM)
+#define GPIO71_CCIC_IN3                MFP_CFG_DRV(GPIO71, AF1, MEDIUM)
+#define GPIO72_CCIC_IN2                MFP_CFG_DRV(GPIO72, AF1, MEDIUM)
+#define GPIO73_CCIC_IN1                MFP_CFG_DRV(GPIO73, AF1, MEDIUM)
+#define GPIO74_CCIC_IN0                MFP_CFG_DRV(GPIO74, AF1, MEDIUM)
+#define GPIO75_CAM_HSYNC       MFP_CFG_DRV(GPIO75, AF1, MEDIUM)
+#define GPIO76_CAM_VSYNC       MFP_CFG_DRV(GPIO76, AF1, MEDIUM)
+#define GPIO77_CAM_MCLK                MFP_CFG_DRV(GPIO77, AF1, MEDIUM)
+#define GPIO78_CAM_PCLK                MFP_CFG_DRV(GPIO78, AF1, MEDIUM)
+
+/* MMC1 */
+#define MMC1_DAT7_MMC1_DAT7    MFP_CFG_DRV(MMC1_DAT7, AF0, MEDIUM)
+#define MMC1_DAT6_MMC1_DAT6    MFP_CFG_DRV(MMC1_DAT6, AF0, MEDIUM)
+#define MMC1_DAT5_MMC1_DAT5    MFP_CFG_DRV(MMC1_DAT5, AF0, MEDIUM)
+#define MMC1_DAT4_MMC1_DAT4    MFP_CFG_DRV(MMC1_DAT4, AF0, MEDIUM)
+#define MMC1_DAT3_MMC1_DAT3    MFP_CFG_DRV(MMC1_DAT3, AF0, MEDIUM)
+#define MMC1_DAT2_MMC1_DAT2    MFP_CFG_DRV(MMC1_DAT2, AF0, MEDIUM)
+#define MMC1_DAT1_MMC1_DAT1    MFP_CFG_DRV(MMC1_DAT1, AF0, MEDIUM)
+#define MMC1_DAT0_MMC1_DAT0    MFP_CFG_DRV(MMC1_DAT0, AF0, MEDIUM)
+#define MMC1_CMD_MMC1_CMD      MFP_CFG_DRV(MMC1_CMD, AF0, MEDIUM)
+#define MMC1_CLK_MMC1_CLK      MFP_CFG_DRV(MMC1_CLK, AF0, MEDIUM)
+#define MMC1_CD_MMC1_CD                MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
+#define MMC1_WP_MMC1_WP                MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
+
+/* PWM */
+#define GPIO27_PWM3_AF2                MFP_CFG(GPIO27, AF2)
+#define GPIO51_PWM2_OUT                MFP_CFG(GPIO51, AF2)
+#define GPIO117_PWM1_OUT       MFP_CFG(GPIO117, AF2)
+#define GPIO118_PWM2_OUT       MFP_CFG(GPIO118, AF2)
+#define GPIO119_PWM3_OUT       MFP_CFG(GPIO119, AF2)
+#define GPIO120_PWM4_OUT       MFP_CFG(GPIO120, AF2)
+
+#endif /* __ASM_MACH MFP_PXA910_H */
diff --git a/arch/arm/mach-mmp/mfp.h b/arch/arm/mach-mmp/mfp.h
new file mode 100644 (file)
index 0000000..62e510e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_MFP_H
+#define __ASM_MACH_MFP_H
+
+#include <plat/mfp.h>
+
+/*
+ * NOTE: the MFPR register bit definitions on PXA168 processor lines are a
+ * bit different from those on PXA3xx.  Bit [7:10] are now reserved, which
+ * were SLEEP_OE_N, SLEEP_DATA, SLEEP_SEL and the LSB of DRIVE bits.
+ *
+ * To cope with this difference and re-use the pxa3xx mfp code as much as
+ * possible, we make the following compromise:
+ *
+ * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT)
+ * 2. DRIVE strength definitions redefined to include the reserved bit
+ *    - the reserved bit differs between pxa168 and pxa910, and the
+ *      MFP_DRIVE_* macros are individually defined in mfp-pxa{168,910}.h
+ * 3. Override MFP_CFG() and MFP_CFG_DRV()
+ * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X()
+ */
+
+#undef MFP_CFG
+#undef MFP_CFG_DRV
+#undef MFP_CFG_LPM
+#undef MFP_CFG_X
+#undef MFP_CFG_DEFAULT
+
+#define MFP_CFG(pin, af)               \
+       (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
+
+#define MFP_CFG_DRV(pin, af, drv)      \
+       (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
+
+#endif /* __ASM_MACH_MFP_H */
index a70b553..afba546 100644 (file)
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/clk/mmp.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <asm/hardware/cache-tauros2.h>
 
 #include <asm/mach/time.h>
-#include <mach/addr-map.h>
-#include <mach/regs-apbc.h>
-#include <mach/cputype.h>
-#include <mach/irqs.h>
-#include <mach/dma.h>
-#include <mach/mfp.h>
-#include <mach/devices.h>
-#include <mach/mmp2.h>
-#include <mach/pm-mmp2.h>
+#include "addr-map.h"
+#include "regs-apbc.h"
+#include "cputype.h"
+#include "irqs.h"
+#include "mfp.h"
+#include "devices.h"
+#include "mmp2.h"
+#include "pm-mmp2.h"
 
 #include "common.h"
 
@@ -110,8 +110,9 @@ static int __init mmp2_init(void)
 #endif
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(mmp2_addr_map);
-               pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16);
-               mmp2_clk_init();
+               mmp2_clk_init(APB_PHYS_BASE + 0x50000,
+                             AXI_PHYS_BASE + 0x82800,
+                             APB_PHYS_BASE + 0x15000);
        }
 
        return 0;
diff --git a/arch/arm/mach-mmp/mmp2.h b/arch/arm/mach-mmp/mmp2.h
new file mode 100644 (file)
index 0000000..9b5e75e
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef __ASM_MACH_MMP2_H
+#define __ASM_MACH_MMP2_H
+
+#include <linux/platform_data/pxa_sdhci.h>
+
+extern void mmp2_timer_init(void);
+extern void __init mmp2_init_icu(void);
+extern void __init mmp2_init_irq(void);
+extern void mmp2_clear_pmic_int(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/platform_data/dma-mmp_tdma.h>
+
+#include "devices.h"
+
+extern struct pxa_device_desc mmp2_device_uart1;
+extern struct pxa_device_desc mmp2_device_uart2;
+extern struct pxa_device_desc mmp2_device_uart3;
+extern struct pxa_device_desc mmp2_device_uart4;
+extern struct pxa_device_desc mmp2_device_twsi1;
+extern struct pxa_device_desc mmp2_device_twsi2;
+extern struct pxa_device_desc mmp2_device_twsi3;
+extern struct pxa_device_desc mmp2_device_twsi4;
+extern struct pxa_device_desc mmp2_device_twsi5;
+extern struct pxa_device_desc mmp2_device_twsi6;
+extern struct pxa_device_desc mmp2_device_sdh0;
+extern struct pxa_device_desc mmp2_device_sdh1;
+extern struct pxa_device_desc mmp2_device_sdh2;
+extern struct pxa_device_desc mmp2_device_sdh3;
+extern struct pxa_device_desc mmp2_device_asram;
+extern struct pxa_device_desc mmp2_device_isram;
+
+extern struct platform_device mmp2_device_gpio;
+
+static inline int mmp2_add_uart(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &mmp2_device_uart1; break;
+       case 2: d = &mmp2_device_uart2; break;
+       case 3: d = &mmp2_device_uart3; break;
+       case 4: d = &mmp2_device_uart4; break;
+       default:
+               return -EINVAL;
+       }
+
+       return pxa_register_device(d, NULL, 0);
+}
+
+static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
+                                 struct i2c_board_info *info, unsigned size)
+{
+       struct pxa_device_desc *d = NULL;
+       int ret;
+
+       switch (id) {
+       case 1: d = &mmp2_device_twsi1; break;
+       case 2: d = &mmp2_device_twsi2; break;
+       case 3: d = &mmp2_device_twsi3; break;
+       case 4: d = &mmp2_device_twsi4; break;
+       case 5: d = &mmp2_device_twsi5; break;
+       case 6: d = &mmp2_device_twsi6; break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = i2c_register_board_info(id - 1, info, size);
+       if (ret)
+               return ret;
+
+       return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 0: d = &mmp2_device_sdh0; break;
+       case 1: d = &mmp2_device_sdh1; break;
+       case 2: d = &mmp2_device_sdh2; break;
+       case 3: d = &mmp2_device_sdh3; break;
+       default:
+               return -EINVAL;
+       }
+
+       return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int mmp2_add_asram(struct sram_platdata *data)
+{
+       return pxa_register_device(&mmp2_device_asram, data, sizeof(*data));
+}
+
+static inline int mmp2_add_isram(struct sram_platdata *data)
+{
+       return pxa_register_device(&mmp2_device_isram, data, sizeof(*data));
+}
+
+#endif /* __ASM_MACH_MMP2_H */
+
index 43b1a51..17699be 100644 (file)
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/cputype.h>
-#include <mach/addr-map.h>
-#include <mach/pm-mmp2.h>
-#include <mach/regs-icu.h>
-#include <mach/irqs.h>
+
+#include "cputype.h"
+#include "addr-map.h"
+#include "pm-mmp2.h"
+#include "regs-icu.h"
+#include "irqs.h"
 
 int mmp2_set_wake(struct irq_data *d, unsigned int on)
 {
diff --git a/arch/arm/mach-mmp/pm-mmp2.h b/arch/arm/mach-mmp/pm-mmp2.h
new file mode 100644 (file)
index 0000000..486e059
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * MMP2 Power Management Routines
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * (C) Copyright 2010 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#ifndef __MMP2_PM_H__
+#define __MMP2_PM_H__
+
+#include "addr-map.h"
+
+#define APMU_PJ_IDLE_CFG                       APMU_REG(0x018)
+#define APMU_PJ_IDLE_CFG_PJ_IDLE               (1 << 1)
+#define APMU_PJ_IDLE_CFG_PJ_PWRDWN             (1 << 5)
+#define APMU_PJ_IDLE_CFG_PWR_SW(x)             ((x) << 16)
+#define APMU_PJ_IDLE_CFG_L2_PWR_SW             (1 << 19)
+#define APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK   (3 << 28)
+
+#define APMU_SRAM_PWR_DWN                      APMU_REG(0x08c)
+
+#define MPMU_SCCR                              MPMU_REG(0x038)
+#define MPMU_PCR_PJ                            MPMU_REG(0x1000)
+#define MPMU_PCR_PJ_AXISD                      (1 << 31)
+#define MPMU_PCR_PJ_SLPEN                      (1 << 29)
+#define MPMU_PCR_PJ_SPSD                       (1 << 28)
+#define MPMU_PCR_PJ_DDRCORSD                   (1 << 27)
+#define MPMU_PCR_PJ_APBSD                      (1 << 26)
+#define MPMU_PCR_PJ_INTCLR                     (1 << 24)
+#define MPMU_PCR_PJ_SLPWP0                     (1 << 23)
+#define MPMU_PCR_PJ_SLPWP1                     (1 << 22)
+#define MPMU_PCR_PJ_SLPWP2                     (1 << 21)
+#define MPMU_PCR_PJ_SLPWP3                     (1 << 20)
+#define MPMU_PCR_PJ_VCTCXOSD                   (1 << 19)
+#define MPMU_PCR_PJ_SLPWP4                     (1 << 18)
+#define MPMU_PCR_PJ_SLPWP5                     (1 << 17)
+#define MPMU_PCR_PJ_SLPWP6                     (1 << 16)
+#define MPMU_PCR_PJ_SLPWP7                     (1 << 15)
+
+#define MPMU_PLL2_CTRL1                                MPMU_REG(0x0414)
+#define MPMU_CGR_PJ                            MPMU_REG(0x1024)
+#define MPMU_WUCRM_PJ                          MPMU_REG(0x104c)
+#define MPMU_WUCRM_PJ_WAKEUP(x)                        (1 << (x))
+#define MPMU_WUCRM_PJ_RTC_ALARM                        (1 << 17)
+
+enum {
+       POWER_MODE_ACTIVE = 0,
+       POWER_MODE_CORE_INTIDLE,
+       POWER_MODE_CORE_EXTIDLE,
+       POWER_MODE_APPS_IDLE,
+       POWER_MODE_APPS_SLEEP,
+       POWER_MODE_CHIP_SLEEP,
+       POWER_MODE_SYS_SLEEP,
+};
+
+extern void mmp2_pm_enter_lowpower_mode(int state);
+extern int mmp2_set_wake(struct irq_data *d, unsigned int on);
+#endif
index 7db5870..8b47600 100644 (file)
 #include <linux/irq.h>
 #include <asm/mach-types.h>
 #include <asm/outercache.h>
-#include <mach/hardware.h>
-#include <mach/cputype.h>
-#include <mach/addr-map.h>
-#include <mach/pm-pxa910.h>
-#include <mach/regs-icu.h>
-#include <mach/irqs.h>
+
+#include "cputype.h"
+#include "addr-map.h"
+#include "pm-pxa910.h"
+#include "regs-icu.h"
+#include "irqs.h"
 
 int pxa910_set_wake(struct irq_data *data, unsigned int on)
 {
diff --git a/arch/arm/mach-mmp/pm-pxa910.h b/arch/arm/mach-mmp/pm-pxa910.h
new file mode 100644 (file)
index 0000000..8cac8ab
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * PXA910 Power Management Routines
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * (C) Copyright 2009 Marvell International Ltd.
+ * All Rights Reserved
+ */
+
+#ifndef __PXA910_PM_H__
+#define __PXA910_PM_H__
+
+#define APMU_MOH_IDLE_CFG                      APMU_REG(0x0018)
+#define APMU_MOH_IDLE_CFG_MOH_IDLE             (1 << 1)
+#define APMU_MOH_IDLE_CFG_MOH_PWRDWN           (1 << 5)
+#define APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN      (1 << 6)
+#define APMU_MOH_IDLE_CFG_MOH_PWR_SW(x)                (((x) & 0x3) << 16)
+#define APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(x)     (((x) & 0x3) << 18)
+#define APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ    (1 << 21)
+#define APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN       (1 << 20)
+
+#define APMU_SQU_CLK_GATE_CTRL                 APMU_REG(0x001c)
+#define APMU_MC_HW_SLP_TYPE                    APMU_REG(0x00b0)
+
+#define MPMU_FCCR                              MPMU_REG(0x0008)
+#define MPMU_APCR                              MPMU_REG(0x1000)
+#define MPMU_APCR_AXISD                                (1 << 31)
+#define MPMU_APCR_DSPSD                                (1 << 30)
+#define MPMU_APCR_SLPEN                                (1 << 29)
+#define MPMU_APCR_DTCMSD                       (1 << 28)
+#define MPMU_APCR_DDRCORSD                     (1 << 27)
+#define MPMU_APCR_APBSD                                (1 << 26)
+#define MPMU_APCR_BBSD                         (1 << 25)
+#define MPMU_APCR_SLPWP0                       (1 << 23)
+#define MPMU_APCR_SLPWP1                       (1 << 22)
+#define MPMU_APCR_SLPWP2                       (1 << 21)
+#define MPMU_APCR_SLPWP3                       (1 << 20)
+#define MPMU_APCR_VCTCXOSD                     (1 << 19)
+#define MPMU_APCR_SLPWP4                       (1 << 18)
+#define MPMU_APCR_SLPWP5                       (1 << 17)
+#define MPMU_APCR_SLPWP6                       (1 << 16)
+#define MPMU_APCR_SLPWP7                       (1 << 15)
+#define MPMU_APCR_MSASLPEN                     (1 << 14)
+#define MPMU_APCR_STBYEN                       (1 << 13)
+
+#define MPMU_AWUCRM                            MPMU_REG(0x104c)
+#define MPMU_AWUCRM_AP_ASYNC_INT               (1 << 25)
+#define MPMU_AWUCRM_AP_FULL_IDLE               (1 << 24)
+#define MPMU_AWUCRM_SDH1                       (1 << 23)
+#define MPMU_AWUCRM_SDH2                       (1 << 22)
+#define MPMU_AWUCRM_KEYPRESS                   (1 << 21)
+#define MPMU_AWUCRM_TRACKBALL                  (1 << 20)
+#define MPMU_AWUCRM_NEWROTARY                  (1 << 19)
+#define MPMU_AWUCRM_RTC_ALARM                  (1 << 17)
+#define MPMU_AWUCRM_AP2_TIMER_3                        (1 << 13)
+#define MPMU_AWUCRM_AP2_TIMER_2                        (1 << 12)
+#define MPMU_AWUCRM_AP2_TIMER_1                        (1 << 11)
+#define MPMU_AWUCRM_AP1_TIMER_3                        (1 << 10)
+#define MPMU_AWUCRM_AP1_TIMER_2                        (1 << 9)
+#define MPMU_AWUCRM_AP1_TIMER_1                        (1 << 8)
+#define MPMU_AWUCRM_WAKEUP(x)                  (1 << ((x) & 0x7))
+
+enum {
+       POWER_MODE_ACTIVE = 0,
+       POWER_MODE_CORE_INTIDLE,
+       POWER_MODE_CORE_EXTIDLE,
+       POWER_MODE_APPS_IDLE,
+       POWER_MODE_APPS_SLEEP,
+       POWER_MODE_SYS_SLEEP,
+       POWER_MODE_HIBERNATE,
+       POWER_MODE_UDR,
+};
+
+extern int pxa910_set_wake(struct irq_data *data, unsigned int on);
+
+#endif
index 144e997..0f5f16f 100644 (file)
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clk/mmp.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/mv_usb.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
-#include <mach/cputype.h>
-#include <mach/addr-map.h>
-#include <mach/regs-apbc.h>
-#include <mach/regs-apmu.h>
-#include <mach/irqs.h>
-#include <mach/dma.h>
-#include <mach/devices.h>
-#include <mach/mfp.h>
-#include <linux/dma-mapping.h>
-#include <mach/pxa168.h>
-#include <mach/regs-usb.h>
 
-#include "common.h"
+#include "addr-map.h"
 #include "clock.h"
+#include "common.h"
+#include "cputype.h"
+#include "devices.h"
+#include "irqs.h"
+#include "mfp.h"
+#include "pxa168.h"
+#include "regs-apbc.h"
+#include "regs-apmu.h"
+#include "regs-usb.h"
 
 #define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
 
@@ -55,8 +55,9 @@ static int __init pxa168_init(void)
        if (cpu_is_pxa168()) {
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(pxa168_mfp_addr_map);
-               pxa_init_dma(IRQ_PXA168_DMA_INT0, 32);
-               pxa168_clk_init();
+               pxa168_clk_init(APB_PHYS_BASE + 0x50000,
+                               AXI_PHYS_BASE + 0x82800,
+                               APB_PHYS_BASE + 0x15000);
        }
 
        return 0;
diff --git a/arch/arm/mach-mmp/pxa168.h b/arch/arm/mach-mmp/pxa168.h
new file mode 100644 (file)
index 0000000..75841e9
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef __ASM_MACH_PXA168_H
+#define __ASM_MACH_PXA168_H
+
+#include <linux/reboot.h>
+
+extern void pxa168_timer_init(void);
+extern void __init icu_init_irq(void);
+extern void __init pxa168_init_irq(void);
+extern void pxa168_restart(enum reboot_mode, const char *);
+extern void pxa168_clear_keypad_wakeup(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <video/pxa168fb.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/pxa168_eth.h>
+#include <linux/platform_data/mv_usb.h>
+
+#include "devices.h"
+#include "cputype.h"
+
+extern struct pxa_device_desc pxa168_device_uart1;
+extern struct pxa_device_desc pxa168_device_uart2;
+extern struct pxa_device_desc pxa168_device_uart3;
+extern struct pxa_device_desc pxa168_device_twsi0;
+extern struct pxa_device_desc pxa168_device_twsi1;
+extern struct pxa_device_desc pxa168_device_pwm1;
+extern struct pxa_device_desc pxa168_device_pwm2;
+extern struct pxa_device_desc pxa168_device_pwm3;
+extern struct pxa_device_desc pxa168_device_pwm4;
+extern struct pxa_device_desc pxa168_device_ssp1;
+extern struct pxa_device_desc pxa168_device_ssp2;
+extern struct pxa_device_desc pxa168_device_ssp3;
+extern struct pxa_device_desc pxa168_device_ssp4;
+extern struct pxa_device_desc pxa168_device_ssp5;
+extern struct pxa_device_desc pxa168_device_nand;
+extern struct pxa_device_desc pxa168_device_fb;
+extern struct pxa_device_desc pxa168_device_keypad;
+extern struct pxa_device_desc pxa168_device_eth;
+
+/* pdata can be NULL */
+extern int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata);
+
+
+extern struct platform_device pxa168_device_gpio;
+
+static inline int pxa168_add_uart(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &pxa168_device_uart1; break;
+       case 2: d = &pxa168_device_uart2; break;
+       case 3: d = &pxa168_device_uart3; break;
+       }
+
+       if (d == NULL)
+               return -EINVAL;
+
+       return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data,
+                                 struct i2c_board_info *info, unsigned size)
+{
+       struct pxa_device_desc *d = NULL;
+       int ret;
+
+       switch (id) {
+       case 0: d = &pxa168_device_twsi0; break;
+       case 1: d = &pxa168_device_twsi1; break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = i2c_register_board_info(id, info, size);
+       if (ret)
+               return ret;
+
+       return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int pxa168_add_pwm(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &pxa168_device_pwm1; break;
+       case 2: d = &pxa168_device_pwm2; break;
+       case 3: d = &pxa168_device_pwm3; break;
+       case 4: d = &pxa168_device_pwm4; break;
+       default:
+               return -EINVAL;
+       }
+
+       return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa168_add_ssp(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &pxa168_device_ssp1; break;
+       case 2: d = &pxa168_device_ssp2; break;
+       case 3: d = &pxa168_device_ssp3; break;
+       case 4: d = &pxa168_device_ssp4; break;
+       case 5: d = &pxa168_device_ssp5; break;
+       default:
+               return -EINVAL;
+       }
+       return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
+{
+       return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
+}
+
+static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi)
+{
+       return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi));
+}
+
+static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
+{
+       if (cpu_is_pxa168())
+               data->clear_wakeup_event = pxa168_clear_keypad_wakeup;
+
+       return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
+}
+
+static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data)
+{
+       return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
+}
+#endif /* __ASM_MACH_PXA168_H */
index eb57ee1..1ccbba9 100644 (file)
@@ -7,6 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/clk/mmp.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 
 #include <asm/hardware/cache-tauros2.h>
 #include <asm/mach/time.h>
-#include <mach/addr-map.h>
-#include <mach/regs-apbc.h>
-#include <mach/cputype.h>
-#include <mach/irqs.h>
-#include <mach/dma.h>
-#include <mach/mfp.h>
-#include <mach/devices.h>
-#include <mach/pm-pxa910.h>
-#include <mach/pxa910.h>
+#include "addr-map.h"
+#include "regs-apbc.h"
+#include "cputype.h"
+#include "irqs.h"
+#include "mfp.h"
+#include "devices.h"
+#include "pm-pxa910.h"
+#include "pxa910.h"
 
 #include "common.h"
 
@@ -96,8 +96,10 @@ static int __init pxa910_init(void)
 #endif
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(pxa910_mfp_addr_map);
-               pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
-               pxa910_clk_init();
+               pxa910_clk_init(APB_PHYS_BASE + 0x50000,
+                               AXI_PHYS_BASE + 0x82800,
+                               APB_PHYS_BASE + 0x15000,
+                               APB_PHYS_BASE + 0x3b000);
        }
 
        return 0;
diff --git a/arch/arm/mach-mmp/pxa910.h b/arch/arm/mach-mmp/pxa910.h
new file mode 100644 (file)
index 0000000..a211e81
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef __ASM_MACH_PXA910_H
+#define __ASM_MACH_PXA910_H
+
+extern void pxa910_timer_init(void);
+extern void __init icu_init_irq(void);
+extern void __init pxa910_init_irq(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <video/mmp_disp.h>
+
+#include "devices.h"
+
+extern struct pxa_device_desc pxa910_device_uart1;
+extern struct pxa_device_desc pxa910_device_uart2;
+extern struct pxa_device_desc pxa910_device_twsi0;
+extern struct pxa_device_desc pxa910_device_twsi1;
+extern struct pxa_device_desc pxa910_device_pwm1;
+extern struct pxa_device_desc pxa910_device_pwm2;
+extern struct pxa_device_desc pxa910_device_pwm3;
+extern struct pxa_device_desc pxa910_device_pwm4;
+extern struct pxa_device_desc pxa910_device_nand;
+extern struct platform_device pxa168_device_u2o;
+extern struct platform_device pxa168_device_u2ootg;
+extern struct platform_device pxa168_device_u2oehci;
+extern struct pxa_device_desc pxa910_device_disp;
+extern struct pxa_device_desc pxa910_device_fb;
+extern struct pxa_device_desc pxa910_device_panel;
+extern struct platform_device pxa910_device_gpio;
+extern struct platform_device pxa910_device_rtc;
+
+static inline int pxa910_add_uart(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &pxa910_device_uart1; break;
+       case 2: d = &pxa910_device_uart2; break;
+       }
+
+       if (d == NULL)
+               return -EINVAL;
+
+       return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data,
+                                 struct i2c_board_info *info, unsigned size)
+{
+       struct pxa_device_desc *d = NULL;
+       int ret;
+
+       switch (id) {
+       case 0: d = &pxa910_device_twsi0; break;
+       case 1: d = &pxa910_device_twsi1; break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = i2c_register_board_info(id, info, size);
+       if (ret)
+               return ret;
+
+       return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int pxa910_add_pwm(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &pxa910_device_pwm1; break;
+       case 2: d = &pxa910_device_pwm2; break;
+       case 3: d = &pxa910_device_pwm3; break;
+       case 4: d = &pxa910_device_pwm4; break;
+       default:
+               return -EINVAL;
+       }
+
+       return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa910_add_nand(struct pxa3xx_nand_platform_data *info)
+{
+       return pxa_register_device(&pxa910_device_nand, info, sizeof(*info));
+}
+#endif /* __ASM_MACH_PXA910_H */
diff --git a/arch/arm/mach-mmp/regs-apbc.h b/arch/arm/mach-mmp/regs-apbc.h
new file mode 100644 (file)
index 0000000..704bcae
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *   Application Peripheral Bus Clock Unit
+ *
+ * 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_MACH_REGS_APBC_H
+#define __ASM_MACH_REGS_APBC_H
+
+#include "addr-map.h"
+
+/* Common APB clock register bit definitions */
+#define APBC_APBCLK    (1 << 0)  /* APB Bus Clock Enable */
+#define APBC_FNCLK     (1 << 1)  /* Functional Clock Enable */
+#define APBC_RST       (1 << 2)  /* Reset Generation */
+
+/* Functional Clock Selection Mask */
+#define APBC_FNCLKSEL(x)       (((x) & 0xf) << 4)
+
+#endif /* __ASM_MACH_REGS_APBC_H */
diff --git a/arch/arm/mach-mmp/regs-apmu.h b/arch/arm/mach-mmp/regs-apmu.h
new file mode 100644 (file)
index 0000000..23f6209
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *   Application Subsystem Power Management Unit
+ *
+ * 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_MACH_REGS_APMU_H
+#define __ASM_MACH_REGS_APMU_H
+
+#include "addr-map.h"
+
+#define APMU_FNCLK_EN  (1 << 4)
+#define APMU_AXICLK_EN (1 << 3)
+#define APMU_FNRST_DIS (1 << 1)
+#define APMU_AXIRST_DIS        (1 << 0)
+
+/* Wake Clear Register */
+#define APMU_WAKE_CLR  APMU_REG(0x07c)
+
+#define APMU_PXA168_KP_WAKE_CLR                (1 << 7)
+#define APMU_PXA168_CFI_WAKE_CLR       (1 << 6)
+#define APMU_PXA168_XD_WAKE_CLR                (1 << 5)
+#define APMU_PXA168_MSP_WAKE_CLR       (1 << 4)
+#define APMU_PXA168_SD4_WAKE_CLR       (1 << 3)
+#define APMU_PXA168_SD3_WAKE_CLR       (1 << 2)
+#define APMU_PXA168_SD2_WAKE_CLR       (1 << 1)
+#define APMU_PXA168_SD1_WAKE_CLR       (1 << 0)
+
+#endif /* __ASM_MACH_REGS_APMU_H */
diff --git a/arch/arm/mach-mmp/regs-icu.h b/arch/arm/mach-mmp/regs-icu.h
new file mode 100644 (file)
index 0000000..0328abe
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *   Interrupt Control Unit
+ *
+ * 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_MACH_ICU_H
+#define __ASM_MACH_ICU_H
+
+#include "addr-map.h"
+
+#define ICU_VIRT_BASE  (AXI_VIRT_BASE + 0x82000)
+#define ICU_REG(x)     (ICU_VIRT_BASE + (x))
+
+#define ICU_INT_CONF(n)                ICU_REG((n) << 2)
+#define ICU_INT_CONF_MASK      (0xf)
+
+/************ PXA168/PXA910 (MMP) *********************/
+#define ICU_INT_CONF_AP_INT    (1 << 6)
+#define ICU_INT_CONF_CP_INT    (1 << 5)
+#define ICU_INT_CONF_IRQ       (1 << 4)
+
+#define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108)  /* AP FIQ Selected Interrupt */
+#define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C)  /* AP IRQ Selected Interrupt */
+#define ICU_AP_GBL_IRQ_MSK     ICU_REG(0x114)  /* AP Global Interrupt Mask */
+#define ICU_INT_STATUS_0       ICU_REG(0x128)  /* Interrupt Stuats 0 */
+#define ICU_INT_STATUS_1       ICU_REG(0x12C)  /* Interrupt Status 1 */
+
+/************************** MMP2 ***********************/
+
+/*
+ * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
+ * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
+ */
+#define ICU_INT_ROUTE_SP_IRQ           (1 << 4)
+#define ICU_INT_ROUTE_PJ4_IRQ          (1 << 5)
+#define ICU_INT_ROUTE_PJ4_FIQ          (1 << 6)
+
+#define MMP2_ICU_PJ4_IRQ_STATUS0       ICU_REG(0x138)
+#define MMP2_ICU_PJ4_IRQ_STATUS1       ICU_REG(0x13c)
+#define MMP2_ICU_PJ4_FIQ_STATUS0       ICU_REG(0x140)
+#define MMP2_ICU_PJ4_FIQ_STATUS1       ICU_REG(0x144)
+
+#define MMP2_ICU_INT4_STATUS           ICU_REG(0x150)
+#define MMP2_ICU_INT5_STATUS           ICU_REG(0x154)
+#define MMP2_ICU_INT17_STATUS          ICU_REG(0x158)
+#define MMP2_ICU_INT35_STATUS          ICU_REG(0x15c)
+#define MMP2_ICU_INT51_STATUS          ICU_REG(0x160)
+
+#define MMP2_ICU_INT4_MASK             ICU_REG(0x168)
+#define MMP2_ICU_INT5_MASK             ICU_REG(0x16C)
+#define MMP2_ICU_INT17_MASK            ICU_REG(0x170)
+#define MMP2_ICU_INT35_MASK            ICU_REG(0x174)
+#define MMP2_ICU_INT51_MASK            ICU_REG(0x178)
+
+#define MMP2_ICU_SP_IRQ_SEL            ICU_REG(0x100)
+#define MMP2_ICU_PJ4_IRQ_SEL           ICU_REG(0x104)
+#define MMP2_ICU_PJ4_FIQ_SEL           ICU_REG(0x108)
+
+#define MMP2_ICU_INVERT                        ICU_REG(0x164)
+
+#define MMP2_ICU_INV_PMIC              (1 << 0)
+#define MMP2_ICU_INV_PERF              (1 << 1)
+#define MMP2_ICU_INV_COMMTX            (1 << 2)
+#define MMP2_ICU_INV_COMMRX            (1 << 3)
+
+#endif /* __ASM_MACH_ICU_H */
diff --git a/arch/arm/mach-mmp/regs-timers.h b/arch/arm/mach-mmp/regs-timers.h
new file mode 100644 (file)
index 0000000..d3611c0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *   Timers Module
+ *
+ * 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_MACH_REGS_TIMERS_H
+#define __ASM_MACH_REGS_TIMERS_H
+
+#include "addr-map.h"
+
+#define TIMERS1_VIRT_BASE      (APB_VIRT_BASE + 0x14000)
+#define TIMERS2_VIRT_BASE      (APB_VIRT_BASE + 0x16000)
+
+#define TMR_CCR                (0x0000)
+#define TMR_TN_MM(n, m)        (0x0004 + ((n) << 3) + (((n) + (m)) << 2))
+#define TMR_CR(n)      (0x0028 + ((n) << 2))
+#define TMR_SR(n)      (0x0034 + ((n) << 2))
+#define TMR_IER(n)     (0x0040 + ((n) << 2))
+#define TMR_PLVR(n)    (0x004c + ((n) << 2))
+#define TMR_PLCR(n)    (0x0058 + ((n) << 2))
+#define TMR_WMER       (0x0064)
+#define TMR_WMR                (0x0068)
+#define TMR_WVR                (0x006c)
+#define TMR_WSR                (0x0070)
+#define TMR_ICR(n)     (0x0074 + ((n) << 2))
+#define TMR_WICR       (0x0080)
+#define TMR_CER                (0x0084)
+#define TMR_CMR                (0x0088)
+#define TMR_ILR(n)     (0x008c + ((n) << 2))
+#define TMR_WCR                (0x0098)
+#define TMR_WFAR       (0x009c)
+#define TMR_WSAR       (0x00A0)
+#define TMR_CVWR(n)    (0x00A4 + ((n) << 2))
+
+#define TMR_CCR_CS_0(x)        (((x) & 0x3) << 0)
+#define TMR_CCR_CS_1(x)        (((x) & 0x7) << 2)
+#define TMR_CCR_CS_2(x)        (((x) & 0x3) << 5)
+
+#endif /* __ASM_MACH_REGS_TIMERS_H */
diff --git a/arch/arm/mach-mmp/regs-usb.h b/arch/arm/mach-mmp/regs-usb.h
new file mode 100644 (file)
index 0000000..b047bf4
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_H
+#define __ASM_ARCH_REGS_USB_H
+
+#define PXA168_U2O_REGBASE     (0xd4208000)
+#define PXA168_U2O_PHYBASE     (0xd4207000)
+
+#define PXA168_U2H_REGBASE      (0xd4209000)
+#define PXA168_U2H_PHYBASE      (0xd4206000)
+
+#define MMP3_HSIC1_REGBASE     (0xf0001000)
+#define MMP3_HSIC1_PHYBASE     (0xf0001800)
+
+#define MMP3_HSIC2_REGBASE     (0xf0002000)
+#define MMP3_HSIC2_PHYBASE     (0xf0002800)
+
+#define MMP3_FSIC_REGBASE      (0xf0003000)
+#define MMP3_FSIC_PHYBASE      (0xf0003800)
+
+
+#define USB_REG_RANGE          (0x1ff)
+#define USB_PHY_RANGE          (0xff)
+
+/* registers */
+#define U2x_CAPREGS_OFFSET       0x100
+
+/* phy regs */
+#define UTMI_REVISION          0x0
+#define UTMI_CTRL              0x4
+#define UTMI_PLL               0x8
+#define UTMI_TX                        0xc
+#define UTMI_RX                        0x10
+#define UTMI_IVREF             0x14
+#define UTMI_T0                        0x18
+#define UTMI_T1                        0x1c
+#define UTMI_T2                        0x20
+#define UTMI_T3                        0x24
+#define UTMI_T4                        0x28
+#define UTMI_T5                        0x2c
+#define UTMI_RESERVE           0x30
+#define UTMI_USB_INT           0x34
+#define UTMI_DBG_CTL           0x38
+#define UTMI_OTG_ADDON         0x3c
+
+/* For UTMICTRL Register */
+#define UTMI_CTRL_USB_CLK_EN                    (1 << 31)
+/* pxa168 */
+#define UTMI_CTRL_SUSPEND_SET1                  (1 << 30)
+#define UTMI_CTRL_SUSPEND_SET2                  (1 << 29)
+#define UTMI_CTRL_RXBUF_PDWN                    (1 << 24)
+#define UTMI_CTRL_TXBUF_PDWN                    (1 << 11)
+
+#define UTMI_CTRL_INPKT_DELAY_SHIFT             30
+#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT                28
+#define UTMI_CTRL_PU_REF_SHIFT                 20
+#define UTMI_CTRL_ARC_PULLDN_SHIFT              12
+#define UTMI_CTRL_PLL_PWR_UP_SHIFT              1
+#define UTMI_CTRL_PWR_UP_SHIFT                  0
+
+/* For UTMI_PLL Register */
+#define UTMI_PLL_PLLCALI12_SHIFT               29
+#define UTMI_PLL_PLLCALI12_MASK                        (0x3 << 29)
+
+#define UTMI_PLL_PLLVDD18_SHIFT                        27
+#define UTMI_PLL_PLLVDD18_MASK                 (0x3 << 27)
+
+#define UTMI_PLL_PLLVDD12_SHIFT                        25
+#define UTMI_PLL_PLLVDD12_MASK                 (0x3 << 25)
+
+#define UTMI_PLL_CLK_BLK_EN_SHIFT               24
+#define CLK_BLK_EN                              (0x1 << 24)
+#define PLL_READY                               (0x1 << 23)
+#define KVCO_EXT                                (0x1 << 22)
+#define VCOCAL_START                            (0x1 << 21)
+
+#define UTMI_PLL_KVCO_SHIFT                    15
+#define UTMI_PLL_KVCO_MASK                      (0x7 << 15)
+
+#define UTMI_PLL_ICP_SHIFT                     12
+#define UTMI_PLL_ICP_MASK                       (0x7 << 12)
+
+#define UTMI_PLL_FBDIV_SHIFT                    4
+#define UTMI_PLL_FBDIV_MASK                     (0xFF << 4)
+
+#define UTMI_PLL_REFDIV_SHIFT                   0
+#define UTMI_PLL_REFDIV_MASK                    (0xF << 0)
+
+/* For UTMI_TX Register */
+#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT          27
+#define UTMI_TX_REG_EXT_FS_RCAL_MASK           (0xf << 27)
+
+#define UTMI_TX_REG_EXT_FS_RCAL_EN_SHIFT       26
+#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK                (0x1 << 26)
+
+#define UTMI_TX_TXVDD12_SHIFT                   22
+#define UTMI_TX_TXVDD12_MASK                    (0x3 << 22)
+
+#define UTMI_TX_CK60_PHSEL_SHIFT                17
+#define UTMI_TX_CK60_PHSEL_MASK                 (0xf << 17)
+
+#define UTMI_TX_IMPCAL_VTH_SHIFT                14
+#define UTMI_TX_IMPCAL_VTH_MASK                 (0x7 << 14)
+
+#define REG_RCAL_START                          (0x1 << 12)
+
+#define UTMI_TX_LOW_VDD_EN_SHIFT                11
+
+#define UTMI_TX_AMP_SHIFT                      0
+#define UTMI_TX_AMP_MASK                       (0x7 << 0)
+
+/* For UTMI_RX Register */
+#define UTMI_REG_SQ_LENGTH_SHIFT                15
+#define UTMI_REG_SQ_LENGTH_MASK                 (0x3 << 15)
+
+#define UTMI_RX_SQ_THRESH_SHIFT                 4
+#define UTMI_RX_SQ_THRESH_MASK                  (0xf << 4)
+
+#define UTMI_OTG_ADDON_OTG_ON                  (1 << 0)
+
+/* For MMP3 USB Phy */
+#define USB2_PLL_REG0          0x4
+#define USB2_PLL_REG1          0x8
+#define USB2_TX_REG0           0x10
+#define USB2_TX_REG1           0x14
+#define USB2_TX_REG2           0x18
+#define USB2_RX_REG0           0x20
+#define USB2_RX_REG1           0x24
+#define USB2_RX_REG2           0x28
+#define USB2_ANA_REG0          0x30
+#define USB2_ANA_REG1          0x34
+#define USB2_ANA_REG2          0x38
+#define USB2_DIG_REG0          0x3C
+#define USB2_DIG_REG1          0x40
+#define USB2_DIG_REG2          0x44
+#define USB2_DIG_REG3          0x48
+#define USB2_TEST_REG0         0x4C
+#define USB2_TEST_REG1         0x50
+#define USB2_TEST_REG2         0x54
+#define USB2_CHARGER_REG0      0x58
+#define USB2_OTG_REG0          0x5C
+#define USB2_PHY_MON0          0x60
+#define USB2_RESETVE_REG0      0x64
+#define USB2_ICID_REG0         0x78
+#define USB2_ICID_REG1         0x7C
+
+/* USB2_PLL_REG0 */
+/* This is for Ax stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3              0
+#define USB2_PLL_FBDIV_MASK_MMP3               (0xFF << 0)
+
+#define USB2_PLL_REFDIV_SHIFT_MMP3             8
+#define USB2_PLL_REFDIV_MASK_MMP3              (0xF << 8)
+
+#define USB2_PLL_VDD12_SHIFT_MMP3              12
+#define USB2_PLL_VDD18_SHIFT_MMP3              14
+
+/* This is for B0 stepping */
+#define USB2_PLL_FBDIV_SHIFT_MMP3_B0           0
+#define USB2_PLL_REFDIV_SHIFT_MMP3_B0          9
+#define USB2_PLL_VDD18_SHIFT_MMP3_B0           14
+#define USB2_PLL_FBDIV_MASK_MMP3_B0            0x01FF
+#define USB2_PLL_REFDIV_MASK_MMP3_B0           0x3E00
+
+#define USB2_PLL_CAL12_SHIFT_MMP3              0
+#define USB2_PLL_CALI12_MASK_MMP3              (0x3 << 0)
+
+#define USB2_PLL_VCOCAL_START_SHIFT_MMP3       2
+
+#define USB2_PLL_KVCO_SHIFT_MMP3               4
+#define USB2_PLL_KVCO_MASK_MMP3                        (0x7<<4)
+
+#define USB2_PLL_ICP_SHIFT_MMP3                        8
+#define USB2_PLL_ICP_MASK_MMP3                 (0x7<<8)
+
+#define USB2_PLL_LOCK_BYPASS_SHIFT_MMP3                12
+
+#define USB2_PLL_PU_PLL_SHIFT_MMP3             13
+#define USB2_PLL_PU_PLL_MASK                   (0x1 << 13)
+
+#define USB2_PLL_READY_MASK_MMP3               (0x1 << 15)
+
+/* USB2_TX_REG0 */
+#define USB2_TX_IMPCAL_VTH_SHIFT_MMP3          8
+#define USB2_TX_IMPCAL_VTH_MASK_MMP3           (0x7 << 8)
+
+#define USB2_TX_RCAL_START_SHIFT_MMP3          13
+
+/* USB2_TX_REG1 */
+#define USB2_TX_CK60_PHSEL_SHIFT_MMP3          0
+#define USB2_TX_CK60_PHSEL_MASK_MMP3           (0xf << 0)
+
+#define USB2_TX_AMP_SHIFT_MMP3                 4
+#define USB2_TX_AMP_MASK_MMP3                  (0x7 << 4)
+
+#define USB2_TX_VDD12_SHIFT_MMP3               8
+#define USB2_TX_VDD12_MASK_MMP3                        (0x3 << 8)
+
+/* USB2_TX_REG2 */
+#define USB2_TX_DRV_SLEWRATE_SHIFT             10
+
+/* USB2_RX_REG0 */
+#define USB2_RX_SQ_THRESH_SHIFT_MMP3           4
+#define USB2_RX_SQ_THRESH_MASK_MMP3            (0xf << 4)
+
+#define USB2_RX_SQ_LENGTH_SHIFT_MMP3           10
+#define USB2_RX_SQ_LENGTH_MASK_MMP3            (0x3 << 10)
+
+/* USB2_ANA_REG1*/
+#define USB2_ANA_PU_ANA_SHIFT_MMP3             14
+
+/* USB2_OTG_REG0 */
+#define USB2_OTG_PU_OTG_SHIFT_MMP3             3
+
+/* fsic registers */
+#define FSIC_MISC                      0x4
+#define FSIC_INT                       0x28
+#define FSIC_CTRL                      0x30
+
+/* HSIC registers */
+#define HSIC_PAD_CTRL                  0x4
+
+#define HSIC_CTRL                      0x8
+#define HSIC_CTRL_HSIC_ENABLE          (1<<7)
+#define HSIC_CTRL_PLL_BYPASS           (1<<4)
+
+#define TEST_GRP_0                     0xc
+#define TEST_GRP_1                     0x10
+
+#define HSIC_INT                       0x14
+#define HSIC_INT_READY_INT_EN          (1<<10)
+#define HSIC_INT_CONNECT_INT_EN                (1<<9)
+#define HSIC_INT_CORE_INT_EN           (1<<8)
+#define HSIC_INT_HS_READY              (1<<2)
+#define HSIC_INT_CONNECT               (1<<1)
+#define HSIC_INT_CORE                  (1<<0)
+
+#define HSIC_CONFIG                    0x18
+#define USBHSIC_CTRL                   0x20
+
+#define HSIC_USB_CTRL                  0x28
+#define HSIC_USB_CTRL_CLKEN            1
+#define        HSIC_USB_CLK_PHY                0x0
+#define HSIC_USB_CLK_PMU               0x1
+
+#endif /* __ASM_ARCH_PXA_U2O_H */
index cdfc9bf..efe35fa 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-pxa910.h>
-#include <mach/pxa910.h>
-#include <mach/irqs.h>
+#include "addr-map.h"
+#include "mfp-pxa910.h"
+#include "pxa910.h"
+#include "irqs.h"
 
 #include "common.h"
 
index 6aa53fb..cf038eb 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-pxa168.h>
-#include <mach/pxa168.h>
-#include <mach/teton_bga.h>
-#include <mach/irqs.h>
+#include "addr-map.h"
+#include "mfp-pxa168.h"
+#include "pxa168.h"
+#include "teton_bga.h"
+#include "irqs.h"
 
 #include "common.h"
 
diff --git a/arch/arm/mach-mmp/teton_bga.h b/arch/arm/mach-mmp/teton_bga.h
new file mode 100644 (file)
index 0000000..019730f
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ *  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
+ *  publishhed by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_TETON_BGA_H
+#define __ASM_MACH_TETON_BGA_H
+
+/* GPIOs */
+#define MMC_PWENA_GPIO         27
+#define USBHPENB_GPIO          55
+#define RTC_INT_GPIO           78
+#define LCD_VBLK_EN_GPIO       79
+#define LCD_DVDD_EN_GPIO       80
+#define RST_WIFI_GPIO          81
+#define CF_PWEN_GPIO           82
+#define USB_OC_GPIO            83
+#define PWM_GPIO               84
+#define USBHPENA_GPIO          85
+#define TS_INT_GPIO            86
+#define CIR_GPIO               108
+
+#endif /* __ASM_MACH_TETON_BGA_H */
index dbc697b..3c2c92a 100644 (file)
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/sched_clock.h>
-
-#include <mach/addr-map.h>
-#include <mach/regs-timers.h>
-#include <mach/regs-apbc.h>
-#include <mach/irqs.h>
-#include <mach/cputype.h>
 #include <asm/mach/time.h>
 
+#include "addr-map.h"
+#include "regs-timers.h"
+#include "regs-apbc.h"
+#include "irqs.h"
+#include "cputype.h"
 #include "clock.h"
 
 #ifdef CONFIG_CPU_MMP2
index ac4af81..d90c74f 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <mach/addr-map.h>
-#include <mach/mfp-pxa910.h>
-#include <mach/pxa910.h>
-#include <mach/irqs.h>
-#include <mach/regs-usb.h>
+#include "addr-map.h"
+#include "mfp-pxa910.h"
+#include "pxa910.h"
+#include "irqs.h"
+#include "regs-usb.h"
 
 #include "common.h"
 
index f49328c..180d9d2 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_MOXART
-       bool "MOXA ART SoC" if ARCH_MULTI_V4
+       bool "MOXA ART SoC"
+       depends on ARCH_MULTI_V4
        select CPU_FA526
        select ARM_DMA_MEM_BUFFERABLE
        select CLKSRC_MMIO
index f2d309d..a32575f 100644 (file)
@@ -1,6 +1,15 @@
-if ARCH_MV78XX0
+menuconfig ARCH_MV78XX0
+       bool "Marvell MV78xx0" if ARCH_MULTI_V5
+       select ARCH_REQUIRE_GPIOLIB
+       select CPU_FEROCEON
+       select MVEBU_MBUS
+       select PCI
+       select PLAT_ORION_LEGACY
+       help
+         Support for the following Marvell MV78xx0 series SoCs:
+         MV781x0, MV782x0.
 
-menu "Marvell MV78xx0 Implementations"
+if ARCH_MV78XX0
 
 config MACH_DB78X00_BP
        bool "Marvell DB-78x00-BP Development Board"
@@ -20,6 +29,4 @@ config MACH_TERASTATION_WXL
          Say 'Y' here if you want your kernel to support the
          Buffalo WXL Nas.
 
-endmenu
-
 endif
index 7cd0463..ddb3aa9 100644 (file)
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include
+
 obj-y                          += common.o mpp.o irq.o pcie.o
 obj-$(CONFIG_MACH_DB78X00_BP)  += db78x00-bp-setup.o
 obj-$(CONFIG_MACH_RD78X00_MASA)        += rd78x00-masa-setup.o
diff --git a/arch/arm/mach-mv78xx0/bridge-regs.h b/arch/arm/mach-mv78xx0/bridge-regs.h
new file mode 100644 (file)
index 0000000..2f54e17
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include "mv78xx0.h"
+
+#define CPU_CONTROL            (BRIDGE_VIRT_BASE + 0x0104)
+#define L2_WRITETHROUGH                0x00020000
+
+#define RSTOUTn_MASK           (BRIDGE_VIRT_BASE + 0x0108)
+#define RSTOUTn_MASK_PHYS      (BRIDGE_PHYS_BASE + 0x0108)
+#define SOFT_RESET_OUT_EN      0x00000004
+
+#define SYSTEM_SOFT_RESET      (BRIDGE_VIRT_BASE + 0x010c)
+#define SOFT_RESET             0x00000001
+
+#define BRIDGE_INT_TIMER1_CLR  (~0x0004)
+
+#define IRQ_VIRT_BASE          (BRIDGE_VIRT_BASE + 0x0200)
+#define IRQ_CAUSE_ERR_OFF      0x0000
+#define IRQ_CAUSE_LOW_OFF      0x0004
+#define IRQ_CAUSE_HIGH_OFF     0x0008
+#define IRQ_MASK_ERR_OFF       0x000c
+#define IRQ_MASK_LOW_OFF       0x0010
+#define IRQ_MASK_HIGH_OFF      0x0014
+
+#define TIMER_VIRT_BASE                (BRIDGE_VIRT_BASE + 0x0300)
+#define TIMER_PHYS_BASE                (BRIDGE_PHYS_BASE + 0x0300)
+
+#endif
index 1f2ef98..e112f2e 100644 (file)
@@ -17,9 +17,9 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
 #include <linux/i2c.h>
-#include <mach/mv78xx0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include "mv78xx0.h"
 #include "common.h"
 #include "mpp.h"
 
@@ -146,6 +146,7 @@ subsys_initcall(wxl_pci_init);
 MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
        /* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
        .atag_offset    = 0x100,
+       .nr_irqs        = MV78XX0_NR_IRQS,
        .init_machine   = wxl_init,
        .map_io         = mv78xx0_map_io,
        .init_early     = mv78xx0_init_early,
index e6ac679..a1a04df 100644 (file)
 #include <asm/hardware/cache-feroceon-l2.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <mach/mv78xx0.h>
-#include <mach/bridge-regs.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 #include <plat/time.h>
 #include <plat/common.h>
 #include <plat/addr-map.h>
+#include "mv78xx0.h"
+#include "bridge-regs.h"
 #include "common.h"
 
 static int get_tclk(void);
index 4e0f22b..cf16e08 100644 (file)
@@ -15,9 +15,9 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
 #include <linux/i2c.h>
-#include <mach/mv78xx0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include "mv78xx0.h"
 #include "common.h"
 
 static struct mv643xx_eth_platform_data db78x00_ge00_data = {
@@ -94,6 +94,7 @@ subsys_initcall(db78x00_pci_init);
 MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")
        /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = MV78XX0_NR_IRQS,
        .init_machine   = db78x00_init,
        .map_io         = mv78xx0_map_io,
        .init_early     = mv78xx0_init_early,
diff --git a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
deleted file mode 100644 (file)
index e20d6da..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
- *
- * 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 __ASM_ARCH_BRIDGE_REGS_H
-#define __ASM_ARCH_BRIDGE_REGS_H
-
-#include <mach/mv78xx0.h>
-
-#define CPU_CONTROL            (BRIDGE_VIRT_BASE + 0x0104)
-#define L2_WRITETHROUGH                0x00020000
-
-#define RSTOUTn_MASK           (BRIDGE_VIRT_BASE + 0x0108)
-#define RSTOUTn_MASK_PHYS      (BRIDGE_PHYS_BASE + 0x0108)
-#define SOFT_RESET_OUT_EN      0x00000004
-
-#define SYSTEM_SOFT_RESET      (BRIDGE_VIRT_BASE + 0x010c)
-#define SOFT_RESET             0x00000001
-
-#define BRIDGE_INT_TIMER1_CLR  (~0x0004)
-
-#define IRQ_VIRT_BASE          (BRIDGE_VIRT_BASE + 0x0200)
-#define IRQ_CAUSE_ERR_OFF      0x0000
-#define IRQ_CAUSE_LOW_OFF      0x0004
-#define IRQ_CAUSE_HIGH_OFF     0x0008
-#define IRQ_MASK_ERR_OFF       0x000c
-#define IRQ_MASK_LOW_OFF       0x0010
-#define IRQ_MASK_HIGH_OFF      0x0014
-
-#define TIMER_VIRT_BASE                (BRIDGE_VIRT_BASE + 0x0300)
-#define TIMER_PHYS_BASE                (BRIDGE_PHYS_BASE + 0x0300)
-
-#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 6b1f088..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for Marvell MV78xx0 platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <mach/bridge-regs.h>
-
-       .macro  get_irqnr_preamble, base, tmp
-       ldr     \base, =IRQ_VIRT_BASE
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       @ check low interrupts
-       ldr     \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
-       ldr     \tmp, [\base, #IRQ_MASK_LOW_OFF]
-       mov     \irqnr, #31
-       ands    \irqstat, \irqstat, \tmp
-       bne     1001f
-
-       @ if no low interrupts set, check high interrupts
-       ldr     \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
-       ldr     \tmp, [\base, #IRQ_MASK_HIGH_OFF]
-       mov     \irqnr, #63
-       ands    \irqstat, \irqstat, \tmp
-       bne     1001f
-
-       @ if no high interrupts set, check error interrupts
-       ldr     \irqstat, [\base, #IRQ_CAUSE_ERR_OFF]
-       ldr     \tmp, [\base, #IRQ_MASK_ERR_OFF]
-       mov     \irqnr, #95
-       ands    \irqstat, \irqstat, \tmp
-
-       @ find first active interrupt source
-1001:  clzne   \irqstat, \irqstat
-       subne   \irqnr, \irqnr, \irqstat
-       .endm
diff --git a/arch/arm/mach-mv78xx0/include/mach/hardware.h b/arch/arm/mach-mv78xx0/include/mach/hardware.h
deleted file mode 100644 (file)
index 67cab0a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/hardware.h
- *
- * 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 __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include "mv78xx0.h"
-
-#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/irqs.h b/arch/arm/mach-mv78xx0/include/mach/irqs.h
deleted file mode 100644 (file)
index fa1d422..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/irqs.h
- *
- * IRQ definitions for Marvell MV78xx0 SoCs
- *
- * 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 __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H
-
-/*
- * MV78xx0 Low Interrupt Controller
- */
-#define IRQ_MV78XX0_ERR                0
-#define IRQ_MV78XX0_SPI                1
-#define IRQ_MV78XX0_I2C_0      2
-#define IRQ_MV78XX0_I2C_1      3
-#define IRQ_MV78XX0_IDMA_0     4
-#define IRQ_MV78XX0_IDMA_1     5
-#define IRQ_MV78XX0_IDMA_2     6
-#define IRQ_MV78XX0_IDMA_3     7
-#define IRQ_MV78XX0_TIMER_0    8
-#define IRQ_MV78XX0_TIMER_1    9
-#define IRQ_MV78XX0_TIMER_2    10
-#define IRQ_MV78XX0_TIMER_3    11
-#define IRQ_MV78XX0_UART_0     12
-#define IRQ_MV78XX0_UART_1     13
-#define IRQ_MV78XX0_UART_2     14
-#define IRQ_MV78XX0_UART_3     15
-#define IRQ_MV78XX0_USB_0      16
-#define IRQ_MV78XX0_USB_1      17
-#define IRQ_MV78XX0_USB_2      18
-#define IRQ_MV78XX0_CRYPTO     19
-#define IRQ_MV78XX0_SDIO_0     20
-#define IRQ_MV78XX0_SDIO_1     21
-#define IRQ_MV78XX0_XOR_0      22
-#define IRQ_MV78XX0_XOR_1      23
-#define IRQ_MV78XX0_I2S_0      24
-#define IRQ_MV78XX0_I2S_1      25
-#define IRQ_MV78XX0_SATA       26
-#define IRQ_MV78XX0_TDMI       27
-
-/*
- * MV78xx0 High Interrupt Controller
- */
-#define IRQ_MV78XX0_PCIE_00    32
-#define IRQ_MV78XX0_PCIE_01    33
-#define IRQ_MV78XX0_PCIE_02    34
-#define IRQ_MV78XX0_PCIE_03    35
-#define IRQ_MV78XX0_PCIE_10    36
-#define IRQ_MV78XX0_PCIE_11    37
-#define IRQ_MV78XX0_PCIE_12    38
-#define IRQ_MV78XX0_PCIE_13    39
-#define IRQ_MV78XX0_GE00_SUM   40
-#define IRQ_MV78XX0_GE00_RX    41
-#define IRQ_MV78XX0_GE00_TX    42
-#define IRQ_MV78XX0_GE00_MISC  43
-#define IRQ_MV78XX0_GE01_SUM   44
-#define IRQ_MV78XX0_GE01_RX    45
-#define IRQ_MV78XX0_GE01_TX    46
-#define IRQ_MV78XX0_GE01_MISC  47
-#define IRQ_MV78XX0_GE10_SUM   48
-#define IRQ_MV78XX0_GE10_RX    49
-#define IRQ_MV78XX0_GE10_TX    50
-#define IRQ_MV78XX0_GE10_MISC  51
-#define IRQ_MV78XX0_GE11_SUM   52
-#define IRQ_MV78XX0_GE11_RX    53
-#define IRQ_MV78XX0_GE11_TX    54
-#define IRQ_MV78XX0_GE11_MISC  55
-#define IRQ_MV78XX0_GPIO_0_7   56
-#define IRQ_MV78XX0_GPIO_8_15  57
-#define IRQ_MV78XX0_GPIO_16_23 58
-#define IRQ_MV78XX0_GPIO_24_31 59
-#define IRQ_MV78XX0_DB_IN      60
-#define IRQ_MV78XX0_DB_OUT     61
-
-/*
- * MV78xx0 Error Interrupt Controller
- */
-#define IRQ_MV78XX0_GE_ERR     70
-
-/*
- * MV78XX0 General Purpose Pins
- */
-#define IRQ_MV78XX0_GPIO_START 96
-#define NR_GPIO_IRQS           32
-
-#define NR_IRQS                        (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
-
-
-#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
deleted file mode 100644 (file)
index 723748d..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
- *
- * Generic definitions for Marvell MV78xx0 SoC flavors:
- *  MV781x0 and MV782x0.
- *
- * 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 __ASM_ARCH_MV78XX0_H
-#define __ASM_ARCH_MV78XX0_H
-
-/*
- * Marvell MV78xx0 address maps.
- *
- * phys
- * c0000000    PCIe Memory space
- * f0800000    PCIe #0 I/O space
- * f0900000    PCIe #1 I/O space
- * f0a00000    PCIe #2 I/O space
- * f0b00000    PCIe #3 I/O space
- * f0c00000    PCIe #4 I/O space
- * f0d00000    PCIe #5 I/O space
- * f0e00000    PCIe #6 I/O space
- * f0f00000    PCIe #7 I/O space
- * f1000000    on-chip peripheral registers
- *
- * virt                phys            size
- * fe400000    f102x000        16K     core-specific peripheral registers
- * fee00000    f0800000        64K     PCIe #0 I/O space
- * fee10000    f0900000        64K     PCIe #1 I/O space
- * fee20000    f0a00000        64K     PCIe #2 I/O space
- * fee30000    f0b00000        64K     PCIe #3 I/O space
- * fee40000    f0c00000        64K     PCIe #4 I/O space
- * fee50000    f0d00000        64K     PCIe #5 I/O space
- * fee60000    f0e00000        64K     PCIe #6 I/O space
- * fee70000    f0f00000        64K     PCIe #7 I/O space
- * fd000000    f1000000        1M      on-chip peripheral registers
- */
-#define MV78XX0_CORE0_REGS_PHYS_BASE   0xf1020000
-#define MV78XX0_CORE1_REGS_PHYS_BASE   0xf1024000
-#define MV78XX0_CORE_REGS_VIRT_BASE    IOMEM(0xfe400000)
-#define MV78XX0_CORE_REGS_PHYS_BASE    0xfe400000
-#define MV78XX0_CORE_REGS_SIZE         SZ_16K
-
-#define MV78XX0_PCIE_IO_PHYS_BASE(i)   (0xf0800000 + ((i) << 20))
-#define MV78XX0_PCIE_IO_SIZE           SZ_1M
-
-#define MV78XX0_REGS_PHYS_BASE         0xf1000000
-#define MV78XX0_REGS_VIRT_BASE         IOMEM(0xfd000000)
-#define MV78XX0_REGS_SIZE              SZ_1M
-
-#define MV78XX0_PCIE_MEM_PHYS_BASE     0xc0000000
-#define MV78XX0_PCIE_MEM_SIZE          0x30000000
-
-/*
- * Core-specific peripheral registers.
- */
-#define BRIDGE_VIRT_BASE       (MV78XX0_CORE_REGS_VIRT_BASE)
-#define BRIDGE_PHYS_BASE       (MV78XX0_CORE_REGS_PHYS_BASE)
-#define  BRIDGE_WINS_CPU0_BASE  (MV78XX0_CORE0_REGS_PHYS_BASE)
-#define  BRIDGE_WINS_CPU1_BASE  (MV78XX0_CORE1_REGS_PHYS_BASE)
-#define  BRIDGE_WINS_SZ         (0xA000)
-
-/*
- * Register Map
- */
-#define DDR_VIRT_BASE          (MV78XX0_REGS_VIRT_BASE + 0x00000)
-#define DDR_PHYS_BASE           (MV78XX0_REGS_PHYS_BASE + 0x00000)
-#define  DDR_WINDOW_CPU0_BASE  (DDR_PHYS_BASE + 0x1500)
-#define  DDR_WINDOW_CPU1_BASE  (DDR_PHYS_BASE + 0x1570)
-#define  DDR_WINDOW_CPU_SZ      (0x20)
-
-#define DEV_BUS_PHYS_BASE      (MV78XX0_REGS_PHYS_BASE + 0x10000)
-#define DEV_BUS_VIRT_BASE      (MV78XX0_REGS_VIRT_BASE + 0x10000)
-#define  SAMPLE_AT_RESET_LOW   (DEV_BUS_VIRT_BASE + 0x0030)
-#define  SAMPLE_AT_RESET_HIGH  (DEV_BUS_VIRT_BASE + 0x0034)
-#define  GPIO_VIRT_BASE                (DEV_BUS_VIRT_BASE + 0x0100)
-#define  I2C_0_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x1000)
-#define  I2C_1_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x1100)
-#define  UART0_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2000)
-#define  UART0_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2000)
-#define  UART1_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2100)
-#define  UART1_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2100)
-#define  UART2_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2200)
-#define  UART2_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2200)
-#define  UART3_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2300)
-#define  UART3_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2300)
-
-#define GE10_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x30000)
-#define GE11_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x34000)
-
-#define PCIE00_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x40000)
-#define PCIE01_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x44000)
-#define PCIE02_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x48000)
-#define PCIE03_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x4c000)
-
-#define USB0_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x50000)
-#define USB1_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x51000)
-#define USB2_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x52000)
-
-#define GE00_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x70000)
-#define GE01_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x74000)
-
-#define PCIE10_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x80000)
-#define PCIE11_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x84000)
-#define PCIE12_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x88000)
-#define PCIE13_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x8c000)
-
-#define SATA_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0xa0000)
-
-/*
- * Supported devices and revisions.
- */
-#define MV78X00_Z0_DEV_ID      0x6381
-#define MV78X00_REV_Z0         1
-
-#define MV78100_DEV_ID         0x7810
-#define MV78100_REV_A0         1
-#define MV78100_REV_A1         2
-
-#define MV78200_DEV_ID         0x7820
-#define MV78200_REV_A0         1
-
-#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/uncompress.h b/arch/arm/mach-mv78xx0/include/mach/uncompress.h
deleted file mode 100644 (file)
index 6a761c4..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/uncompress.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/serial_reg.h>
-#include <mach/mv78xx0.h>
-
-#define SERIAL_BASE    ((unsigned char *)UART0_PHYS_BASE)
-
-static void putc(const char c)
-{
-       unsigned char *base = SERIAL_BASE;
-       int i;
-
-       for (i = 0; i < 0x1000; i++) {
-               if (base[UART_LSR << 2] & UART_LSR_THRE)
-                       break;
-               barrier();
-       }
-
-       base[UART_TX << 2] = c;
-}
-
-static void flush(void)
-{
-       unsigned char *base = SERIAL_BASE;
-       unsigned char mask;
-       int i;
-
-       mask = UART_LSR_TEMT | UART_LSR_THRE;
-
-       for (i = 0; i < 0x1000; i++) {
-               if ((base[UART_LSR << 2] & mask) == mask)
-                       break;
-               barrier();
-       }
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
index 3207344..788569e 100644 (file)
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <mach/bridge-regs.h>
+#include <asm/exception.h>
 #include <plat/orion-gpio.h>
 #include <plat/irq.h>
+#include "bridge-regs.h"
 #include "common.h"
 
 static int __initdata gpio0_irqs[4] = {
@@ -23,12 +24,44 @@ static int __initdata gpio0_irqs[4] = {
        IRQ_MV78XX0_GPIO_24_31,
 };
 
+static void __iomem *mv78xx0_irq_base = IRQ_VIRT_BASE;
+
+static asmlinkage void
+__exception_irq_entry mv78xx0_legacy_handle_irq(struct pt_regs *regs)
+{
+       u32 stat;
+
+       stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_LOW_OFF);
+       stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_LOW_OFF);
+       if (stat) {
+               unsigned int hwirq = __fls(stat);
+               handle_IRQ(hwirq, regs);
+               return;
+       }
+       stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_HIGH_OFF);
+       stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_HIGH_OFF);
+       if (stat) {
+               unsigned int hwirq = 32 + __fls(stat);
+               handle_IRQ(hwirq, regs);
+               return;
+       }
+       stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_ERR_OFF);
+       stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_ERR_OFF);
+       if (stat) {
+               unsigned int hwirq = 64 + __fls(stat);
+               handle_IRQ(hwirq, regs);
+               return;
+       }
+}
+
 void __init mv78xx0_init_irq(void)
 {
        orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
        orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
        orion_irq_init(64, IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF);
 
+       set_handle_irq(mv78xx0_legacy_handle_irq);
+
        /*
         * Initialize gpiolib for GPIOs 0-31.  (The GPIO interrupt mask
         * registers for core #1 are at an offset of 0x18 from those of
diff --git a/arch/arm/mach-mv78xx0/irqs.h b/arch/arm/mach-mv78xx0/irqs.h
new file mode 100644 (file)
index 0000000..67e0fe7
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * IRQ definitions for Marvell MV78xx0 SoCs
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * MV78xx0 Low Interrupt Controller
+ */
+#define IRQ_MV78XX0_ERR                0
+#define IRQ_MV78XX0_SPI                1
+#define IRQ_MV78XX0_I2C_0      2
+#define IRQ_MV78XX0_I2C_1      3
+#define IRQ_MV78XX0_IDMA_0     4
+#define IRQ_MV78XX0_IDMA_1     5
+#define IRQ_MV78XX0_IDMA_2     6
+#define IRQ_MV78XX0_IDMA_3     7
+#define IRQ_MV78XX0_TIMER_0    8
+#define IRQ_MV78XX0_TIMER_1    9
+#define IRQ_MV78XX0_TIMER_2    10
+#define IRQ_MV78XX0_TIMER_3    11
+#define IRQ_MV78XX0_UART_0     12
+#define IRQ_MV78XX0_UART_1     13
+#define IRQ_MV78XX0_UART_2     14
+#define IRQ_MV78XX0_UART_3     15
+#define IRQ_MV78XX0_USB_0      16
+#define IRQ_MV78XX0_USB_1      17
+#define IRQ_MV78XX0_USB_2      18
+#define IRQ_MV78XX0_CRYPTO     19
+#define IRQ_MV78XX0_SDIO_0     20
+#define IRQ_MV78XX0_SDIO_1     21
+#define IRQ_MV78XX0_XOR_0      22
+#define IRQ_MV78XX0_XOR_1      23
+#define IRQ_MV78XX0_I2S_0      24
+#define IRQ_MV78XX0_I2S_1      25
+#define IRQ_MV78XX0_SATA       26
+#define IRQ_MV78XX0_TDMI       27
+
+/*
+ * MV78xx0 High Interrupt Controller
+ */
+#define IRQ_MV78XX0_PCIE_00    32
+#define IRQ_MV78XX0_PCIE_01    33
+#define IRQ_MV78XX0_PCIE_02    34
+#define IRQ_MV78XX0_PCIE_03    35
+#define IRQ_MV78XX0_PCIE_10    36
+#define IRQ_MV78XX0_PCIE_11    37
+#define IRQ_MV78XX0_PCIE_12    38
+#define IRQ_MV78XX0_PCIE_13    39
+#define IRQ_MV78XX0_GE00_SUM   40
+#define IRQ_MV78XX0_GE00_RX    41
+#define IRQ_MV78XX0_GE00_TX    42
+#define IRQ_MV78XX0_GE00_MISC  43
+#define IRQ_MV78XX0_GE01_SUM   44
+#define IRQ_MV78XX0_GE01_RX    45
+#define IRQ_MV78XX0_GE01_TX    46
+#define IRQ_MV78XX0_GE01_MISC  47
+#define IRQ_MV78XX0_GE10_SUM   48
+#define IRQ_MV78XX0_GE10_RX    49
+#define IRQ_MV78XX0_GE10_TX    50
+#define IRQ_MV78XX0_GE10_MISC  51
+#define IRQ_MV78XX0_GE11_SUM   52
+#define IRQ_MV78XX0_GE11_RX    53
+#define IRQ_MV78XX0_GE11_TX    54
+#define IRQ_MV78XX0_GE11_MISC  55
+#define IRQ_MV78XX0_GPIO_0_7   56
+#define IRQ_MV78XX0_GPIO_8_15  57
+#define IRQ_MV78XX0_GPIO_16_23 58
+#define IRQ_MV78XX0_GPIO_24_31 59
+#define IRQ_MV78XX0_DB_IN      60
+#define IRQ_MV78XX0_DB_OUT     61
+
+/*
+ * MV78xx0 Error Interrupt Controller
+ */
+#define IRQ_MV78XX0_GE_ERR     70
+
+/*
+ * MV78XX0 General Purpose Pins
+ */
+#define IRQ_MV78XX0_GPIO_START 96
+#define NR_GPIO_IRQS           32
+
+#define MV78XX0_NR_IRQS                (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
index df50342..72843c0 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <plat/mpp.h>
-#include <mach/hardware.h>
+#include "mv78xx0.h"
 #include "common.h"
 #include "mpp.h"
 
diff --git a/arch/arm/mach-mv78xx0/mv78xx0.h b/arch/arm/mach-mv78xx0/mv78xx0.h
new file mode 100644 (file)
index 0000000..2db1265
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Generic definitions for Marvell MV78xx0 SoC flavors:
+ *  MV781x0 and MV782x0.
+ *
+ * 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 __ASM_ARCH_MV78XX0_H
+#define __ASM_ARCH_MV78XX0_H
+
+#include "irqs.h"
+
+/*
+ * Marvell MV78xx0 address maps.
+ *
+ * phys
+ * c0000000    PCIe Memory space
+ * f0800000    PCIe #0 I/O space
+ * f0900000    PCIe #1 I/O space
+ * f0a00000    PCIe #2 I/O space
+ * f0b00000    PCIe #3 I/O space
+ * f0c00000    PCIe #4 I/O space
+ * f0d00000    PCIe #5 I/O space
+ * f0e00000    PCIe #6 I/O space
+ * f0f00000    PCIe #7 I/O space
+ * f1000000    on-chip peripheral registers
+ *
+ * virt                phys            size
+ * fe400000    f102x000        16K     core-specific peripheral registers
+ * fee00000    f0800000        64K     PCIe #0 I/O space
+ * fee10000    f0900000        64K     PCIe #1 I/O space
+ * fee20000    f0a00000        64K     PCIe #2 I/O space
+ * fee30000    f0b00000        64K     PCIe #3 I/O space
+ * fee40000    f0c00000        64K     PCIe #4 I/O space
+ * fee50000    f0d00000        64K     PCIe #5 I/O space
+ * fee60000    f0e00000        64K     PCIe #6 I/O space
+ * fee70000    f0f00000        64K     PCIe #7 I/O space
+ * fd000000    f1000000        1M      on-chip peripheral registers
+ */
+#define MV78XX0_CORE0_REGS_PHYS_BASE   0xf1020000
+#define MV78XX0_CORE1_REGS_PHYS_BASE   0xf1024000
+#define MV78XX0_CORE_REGS_VIRT_BASE    IOMEM(0xfe400000)
+#define MV78XX0_CORE_REGS_PHYS_BASE    0xfe400000
+#define MV78XX0_CORE_REGS_SIZE         SZ_16K
+
+#define MV78XX0_PCIE_IO_PHYS_BASE(i)   (0xf0800000 + ((i) << 20))
+#define MV78XX0_PCIE_IO_SIZE           SZ_1M
+
+#define MV78XX0_REGS_PHYS_BASE         0xf1000000
+#define MV78XX0_REGS_VIRT_BASE         IOMEM(0xfd000000)
+#define MV78XX0_REGS_SIZE              SZ_1M
+
+#define MV78XX0_PCIE_MEM_PHYS_BASE     0xc0000000
+#define MV78XX0_PCIE_MEM_SIZE          0x30000000
+
+/*
+ * Core-specific peripheral registers.
+ */
+#define BRIDGE_VIRT_BASE       (MV78XX0_CORE_REGS_VIRT_BASE)
+#define BRIDGE_PHYS_BASE       (MV78XX0_CORE_REGS_PHYS_BASE)
+#define  BRIDGE_WINS_CPU0_BASE  (MV78XX0_CORE0_REGS_PHYS_BASE)
+#define  BRIDGE_WINS_CPU1_BASE  (MV78XX0_CORE1_REGS_PHYS_BASE)
+#define  BRIDGE_WINS_SZ         (0xA000)
+
+/*
+ * Register Map
+ */
+#define DDR_VIRT_BASE          (MV78XX0_REGS_VIRT_BASE + 0x00000)
+#define DDR_PHYS_BASE           (MV78XX0_REGS_PHYS_BASE + 0x00000)
+#define  DDR_WINDOW_CPU0_BASE  (DDR_PHYS_BASE + 0x1500)
+#define  DDR_WINDOW_CPU1_BASE  (DDR_PHYS_BASE + 0x1570)
+#define  DDR_WINDOW_CPU_SZ      (0x20)
+
+#define DEV_BUS_PHYS_BASE      (MV78XX0_REGS_PHYS_BASE + 0x10000)
+#define DEV_BUS_VIRT_BASE      (MV78XX0_REGS_VIRT_BASE + 0x10000)
+#define  SAMPLE_AT_RESET_LOW   (DEV_BUS_VIRT_BASE + 0x0030)
+#define  SAMPLE_AT_RESET_HIGH  (DEV_BUS_VIRT_BASE + 0x0034)
+#define  GPIO_VIRT_BASE                (DEV_BUS_VIRT_BASE + 0x0100)
+#define  I2C_0_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x1000)
+#define  I2C_1_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x1100)
+#define  UART0_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2000)
+#define  UART0_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2000)
+#define  UART1_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2100)
+#define  UART1_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2100)
+#define  UART2_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2200)
+#define  UART2_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2200)
+#define  UART3_PHYS_BASE       (DEV_BUS_PHYS_BASE + 0x2300)
+#define  UART3_VIRT_BASE       (DEV_BUS_VIRT_BASE + 0x2300)
+
+#define GE10_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x30000)
+#define GE11_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x34000)
+
+#define PCIE00_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x40000)
+#define PCIE01_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x44000)
+#define PCIE02_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x48000)
+#define PCIE03_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x4c000)
+
+#define USB0_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x50000)
+#define USB1_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x51000)
+#define USB2_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x52000)
+
+#define GE00_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x70000)
+#define GE01_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0x74000)
+
+#define PCIE10_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x80000)
+#define PCIE11_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x84000)
+#define PCIE12_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x88000)
+#define PCIE13_VIRT_BASE       (MV78XX0_REGS_VIRT_BASE + 0x8c000)
+
+#define SATA_PHYS_BASE         (MV78XX0_REGS_PHYS_BASE + 0xa0000)
+
+/*
+ * Supported devices and revisions.
+ */
+#define MV78X00_Z0_DEV_ID      0x6381
+#define MV78X00_REV_Z0         1
+
+#define MV78100_DEV_ID         0x7810
+#define MV78100_REV_A0         1
+#define MV78100_REV_A1         2
+
+#define MV78200_DEV_ID         0x7820
+#define MV78200_REV_A0         1
+
+#endif
index 097ea4c..13a7d72 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
 #include <plat/pcie.h>
-#include <mach/mv78xx0.h>
+#include "mv78xx0.h"
 #include "common.h"
 
 #define MV78XX0_MBUS_PCIE_MEM_TARGET(port, lane) ((port) ? 8 : 4)
index d2d06f3..308ab71 100644 (file)
@@ -14,9 +14,9 @@
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
-#include <mach/mv78xx0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include "mv78xx0.h"
 #include "common.h"
 
 static struct mv643xx_eth_platform_data rd78x00_masa_ge00_data = {
@@ -79,6 +79,7 @@ subsys_initcall(rd78x00_pci_init);
 MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
        /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = MV78XX0_NR_IRQS,
        .init_machine   = rd78x00_masa_init,
        .map_io         = mv78xx0_map_io,
        .init_early     = mv78xx0_init_early,
index e20fc41..64e3d2c 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_MVEBU
-       bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5)
+       bool "Marvell Engineering Business Unit (MVEBU) SoCs"
+       depends on ARCH_MULTI_V7 || ARCH_MULTI_V5
        select ARCH_SUPPORTS_BIG_ENDIAN
        select CLKSRC_MMIO
        select GENERIC_IRQ_CHIP
@@ -25,7 +26,8 @@ config MACH_MVEBU_V7
        select MACH_MVEBU_ANY
 
 config MACH_ARMADA_370
-       bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
+       bool "Marvell Armada 370 boards"
+       depends on ARCH_MULTI_V7
        select ARMADA_370_CLK
        select CPU_PJ4B
        select MACH_MVEBU_V7
@@ -35,7 +37,8 @@ config MACH_ARMADA_370
          on the Marvell Armada 370 SoC with device tree.
 
 config MACH_ARMADA_375
-       bool "Marvell Armada 375 boards" if ARCH_MULTI_V7
+       bool "Marvell Armada 375 boards"
+       depends on ARCH_MULTI_V7
        select ARM_ERRATA_720789
        select ARM_ERRATA_753970
        select ARM_GIC
@@ -50,7 +53,8 @@ config MACH_ARMADA_375
          on the Marvell Armada 375 SoC with device tree.
 
 config MACH_ARMADA_38X
-       bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
+       bool "Marvell Armada 380/385 boards"
+       depends on ARCH_MULTI_V7
        select ARM_ERRATA_720789
        select ARM_ERRATA_753970
        select ARM_GIC
@@ -65,7 +69,8 @@ config MACH_ARMADA_38X
          on the Marvell Armada 380/385 SoC with device tree.
 
 config MACH_ARMADA_39X
-       bool "Marvell Armada 39x boards" if ARCH_MULTI_V7
+       bool "Marvell Armada 39x boards"
+       depends on ARCH_MULTI_V7
        select ARM_GIC
        select ARMADA_39X_CLK
        select CACHE_L2X0
@@ -79,7 +84,8 @@ config MACH_ARMADA_39X
          on the Marvell Armada 39x SoC with device tree.
 
 config MACH_ARMADA_XP
-       bool "Marvell Armada XP boards" if ARCH_MULTI_V7
+       bool "Marvell Armada XP boards"
+       depends on ARCH_MULTI_V7
        select ARMADA_XP_CLK
        select CPU_PJ4B
        select MACH_MVEBU_V7
@@ -89,7 +95,8 @@ config MACH_ARMADA_XP
          on the Marvell Armada XP SoC with device tree.
 
 config MACH_DOVE
-       bool "Marvell Dove boards" if ARCH_MULTI_V7
+       bool "Marvell Dove boards"
+       depends on ARCH_MULTI_V7
        select CACHE_L2X0
        select CPU_PJ4
        select DOVE_CLK
@@ -103,7 +110,8 @@ config MACH_DOVE
          Marvell Dove using flattened device tree.
 
 config MACH_KIRKWOOD
-       bool "Marvell Kirkwood boards" if ARCH_MULTI_V5
+       bool "Marvell Kirkwood boards"
+       depends on ARCH_MULTI_V5
        select ARCH_REQUIRE_GPIOLIB
        select CPU_FEROCEON
        select KIRKWOOD_CLK
index c55bbf8..09413b6 100644 (file)
@@ -17,7 +17,7 @@
 
 #ifdef CONFIG_SMP
 void armada_xp_secondary_startup(void);
-extern struct smp_operations armada_xp_smp_ops;
+extern const struct smp_operations armada_xp_smp_ops;
 #endif
 
 #endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/include/mach/gpio.h b/arch/arm/mach-mvebu/include/mach/gpio.h
deleted file mode 100644 (file)
index 40a8c17..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* empty */
index 3d50004..d715dec 100644 (file)
@@ -93,11 +93,11 @@ static int armada_38x_cpu_kill(unsigned int cpu)
 }
 #endif
 
-static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
+static const struct smp_operations mvebu_cortex_a9_smp_ops __initconst = {
        .smp_boot_secondary     = mvebu_cortex_a9_boot_secondary,
 };
 
-static struct smp_operations armada_38x_smp_ops __initdata = {
+static const struct smp_operations armada_38x_smp_ops __initconst = {
        .smp_boot_secondary     = mvebu_cortex_a9_boot_secondary,
        .smp_secondary_init     = armada_38x_secondary_init,
 #ifdef CONFIG_HOTPLUG_CPU
index 58cc8c1..f9597b7 100644 (file)
@@ -170,7 +170,7 @@ static int armada_xp_cpu_kill(unsigned int cpu)
 }
 #endif
 
-struct smp_operations armada_xp_smp_ops __initdata = {
+const struct smp_operations armada_xp_smp_ops __initconst = {
        .smp_init_cpus          = armada_xp_smp_init_cpus,
        .smp_prepare_cpus       = armada_xp_smp_prepare_cpus,
        .smp_boot_secondary     = armada_xp_boot_secondary,
diff --git a/arch/arm/mach-netx/include/mach/param.h b/arch/arm/mach-netx/include/mach/param.h
deleted file mode 100644 (file)
index a771459..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *  arch/arm/mach-netx/include/mach/param.h
- *
- * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
index 97e6655..6613a6f 100644 (file)
@@ -41,7 +41,7 @@
 
 #include <mach/hardware.h>
 #include <mach/ams-delta-fiq.h>
-#include <mach/camera.h>
+#include "camera.h"
 #include <mach/usb.h>
 
 #include "iomap.h"
index 0fb51d2..fad95b7 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <mach/tc.h>
 #include <mach/mux.h>
-#include <mach/flash.h>
+#include "flash.h"
 #include <linux/platform_data/keypad-omap.h>
 
 #include <mach/hardware.h>
index 8340d68..cd146ed 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
 #include <linux/platform_data/keypad-omap.h>
-#include <mach/flash.h>
+#include "flash.h"
 
 #include <mach/hardware.h>
 #include <mach/usb.h>
index 086ff34..f7c8c63 100644 (file)
@@ -44,7 +44,7 @@
 #include <mach/tc.h>
 #include <linux/platform_data/keypad-omap.h>
 #include <linux/omap-dma.h>
-#include <mach/flash.h>
+#include "flash.h"
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
index ed4e045..ae90bd0 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/mux.h>
-#include <mach/flash.h>
+#include "flash.h"
 #include <mach/tc.h>
 #include <linux/platform_data/keypad-omap.h>
 
index 0efd165..209aecb 100644 (file)
@@ -46,7 +46,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/flash.h>
+#include "flash.h"
 #include <mach/mux.h>
 #include <mach/tc.h>
 
index 1142ae4..e5288cd 100644 (file)
@@ -34,7 +34,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/flash.h>
+#include "flash.h"
 #include <mach/mux.h>
 #include <mach/tc.h>
 #include <linux/omap-dma.h>
index 54a547a..d672495 100644 (file)
@@ -34,7 +34,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/flash.h>
+#include "flash.h"
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
index 87ec04a..aaf741b 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/flash.h>
+#include "flash.h"
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
index 3d76f05..150b57b 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <mach/tc.h>
 #include <mach/mux.h>
-#include <mach/flash.h>
+#include "flash.h"
 
 #include <mach/hardware.h>
 
index 4fcf19c..a937357 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/platform_device.h>
 
 #include <mach/hardware.h>
-#include <mach/board-sx1.h>
+#include "board-sx1.h"
 
 #include "mmc.h"
 
index 939991e..6c48225 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/flash.h>
+#include "flash.h"
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
-#include <mach/board-sx1.h>
+#include "board-sx1.h"
 
 #include <mach/hardware.h>
 #include <mach/usb.h>
diff --git a/arch/arm/mach-omap1/board-sx1.h b/arch/arm/mach-omap1/board-sx1.h
new file mode 100644 (file)
index 0000000..355adbd
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Siemens SX1 board definitions
+ *
+ * Copyright: Vovan888 at gmail com
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
+#define __ASM_ARCH_SX1_I2C_CHIPS_H
+
+#define SOFIA_MAX_LIGHT_VAL    0x2B
+
+#define SOFIA_I2C_ADDR         0x32
+/* Sofia reg 3 bits masks */
+#define SOFIA_POWER1_REG       0x03
+
+#define        SOFIA_USB_POWER         0x01
+#define        SOFIA_MMC_POWER         0x04
+#define        SOFIA_BLUETOOTH_POWER   0x08
+#define        SOFIA_MMILIGHT_POWER    0x20
+
+#define SOFIA_POWER2_REG       0x04
+#define SOFIA_BACKLIGHT_REG    0x06
+#define SOFIA_KEYLIGHT_REG     0x07
+#define SOFIA_DIMMING_REG      0x09
+
+
+/* Function Prototypes for SX1 devices control on I2C bus */
+
+int sx1_setbacklight(u8 backlight);
+int sx1_getbacklight(u8 *backlight);
+int sx1_setkeylight(u8 keylight);
+int sx1_getkeylight(u8 *keylight);
+
+int sx1_setmmipower(u8 onoff);
+int sx1_setusbpower(u8 onoff);
+int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value);
+int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value);
+
+/* MMC prototypes */
+
+extern void sx1_mmc_init(void);
+extern void sx1_mmc_slot_cover_handler(void *arg, int state);
+
+#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
diff --git a/arch/arm/mach-omap1/camera.h b/arch/arm/mach-omap1/camera.h
new file mode 100644 (file)
index 0000000..caa6c0d
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#include <linux/platform_data/media/omap1_camera.h>
+
+void omap1_camera_init(void *);
+
+static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info)
+{
+       omap1_camera_init(info);
+}
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
index 325e603..8c8be86 100644 (file)
@@ -25,7 +25,7 @@
 #include <mach/mux.h>
 
 #include <mach/omap7xx.h>
-#include <mach/camera.h>
+#include "camera.h"
 #include <mach/hardware.h>
 
 #include "common.h"
 #include "mmc.h"
 #include "sram.h"
 
-#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
-
-static struct platform_device omap_pcm = {
-       .name   = "omap-pcm-audio",
-       .id     = -1,
-};
-
-static void omap_init_audio(void)
-{
-       platform_device_register(&omap_pcm);
-}
-
-#else
-static inline void omap_init_audio(void) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
-
 #if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
 
 #define        OMAP_RTC_BASE           0xfffb4800
@@ -425,7 +407,6 @@ static int __init omap1_init_devices(void)
         * in alphabetical order so they're easier to sort through.
         */
 
-       omap_init_audio();
        omap_init_mbox();
        omap_init_rtc();
        omap_init_spi100k();
index b3fb531..99cda40 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/mtd/map.h>
 
 #include <mach/tc.h>
-#include <mach/flash.h>
+#include "flash.h"
 
 #include <mach/hardware.h>
 
diff --git a/arch/arm/mach-omap1/flash.h b/arch/arm/mach-omap1/flash.h
new file mode 100644 (file)
index 0000000..0d88499
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Flash support for OMAP1
+ *
+ * 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 __OMAP_FLASH_H
+#define __OMAP_FLASH_H
+
+#include <linux/mtd/map.h>
+
+struct platform_device;
+extern void omap1_set_vpp(struct platform_device *pdev, int enable);
+
+#endif
diff --git a/arch/arm/mach-omap1/include/mach/board-sx1.h b/arch/arm/mach-omap1/include/mach/board-sx1.h
deleted file mode 100644 (file)
index 355adbd..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Siemens SX1 board definitions
- *
- * Copyright: Vovan888 at gmail com
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
-#define __ASM_ARCH_SX1_I2C_CHIPS_H
-
-#define SOFIA_MAX_LIGHT_VAL    0x2B
-
-#define SOFIA_I2C_ADDR         0x32
-/* Sofia reg 3 bits masks */
-#define SOFIA_POWER1_REG       0x03
-
-#define        SOFIA_USB_POWER         0x01
-#define        SOFIA_MMC_POWER         0x04
-#define        SOFIA_BLUETOOTH_POWER   0x08
-#define        SOFIA_MMILIGHT_POWER    0x20
-
-#define SOFIA_POWER2_REG       0x04
-#define SOFIA_BACKLIGHT_REG    0x06
-#define SOFIA_KEYLIGHT_REG     0x07
-#define SOFIA_DIMMING_REG      0x09
-
-
-/* Function Prototypes for SX1 devices control on I2C bus */
-
-int sx1_setbacklight(u8 backlight);
-int sx1_getbacklight(u8 *backlight);
-int sx1_setkeylight(u8 keylight);
-int sx1_getkeylight(u8 *keylight);
-
-int sx1_setmmipower(u8 onoff);
-int sx1_setusbpower(u8 onoff);
-int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value);
-int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value);
-
-/* MMC prototypes */
-
-extern void sx1_mmc_init(void);
-extern void sx1_mmc_slot_cover_handler(void *arg, int state);
-
-#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
diff --git a/arch/arm/mach-omap1/include/mach/camera.h b/arch/arm/mach-omap1/include/mach/camera.h
deleted file mode 100644 (file)
index caa6c0d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ASM_ARCH_CAMERA_H_
-#define __ASM_ARCH_CAMERA_H_
-
-#include <linux/platform_data/media/omap1_camera.h>
-
-void omap1_camera_init(void *);
-
-static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info)
-{
-       omap1_camera_init(info);
-}
-
-#endif /* __ASM_ARCH_CAMERA_H_ */
diff --git a/arch/arm/mach-omap1/include/mach/flash.h b/arch/arm/mach-omap1/include/mach/flash.h
deleted file mode 100644 (file)
index 0d88499..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Flash support for OMAP1
- *
- * 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 __OMAP_FLASH_H
-#define __OMAP_FLASH_H
-
-#include <linux/mtd/map.h>
-
-struct platform_device;
-extern void omap1_set_vpp(struct platform_device *pdev, int enable);
-
-#endif
index ceefcee..0ba6a0e 100644 (file)
@@ -223,8 +223,6 @@ obj-$(CONFIG_SOC_DRA7XX)            += omap_hwmod_7xx_data.o
 # EMU peripherals
 obj-$(CONFIG_HW_PERF_EVENTS)           += pmu.o
 
-obj-$(CONFIG_OMAP_IOMMU)               += omap-iommu.o
-
 # OMAP2420 MSDI controller integration support ("MMC")
 obj-$(CONFIG_SOC_OMAP2420)             += msdi.o
 
index 0a0567f..da174c0 100644 (file)
@@ -1257,7 +1257,7 @@ static struct platform_device omap3_rom_rng_device = {
 static void __init rx51_init_omap3_rom_rng(void)
 {
        if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
-               pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+               pr_info("RX-51: Registering OMAP3 HWRNG device\n");
                platform_device_register(&omap3_rom_rng_device);
        }
 }
index 53442c8..3b5fb05 100644 (file)
@@ -83,6 +83,14 @@ static struct clockdomain mmu_cfg_81xx_clkdm = {
        .flags          = CLKDM_CAN_SWSUP,
 };
 
+static struct clockdomain default_l3_slow_81xx_clkdm = {
+       .name           = "default_l3_slow_clkdm",
+       .pwrdm          = { .name = "default_pwrdm" },
+       .cm_inst        = TI81XX_CM_DEFAULT_MOD,
+       .clkdm_offs     = TI816X_CM_DEFAULT_L3_SLOW_CLKDM,
+       .flags          = CLKDM_CAN_SWSUP,
+};
+
 /* 816x only */
 
 static struct clockdomain alwon_mpu_816x_clkdm = {
@@ -96,7 +104,7 @@ static struct clockdomain alwon_mpu_816x_clkdm = {
 static struct clockdomain active_gem_816x_clkdm = {
        .name           = "active_gem_clkdm",
        .pwrdm          = { .name = "active_pwrdm" },
-       .cm_inst        = TI816X_CM_ACTIVE_MOD,
+       .cm_inst        = TI81XX_CM_ACTIVE_MOD,
        .clkdm_offs     = TI816X_CM_ACTIVE_GEM_CLKDM,
        .flags          = CLKDM_CAN_SWSUP,
 };
@@ -128,7 +136,7 @@ static struct clockdomain ivahd2_816x_clkdm = {
 static struct clockdomain sgx_816x_clkdm = {
        .name           = "sgx_clkdm",
        .pwrdm          = { .name = "sgx_pwrdm" },
-       .cm_inst        = TI816X_CM_SGX_MOD,
+       .cm_inst        = TI81XX_CM_SGX_MOD,
        .clkdm_offs     = TI816X_CM_SGX_CLKDM,
        .flags          = CLKDM_CAN_SWSUP,
 };
@@ -136,7 +144,7 @@ static struct clockdomain sgx_816x_clkdm = {
 static struct clockdomain default_l3_med_816x_clkdm = {
        .name           = "default_l3_med_clkdm",
        .pwrdm          = { .name = "default_pwrdm" },
-       .cm_inst        = TI816X_CM_DEFAULT_MOD,
+       .cm_inst        = TI81XX_CM_DEFAULT_MOD,
        .clkdm_offs     = TI816X_CM_DEFAULT_L3_MED_CLKDM,
        .flags          = CLKDM_CAN_SWSUP,
 };
@@ -144,7 +152,7 @@ static struct clockdomain default_l3_med_816x_clkdm = {
 static struct clockdomain default_ducati_816x_clkdm = {
        .name           = "default_ducati_clkdm",
        .pwrdm          = { .name = "default_pwrdm" },
-       .cm_inst        = TI816X_CM_DEFAULT_MOD,
+       .cm_inst        = TI81XX_CM_DEFAULT_MOD,
        .clkdm_offs     = TI816X_CM_DEFAULT_DUCATI_CLKDM,
        .flags          = CLKDM_CAN_SWSUP,
 };
@@ -152,19 +160,11 @@ static struct clockdomain default_ducati_816x_clkdm = {
 static struct clockdomain default_pci_816x_clkdm = {
        .name           = "default_pci_clkdm",
        .pwrdm          = { .name = "default_pwrdm" },
-       .cm_inst        = TI816X_CM_DEFAULT_MOD,
+       .cm_inst        = TI81XX_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_ti814x[] __initdata = {
        &alwon_l3_slow_81xx_clkdm,
        &alwon_l3_med_81xx_clkdm,
@@ -172,6 +172,7 @@ static struct clockdomain *clockdomains_ti814x[] __initdata = {
        &alwon_ethernet_81xx_clkdm,
        &mmu_81xx_clkdm,
        &mmu_cfg_81xx_clkdm,
+       &default_l3_slow_81xx_clkdm,
        NULL,
 };
 
@@ -198,7 +199,7 @@ static struct clockdomain *clockdomains_ti816x[] __initdata = {
        &default_l3_med_816x_clkdm,
        &default_ducati_816x_clkdm,
        &default_pci_816x_clkdm,
-       &default_l3_slow_816x_clkdm,
+       &default_l3_slow_81xx_clkdm,
        NULL,
 };
 
index 45cb407..3a0ccf0 100644 (file)
 #define __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
 
 /* TI81XX common CM module offsets */
+#define TI81XX_CM_ACTIVE_MOD                   0x0400  /* 256B */
+#define TI81XX_CM_DEFAULT_MOD                  0x0500  /* 256B */
 #define TI81XX_CM_ALWON_MOD                    0x1400  /* 1KB */
+#define TI81XX_CM_SGX_MOD                      0x0900  /* 256B */
 
 /* 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
index 0cba957..f7666b9 100644 (file)
@@ -270,7 +270,7 @@ extern u32 omap_read_auxcoreboot0(void);
 
 extern void omap4_cpu_die(unsigned int cpu);
 
-extern struct smp_operations omap4_smp_ops;
+extern const struct smp_operations omap4_smp_ops;
 
 extern void omap5_secondary_startup(void);
 extern void omap5_secondary_hyp_startup(void);
index 9374da3..9cda974 100644 (file)
@@ -94,22 +94,6 @@ static inline void omap_init_mbox(void) { }
 
 static inline void omap_init_sti(void) {}
 
-#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
-
-static struct platform_device omap_pcm = {
-       .name   = "omap-pcm-audio",
-       .id     = -1,
-};
-
-static void omap_init_audio(void)
-{
-       platform_device_register(&omap_pcm);
-}
-
-#else
-static inline void omap_init_audio(void) {}
-#endif
-
 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
@@ -239,13 +223,12 @@ static int __init omap2_init_devices(void)
        if (!of_have_populated_dt())
                pinctrl_provide_dummies();
 
-       /*
-        * please keep these calls, and their implementations above,
-        * in alphabetical order so they're easier to sort through.
-        */
-       omap_init_audio();
        /* If dtb is there, the devices will be created dynamically */
        if (!of_have_populated_dt()) {
+               /*
+                * please keep these calls, and their implementations above,
+                * in alphabetical order so they're easier to sort through.
+                */
                omap_init_mbox();
                omap_init_mcspi();
                omap_init_sham();
index 8a2ae82..d85c249 100644 (file)
@@ -488,6 +488,7 @@ void __init omap3xxx_check_revision(void)
                }
                break;
        case 0xb8f2:
+       case 0xb968:
                switch (rev) {
                case 0:
                /* FALLTHROUGH */
@@ -511,7 +512,8 @@ void __init omap3xxx_check_revision(void)
                /* Unknown default to latest silicon rev as default */
                omap_revision = OMAP3630_REV_ES1_2;
                cpu_rev = "1.2";
-               pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n");
+               pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
+                       hawkeye);
        }
        sprintf(soc_rev, "ES%s", cpu_rev);
 }
index 3eaeaca..3c87e40 100644 (file)
@@ -612,8 +612,7 @@ void __init ti814x_init_early(void)
        ti814x_clockdomains_init();
        dm814x_hwmod_init();
        omap_hwmod_init_postsetup();
-       if (of_have_populated_dt())
-               omap_clk_soc_init = dm814x_dt_clk_init;
+       omap_clk_soc_init = dm814x_dt_clk_init;
 }
 
 void __init ti816x_init_early(void)
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
deleted file mode 100644 (file)
index 8867eb4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * omap iommu: omap device registration
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.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/of.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-
-#include <linux/platform_data/iommu-omap.h>
-#include "soc.h"
-#include "omap_hwmod.h"
-#include "omap_device.h"
-
-static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
-{
-       struct platform_device *pdev;
-       struct iommu_platform_data *pdata;
-       struct omap_mmu_dev_attr *a = (struct omap_mmu_dev_attr *)oh->dev_attr;
-       static int i;
-
-       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
-       if (!pdata)
-               return -ENOMEM;
-
-       pdata->name = oh->name;
-       pdata->nr_tlb_entries = a->nr_tlb_entries;
-
-       if (oh->rst_lines_cnt == 1) {
-               pdata->reset_name = oh->rst_lines->name;
-               pdata->assert_reset = omap_device_assert_hardreset;
-               pdata->deassert_reset = omap_device_deassert_hardreset;
-       }
-
-       pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata));
-
-       kfree(pdata);
-
-       if (IS_ERR(pdev)) {
-               pr_err("%s: device build err: %ld\n", __func__, PTR_ERR(pdev));
-               return PTR_ERR(pdev);
-       }
-
-       i++;
-
-       return 0;
-}
-
-static int __init omap_iommu_init(void)
-{
-       /* If dtb is there, the devices will be created dynamically */
-       if (of_have_populated_dt())
-               return -ENODEV;
-
-       return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
-}
-omap_subsys_initcall(omap_iommu_init);
-/* must be ready before omap3isp is probed */
index 79e1f87..c625cc1 100644 (file)
@@ -241,7 +241,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
 
 }
 
-struct smp_operations omap4_smp_ops __initdata = {
+const struct smp_operations omap4_smp_ops __initconst = {
        .smp_init_cpus          = omap4_smp_init_cpus,
        .smp_prepare_cpus       = omap4_smp_prepare_cpus,
        .smp_secondary_init     = omap4_secondary_init,
index d937b2e..497269d 100644 (file)
@@ -62,4 +62,4 @@ static int __init omap2xxx_common_look_up_clks_for_reset(void)
 
        return 0;
 }
-omap_core_initcall(omap2xxx_common_look_up_clks_for_reset);
+omap_postcore_initcall(omap2xxx_common_look_up_clks_for_reset);
index 72ebc4c..0437537 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/notifier.h>
@@ -168,7 +169,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
                        r->name = dev_name(&pdev->dev);
        }
 
-       pdev->dev.pm_domain = &omap_device_pm_domain;
+       dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
 
        if (device_active) {
                omap_device_enable(pdev);
@@ -180,7 +181,7 @@ odbfd_exit1:
 odbfd_exit:
        /* if data/we are at fault.. load up a fail handler */
        if (ret)
-               pdev->dev.pm_domain = &omap_device_fail_pm_domain;
+               dev_pm_domain_set(&pdev->dev, &omap_device_fail_pm_domain);
 
        return ret;
 }
@@ -701,7 +702,7 @@ int omap_device_register(struct platform_device *pdev)
 {
        pr_debug("omap_device: %s: registering\n", pdev->name);
 
-       pdev->dev.pm_domain = &omap_device_pm_domain;
+       dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
        return platform_device_add(pdev);
 }
 
@@ -869,7 +870,7 @@ static int __init omap_device_init(void)
        bus_register_notifier(&platform_bus_type, &platform_nb);
        return 0;
 }
-omap_core_initcall(omap_device_init);
+omap_postcore_initcall(omap_device_init);
 
 /**
  * omap_device_late_idle - idle devices without drivers
index 48495ad..e9f65fe 100644 (file)
@@ -3313,7 +3313,7 @@ static int __init omap_hwmod_setup_all(void)
 
        return 0;
 }
-omap_core_initcall(omap_hwmod_setup_all);
+omap_postcore_initcall(omap_hwmod_setup_all);
 
 /**
  * omap_hwmod_enable - enable an omap_hwmod
index aff78d5..0a98532 100644 (file)
@@ -25,7 +25,6 @@
 #include "l4_3xxx.h"
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/platform_data/iommu-omap.h>
 #include <plat/dmtimer.h>
 
 #include "soc.h"
@@ -2957,80 +2956,40 @@ static struct omap_hwmod_class omap3xxx_mmu_hwmod_class = {
 };
 
 /* mmu isp */
-
-static struct omap_mmu_dev_attr mmu_isp_dev_attr = {
-       .nr_tlb_entries = 8,
-};
-
 static struct omap_hwmod omap3xxx_mmu_isp_hwmod;
-static struct omap_hwmod_irq_info omap3xxx_mmu_isp_irqs[] = {
-       { .irq = 24 + OMAP_INTC_START, },
-       { .irq = -1 }
-};
-
-static struct omap_hwmod_addr_space omap3xxx_mmu_isp_addrs[] = {
-       {
-               .pa_start       = 0x480bd400,
-               .pa_end         = 0x480bd47f,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
 
 /* l4_core -> mmu isp */
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmu_isp = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap3xxx_mmu_isp_hwmod,
-       .addr           = omap3xxx_mmu_isp_addrs,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 static struct omap_hwmod omap3xxx_mmu_isp_hwmod = {
        .name           = "mmu_isp",
        .class          = &omap3xxx_mmu_hwmod_class,
-       .mpu_irqs       = omap3xxx_mmu_isp_irqs,
        .main_clk       = "cam_ick",
-       .dev_attr       = &mmu_isp_dev_attr,
        .flags          = HWMOD_NO_IDLEST,
 };
 
 /* mmu iva */
 
-static struct omap_mmu_dev_attr mmu_iva_dev_attr = {
-       .nr_tlb_entries = 32,
-};
-
 static struct omap_hwmod omap3xxx_mmu_iva_hwmod;
-static struct omap_hwmod_irq_info omap3xxx_mmu_iva_irqs[] = {
-       { .irq = 28 + OMAP_INTC_START, },
-       { .irq = -1 }
-};
 
 static struct omap_hwmod_rst_info omap3xxx_mmu_iva_resets[] = {
        { .name = "mmu", .rst_shift = 1, .st_shift = 9 },
 };
 
-static struct omap_hwmod_addr_space omap3xxx_mmu_iva_addrs[] = {
-       {
-               .pa_start       = 0x5d000000,
-               .pa_end         = 0x5d00007f,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
 /* l3_main -> iva mmu */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__mmu_iva = {
        .master         = &omap3xxx_l3_main_hwmod,
        .slave          = &omap3xxx_mmu_iva_hwmod,
-       .addr           = omap3xxx_mmu_iva_addrs,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
        .name           = "mmu_iva",
        .class          = &omap3xxx_mmu_hwmod_class,
-       .mpu_irqs       = omap3xxx_mmu_iva_irqs,
        .clkdm_name     = "iva2_clkdm",
        .rst_lines      = omap3xxx_mmu_iva_resets,
        .rst_lines_cnt  = ARRAY_SIZE(omap3xxx_mmu_iva_resets),
@@ -3043,7 +3002,6 @@ static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
                        .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
                },
        },
-       .dev_attr       = &mmu_iva_dev_attr,
        .flags          = HWMOD_NO_IDLEST,
 };
 
index a5e444b..dad871a 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <linux/platform_data/iommu-omap.h>
 #include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
@@ -2088,30 +2087,16 @@ static struct omap_hwmod_class omap44xx_mmu_hwmod_class = {
 
 /* mmu ipu */
 
-static struct omap_mmu_dev_attr mmu_ipu_dev_attr = {
-       .nr_tlb_entries = 32,
-};
-
 static struct omap_hwmod omap44xx_mmu_ipu_hwmod;
 static struct omap_hwmod_rst_info omap44xx_mmu_ipu_resets[] = {
        { .name = "mmu_cache", .rst_shift = 2 },
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmu_ipu_addrs[] = {
-       {
-               .pa_start       = 0x55082000,
-               .pa_end         = 0x550820ff,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
 /* l3_main_2 -> mmu_ipu */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_2__mmu_ipu = {
        .master         = &omap44xx_l3_main_2_hwmod,
        .slave          = &omap44xx_mmu_ipu_hwmod,
        .clk            = "l3_div_ck",
-       .addr           = omap44xx_mmu_ipu_addrs,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -2130,35 +2115,20 @@ static struct omap_hwmod omap44xx_mmu_ipu_hwmod = {
                        .modulemode   = MODULEMODE_HWCTRL,
                },
        },
-       .dev_attr       = &mmu_ipu_dev_attr,
 };
 
 /* mmu dsp */
 
-static struct omap_mmu_dev_attr mmu_dsp_dev_attr = {
-       .nr_tlb_entries = 32,
-};
-
 static struct omap_hwmod omap44xx_mmu_dsp_hwmod;
 static struct omap_hwmod_rst_info omap44xx_mmu_dsp_resets[] = {
        { .name = "mmu_cache", .rst_shift = 1 },
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmu_dsp_addrs[] = {
-       {
-               .pa_start       = 0x4a066000,
-               .pa_end         = 0x4a0660ff,
-               .flags          = ADDR_TYPE_RT,
-       },
-       { }
-};
-
 /* l4_cfg -> dsp */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mmu_dsp = {
        .master         = &omap44xx_l4_cfg_hwmod,
        .slave          = &omap44xx_mmu_dsp_hwmod,
        .clk            = "l4_div_ck",
-       .addr           = omap44xx_mmu_dsp_addrs,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -2177,7 +2147,6 @@ static struct omap_hwmod omap44xx_mmu_dsp_hwmod = {
                        .modulemode   = MODULEMODE_HWCTRL,
                },
        },
-       .dev_attr       = &mmu_dsp_dev_attr,
 };
 
 /*
@@ -3915,21 +3884,11 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_elm_addrs[] = {
-       {
-               .pa_start       = 0x48078000,
-               .pa_end         = 0x48078fff,
-               .flags          = ADDR_TYPE_RT
-       },
-       { }
-};
-
 /* l4_per -> elm */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = {
        .master         = &omap44xx_l4_per_hwmod,
        .slave          = &omap44xx_elm_hwmod,
        .clk            = "l4_div_ck",
-       .addr           = omap44xx_elm_addrs,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index ee4e044..848356e 100644 (file)
@@ -2103,7 +2103,7 @@ static struct omap_hwmod dra7xx_uart4_hwmod = {
        .class          = &dra7xx_uart_hwmod_class,
        .clkdm_name     = "l4per_clkdm",
        .main_clk       = "uart4_gfclk_mux",
-       .flags          = HWMOD_SWSUP_SIDLE_ACT,
+       .flags          = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP4UART4_FLAGS,
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = DRA7XX_CM_L4PER_UART4_CLKCTRL_OFFSET,
index 6256052..e493ae3 100644 (file)
  * 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)
+#define DM81XX_CM_DEFAULT_OFFSET       0x500
+#define DM81XX_CM_DEFAULT_USB_CLKCTRL  (0x558 - DM81XX_CM_DEFAULT_OFFSET)
 
 /* L3 Interconnect entries clocked at 125, 250 and 500MHz */
 static struct omap_hwmod dm81xx_alwon_l3_slow_hwmod = {
@@ -557,22 +557,42 @@ static struct omap_hwmod_class dm81xx_usbotg_class = {
        .sysc = &dm81xx_usbhsotg_sysc,
 };
 
-static struct omap_hwmod dm81xx_usbss_hwmod = {
+static struct omap_hwmod dm814x_usbss_hwmod = {
+       .name           = "usb_otg_hs",
+       .clkdm_name     = "default_l3_slow_clkdm",
+       .main_clk       = "pll260dcoclkldo",    /* 481c5260.adpll.dcoclkldo */
+       .prcm           = {
+               .omap4 = {
+                       .clkctrl_offs = DM81XX_CM_DEFAULT_USB_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+       .class          = &dm81xx_usbotg_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_default_l3_slow__usbss = {
+       .master         = &dm81xx_default_l3_slow_hwmod,
+       .slave          = &dm814x_usbss_hwmod,
+       .clk            = "sysclk6_ck",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_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,
+                       .clkctrl_offs = DM81XX_CM_DEFAULT_USB_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
        .class          = &dm81xx_usbotg_class,
 };
 
-static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = {
+static struct omap_hwmod_ocp_if dm816x_default_l3_slow__usbss = {
        .master         = &dm81xx_default_l3_slow_hwmod,
-       .slave          = &dm81xx_usbss_hwmod,
+       .slave          = &dm816x_usbss_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
@@ -599,7 +619,7 @@ static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
 static struct omap_hwmod dm814x_timer1_hwmod = {
        .name           = "timer1",
        .clkdm_name     = "alwon_l3s_clkdm",
-       .main_clk       = "timer_sys_ck",
+       .main_clk       = "timer1_fck",
        .dev_attr       = &capability_alwon_dev_attr,
        .class          = &dm816x_timer_hwmod_class,
        .flags          = HWMOD_NO_IDLEST,
@@ -608,7 +628,7 @@ static struct omap_hwmod dm814x_timer1_hwmod = {
 static struct omap_hwmod_ocp_if dm814x_l4_ls__timer1 = {
        .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm814x_timer1_hwmod,
-       .clk            = "timer_sys_ck",
+       .clk            = "timer1_fck",
        .user           = OCP_USER_MPU,
 };
 
@@ -636,7 +656,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = {
 static struct omap_hwmod dm814x_timer2_hwmod = {
        .name           = "timer2",
        .clkdm_name     = "alwon_l3s_clkdm",
-       .main_clk       = "timer_sys_ck",
+       .main_clk       = "timer2_fck",
        .dev_attr       = &capability_alwon_dev_attr,
        .class          = &dm816x_timer_hwmod_class,
        .flags          = HWMOD_NO_IDLEST,
@@ -645,7 +665,7 @@ static struct omap_hwmod dm814x_timer2_hwmod = {
 static struct omap_hwmod_ocp_if dm814x_l4_ls__timer2 = {
        .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm814x_timer2_hwmod,
-       .clk            = "timer_sys_ck",
+       .clk            = "timer2_fck",
        .user           = OCP_USER_MPU,
 };
 
@@ -912,7 +932,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
+static struct omap_hwmod_class_sysconfig dm81xx_mmc_sysc = {
        .rev_offs       = 0x0,
        .sysc_offs      = 0x110,
        .syss_offs      = 0x114,
@@ -923,24 +943,94 @@ static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
        .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
-static struct omap_hwmod_class dm816x_mmc_class = {
+static struct omap_hwmod_class dm81xx_mmc_class = {
        .name = "mmc",
-       .sysc = &dm816x_mmc_sysc,
+       .sysc = &dm81xx_mmc_sysc,
 };
 
-static struct omap_hwmod_opt_clk dm816x_mmc1_opt_clks[] = {
+static struct omap_hwmod_opt_clk dm81xx_mmc_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_hsmmc_dev_attr mmc_dev_attr = {
+};
+
+static struct omap_hwmod dm814x_mmc1_hwmod = {
+       .name           = "mmc1",
+       .clkdm_name     = "alwon_l3s_clkdm",
+       .opt_clks       = dm81xx_mmc_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dm81xx_mmc_opt_clks),
+       .main_clk       = "sysclk8_ck",
+       .prcm           = {
+               .omap4 = {
+                       .clkctrl_offs = DM814X_CM_ALWON_MMCHS_0_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mmc_dev_attr,
+       .class          = &dm81xx_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_ls__mmc1 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm814x_mmc1_hwmod,
+       .clk            = "sysclk6_ck",
+       .user           = OCP_USER_MPU,
+       .flags          = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod dm814x_mmc2_hwmod = {
+       .name           = "mmc2",
+       .clkdm_name     = "alwon_l3s_clkdm",
+       .opt_clks       = dm81xx_mmc_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dm81xx_mmc_opt_clks),
+       .main_clk       = "sysclk8_ck",
+       .prcm           = {
+               .omap4 = {
+                       .clkctrl_offs = DM814X_CM_ALWON_MMCHS_1_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mmc_dev_attr,
+       .class          = &dm81xx_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_ls__mmc2 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm814x_mmc2_hwmod,
+       .clk            = "sysclk6_ck",
+       .user           = OCP_USER_MPU,
+       .flags          = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod dm814x_mmc3_hwmod = {
+       .name           = "mmc3",
+       .clkdm_name     = "alwon_l3_med_clkdm",
+       .opt_clks       = dm81xx_mmc_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dm81xx_mmc_opt_clks),
+       .main_clk       = "sysclk8_ck",
+       .prcm           = {
+               .omap4 = {
+                       .clkctrl_offs = DM814X_CM_ALWON_MMCHS_2_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+       .dev_attr       = &mmc_dev_attr,
+       .class          = &dm81xx_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_alwon_l3_med__mmc3 = {
+       .master         = &dm81xx_alwon_l3_med_hwmod,
+       .slave          = &dm814x_mmc3_hwmod,
+       .clk            = "sysclk4_ck",
+       .user           = OCP_USER_MPU,
 };
 
 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),
+       .opt_clks       = dm81xx_mmc_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dm81xx_mmc_opt_clks),
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
@@ -948,8 +1038,8 @@ static struct omap_hwmod dm816x_mmc1_hwmod = {
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
-       .dev_attr       = &mmc1_dev_attr,
-       .class          = &dm816x_mmc_class,
+       .dev_attr       = &mmc_dev_attr,
+       .class          = &dm81xx_mmc_class,
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = {
@@ -1036,6 +1126,40 @@ static struct omap_hwmod_ocp_if dm81xx_l4_ls__mailbox = {
        .user           = OCP_USER_MPU,
 };
 
+static struct omap_hwmod_class_sysconfig dm81xx_spinbox_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 dm81xx_spinbox_hwmod_class = {
+       .name = "spinbox",
+       .sysc = &dm81xx_spinbox_sysc,
+};
+
+static struct omap_hwmod dm81xx_spinbox_hwmod = {
+       .name           = "spinbox",
+       .clkdm_name     = "alwon_l3s_clkdm",
+       .class          = &dm81xx_spinbox_hwmod_class,
+       .main_clk       = "sysclk6_ck",
+       .prcm           = {
+               .omap4 = {
+                       .clkctrl_offs = DM81XX_CM_ALWON_SPINBOX_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__spinbox = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_spinbox_hwmod,
+       .user           = OCP_USER_MPU,
+};
+
 static struct omap_hwmod_class dm81xx_tpcc_hwmod_class = {
        .name           = "tpcc",
 };
@@ -1230,11 +1354,7 @@ static struct omap_hwmod_ocp_if dm81xx_tptc3__alwon_l3_fast = {
 
 /*
  * REVISIT: Test and enable the following once clocks work:
- * dm81xx_l4_ls__gpio1
- * dm81xx_l4_ls__gpio2
  * dm81xx_l4_ls__mailbox
- * dm81xx_alwon_l3_slow__gpmc
- * dm81xx_default_l3_slow__usbss
  *
  * Also note that some devices share a single clkctrl_offs..
  * For example, i2c1 and 3 share one, and i2c2 and 4 share one.
@@ -1250,8 +1370,12 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = {
        &dm81xx_l4_ls__wd_timer1,
        &dm81xx_l4_ls__i2c1,
        &dm81xx_l4_ls__i2c2,
+       &dm81xx_l4_ls__gpio1,
+       &dm81xx_l4_ls__gpio2,
        &dm81xx_l4_ls__elm,
        &dm81xx_l4_ls__mcspi1,
+       &dm814x_l4_ls__mmc1,
+       &dm814x_l4_ls__mmc2,
        &dm81xx_alwon_l3_fast__tpcc,
        &dm81xx_alwon_l3_fast__tptc0,
        &dm81xx_alwon_l3_fast__tptc1,
@@ -1265,6 +1389,9 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = {
        &dm814x_l4_ls__timer2,
        &dm814x_l4_hs__cpgmac0,
        &dm814x_cpgmac0__mdio,
+       &dm81xx_alwon_l3_slow__gpmc,
+       &dm814x_default_l3_slow__usbss,
+       &dm814x_alwon_l3_med__mmc3,
        NULL,
 };
 
@@ -1298,6 +1425,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
        &dm816x_l4_ls__timer7,
        &dm81xx_l4_ls__mcspi1,
        &dm81xx_l4_ls__mailbox,
+       &dm81xx_l4_ls__spinbox,
        &dm81xx_l4_hs__emac0,
        &dm81xx_emac0__mdio,
        &dm816x_l4_hs__emac1,
@@ -1311,7 +1439,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
        &dm81xx_tptc2__alwon_l3_fast,
        &dm81xx_tptc3__alwon_l3_fast,
        &dm81xx_alwon_l3_slow__gpmc,
-       &dm81xx_default_l3_slow__usbss,
+       &dm816x_default_l3_slow__usbss,
        NULL,
 };
 
index 5814477..e781e4f 100644 (file)
@@ -150,6 +150,21 @@ static struct platform_device wl18xx_device = {
        }
 };
 
+static struct ti_st_plat_data wilink7_pdata = {
+       .nshutdown_gpio = 162,
+       .dev_name = "/dev/ttyO1",
+       .flow_cntrl = 1,
+       .baud_rate = 300000,
+};
+
+static struct platform_device wl128x_device = {
+       .name   = "kim",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &wilink7_pdata,
+       }
+};
+
 static struct platform_device btwilink_device = {
        .name   = "btwilink",
        .id     = -1,
@@ -265,7 +280,7 @@ static void __init nokia_n900_legacy_init(void)
                        pr_warn("Thumb binaries may crash randomly without this workaround\n");
                }
 
-               pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+               pr_info("RX-51: Registering OMAP3 HWRNG device\n");
                platform_device_register(&omap3_rom_rng_device);
 
        }
@@ -276,6 +291,13 @@ static void __init omap3_tao3530_legacy_init(void)
        hsmmc2_internal_input_clk();
 }
 
+static void __init omap3_logicpd_torpedo_init(void)
+{
+       omap3_gpio126_127_129();
+       platform_device_register(&wl128x_device);
+       platform_device_register(&btwilink_device);
+}
+
 /* omap3pandora legacy devices */
 #define PANDORA_WIFI_IRQ_GPIO          21
 #define PANDORA_WIFI_NRESET_GPIO       23
@@ -503,7 +525,7 @@ static struct pdata_init pdata_quirks[] __initdata = {
        { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
        { "isee,omap3-igep0020-rev-f", omap3_igep0020_rev_f_legacy_init, },
        { "isee,omap3-igep0030-rev-g", omap3_igep0030_rev_g_legacy_init, },
-       { "logicpd,dm3730-torpedo-devkit", omap3_gpio126_127_129, },
+       { "logicpd,dm3730-torpedo-devkit", omap3_logicpd_torpedo_init, },
        { "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
        { "ti,am3517-evm", am3517_evm_legacy_init, },
        { "technexion,omap3-tao3530", omap3_tao3530_legacy_init, },
index 2e00c7f..eb27ae0 100644 (file)
@@ -384,14 +384,14 @@ static struct powerdomain isp_814x_pwrdm = {
        .voltdm         = { .name = "core" },
 };
 
-static struct powerdomain active_816x_pwrdm = {
+static struct powerdomain active_81xx_pwrdm = {
        .name             = "active_pwrdm",
        .prcm_offs        = TI816X_PRM_ACTIVE_MOD,
        .pwrsts           = PWRSTS_OFF_ON,
        .voltdm           = { .name = "core" },
 };
 
-static struct powerdomain default_816x_pwrdm = {
+static struct powerdomain default_81xx_pwrdm = {
        .name             = "default_pwrdm",
        .prcm_offs        = TI81XX_PRM_DEFAULT_MOD,
        .pwrsts           = PWRSTS_OFF_ON,
@@ -486,6 +486,8 @@ static struct powerdomain *powerdomains_am35x[] __initdata = {
 static struct powerdomain *powerdomains_ti814x[] __initdata = {
        &alwon_81xx_pwrdm,
        &device_81xx_pwrdm,
+       &active_81xx_pwrdm,
+       &default_81xx_pwrdm,
        &gem_814x_pwrdm,
        &ivahd_814x_pwrdm,
        &hdvpss_814x_pwrdm,
@@ -497,8 +499,8 @@ static struct powerdomain *powerdomains_ti814x[] __initdata = {
 static struct powerdomain *powerdomains_ti816x[] __initdata = {
        &alwon_81xx_pwrdm,
        &device_81xx_pwrdm,
-       &active_816x_pwrdm,
-       &default_816x_pwrdm,
+       &active_81xx_pwrdm,
+       &default_81xx_pwrdm,
        &ivahd0_816x_pwrdm,
        &ivahd1_816x_pwrdm,
        &ivahd2_816x_pwrdm,
index 3fc2cbe..5b2f513 100644 (file)
@@ -664,6 +664,13 @@ static struct omap_prcm_init_data am3_prm_data __initdata = {
 };
 #endif
 
+#ifdef CONFIG_SOC_TI81XX
+static struct omap_prcm_init_data dm814_pllss_data __initdata = {
+       .index = TI_CLKM_PLLSS,
+       .init = am33xx_prm_init,
+};
+#endif
+
 #ifdef CONFIG_ARCH_OMAP4
 static struct omap_prcm_init_data omap4_prm_data __initdata = {
        .index = TI_CLKM_PRM,
@@ -715,6 +722,7 @@ static const struct of_device_id const omap_prcm_dt_match_table[] __initconst =
 #endif
 #ifdef CONFIG_SOC_TI81XX
        { .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
+       { .compatible = "ti,dm814-pllss", .data = &dm814_pllss_data },
        { .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
 #endif
 #ifdef CONFIG_ARCH_OMAP2
index 5fb50fe..f164c6b 100644 (file)
@@ -213,7 +213,7 @@ static int __init omap_serial_early_init(void)
 
        return 0;
 }
-omap_core_initcall(omap_serial_early_init);
+omap_postcore_initcall(omap_serial_early_init);
 
 /**
  * omap_serial_init_port() - initialize single serial port
index f86692d..5b385bb 100644 (file)
@@ -194,8 +194,8 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
 /**
  * omap_dmtimer_init - initialisation function when device tree is used
  *
- * For secure OMAP3 devices, timers with device type "timer-secure" cannot
- * be used by the kernel as they are reserved. Therefore, to prevent the
+ * For secure OMAP3/DRA7xx devices, timers with device type "timer-secure"
+ * cannot be used by the kernel as they are reserved. Therefore, to prevent the
  * kernel registering these devices remove them dynamically from the device
  * tree on boot.
  */
@@ -203,7 +203,7 @@ static void __init omap_dmtimer_init(void)
 {
        struct device_node *np;
 
-       if (!cpu_is_omap34xx())
+       if (!cpu_is_omap34xx() && !soc_is_dra7xx())
                return;
 
        /* If we are a secure device, remove any secure timer nodes */
index 66f1c95..a9ad95f 100644 (file)
@@ -1,6 +1,18 @@
-if ARCH_ORION5X
+menuconfig ARCH_ORION5X
+       bool "Marvell Orion"
+       depends on MMU && ARCH_MULTI_V5
+       select ARCH_REQUIRE_GPIOLIB
+       select CPU_FEROCEON
+       select GENERIC_CLOCKEVENTS
+       select MVEBU_MBUS
+       select PCI
+       select PLAT_ORION_LEGACY
+       help
+         Support for the following Marvell Orion 5x series SoCs:
+         Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
+         Orion-2 (5281), Orion-1-90 (6183).
 
-menu "Orion Implementations"
+if ARCH_ORION5X
 
 config ARCH_ORION5X_DT
        bool "Marvell Orion5x Flattened Device Tree"
@@ -163,6 +175,4 @@ config MACH_RD88F6183AP_GE
          Say 'Y' here if you want your kernel to support the
          Marvell Orion-1-90 (88F6183) AP GE RD.
 
-endmenu
-
 endif
index a1e0fbe..4b2502b 100644 (file)
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include
+
 obj-y                          += common.o pci.o irq.o mpp.o
 obj-$(CONFIG_MACH_DB88F5281)   += db88f5281-setup.o
 obj-$(CONFIG_MACH_RD88F5182)   += rd88f5182-setup.o
index 8a72841..a89376a 100644 (file)
@@ -20,9 +20,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include <plat/orion-gpio.h>
 #include "common.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * LaCie d2 Network Info
index d087178..6f4c2c4 100644 (file)
 #include <asm/system_misc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <mach/orion5x.h>
-#include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include <plat/time.h>
+#include "orion5x.h"
+#include "bridge-regs.h"
 #include "common.h"
 
 static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
index 66f9c3b..79202fd 100644 (file)
@@ -17,8 +17,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
-#include <mach/bridge-regs.h>
+#include "orion5x.h"
+#include "bridge-regs.h"
 #include "common.h"
 
 /*****************************************************************************
index 270824b..b7b0f52 100644 (file)
@@ -18,8 +18,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * RD-88F5182 Info
diff --git a/arch/arm/mach-orion5x/bridge-regs.h b/arch/arm/mach-orion5x/bridge-regs.h
new file mode 100644 (file)
index 0000000..305598e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Orion CPU Bridge Registers
+ *
+ * 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 __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include "orion5x.h"
+
+#define CPU_CONF               (ORION5X_BRIDGE_VIRT_BASE + 0x100)
+
+#define CPU_CTRL               (ORION5X_BRIDGE_VIRT_BASE + 0x104)
+
+#define RSTOUTn_MASK           (ORION5X_BRIDGE_VIRT_BASE + 0x108)
+#define RSTOUTn_MASK_PHYS      (ORION5X_BRIDGE_PHYS_BASE + 0x108)
+
+#define CPU_SOFT_RESET         (ORION5X_BRIDGE_VIRT_BASE + 0x10c)
+
+#define BRIDGE_CAUSE           (ORION5X_BRIDGE_VIRT_BASE + 0x110)
+
+#define POWER_MNG_CTRL_REG     (ORION5X_BRIDGE_VIRT_BASE + 0x11C)
+
+#define BRIDGE_INT_TIMER1_CLR  (~0x0004)
+
+#define MAIN_IRQ_CAUSE         (ORION5X_BRIDGE_VIRT_BASE + 0x200)
+
+#define MAIN_IRQ_MASK          (ORION5X_BRIDGE_VIRT_BASE + 0x204)
+
+#define TIMER_VIRT_BASE                (ORION5X_BRIDGE_VIRT_BASE + 0x300)
+#define TIMER_PHYS_BASE                (ORION5X_BRIDGE_PHYS_BASE + 0x300)
+#endif
index 6bbb7b5..70c3366 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <mach/bridge-regs.h>
-#include <mach/hardware.h>
-#include <mach/orion5x.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <plat/time.h>
 #include <plat/common.h>
+
+#include "bridge-regs.h"
 #include "common.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * I/O Address Mapping
@@ -184,9 +184,21 @@ static void __init orion5x_crypto_init(void)
 /*****************************************************************************
  * Watchdog
  ****************************************************************************/
+static struct resource orion_wdt_resource[] = {
+               DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04),
+               DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04),
+};
+
+static struct platform_device orion_wdt_device = {
+       .name           = "orion_wdt",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(orion_wdt_resource),
+       .resource       = orion_wdt_resource,
+};
+
 static void __init orion5x_wdt_init(void)
 {
-       orion_wdt_init();
+       platform_device_register(&orion_wdt_device);
 }
 
 
index dc01c4f..12f74b4 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * DB-88F5281 on board devices
@@ -369,6 +369,7 @@ static void __init db88f5281_init(void)
 MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
        /* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = db88f5281_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index bc279a8..cd483bf 100644 (file)
@@ -33,8 +33,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <asm/system_info.h>
-#include <mach/orion5x.h>
 #include <plat/orion-gpio.h>
+#include "orion5x.h"
 #include "common.h"
 #include "mpp.h"
 
@@ -666,6 +666,7 @@ static void __init dns323_init(void)
 MACHINE_START(DNS323, "D-Link DNS-323")
        /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = dns323_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
deleted file mode 100644 (file)
index 5766e3f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/bridge-regs.h
- *
- * Orion CPU Bridge Registers
- *
- * 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 __ASM_ARCH_BRIDGE_REGS_H
-#define __ASM_ARCH_BRIDGE_REGS_H
-
-#include <mach/orion5x.h>
-
-#define CPU_CONF               (ORION5X_BRIDGE_VIRT_BASE + 0x100)
-
-#define CPU_CTRL               (ORION5X_BRIDGE_VIRT_BASE + 0x104)
-
-#define RSTOUTn_MASK           (ORION5X_BRIDGE_VIRT_BASE + 0x108)
-#define RSTOUTn_MASK_PHYS      (ORION5X_BRIDGE_PHYS_BASE + 0x108)
-
-#define CPU_SOFT_RESET         (ORION5X_BRIDGE_VIRT_BASE + 0x10c)
-
-#define BRIDGE_CAUSE           (ORION5X_BRIDGE_VIRT_BASE + 0x110)
-
-#define POWER_MNG_CTRL_REG     (ORION5X_BRIDGE_VIRT_BASE + 0x11C)
-
-#define BRIDGE_INT_TIMER1_CLR  (~0x0004)
-
-#define MAIN_IRQ_CAUSE         (ORION5X_BRIDGE_VIRT_BASE + 0x200)
-
-#define MAIN_IRQ_MASK          (ORION5X_BRIDGE_VIRT_BASE + 0x204)
-
-#define TIMER_VIRT_BASE                (ORION5X_BRIDGE_VIRT_BASE + 0x300)
-#define TIMER_PHYS_BASE                (ORION5X_BRIDGE_PHYS_BASE + 0x300)
-#endif
diff --git a/arch/arm/mach-orion5x/include/mach/entry-macro.S b/arch/arm/mach-orion5x/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 73919a3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for Orion platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <mach/bridge-regs.h>
-
-       .macro  get_irqnr_preamble, base, tmp
-       ldr     \base, =MAIN_IRQ_CAUSE
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       ldr     \irqstat, [\base, #0]           @ main cause
-       ldr     \tmp, [\base, #(MAIN_IRQ_MASK - MAIN_IRQ_CAUSE)] @ main mask
-       mov     \irqnr, #0                      @ default irqnr
-       @ find cause bits that are unmasked
-       ands    \irqstat, \irqstat, \tmp        @ clear Z flag if any
-       clzne   \irqnr, \irqstat                @ calc irqnr
-       rsbne   \irqnr, \irqnr, #32
-       .endm
diff --git a/arch/arm/mach-orion5x/include/mach/hardware.h b/arch/arm/mach-orion5x/include/mach/hardware.h
deleted file mode 100644 (file)
index 3957354..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/hardware.h
- *
- * 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_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include "orion5x.h"
-
-#endif
diff --git a/arch/arm/mach-orion5x/include/mach/irqs.h b/arch/arm/mach-orion5x/include/mach/irqs.h
deleted file mode 100644 (file)
index 2431d99..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/irqs.h
- *
- * IRQ definitions for Orion SoC
- *
- *  Maintainer: Tzachi Perelstein <tzachi@marvell.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 __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H
-
-/*
- * Orion Main Interrupt Controller
- */
-#define IRQ_ORION5X_BRIDGE             (1 + 0)
-#define IRQ_ORION5X_DOORBELL_H2C       (1 + 1)
-#define IRQ_ORION5X_DOORBELL_C2H       (1 + 2)
-#define IRQ_ORION5X_UART0              (1 + 3)
-#define IRQ_ORION5X_UART1              (1 + 4)
-#define IRQ_ORION5X_I2C                        (1 + 5)
-#define IRQ_ORION5X_GPIO_0_7           (1 + 6)
-#define IRQ_ORION5X_GPIO_8_15          (1 + 7)
-#define IRQ_ORION5X_GPIO_16_23         (1 + 8)
-#define IRQ_ORION5X_GPIO_24_31         (1 + 9)
-#define IRQ_ORION5X_PCIE0_ERR          (1 + 10)
-#define IRQ_ORION5X_PCIE0_INT          (1 + 11)
-#define IRQ_ORION5X_USB1_CTRL          (1 + 12)
-#define IRQ_ORION5X_DEV_BUS_ERR                (1 + 14)
-#define IRQ_ORION5X_PCI_ERR            (1 + 15)
-#define IRQ_ORION5X_USB_BR_ERR         (1 + 16)
-#define IRQ_ORION5X_USB0_CTRL          (1 + 17)
-#define IRQ_ORION5X_ETH_RX             (1 + 18)
-#define IRQ_ORION5X_ETH_TX             (1 + 19)
-#define IRQ_ORION5X_ETH_MISC           (1 + 20)
-#define IRQ_ORION5X_ETH_SUM            (1 + 21)
-#define IRQ_ORION5X_ETH_ERR            (1 + 22)
-#define IRQ_ORION5X_IDMA_ERR           (1 + 23)
-#define IRQ_ORION5X_IDMA_0             (1 + 24)
-#define IRQ_ORION5X_IDMA_1             (1 + 25)
-#define IRQ_ORION5X_IDMA_2             (1 + 26)
-#define IRQ_ORION5X_IDMA_3             (1 + 27)
-#define IRQ_ORION5X_CESA               (1 + 28)
-#define IRQ_ORION5X_SATA               (1 + 29)
-#define IRQ_ORION5X_XOR0               (1 + 30)
-#define IRQ_ORION5X_XOR1               (1 + 31)
-
-/*
- * Orion General Purpose Pins
- */
-#define IRQ_ORION5X_GPIO_START 33
-#define NR_GPIO_IRQS           32
-
-#define NR_IRQS                        (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
-
-
-#endif
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
deleted file mode 100644 (file)
index b78ff32..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/orion5x.h
- *
- * Generic definitions of Orion SoC flavors:
- *  Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
- *
- * Maintainer: Tzachi Perelstein <tzachi@marvell.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 __ASM_ARCH_ORION5X_H
-#define __ASM_ARCH_ORION5X_H
-
-/*****************************************************************************
- * Orion Address Maps
- *
- * phys
- * e0000000    PCIe MEM space
- * e8000000    PCI MEM space
- * f0000000    PCIe WA space (Orion-1/Orion-NAS only)
- * f1000000    on-chip peripheral registers
- * f2000000    PCIe I/O space
- * f2100000    PCI I/O space
- * f2200000    SRAM dedicated for the crypto unit
- * f4000000    device bus mappings (boot)
- * fa000000    device bus mappings (cs0)
- * fa800000    device bus mappings (cs2)
- * fc000000    device bus mappings (cs0/cs1)
- *
- * virt                phys            size
- * fe000000    f1000000        1M      on-chip peripheral registers
- * fee00000    f2000000        64K     PCIe I/O space
- * fee10000    f2100000        64K     PCI I/O space
- * fd000000    f0000000        16M     PCIe WA space (Orion-1/Orion-NAS only)
- ****************************************************************************/
-#define ORION5X_REGS_PHYS_BASE         0xf1000000
-#define ORION5X_REGS_VIRT_BASE         IOMEM(0xfe000000)
-#define ORION5X_REGS_SIZE              SZ_1M
-
-#define ORION5X_PCIE_IO_PHYS_BASE      0xf2000000
-#define ORION5X_PCIE_IO_BUS_BASE       0x00000000
-#define ORION5X_PCIE_IO_SIZE           SZ_64K
-
-#define ORION5X_PCI_IO_PHYS_BASE       0xf2100000
-#define ORION5X_PCI_IO_BUS_BASE                0x00010000
-#define ORION5X_PCI_IO_SIZE            SZ_64K
-
-#define ORION5X_SRAM_PHYS_BASE         (0xf2200000)
-#define ORION5X_SRAM_SIZE              SZ_8K
-
-/* Relevant only for Orion-1/Orion-NAS */
-#define ORION5X_PCIE_WA_PHYS_BASE      0xf0000000
-#define ORION5X_PCIE_WA_VIRT_BASE      IOMEM(0xfd000000)
-#define ORION5X_PCIE_WA_SIZE           SZ_16M
-
-#define ORION5X_PCIE_MEM_PHYS_BASE     0xe0000000
-#define ORION5X_PCIE_MEM_SIZE          SZ_128M
-
-#define ORION5X_PCI_MEM_PHYS_BASE      0xe8000000
-#define ORION5X_PCI_MEM_SIZE           SZ_128M
-
-/*******************************************************************************
- * Orion Registers Map
- ******************************************************************************/
-
-#define ORION5X_DDR_PHYS_BASE           (ORION5X_REGS_PHYS_BASE + 0x00000)
-#define  ORION5X_DDR_WINS_BASE          (ORION5X_DDR_PHYS_BASE + 0x1500)
-#define  ORION5X_DDR_WINS_SZ            (0x10)
-#define ORION5X_DDR_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x00000)
-#define ORION5X_DEV_BUS_PHYS_BASE      (ORION5X_REGS_PHYS_BASE + 0x10000)
-#define ORION5X_DEV_BUS_VIRT_BASE      (ORION5X_REGS_VIRT_BASE + 0x10000)
-#define ORION5X_DEV_BUS_REG(x)         (ORION5X_DEV_BUS_VIRT_BASE + (x))
-#define  GPIO_VIRT_BASE                        ORION5X_DEV_BUS_REG(0x0100)
-#define  SPI_PHYS_BASE                 (ORION5X_DEV_BUS_PHYS_BASE + 0x0600)
-#define  I2C_PHYS_BASE                 (ORION5X_DEV_BUS_PHYS_BASE + 0x1000)
-#define  UART0_PHYS_BASE               (ORION5X_DEV_BUS_PHYS_BASE + 0x2000)
-#define  UART0_VIRT_BASE               (ORION5X_DEV_BUS_VIRT_BASE + 0x2000)
-#define  UART1_PHYS_BASE               (ORION5X_DEV_BUS_PHYS_BASE + 0x2100)
-#define  UART1_VIRT_BASE               (ORION5X_DEV_BUS_VIRT_BASE + 0x2100)
-
-#define ORION5X_BRIDGE_VIRT_BASE       (ORION5X_REGS_VIRT_BASE + 0x20000)
-#define ORION5X_BRIDGE_PHYS_BASE       (ORION5X_REGS_PHYS_BASE + 0x20000)
-#define  ORION5X_BRIDGE_WINS_BASE       (ORION5X_BRIDGE_PHYS_BASE)
-#define  ORION5X_BRIDGE_WINS_SZ         (0x80)
-
-#define ORION5X_PCI_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x30000)
-
-#define ORION5X_PCIE_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0x40000)
-
-#define ORION5X_USB0_PHYS_BASE         (ORION5X_REGS_PHYS_BASE + 0x50000)
-#define ORION5X_USB0_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0x50000)
-
-#define ORION5X_XOR_PHYS_BASE          (ORION5X_REGS_PHYS_BASE + 0x60900)
-#define ORION5X_XOR_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x60900)
-
-#define ORION5X_ETH_PHYS_BASE          (ORION5X_REGS_PHYS_BASE + 0x70000)
-#define ORION5X_ETH_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x70000)
-
-#define ORION5X_SATA_PHYS_BASE         (ORION5X_REGS_PHYS_BASE + 0x80000)
-#define ORION5X_SATA_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0x80000)
-
-#define ORION5X_CRYPTO_PHYS_BASE       (ORION5X_REGS_PHYS_BASE + 0x90000)
-
-#define ORION5X_USB1_PHYS_BASE         (ORION5X_REGS_PHYS_BASE + 0xa0000)
-#define ORION5X_USB1_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0xa0000)
-
-/*******************************************************************************
- * Device Bus Registers
- ******************************************************************************/
-#define MPP_0_7_CTRL           ORION5X_DEV_BUS_REG(0x000)
-#define MPP_8_15_CTRL          ORION5X_DEV_BUS_REG(0x004)
-#define MPP_16_19_CTRL         ORION5X_DEV_BUS_REG(0x050)
-#define MPP_DEV_CTRL           ORION5X_DEV_BUS_REG(0x008)
-#define MPP_RESET_SAMPLE       ORION5X_DEV_BUS_REG(0x010)
-#define DEV_BANK_0_PARAM       ORION5X_DEV_BUS_REG(0x45c)
-#define DEV_BANK_1_PARAM       ORION5X_DEV_BUS_REG(0x460)
-#define DEV_BANK_2_PARAM       ORION5X_DEV_BUS_REG(0x464)
-#define DEV_BANK_BOOT_PARAM    ORION5X_DEV_BUS_REG(0x46c)
-#define DEV_BUS_CTRL           ORION5X_DEV_BUS_REG(0x4c0)
-#define DEV_BUS_INT_CAUSE      ORION5X_DEV_BUS_REG(0x4d0)
-#define DEV_BUS_INT_MASK       ORION5X_DEV_BUS_REG(0x4d4)
-
-/*******************************************************************************
- * Supported Devices & Revisions
- ******************************************************************************/
-/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
-#define MV88F5181_DEV_ID       0x5181
-#define MV88F5181_REV_B1       3
-#define MV88F5181L_REV_A0      8
-#define MV88F5181L_REV_A1      9
-/* Orion-NAS (88F5182) */
-#define MV88F5182_DEV_ID       0x5182
-#define MV88F5182_REV_A2       2
-/* Orion-2 (88F5281) */
-#define MV88F5281_DEV_ID       0x5281
-#define MV88F5281_REV_D0       4
-#define MV88F5281_REV_D1       5
-#define MV88F5281_REV_D2       6
-/* Orion-1-90 (88F6183) */
-#define MV88F6183_DEV_ID       0x6183
-#define MV88F6183_REV_B0       3
-
-#endif
diff --git a/arch/arm/mach-orion5x/include/mach/uncompress.h b/arch/arm/mach-orion5x/include/mach/uncompress.h
deleted file mode 100644 (file)
index abd26b5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/uncompress.h
- *
- * Tzachi Perelstein <tzachi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/serial_reg.h>
-#include <mach/orion5x.h>
-
-#define SERIAL_BASE    ((unsigned char *)UART0_PHYS_BASE)
-
-static void putc(const char c)
-{
-       unsigned char *base = SERIAL_BASE;
-       int i;
-
-       for (i = 0; i < 0x1000; i++) {
-               if (base[UART_LSR << 2] & UART_LSR_THRE)
-                       break;
-               barrier();
-       }
-
-       base[UART_TX << 2] = c;
-}
-
-static void flush(void)
-{
-       unsigned char *base = SERIAL_BASE;
-       unsigned char mask;
-       int i;
-
-       mask = UART_LSR_TEMT | UART_LSR_THRE;
-
-       for (i = 0; i < 0x1000; i++) {
-               if ((base[UART_LSR << 2] & mask) == mask)
-                       break;
-               barrier();
-       }
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
index 086ecb8..de980ef 100644 (file)
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <mach/bridge-regs.h>
 #include <plat/orion-gpio.h>
 #include <plat/irq.h>
 #include <asm/exception.h>
+#include "bridge-regs.h"
 #include "common.h"
 
 static int __initdata gpio0_irqs[4] = {
@@ -26,14 +26,6 @@ static int __initdata gpio0_irqs[4] = {
        IRQ_ORION5X_GPIO_24_31,
 };
 
-#ifdef CONFIG_MULTI_IRQ_HANDLER
-/*
- * Compiling with both non-DT and DT support enabled, will
- * break asm irq handler used by non-DT boards. Therefore,
- * we provide a C-style irq handler even for non-DT boards,
- * if MULTI_IRQ_HANDLER is set.
- */
-
 asmlinkage void
 __exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
 {
@@ -47,15 +39,12 @@ __exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
                return;
        }
 }
-#endif
 
 void __init orion5x_init_irq(void)
 {
        orion_irq_init(1, MAIN_IRQ_MASK);
 
-#ifdef CONFIG_MULTI_IRQ_HANDLER
        set_handle_irq(orion5x_legacy_handle_irq);
-#endif
 
        /*
         * Initialize gpiolib for GPIOs 0-31.
diff --git a/arch/arm/mach-orion5x/irqs.h b/arch/arm/mach-orion5x/irqs.h
new file mode 100644 (file)
index 0000000..506c8e0
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * IRQ definitions for Orion SoC
+ *
+ *  Maintainer: Tzachi Perelstein <tzachi@marvell.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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * Orion Main Interrupt Controller
+ */
+#define IRQ_ORION5X_BRIDGE             (1 + 0)
+#define IRQ_ORION5X_DOORBELL_H2C       (1 + 1)
+#define IRQ_ORION5X_DOORBELL_C2H       (1 + 2)
+#define IRQ_ORION5X_UART0              (1 + 3)
+#define IRQ_ORION5X_UART1              (1 + 4)
+#define IRQ_ORION5X_I2C                        (1 + 5)
+#define IRQ_ORION5X_GPIO_0_7           (1 + 6)
+#define IRQ_ORION5X_GPIO_8_15          (1 + 7)
+#define IRQ_ORION5X_GPIO_16_23         (1 + 8)
+#define IRQ_ORION5X_GPIO_24_31         (1 + 9)
+#define IRQ_ORION5X_PCIE0_ERR          (1 + 10)
+#define IRQ_ORION5X_PCIE0_INT          (1 + 11)
+#define IRQ_ORION5X_USB1_CTRL          (1 + 12)
+#define IRQ_ORION5X_DEV_BUS_ERR                (1 + 14)
+#define IRQ_ORION5X_PCI_ERR            (1 + 15)
+#define IRQ_ORION5X_USB_BR_ERR         (1 + 16)
+#define IRQ_ORION5X_USB0_CTRL          (1 + 17)
+#define IRQ_ORION5X_ETH_RX             (1 + 18)
+#define IRQ_ORION5X_ETH_TX             (1 + 19)
+#define IRQ_ORION5X_ETH_MISC           (1 + 20)
+#define IRQ_ORION5X_ETH_SUM            (1 + 21)
+#define IRQ_ORION5X_ETH_ERR            (1 + 22)
+#define IRQ_ORION5X_IDMA_ERR           (1 + 23)
+#define IRQ_ORION5X_IDMA_0             (1 + 24)
+#define IRQ_ORION5X_IDMA_1             (1 + 25)
+#define IRQ_ORION5X_IDMA_2             (1 + 26)
+#define IRQ_ORION5X_IDMA_3             (1 + 27)
+#define IRQ_ORION5X_CESA               (1 + 28)
+#define IRQ_ORION5X_SATA               (1 + 29)
+#define IRQ_ORION5X_XOR0               (1 + 30)
+#define IRQ_ORION5X_XOR1               (1 + 31)
+
+/*
+ * Orion General Purpose Pins
+ */
+#define IRQ_ORION5X_GPIO_START 33
+#define NR_GPIO_IRQS           32
+
+#define ORION5X_NR_IRQS                (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
index fe6a48a..9dc3f59 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * KUROBOX-PRO Info
@@ -383,6 +383,7 @@ static void __init kurobox_pro_init(void)
 MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
        /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = kurobox_pro_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
@@ -397,6 +398,7 @@ MACHINE_END
 MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
        /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = kurobox_pro_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 028ea03..dfdaa8a 100644 (file)
@@ -22,9 +22,9 @@
 #include <linux/gpio.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * Linkstation LS-CHL Info
@@ -320,6 +320,7 @@ static void __init lschl_init(void)
 MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)")
        /* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = lschl_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 32b7129..47ba6e0 100644 (file)
@@ -21,9 +21,9 @@
 #include <linux/gpio.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * Linkstation LS-HGL Info
@@ -267,6 +267,7 @@ static void __init ls_hgl_init(void)
 MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
        /* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = ls_hgl_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 5b70026..19ef185 100644 (file)
@@ -11,8 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
 #include <plat/mpp.h>
+#include "orion5x.h"
 #include "mpp.h"
 #include "common.h"
 
index e032f01..2bf8ec7 100644 (file)
@@ -21,9 +21,9 @@
 #include <linux/ata_platform.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 #define MV2120_NOR_BOOT_BASE   0xf4000000
 #define MV2120_NOR_BOOT_SIZE   SZ_512K
@@ -232,6 +232,7 @@ static void __init mv2120_init(void)
 MACHINE_START(MV2120, "HP Media Vault mv2120")
        /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = mv2120_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index ba73dc7..bf6be4c 100644 (file)
 #include <linux/delay.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/orion5x.h>
 #include <plat/orion-gpio.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * LaCie 2Big Network Info
@@ -423,6 +423,7 @@ static void __init net2big_init(void)
 /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
 MACHINE_START(NET2BIG, "LaCie 2Big Network")
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = net2big_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/orion5x.h b/arch/arm/mach-orion5x/orion5x.h
new file mode 100644 (file)
index 0000000..3364df3
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Generic definitions of Orion SoC flavors:
+ *  Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.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 __ASM_ARCH_ORION5X_H
+#define __ASM_ARCH_ORION5X_H
+
+#include "irqs.h"
+
+/*****************************************************************************
+ * Orion Address Maps
+ *
+ * phys
+ * e0000000    PCIe MEM space
+ * e8000000    PCI MEM space
+ * f0000000    PCIe WA space (Orion-1/Orion-NAS only)
+ * f1000000    on-chip peripheral registers
+ * f2000000    PCIe I/O space
+ * f2100000    PCI I/O space
+ * f2200000    SRAM dedicated for the crypto unit
+ * f4000000    device bus mappings (boot)
+ * fa000000    device bus mappings (cs0)
+ * fa800000    device bus mappings (cs2)
+ * fc000000    device bus mappings (cs0/cs1)
+ *
+ * virt                phys            size
+ * fe000000    f1000000        1M      on-chip peripheral registers
+ * fee00000    f2000000        64K     PCIe I/O space
+ * fee10000    f2100000        64K     PCI I/O space
+ * fd000000    f0000000        16M     PCIe WA space (Orion-1/Orion-NAS only)
+ ****************************************************************************/
+#define ORION5X_REGS_PHYS_BASE         0xf1000000
+#define ORION5X_REGS_VIRT_BASE         IOMEM(0xfe000000)
+#define ORION5X_REGS_SIZE              SZ_1M
+
+#define ORION5X_PCIE_IO_PHYS_BASE      0xf2000000
+#define ORION5X_PCIE_IO_BUS_BASE       0x00000000
+#define ORION5X_PCIE_IO_SIZE           SZ_64K
+
+#define ORION5X_PCI_IO_PHYS_BASE       0xf2100000
+#define ORION5X_PCI_IO_BUS_BASE                0x00010000
+#define ORION5X_PCI_IO_SIZE            SZ_64K
+
+#define ORION5X_SRAM_PHYS_BASE         (0xf2200000)
+#define ORION5X_SRAM_SIZE              SZ_8K
+
+/* Relevant only for Orion-1/Orion-NAS */
+#define ORION5X_PCIE_WA_PHYS_BASE      0xf0000000
+#define ORION5X_PCIE_WA_VIRT_BASE      IOMEM(0xfd000000)
+#define ORION5X_PCIE_WA_SIZE           SZ_16M
+
+#define ORION5X_PCIE_MEM_PHYS_BASE     0xe0000000
+#define ORION5X_PCIE_MEM_SIZE          SZ_128M
+
+#define ORION5X_PCI_MEM_PHYS_BASE      0xe8000000
+#define ORION5X_PCI_MEM_SIZE           SZ_128M
+
+/*******************************************************************************
+ * Orion Registers Map
+ ******************************************************************************/
+
+#define ORION5X_DDR_PHYS_BASE           (ORION5X_REGS_PHYS_BASE + 0x00000)
+#define  ORION5X_DDR_WINS_BASE          (ORION5X_DDR_PHYS_BASE + 0x1500)
+#define  ORION5X_DDR_WINS_SZ            (0x10)
+#define ORION5X_DDR_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x00000)
+#define ORION5X_DEV_BUS_PHYS_BASE      (ORION5X_REGS_PHYS_BASE + 0x10000)
+#define ORION5X_DEV_BUS_VIRT_BASE      (ORION5X_REGS_VIRT_BASE + 0x10000)
+#define ORION5X_DEV_BUS_REG(x)         (ORION5X_DEV_BUS_VIRT_BASE + (x))
+#define  GPIO_VIRT_BASE                        ORION5X_DEV_BUS_REG(0x0100)
+#define  SPI_PHYS_BASE                 (ORION5X_DEV_BUS_PHYS_BASE + 0x0600)
+#define  I2C_PHYS_BASE                 (ORION5X_DEV_BUS_PHYS_BASE + 0x1000)
+#define  UART0_PHYS_BASE               (ORION5X_DEV_BUS_PHYS_BASE + 0x2000)
+#define  UART0_VIRT_BASE               (ORION5X_DEV_BUS_VIRT_BASE + 0x2000)
+#define  UART1_PHYS_BASE               (ORION5X_DEV_BUS_PHYS_BASE + 0x2100)
+#define  UART1_VIRT_BASE               (ORION5X_DEV_BUS_VIRT_BASE + 0x2100)
+
+#define ORION5X_BRIDGE_VIRT_BASE       (ORION5X_REGS_VIRT_BASE + 0x20000)
+#define ORION5X_BRIDGE_PHYS_BASE       (ORION5X_REGS_PHYS_BASE + 0x20000)
+#define  ORION5X_BRIDGE_WINS_BASE       (ORION5X_BRIDGE_PHYS_BASE)
+#define  ORION5X_BRIDGE_WINS_SZ         (0x80)
+
+#define ORION5X_PCI_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x30000)
+
+#define ORION5X_PCIE_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0x40000)
+
+#define ORION5X_USB0_PHYS_BASE         (ORION5X_REGS_PHYS_BASE + 0x50000)
+#define ORION5X_USB0_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0x50000)
+
+#define ORION5X_XOR_PHYS_BASE          (ORION5X_REGS_PHYS_BASE + 0x60900)
+#define ORION5X_XOR_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x60900)
+
+#define ORION5X_ETH_PHYS_BASE          (ORION5X_REGS_PHYS_BASE + 0x70000)
+#define ORION5X_ETH_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x70000)
+
+#define ORION5X_SATA_PHYS_BASE         (ORION5X_REGS_PHYS_BASE + 0x80000)
+#define ORION5X_SATA_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0x80000)
+
+#define ORION5X_CRYPTO_PHYS_BASE       (ORION5X_REGS_PHYS_BASE + 0x90000)
+
+#define ORION5X_USB1_PHYS_BASE         (ORION5X_REGS_PHYS_BASE + 0xa0000)
+#define ORION5X_USB1_VIRT_BASE         (ORION5X_REGS_VIRT_BASE + 0xa0000)
+
+/*******************************************************************************
+ * Device Bus Registers
+ ******************************************************************************/
+#define MPP_0_7_CTRL           ORION5X_DEV_BUS_REG(0x000)
+#define MPP_8_15_CTRL          ORION5X_DEV_BUS_REG(0x004)
+#define MPP_16_19_CTRL         ORION5X_DEV_BUS_REG(0x050)
+#define MPP_DEV_CTRL           ORION5X_DEV_BUS_REG(0x008)
+#define MPP_RESET_SAMPLE       ORION5X_DEV_BUS_REG(0x010)
+#define DEV_BANK_0_PARAM       ORION5X_DEV_BUS_REG(0x45c)
+#define DEV_BANK_1_PARAM       ORION5X_DEV_BUS_REG(0x460)
+#define DEV_BANK_2_PARAM       ORION5X_DEV_BUS_REG(0x464)
+#define DEV_BANK_BOOT_PARAM    ORION5X_DEV_BUS_REG(0x46c)
+#define DEV_BUS_CTRL           ORION5X_DEV_BUS_REG(0x4c0)
+#define DEV_BUS_INT_CAUSE      ORION5X_DEV_BUS_REG(0x4d0)
+#define DEV_BUS_INT_MASK       ORION5X_DEV_BUS_REG(0x4d4)
+
+/*******************************************************************************
+ * Supported Devices & Revisions
+ ******************************************************************************/
+/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
+#define MV88F5181_DEV_ID       0x5181
+#define MV88F5181_REV_B1       3
+#define MV88F5181L_REV_A0      8
+#define MV88F5181L_REV_A1      9
+/* Orion-NAS (88F5182) */
+#define MV88F5182_DEV_ID       0x5182
+#define MV88F5182_REV_A2       2
+/* Orion-2 (88F5281) */
+#define MV88F5281_DEV_ID       0x5281
+#define MV88F5281_REV_D0       4
+#define MV88F5281_REV_D1       5
+#define MV88F5281_REV_D2       6
+/* Orion-1-90 (88F6183) */
+#define MV88F6183_DEV_ID       0x6183
+#define MV88F6183_REV_B0       3
+
+#endif
index b02f394..ecb998e 100644 (file)
@@ -19,8 +19,8 @@
 #include <asm/mach/pci.h>
 #include <plat/pcie.h>
 #include <plat/addr-map.h>
-#include <mach/orion5x.h>
 #include "common.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * Orion has one PCIe controller and one PCI controller.
index 213b3e1..c742e7b 100644 (file)
@@ -20,9 +20,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * RD-88F5181L FXO Info
@@ -169,6 +169,7 @@ subsys_initcall(rd88f5181l_fxo_pci_init);
 MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design")
        /* Maintainer: Nicolas Pitre <nico@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = rd88f5181l_fxo_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 594800e..7e977b7 100644 (file)
@@ -21,9 +21,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * RD-88F5181L GE Info
@@ -181,6 +181,7 @@ subsys_initcall(rd88f5181l_ge_pci_init);
 MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design")
        /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = rd88f5181l_ge_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index b576ef5..fe3e67c 100644 (file)
@@ -23,9 +23,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * RD-88F5182 Info
@@ -281,6 +281,7 @@ static void __init rd88f5182_init(void)
 MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
        /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = rd88f5182_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 78a1e6a..4bf80dd 100644 (file)
@@ -22,8 +22,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
+#include "orion5x.h"
 
 static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
        .phy_addr       = -1,
@@ -119,6 +119,7 @@ subsys_initcall(rd88f6183ap_ge_pci_init);
 MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")
        /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = rd88f6183ap_ge_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 1208674..deb5e29 100644 (file)
@@ -22,9 +22,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 
 /*****************************************************************************
  * Terastation Pro 2/Live Info
@@ -359,6 +359,7 @@ static void __init tsp2_init(void)
 MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
        /* Maintainer:  Sylver Bruneau <sylver.bruneau@googlemail.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = tsp2_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index c725b7c..7bd671b 100644 (file)
@@ -25,9 +25,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 #include "tsx09-common.h"
 
 #define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
@@ -324,6 +324,7 @@ static void __init qnap_ts209_init(void)
 MACHINE_START(TS209, "QNAP TS-109/TS-209")
        /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = qnap_ts209_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index cf2ab53..a77613b 100644 (file)
@@ -27,9 +27,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 #include "tsx09-common.h"
 
 /*****************************************************************************
@@ -313,6 +313,7 @@ static void __init qnap_ts409_init(void)
 MACHINE_START(TS409, "QNAP TS-409")
        /* Maintainer:  Sylver Bruneau <sylver.bruneau@gmail.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = qnap_ts409_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 96cf6b5..3a58a5d 100644 (file)
@@ -23,9 +23,9 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "orion5x.h"
 #include "ts78xx-fpga.h"
 
 /*****************************************************************************
@@ -615,6 +615,7 @@ static void __init ts78xx_init(void)
 MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
        /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = ts78xx_init,
        .map_io         = ts78xx_map_io,
        .init_early     = orion5x_init_early,
index d42e006..8977498 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/timex.h>
 #include <linux/serial_reg.h>
-#include <mach/orion5x.h>
+#include "orion5x.h"
 #include "tsx09-common.h"
 #include "common.h"
 
index 80a56ee..4e1e5c8 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
+#include "orion5x.h"
 #include "common.h"
 #include "mpp.h"
 
@@ -174,6 +174,7 @@ subsys_initcall(wnr854t_pci_init);
 MACHINE_START(WNR854T, "Netgear WNR854T")
        /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = wnr854t_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 670e30d..61e9027 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
-#include <mach/orion5x.h>
+#include "orion5x.h"
 #include "common.h"
 #include "mpp.h"
 
@@ -262,6 +262,7 @@ subsys_initcall(wrt350n_v2_pci_init);
 MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")
        /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = ORION5X_NR_IRQS,
        .init_machine   = wrt350n_v2_init,
        .map_io         = orion5x_map_io,
        .init_early     = orion5x_init_early,
index 62240f6..aef92ba 100644 (file)
@@ -1,5 +1,6 @@
 config ARCH_PICOXCELL
-       bool "Picochip PicoXcell" if ARCH_MULTI_V6
+       bool "Picochip PicoXcell"
+       depends on ARCH_MULTI_V6
        select ARCH_REQUIRE_GPIOLIB
        select ARM_VIC
        select DW_APB_TIMER_OF
index 9ab8932..f998eb1 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_SIRF
-       bool "CSR SiRF" if ARCH_MULTI_V7
+       bool "CSR SiRF"
+       depends on ARCH_MULTI_V7
        select ARCH_HAS_RESET_CONTROLLER
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_IRQ_CHIP
index 3916a66..6d77b62 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/mach/time.h>
 #include <asm/exception.h>
 
-extern struct smp_operations   sirfsoc_smp_ops;
+extern const struct smp_operations sirfsoc_smp_ops;
 extern void sirfsoc_secondary_startup(void);
 extern void sirfsoc_cpu_die(unsigned int cpu);
 
index e46c910..0875b99 100644 (file)
@@ -112,7 +112,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
        return pen_release != -1 ? -ENOSYS : 0;
 }
 
-struct smp_operations sirfsoc_smp_ops __initdata = {
+const struct smp_operations sirfsoc_smp_ops __initconst = {
        .smp_secondary_init     = sirfsoc_secondary_init,
        .smp_boot_secondary     = sirfsoc_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index 12fb0f4..50e18ed 100644 (file)
@@ -30,8 +30,8 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 
-#include <mach/pxa25x.h>
-#include <mach/gumstix.h>
+#include "pxa25x.h"
+#include "gumstix.h"
 #include <linux/platform_data/video-pxafb.h>
 
 #include "generic.h"
index 8b90c4f..17d08ab 100644 (file)
@@ -28,8 +28,8 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 
-#include <mach/gumstix.h>
-#include <mach/mfp-pxa25x.h>
+#include "gumstix.h"
+#include "mfp-pxa25x.h"
 #include <mach/irqs.h>
 #include <linux/platform_data/video-pxafb.h>
 
index 7734ec4..8a3c409 100644 (file)
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/balloon3.h>
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/pxa27x-udc.h>
+#include "udc.h"
+#include "pxa27x-udc.h"
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 
index bf366b3..1c3cbfc 100644 (file)
@@ -29,8 +29,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa320.h>
-#include <mach/mxm8x10.h>
+#include "pxa320.h"
+#include "mxm8x10.h"
 
 #include "generic.h"
 
index be75147..b592f79 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 
 #include "generic.h"
 
index 2503db9..fa5f51d 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/libertas_spi.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/mmc-pxamci.h>
 
index a17a91e..7202022 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #undef GPIO24_SSP1_SFRM
-#include <mach/pxa27x.h>
+#undef GPIO86_GPIO
+#undef GPIO87_GPIO
+#undef GPIO88_GPIO
+#undef GPIO89_GPIO
+#include "pxa27x.h"
+#undef GPIO24_SSP1_SFRM
+#undef GPIO86_GPIO
+#undef GPIO87_GPIO
+#undef GPIO88_GPIO
+#undef GPIO89_GPIO
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <mach/smemc.h>
index a7dae60..5f5ac7c 100644 (file)
@@ -47,8 +47,8 @@
 #include <asm/setup.h>
 #include <asm/system_info.h>
 
-#include <mach/pxa300.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa300.h"
+#include "pxa27x-udc.h"
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
index 638b0bb..dc44fbb 100644 (file)
 #include <linux/i2c/pxa-i2c.h>
 #include <asm/io.h>
 
-#include <mach/pxa27x.h>
-#include <mach/colibri.h>
+#include "pxa27x.h"
+#include "colibri.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x-udc.h"
 
 #include "generic.h"
 #include "devices.h"
index db20d25..8cff770 100644 (file)
@@ -30,8 +30,8 @@
 #include <mach/hardware.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "pxa27x-udc.h"
 #include <linux/platform_data/video-pxafb.h>
 
 #include "devices.h"
index 3503826..e68acdd 100644 (file)
@@ -27,8 +27,8 @@
 #include <asm/sizes.h>
 
 #include <mach/audio.h>
-#include <mach/colibri.h>
-#include <mach/pxa27x.h>
+#include "colibri.h"
+#include "pxa27x.h"
 
 #include "devices.h"
 #include "generic.h"
index f1a1ac1..6a5558d 100644 (file)
@@ -22,8 +22,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa300.h>
-#include <mach/colibri.h>
+#include "pxa300.h"
+#include "colibri.h"
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <mach/audio.h>
index f6cc8b0..17067a3 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa320.h>
-#include <mach/colibri.h>
+#include "pxa320.h"
+#include "colibri.h"
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <mach/audio.h>
-#include <mach/pxa27x-udc.h>
-#include <mach/udc.h>
+#include "pxa27x-udc.h"
+#include "udc.h"
 
 #include "generic.h"
 #include "devices.h"
index 8240291..b04431b 100644 (file)
@@ -22,8 +22,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa300.h>
-#include <mach/colibri.h>
+#include "mfp-pxa300.h"
+#include "colibri.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mtd-nand-pxa3xx.h>
diff --git a/arch/arm/mach-pxa/colibri.h b/arch/arm/mach-pxa/colibri.h
new file mode 100644 (file)
index 0000000..cb4236e
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef _COLIBRI_H_
+#define _COLIBRI_H_
+
+#include <net/ax88796.h>
+#include <mach/mfp.h>
+
+/*
+ * base board glue for PXA270 module
+ */
+
+enum {
+       COLIBRI_EVALBOARD = 0,
+       COLIBRI_PXA270_INCOME,
+};
+
+#if defined(CONFIG_MACH_COLIBRI_EVALBOARD)
+extern void colibri_evalboard_init(void);
+#else
+static inline void colibri_evalboard_init(void) {}
+#endif
+
+#if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME)
+extern void colibri_pxa270_income_boardinit(void);
+#else
+static inline void colibri_pxa270_income_boardinit(void) {}
+#endif
+
+/*
+ * common settings for all modules
+ */
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+extern void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin);
+#else
+static inline void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+extern void colibri_pxa3xx_init_lcd(int bl_pin);
+#else
+static inline void colibri_pxa3xx_init_lcd(int bl_pin) {}
+#endif
+
+#if defined(CONFIG_AX88796)
+extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+extern void colibri_pxa3xx_init_nand(void);
+#else
+static inline void colibri_pxa3xx_init_nand(void) {}
+#endif
+
+/* physical memory regions */
+#define COLIBRI_SDRAM_BASE     0xa0000000      /* SDRAM region */
+
+/* GPIO definitions for Colibri PXA270 */
+#define GPIO114_COLIBRI_PXA270_ETH_IRQ 114
+#define GPIO0_COLIBRI_PXA270_SD_DETECT 0
+#define GPIO113_COLIBRI_PXA270_TS_IRQ  113
+
+/* GPIO definitions for Colibri PXA300/310 */
+#define GPIO13_COLIBRI_PXA300_SD_DETECT        13
+
+/* GPIO definitions for Colibri PXA320 */
+#define GPIO28_COLIBRI_PXA320_SD_DETECT        28
+
+#endif /* _COLIBRI_H_ */
+
index 89f790d..dc109dc 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <mach/corgi.h>
-#include <mach/sharpsl_pm.h>
+#include "sharpsl_pm.h"
 
 #include <asm/mach/sharpsl_param.h>
 #include <asm/hardware/scoop.h>
index 7a39efc..d920681 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <mach/corgi.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/sharpsl_pm.h>
+#include "sharpsl_pm.h"
 
 #include "generic.h"
 
index fadfff8..bf19b84 100644 (file)
@@ -21,8 +21,8 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/csb726.h>
-#include <mach/pxa27x.h>
+#include "csb726.h"
+#include "pxa27x.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <mach/audio.h>
diff --git a/arch/arm/mach-pxa/csb726.h b/arch/arm/mach-pxa/csb726.h
new file mode 100644 (file)
index 0000000..f1f2a78
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  Support for Cogent CSB726
+ *
+ *  Copyright (c) 2008 Dmitry Baryshkov
+ *
+ *  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 CSB726_H
+#define CSB726_H
+
+#include <mach/irqs.h> /* PXA_GPIO_TO_IRQ */
+
+#define CSB726_GPIO_IRQ_LAN    52
+#define CSB726_GPIO_IRQ_SM501  53
+#define CSB726_GPIO_MMC_DETECT 100
+#define CSB726_GPIO_MMC_RO     101
+
+#define CSB726_FLASH_SIZE      (64 * 1024 * 1024)
+#define CSB726_FLASH_uMON      (8 * 1024 * 1024)
+
+#define CSB726_IRQ_LAN         PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_LAN)
+#define CSB726_IRQ_SM501       PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_SM501)
+
+#endif
+
index d1211a4..37d8d85 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/i2c/pxa-i2c.h>
 
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/usb-pxa3xx-ulpi.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
index 2a76c4e..6e0268d 100644 (file)
@@ -39,8 +39,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "pxa27x-udc.h"
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
diff --git a/arch/arm/mach-pxa/eseries-irq.h b/arch/arm/mach-pxa/eseries-irq.h
new file mode 100644 (file)
index 0000000..de292b2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  eseries-irq.h
+ *
+ *  Copyright (C) Ian Molton <spyro@f2s.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.
+ *
+ */
+
+#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8)
+#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n))
+
+#define ANGELX_RDY0_IRQ IRQ_ANGELX(0)
+#define ANGELX_ST0_IRQ  IRQ_ANGELX(1)
+#define ANGELX_CD0_IRQ  IRQ_ANGELX(2)
+#define ANGELX_RDY1_IRQ IRQ_ANGELX(3)
+#define ANGELX_ST1_IRQ  IRQ_ANGELX(4)
+#define ANGELX_CD1_IRQ  IRQ_ANGELX(5)
+
+#define TMIO_IRQ_BASE (IRQ_BOARD_START+0)
+#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n))
+
+#define TMIO_SD_IRQ     IRQ_TMIO(1)
+#define TMIO_USB_IRQ    IRQ_TMIO(2)
+
+#define ESERIES_NR_IRQS        (IRQ_BOARD_START + 16)
index 16dc95f..0b00b22 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/eseries-gpio.h>
-#include <mach/eseries-irq.h>
+#include "eseries-irq.h"
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/irda-pxaficp.h>
 
 #include "devices.h"
index cd62240..34ad0a8 100644 (file)
@@ -29,7 +29,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <mach/hardware.h>
@@ -50,7 +50,7 @@
 #define GPIO19_GEN1_CAM_RST            19
 #define GPIO28_GEN2_CAM_RST            28
 
-static struct pwm_lookup ezx_pwm_lookup[] = {
+static struct pwm_lookup ezx_pwm_lookup[] __maybe_unused = {
        PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78700,
                   PWM_POLARITY_NORMAL),
 };
@@ -83,7 +83,7 @@ static struct pxafb_mode_info mode_ezx_old = {
        .sync                   = 0,
 };
 
-static struct pxafb_mach_info ezx_fb_info_1 = {
+static struct pxafb_mach_info ezx_fb_info_1 __maybe_unused = {
        .modes          = &mode_ezx_old,
        .num_modes      = 1,
        .lcd_conn       = LCD_COLOR_TFT_16BPP,
@@ -104,17 +104,17 @@ static struct pxafb_mode_info mode_72r89803y01 = {
        .sync                   = 0,
 };
 
-static struct pxafb_mach_info ezx_fb_info_2 = {
+static struct pxafb_mach_info ezx_fb_info_2 __maybe_unused = {
        .modes          = &mode_72r89803y01,
        .num_modes      = 1,
        .lcd_conn       = LCD_COLOR_TFT_18BPP,
 };
 
-static struct platform_device *ezx_devices[] __initdata = {
+static struct platform_device *ezx_devices[] __initdata __maybe_unused = {
        &ezx_backlight_device,
 };
 
-static unsigned long ezx_pin_config[] __initdata = {
+static unsigned long ezx_pin_config[] __initdata __maybe_unused = {
        /* PWM backlight */
        GPIO16_PWM0_OUT,
 
index f6c76a3..6815a93 100644 (file)
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/gumstix.h>
+#include "udc.h"
+#include "gumstix.h"
 
 #include "generic.h"
 
diff --git a/arch/arm/mach-pxa/gumstix.h b/arch/arm/mach-pxa/gumstix.h
new file mode 100644 (file)
index 0000000..825f2d1
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  arch/arm/mach-pxa/include/mach/gumstix.h
+ *
+ * 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 <mach/irqs.h> /* PXA_GPIO_TO_IRQ */
+
+/* BTRESET - Reset line to Bluetooth module, active low signal. */
+#define GPIO_GUMSTIX_BTRESET          7
+#define GPIO_GUMSTIX_BTRESET_MD                (GPIO_GUMSTIX_BTRESET | GPIO_OUT)
+
+
+/*
+GPIOn - Input from MAX823 (or equiv), normalizing USB +5V into a clean
+interrupt signal for determining cable presence. On the gumstix F,
+this moves to GPIO17 and GPIO37. */
+
+/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn
+has detected a cable insertion; driven low otherwise. */
+
+#define GPIO_GUMSTIX_USB_GPIOn         35
+#define GPIO_GUMSTIX_USB_GPIOx         41
+
+/* usb state change */
+#define GUMSTIX_USB_INTR_IRQ           PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_USB_GPIOn)
+
+#define GPIO_GUMSTIX_USB_GPIOn_MD      (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN)
+#define GPIO_GUMSTIX_USB_GPIOx_CON_MD  (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
+#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD  (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN)
+
+/*
+ * SD/MMC definitions
+ */
+#define GUMSTIX_GPIO_nSD_WP            22 /* SD Write Protect */
+#define GUMSTIX_GPIO_nSD_DETECT                11 /* MMC/SD Card Detect */
+#define GUMSTIX_IRQ_GPIO_nSD_DETECT    PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT)
+
+/*
+ * SMC Ethernet definitions
+ * ETH_RST provides a hardware reset line to the ethernet chip
+ * ETH is the IRQ line in from the ethernet chip to the PXA
+ */
+#define GPIO_GUMSTIX_ETH0_RST          80
+#define GPIO_GUMSTIX_ETH0_RST_MD       (GPIO_GUMSTIX_ETH0_RST | GPIO_OUT)
+#define GPIO_GUMSTIX_ETH1_RST          52
+#define GPIO_GUMSTIX_ETH1_RST_MD       (GPIO_GUMSTIX_ETH1_RST | GPIO_OUT)
+
+#define GPIO_GUMSTIX_ETH0              36
+#define GPIO_GUMSTIX_ETH0_MD           (GPIO_GUMSTIX_ETH0 | GPIO_IN)
+#define GUMSTIX_ETH0_IRQ               PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0)
+#define GPIO_GUMSTIX_ETH1              27
+#define GPIO_GUMSTIX_ETH1_MD           (GPIO_GUMSTIX_ETH1 | GPIO_IN)
+#define GUMSTIX_ETH1_IRQ               PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1)
+
+
+/* CF reset line */
+#define GPIO8_RESET                    8
+
+/* CF slot 0 */
+#define GPIO4_nBVD1                    4
+#define GPIO4_nSTSCHG                  GPIO4_nBVD1
+#define GPIO11_nCD                     11
+#define GPIO26_PRDY_nBSY               26
+#define GUMSTIX_S0_nSTSCHG_IRQ         PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG)
+#define GUMSTIX_S0_nCD_IRQ             PXA_GPIO_TO_IRQ(GPIO11_nCD)
+#define GUMSTIX_S0_PRDY_nBSY_IRQ       PXA_GPIO_TO_IRQ(GPIO26_PRDY_nBSY)
+
+/* CF slot 1 */
+#define GPIO18_nBVD1                   18
+#define GPIO18_nSTSCHG                 GPIO18_nBVD1
+#define GPIO36_nCD                     36
+#define GPIO27_PRDY_nBSY               27
+#define GUMSTIX_S1_nSTSCHG_IRQ         PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG)
+#define GUMSTIX_S1_nCD_IRQ             PXA_GPIO_TO_IRQ(GPIO36_nCD)
+#define GUMSTIX_S1_PRDY_nBSY_IRQ       PXA_GPIO_TO_IRQ(GPIO27_PRDY_nBSY)
+
+/* CF GPIO line modes */
+#define GPIO4_nSTSCHG_MD               (GPIO4_nSTSCHG | GPIO_IN)
+#define GPIO8_RESET_MD                 (GPIO8_RESET | GPIO_OUT)
+#define GPIO11_nCD_MD                  (GPIO11_nCD | GPIO_IN)
+#define GPIO18_nSTSCHG_MD              (GPIO18_nSTSCHG | GPIO_IN)
+#define GPIO26_PRDY_nBSY_MD            (GPIO26_PRDY_nBSY | GPIO_IN)
+#define GPIO27_PRDY_nBSY_MD            (GPIO27_PRDY_nBSY | GPIO_IN)
+#define GPIO36_nCD_MD                  (GPIO36_nCD | GPIO_IN)
+
+/* for expansion boards that can't be programatically detected */
+extern int am200_init(void);
+extern int am300_init(void);
+
index 875ec33..be2a9c3 100644 (file)
@@ -30,9 +30,9 @@
 #include <asm/mach/map.h>
 #include <asm/irq.h>
 
-#include <mach/pxa25x.h>
-#include <mach/h5000.h>
-#include <mach/udc.h>
+#include "pxa25x.h"
+#include "h5000.h"
+#include "udc.h"
 #include <mach/smemc.h>
 
 #include "generic.h"
diff --git a/arch/arm/mach-pxa/h5000.h b/arch/arm/mach-pxa/h5000.h
new file mode 100644 (file)
index 0000000..252461f
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Hardware definitions for HP iPAQ h5xxx Handheld Computers
+ *
+ * Copyright(20)02 Hewlett-Packard Company.
+ *
+ * This program is free software; 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.
+ *
+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * Author: Jamey Hicks
+ */
+
+#ifndef __ASM_ARCH_H5000_H
+#define __ASM_ARCH_H5000_H
+
+#include "mfp-pxa25x.h"
+
+/*
+ * CPU GPIOs
+ */
+
+#define H5000_GPIO_POWER_BUTTON   (0)
+#define H5000_GPIO_RESET_BUTTON_N (1)
+#define H5000_GPIO_OPT_INT        (2)
+#define H5000_GPIO_BACKUP_POWER   (3)
+#define H5000_GPIO_ACTION_BUTTON  (4)
+#define H5000_GPIO_COM_DCD_SOMETHING  (5) /* what is this really ? */
+/* 6 not connected */
+#define H5000_GPIO_RESET_BUTTON_AGAIN_N (7) /* connected to gpio 1 as well */
+/* 8 not connected */
+#define H5000_GPIO_RSO_N          (9)       /* reset output from max1702 which regulates 3.3 and 2.5 */
+#define H5000_GPIO_ASIC_INT_N   (10)       /* from companion asic */
+#define H5000_GPIO_BT_ENV_0     (11)       /* to LMX9814, set to 1 according to regdump */
+/*(12) not connected */
+#define H5000_GPIO_BT_ENV_1     (13)       /* to LMX9814, set to 1 according to regdump */
+#define H5000_GPIO_BT_WU        (14)       /* from LMX9814, Defined as HOST_WAKEUP in the LMX9820 data sheet */
+/*(15) is CS1# */
+/*(16) not connected */
+/*(17) not connected */
+/*(18) is pcmcia ready */
+/*(19) is dreq1 */
+/*(20) is dreq0 */
+#define H5000_GPIO_OE_RD_NWR   (21)       /* output enable on rd/nwr signal to companion asic */
+/*(22) is not connected */
+#define H5000_GPIO_OPT_SPI_CLK  (23)       /* to extension pack */
+#define H5000_GPIO_OPT_SPI_CS_N (24)       /* to extension pack */
+#define H5000_GPIO_OPT_SPI_DOUT (25)       /* to extension pack */
+#define H5000_GPIO_OPT_SPI_DIN  (26)       /* to extension pack */
+/*(27) not connected */
+#define H5000_GPIO_I2S_BITCLK   (28)       /* connected to AC97 codec */
+#define H5000_GPIO_I2S_DATAOUT  (29)       /* connected to AC97 codec */
+#define H5000_GPIO_I2S_DATAIN   (30)       /* connected to AC97 codec */
+#define H5000_GPIO_I2S_LRCLK    (31)       /* connected to AC97 codec */
+#define H5000_GPIO_I2S_SYSCLK   (32)       /* connected to AC97 codec */
+/*(33) is CS5# */
+#define H5000_GPIO_COM_RXD      (34)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_CTS      (35)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_DCD      (36)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_DSR      (37)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_RI       (38)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_TXD      (39)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_DTR      (40)       /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_RTS      (41)       /* connected to cradle/cable connector */
+
+#define H5000_GPIO_BT_RXD       (42)       /* connected to BT (LMX9814) */
+#define H5000_GPIO_BT_TXD       (43)       /* connected to BT (LMX9814) */
+#define H5000_GPIO_BT_CTS       (44)       /* connected to BT (LMX9814) */
+#define H5000_GPIO_BT_RTS       (45)       /* connected to BT (LMX9814) */
+
+#define H5000_GPIO_IRDA_RXD     (46)
+#define H5000_GPIO_IRDA_TXD     (47)
+
+#define H5000_GPIO_POE_N        (48)       /* used for pcmcia */
+#define H5000_GPIO_PWE_N        (49)       /* used for pcmcia */
+#define H5000_GPIO_PIOR_N       (50)       /* used for pcmcia */
+#define H5000_GPIO_PIOW_N       (51)       /* used for pcmcia */
+#define H5000_GPIO_PCE1_N       (52)       /* used for pcmcia */
+#define H5000_GPIO_PCE2_N       (53)       /* used for pcmcia */
+#define H5000_GPIO_PSKTSEL      (54)       /* used for pcmcia */
+#define H5000_GPIO_PREG_N       (55)       /* used for pcmcia */
+#define H5000_GPIO_PWAIT_N      (56)       /* used for pcmcia */
+#define H5000_GPIO_IOIS16_N     (57)       /* used for pcmcia */
+
+#define H5000_GPIO_IRDA_SD      (58)       /* to hsdl3002 sd */
+/*(59) not connected */
+#define H5000_GPIO_POWER_SD_N   (60)       /* controls power to SD */
+#define H5000_GPIO_POWER_RS232_N       (61)       /* inverted FORCEON to rs232 transceiver */
+#define H5000_GPIO_POWER_ACCEL_N       (62)       /* controls power to accel */
+/*(63) is not connected */
+#define H5000_GPIO_OPT_NVRAM    (64)       /* controls power to expansion pack */
+#define H5000_GPIO_CHG_EN       (65)       /* to sc801 en */
+#define H5000_GPIO_USB_PULLUP   (66)       /* USB d+ pullup via 1.5K resistor */
+#define H5000_GPIO_BT_2V8_N     (67)       /* 2.8V used by bluetooth */
+#define H5000_GPIO_EXT_CHG_RATE (68)       /* enables external charging rate */
+/*(69) is not connected */
+#define H5000_GPIO_CIR_RESET    (70)       /* consumer IR reset */
+#define H5000_GPIO_POWER_LIGHT_SENSOR_N        (71)
+#define H5000_GPIO_BT_M_RESET   (72)
+#define H5000_GPIO_STD_CHG_RATE (73)
+#define H5000_GPIO_SD_WP_N      (74)
+#define H5000_GPIO_MOTOR_ON_N   (75)       /* external pullup on this */
+#define H5000_GPIO_HEADPHONE_DETECT    (76)
+#define H5000_GPIO_USB_CHG_RATE (77)       /* select rate for charging via usb */
+/*(78) is CS2# */
+/*(79) is CS3# */
+/*(80) is CS4# */
+
+#endif /* __ASM_ARCH_H5000_H */
index 7a8d749..70e9c06 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 
 #include "generic.h"
 
index b076a83..4a2f9ab 100644 (file)
@@ -44,7 +44,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/hx4700.h>
 #include <linux/platform_data/irda-pxaficp.h>
 
index a1869f9..cbaf4f6 100644 (file)
@@ -20,8 +20,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa320.h>
-#include <mach/mxm8x10.h>
+#include "pxa320.h"
+#include "mxm8x10.h"
 
 #include <linux/spi/spi.h>
 #include <linux/spi/pxa2xx_spi.h>
index f6d02e4..c410d84 100644 (file)
@@ -31,8 +31,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa25x.h>
-#include <mach/idp.h>
+#include "pxa25x.h"
+#include "idp.h"
 #include <linux/platform_data/video-pxafb.h>
 #include <mach/bitfield.h>
 #include <linux/platform_data/mmc-pxamci.h>
diff --git a/arch/arm/mach-pxa/idp.h b/arch/arm/mach-pxa/idp.h
new file mode 100644 (file)
index 0000000..7182ff9
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ *  arch/arm/mach-pxa/include/mach/idp.h
+ *
+ * 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.
+ *
+ * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
+ *
+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
+ *             Initial code
+ *
+ * 2005-02-15: Cliff Brake <cliff.brake@gmail.com>
+ *             <http://www.vibren.com> <http://bec-systems.com>
+ *             Changes for 2.6 kernel.
+ */
+
+
+/*
+ * Note: this file must be safe to include in assembly files
+ *
+ * Support for the Vibren PXA255 IDP requires rev04 or later
+ * IDP hardware.
+ */
+
+#include <mach/irqs.h> /* PXA_GPIO_TO_IRQ */
+
+#define IDP_FLASH_PHYS         (PXA_CS0_PHYS)
+#define IDP_ALT_FLASH_PHYS     (PXA_CS1_PHYS)
+#define IDP_MEDIAQ_PHYS                (PXA_CS3_PHYS)
+#define IDP_IDE_PHYS           (PXA_CS5_PHYS + 0x03000000)
+#define IDP_ETH_PHYS           (PXA_CS5_PHYS + 0x03400000)
+#define IDP_COREVOLT_PHYS      (PXA_CS5_PHYS + 0x03800000)
+#define IDP_CPLD_PHYS          (PXA_CS5_PHYS + 0x03C00000)
+
+
+/*
+ * virtual memory map
+ */
+
+#define IDP_COREVOLT_VIRT      (0xf0000000)
+#define IDP_COREVOLT_SIZE      (1*1024*1024)
+
+#define IDP_CPLD_VIRT          (IDP_COREVOLT_VIRT + IDP_COREVOLT_SIZE)
+#define IDP_CPLD_SIZE          (1*1024*1024)
+
+#if (IDP_CPLD_VIRT + IDP_CPLD_SIZE) > 0xfc000000
+#error Your custom IO space is getting a bit large !!
+#endif
+
+#define CPLD_P2V(x)            ((x) - IDP_CPLD_PHYS + IDP_CPLD_VIRT)
+#define CPLD_V2P(x)            ((x) - IDP_CPLD_VIRT + IDP_CPLD_PHYS)
+
+#ifndef __ASSEMBLY__
+#  define __CPLD_REG(x)                (*((volatile unsigned long *)CPLD_P2V(x)))
+#else
+#  define __CPLD_REG(x)                CPLD_P2V(x)
+#endif
+
+/* board level registers in the CPLD: (offsets from CPLD_VIRT) */
+
+#define _IDP_CPLD_REV                  (IDP_CPLD_PHYS + 0x00)
+#define _IDP_CPLD_PERIPH_PWR           (IDP_CPLD_PHYS + 0x04)
+#define _IDP_CPLD_LED_CONTROL          (IDP_CPLD_PHYS + 0x08)
+#define _IDP_CPLD_KB_COL_HIGH          (IDP_CPLD_PHYS + 0x0C)
+#define _IDP_CPLD_KB_COL_LOW           (IDP_CPLD_PHYS + 0x10)
+#define _IDP_CPLD_PCCARD_EN            (IDP_CPLD_PHYS + 0x14)
+#define _IDP_CPLD_GPIOH_DIR            (IDP_CPLD_PHYS + 0x18)
+#define _IDP_CPLD_GPIOH_VALUE          (IDP_CPLD_PHYS + 0x1C)
+#define _IDP_CPLD_GPIOL_DIR            (IDP_CPLD_PHYS + 0x20)
+#define _IDP_CPLD_GPIOL_VALUE          (IDP_CPLD_PHYS + 0x24)
+#define _IDP_CPLD_PCCARD_PWR           (IDP_CPLD_PHYS + 0x28)
+#define _IDP_CPLD_MISC_CTRL            (IDP_CPLD_PHYS + 0x2C)
+#define _IDP_CPLD_LCD                  (IDP_CPLD_PHYS + 0x30)
+#define _IDP_CPLD_FLASH_WE             (IDP_CPLD_PHYS + 0x34)
+
+#define _IDP_CPLD_KB_ROW               (IDP_CPLD_PHYS + 0x50)
+#define _IDP_CPLD_PCCARD0_STATUS       (IDP_CPLD_PHYS + 0x54)
+#define _IDP_CPLD_PCCARD1_STATUS       (IDP_CPLD_PHYS + 0x58)
+#define _IDP_CPLD_MISC_STATUS          (IDP_CPLD_PHYS + 0x5C)
+
+/* FPGA register virtual addresses */
+
+#define IDP_CPLD_REV                   __CPLD_REG(_IDP_CPLD_REV)
+#define IDP_CPLD_PERIPH_PWR            __CPLD_REG(_IDP_CPLD_PERIPH_PWR)
+#define IDP_CPLD_LED_CONTROL           __CPLD_REG(_IDP_CPLD_LED_CONTROL)
+#define IDP_CPLD_KB_COL_HIGH           __CPLD_REG(_IDP_CPLD_KB_COL_HIGH)
+#define IDP_CPLD_KB_COL_LOW            __CPLD_REG(_IDP_CPLD_KB_COL_LOW)
+#define IDP_CPLD_PCCARD_EN             __CPLD_REG(_IDP_CPLD_PCCARD_EN)
+#define IDP_CPLD_GPIOH_DIR             __CPLD_REG(_IDP_CPLD_GPIOH_DIR)
+#define IDP_CPLD_GPIOH_VALUE           __CPLD_REG(_IDP_CPLD_GPIOH_VALUE)
+#define IDP_CPLD_GPIOL_DIR             __CPLD_REG(_IDP_CPLD_GPIOL_DIR)
+#define IDP_CPLD_GPIOL_VALUE           __CPLD_REG(_IDP_CPLD_GPIOL_VALUE)
+#define IDP_CPLD_PCCARD_PWR            __CPLD_REG(_IDP_CPLD_PCCARD_PWR)
+#define IDP_CPLD_MISC_CTRL             __CPLD_REG(_IDP_CPLD_MISC_CTRL)
+#define IDP_CPLD_LCD                   __CPLD_REG(_IDP_CPLD_LCD)
+#define IDP_CPLD_FLASH_WE              __CPLD_REG(_IDP_CPLD_FLASH_WE)
+
+#define IDP_CPLD_KB_ROW                        __CPLD_REG(_IDP_CPLD_KB_ROW)
+#define IDP_CPLD_PCCARD0_STATUS                __CPLD_REG(_IDP_CPLD_PCCARD0_STATUS)
+#define IDP_CPLD_PCCARD1_STATUS                __CPLD_REG(_IDP_CPLD_PCCARD1_STATUS)
+#define IDP_CPLD_MISC_STATUS           __CPLD_REG(_IDP_CPLD_MISC_STATUS)
+
+
+/*
+ * Bit masks for various registers
+ */
+
+// IDP_CPLD_PCCARD_PWR
+#define PCC0_PWR0      (1 << 0)
+#define PCC0_PWR1      (1 << 1)
+#define PCC0_PWR2      (1 << 2)
+#define PCC0_PWR3      (1 << 3)
+#define PCC1_PWR0      (1 << 4)
+#define PCC1_PWR1      (1 << 5)
+#define PCC1_PWR2      (1 << 6)
+#define PCC1_PWR3      (1 << 7)
+
+// IDP_CPLD_PCCARD_EN
+#define PCC0_RESET     (1 << 6)
+#define PCC1_RESET     (1 << 7)
+#define PCC0_ENABLE    (1 << 0)
+#define PCC1_ENABLE    (1 << 1)
+
+// IDP_CPLD_PCCARDx_STATUS
+#define _PCC_WRPROT    (1 << 7) // 7-4 read as low true
+#define _PCC_RESET     (1 << 6)
+#define _PCC_IRQ       (1 << 5)
+#define _PCC_INPACK    (1 << 4)
+#define PCC_BVD2       (1 << 3)
+#define PCC_BVD1       (1 << 2)
+#define PCC_VS2                (1 << 1)
+#define PCC_VS1                (1 << 0)
+
+/* A listing of interrupts used by external hardware devices */
+
+#define TOUCH_PANEL_IRQ                        PXA_GPIO_TO_IRQ(5)
+#define IDE_IRQ                                PXA_GPIO_TO_IRQ(21)
+
+#define TOUCH_PANEL_IRQ_EDGE           IRQ_TYPE_EDGE_FALLING
+
+#define ETHERNET_IRQ                   PXA_GPIO_TO_IRQ(4)
+#define ETHERNET_IRQ_EDGE              IRQ_TYPE_EDGE_RISING
+
+#define IDE_IRQ_EDGE                   IRQ_TYPE_EDGE_RISING
+
+#define PCMCIA_S0_CD_VALID             PXA_GPIO_TO_IRQ(7)
+#define PCMCIA_S0_CD_VALID_EDGE                IRQ_TYPE_EDGE_BOTH
+
+#define PCMCIA_S1_CD_VALID             PXA_GPIO_TO_IRQ(8)
+#define PCMCIA_S1_CD_VALID_EDGE                IRQ_TYPE_EDGE_BOTH
+
+#define PCMCIA_S0_RDYINT               PXA_GPIO_TO_IRQ(19)
+#define PCMCIA_S1_RDYINT               PXA_GPIO_TO_IRQ(22)
+
+
+/*
+ * Macros for LED Driver
+ */
+
+/* leds 0 = ON */
+#define IDP_HB_LED     (1<<5)
+#define IDP_BUSY_LED   (1<<6)
+
+#define IDP_LEDS_MASK  (IDP_HB_LED | IDP_BUSY_LED)
+
+/*
+ * macros for MTD driver
+ */
+
+#define FLASH_WRITE_PROTECT_DISABLE()  ((IDP_CPLD_FLASH_WE) &= ~(0x1))
+#define FLASH_WRITE_PROTECT_ENABLE()   ((IDP_CPLD_FLASH_WE) |= (0x1))
+
+/*
+ * macros for matrix keyboard driver
+ */
+
+#define KEYBD_MATRIX_NUMBER_INPUTS     7
+#define KEYBD_MATRIX_NUMBER_OUTPUTS    14
+
+#define KEYBD_MATRIX_INVERT_OUTPUT_LOGIC       FALSE
+#define KEYBD_MATRIX_INVERT_INPUT_LOGIC                FALSE
+
+#define KEYBD_MATRIX_SETTLING_TIME_US                  100
+#define KEYBD_MATRIX_KEYSTATE_DEBOUNCE_CONSTANT                2
+
+#define KEYBD_MATRIX_SET_OUTPUTS(outputs) \
+{\
+       IDP_CPLD_KB_COL_LOW = outputs;\
+       IDP_CPLD_KB_COL_HIGH = outputs >> 7;\
+}
+
+#define KEYBD_MATRIX_GET_INPUTS(inputs) \
+{\
+       inputs = (IDP_CPLD_KB_ROW & 0x7f);\
+}
+
+
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h
deleted file mode 100644 (file)
index cb4236e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _COLIBRI_H_
-#define _COLIBRI_H_
-
-#include <net/ax88796.h>
-#include <mach/mfp.h>
-
-/*
- * base board glue for PXA270 module
- */
-
-enum {
-       COLIBRI_EVALBOARD = 0,
-       COLIBRI_PXA270_INCOME,
-};
-
-#if defined(CONFIG_MACH_COLIBRI_EVALBOARD)
-extern void colibri_evalboard_init(void);
-#else
-static inline void colibri_evalboard_init(void) {}
-#endif
-
-#if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME)
-extern void colibri_pxa270_income_boardinit(void);
-#else
-static inline void colibri_pxa270_income_boardinit(void) {}
-#endif
-
-/*
- * common settings for all modules
- */
-
-#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
-extern void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin);
-#else
-static inline void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin) {}
-#endif
-
-#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
-extern void colibri_pxa3xx_init_lcd(int bl_pin);
-#else
-static inline void colibri_pxa3xx_init_lcd(int bl_pin) {}
-#endif
-
-#if defined(CONFIG_AX88796)
-extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
-#endif
-
-#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
-extern void colibri_pxa3xx_init_nand(void);
-#else
-static inline void colibri_pxa3xx_init_nand(void) {}
-#endif
-
-/* physical memory regions */
-#define COLIBRI_SDRAM_BASE     0xa0000000      /* SDRAM region */
-
-/* GPIO definitions for Colibri PXA270 */
-#define GPIO114_COLIBRI_PXA270_ETH_IRQ 114
-#define GPIO0_COLIBRI_PXA270_SD_DETECT 0
-#define GPIO113_COLIBRI_PXA270_TS_IRQ  113
-
-/* GPIO definitions for Colibri PXA300/310 */
-#define GPIO13_COLIBRI_PXA300_SD_DETECT        13
-
-/* GPIO definitions for Colibri PXA320 */
-#define GPIO28_COLIBRI_PXA320_SD_DETECT        28
-
-#endif /* _COLIBRI_H_ */
-
diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h
deleted file mode 100644 (file)
index 00cfbbb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  Support for Cogent CSB726
- *
- *  Copyright (c) 2008 Dmitry Baryshkov
- *
- *  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 CSB726_H
-#define CSB726_H
-
-#include "irqs.h" /* PXA_GPIO_TO_IRQ */
-
-#define CSB726_GPIO_IRQ_LAN    52
-#define CSB726_GPIO_IRQ_SM501  53
-#define CSB726_GPIO_MMC_DETECT 100
-#define CSB726_GPIO_MMC_RO     101
-
-#define CSB726_FLASH_SIZE      (64 * 1024 * 1024)
-#define CSB726_FLASH_uMON      (8 * 1024 * 1024)
-
-#define CSB726_IRQ_LAN         PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_LAN)
-#define CSB726_IRQ_SM501       PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_SM501)
-
-#endif
-
diff --git a/arch/arm/mach-pxa/include/mach/eseries-irq.h b/arch/arm/mach-pxa/include/mach/eseries-irq.h
deleted file mode 100644 (file)
index de292b2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  eseries-irq.h
- *
- *  Copyright (C) Ian Molton <spyro@f2s.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.
- *
- */
-
-#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8)
-#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n))
-
-#define ANGELX_RDY0_IRQ IRQ_ANGELX(0)
-#define ANGELX_ST0_IRQ  IRQ_ANGELX(1)
-#define ANGELX_CD0_IRQ  IRQ_ANGELX(2)
-#define ANGELX_RDY1_IRQ IRQ_ANGELX(3)
-#define ANGELX_ST1_IRQ  IRQ_ANGELX(4)
-#define ANGELX_CD1_IRQ  IRQ_ANGELX(5)
-
-#define TMIO_IRQ_BASE (IRQ_BOARD_START+0)
-#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n))
-
-#define TMIO_SD_IRQ     IRQ_TMIO(1)
-#define TMIO_USB_IRQ    IRQ_TMIO(2)
-
-#define ESERIES_NR_IRQS        (IRQ_BOARD_START + 16)
diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h
deleted file mode 100644 (file)
index f7df27b..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  arch/arm/mach-pxa/include/mach/gumstix.h
- *
- * 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 "irqs.h" /* PXA_GPIO_TO_IRQ */
-
-/* BTRESET - Reset line to Bluetooth module, active low signal. */
-#define GPIO_GUMSTIX_BTRESET          7
-#define GPIO_GUMSTIX_BTRESET_MD                (GPIO_GUMSTIX_BTRESET | GPIO_OUT)
-
-
-/*
-GPIOn - Input from MAX823 (or equiv), normalizing USB +5V into a clean
-interrupt signal for determining cable presence. On the gumstix F,
-this moves to GPIO17 and GPIO37. */
-
-/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn
-has detected a cable insertion; driven low otherwise. */
-
-#define GPIO_GUMSTIX_USB_GPIOn         35
-#define GPIO_GUMSTIX_USB_GPIOx         41
-
-/* usb state change */
-#define GUMSTIX_USB_INTR_IRQ           PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_USB_GPIOn)
-
-#define GPIO_GUMSTIX_USB_GPIOn_MD      (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN)
-#define GPIO_GUMSTIX_USB_GPIOx_CON_MD  (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
-#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD  (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN)
-
-/*
- * SD/MMC definitions
- */
-#define GUMSTIX_GPIO_nSD_WP            22 /* SD Write Protect */
-#define GUMSTIX_GPIO_nSD_DETECT                11 /* MMC/SD Card Detect */
-#define GUMSTIX_IRQ_GPIO_nSD_DETECT    PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT)
-
-/*
- * SMC Ethernet definitions
- * ETH_RST provides a hardware reset line to the ethernet chip
- * ETH is the IRQ line in from the ethernet chip to the PXA
- */
-#define GPIO_GUMSTIX_ETH0_RST          80
-#define GPIO_GUMSTIX_ETH0_RST_MD       (GPIO_GUMSTIX_ETH0_RST | GPIO_OUT)
-#define GPIO_GUMSTIX_ETH1_RST          52
-#define GPIO_GUMSTIX_ETH1_RST_MD       (GPIO_GUMSTIX_ETH1_RST | GPIO_OUT)
-
-#define GPIO_GUMSTIX_ETH0              36
-#define GPIO_GUMSTIX_ETH0_MD           (GPIO_GUMSTIX_ETH0 | GPIO_IN)
-#define GUMSTIX_ETH0_IRQ               PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0)
-#define GPIO_GUMSTIX_ETH1              27
-#define GPIO_GUMSTIX_ETH1_MD           (GPIO_GUMSTIX_ETH1 | GPIO_IN)
-#define GUMSTIX_ETH1_IRQ               PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1)
-
-
-/* CF reset line */
-#define GPIO8_RESET                    8
-
-/* CF slot 0 */
-#define GPIO4_nBVD1                    4
-#define GPIO4_nSTSCHG                  GPIO4_nBVD1
-#define GPIO11_nCD                     11
-#define GPIO26_PRDY_nBSY               26
-#define GUMSTIX_S0_nSTSCHG_IRQ         PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG)
-#define GUMSTIX_S0_nCD_IRQ             PXA_GPIO_TO_IRQ(GPIO11_nCD)
-#define GUMSTIX_S0_PRDY_nBSY_IRQ       PXA_GPIO_TO_IRQ(GPIO26_PRDY_nBSY)
-
-/* CF slot 1 */
-#define GPIO18_nBVD1                   18
-#define GPIO18_nSTSCHG                 GPIO18_nBVD1
-#define GPIO36_nCD                     36
-#define GPIO27_PRDY_nBSY               27
-#define GUMSTIX_S1_nSTSCHG_IRQ         PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG)
-#define GUMSTIX_S1_nCD_IRQ             PXA_GPIO_TO_IRQ(GPIO36_nCD)
-#define GUMSTIX_S1_PRDY_nBSY_IRQ       PXA_GPIO_TO_IRQ(GPIO27_PRDY_nBSY)
-
-/* CF GPIO line modes */
-#define GPIO4_nSTSCHG_MD               (GPIO4_nSTSCHG | GPIO_IN)
-#define GPIO8_RESET_MD                 (GPIO8_RESET | GPIO_OUT)
-#define GPIO11_nCD_MD                  (GPIO11_nCD | GPIO_IN)
-#define GPIO18_nSTSCHG_MD              (GPIO18_nSTSCHG | GPIO_IN)
-#define GPIO26_PRDY_nBSY_MD            (GPIO26_PRDY_nBSY | GPIO_IN)
-#define GPIO27_PRDY_nBSY_MD            (GPIO27_PRDY_nBSY | GPIO_IN)
-#define GPIO36_nCD_MD                  (GPIO36_nCD | GPIO_IN)
-
-/* for expansion boards that can't be programatically detected */
-extern int am200_init(void);
-extern int am300_init(void);
-
diff --git a/arch/arm/mach-pxa/include/mach/h5000.h b/arch/arm/mach-pxa/include/mach/h5000.h
deleted file mode 100644 (file)
index 2a5ae38..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Hardware definitions for HP iPAQ h5xxx Handheld Computers
- *
- * Copyright(20)02 Hewlett-Packard Company.
- *
- * This program is free software; 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.
- *
- * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Author: Jamey Hicks
- */
-
-#ifndef __ASM_ARCH_H5000_H
-#define __ASM_ARCH_H5000_H
-
-#include <mach/mfp-pxa25x.h>
-
-/*
- * CPU GPIOs
- */
-
-#define H5000_GPIO_POWER_BUTTON   (0)
-#define H5000_GPIO_RESET_BUTTON_N (1)
-#define H5000_GPIO_OPT_INT        (2)
-#define H5000_GPIO_BACKUP_POWER   (3)
-#define H5000_GPIO_ACTION_BUTTON  (4)
-#define H5000_GPIO_COM_DCD_SOMETHING  (5) /* what is this really ? */
-/* 6 not connected */
-#define H5000_GPIO_RESET_BUTTON_AGAIN_N (7) /* connected to gpio 1 as well */
-/* 8 not connected */
-#define H5000_GPIO_RSO_N          (9)       /* reset output from max1702 which regulates 3.3 and 2.5 */
-#define H5000_GPIO_ASIC_INT_N   (10)       /* from companion asic */
-#define H5000_GPIO_BT_ENV_0     (11)       /* to LMX9814, set to 1 according to regdump */
-/*(12) not connected */
-#define H5000_GPIO_BT_ENV_1     (13)       /* to LMX9814, set to 1 according to regdump */
-#define H5000_GPIO_BT_WU        (14)       /* from LMX9814, Defined as HOST_WAKEUP in the LMX9820 data sheet */
-/*(15) is CS1# */
-/*(16) not connected */
-/*(17) not connected */
-/*(18) is pcmcia ready */
-/*(19) is dreq1 */
-/*(20) is dreq0 */
-#define H5000_GPIO_OE_RD_NWR   (21)       /* output enable on rd/nwr signal to companion asic */
-/*(22) is not connected */
-#define H5000_GPIO_OPT_SPI_CLK  (23)       /* to extension pack */
-#define H5000_GPIO_OPT_SPI_CS_N (24)       /* to extension pack */
-#define H5000_GPIO_OPT_SPI_DOUT (25)       /* to extension pack */
-#define H5000_GPIO_OPT_SPI_DIN  (26)       /* to extension pack */
-/*(27) not connected */
-#define H5000_GPIO_I2S_BITCLK   (28)       /* connected to AC97 codec */
-#define H5000_GPIO_I2S_DATAOUT  (29)       /* connected to AC97 codec */
-#define H5000_GPIO_I2S_DATAIN   (30)       /* connected to AC97 codec */
-#define H5000_GPIO_I2S_LRCLK    (31)       /* connected to AC97 codec */
-#define H5000_GPIO_I2S_SYSCLK   (32)       /* connected to AC97 codec */
-/*(33) is CS5# */
-#define H5000_GPIO_COM_RXD      (34)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_CTS      (35)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_DCD      (36)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_DSR      (37)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_RI       (38)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_TXD      (39)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_DTR      (40)       /* connected to cradle/cable connector */
-#define H5000_GPIO_COM_RTS      (41)       /* connected to cradle/cable connector */
-
-#define H5000_GPIO_BT_RXD       (42)       /* connected to BT (LMX9814) */
-#define H5000_GPIO_BT_TXD       (43)       /* connected to BT (LMX9814) */
-#define H5000_GPIO_BT_CTS       (44)       /* connected to BT (LMX9814) */
-#define H5000_GPIO_BT_RTS       (45)       /* connected to BT (LMX9814) */
-
-#define H5000_GPIO_IRDA_RXD     (46)
-#define H5000_GPIO_IRDA_TXD     (47)
-
-#define H5000_GPIO_POE_N        (48)       /* used for pcmcia */
-#define H5000_GPIO_PWE_N        (49)       /* used for pcmcia */
-#define H5000_GPIO_PIOR_N       (50)       /* used for pcmcia */
-#define H5000_GPIO_PIOW_N       (51)       /* used for pcmcia */
-#define H5000_GPIO_PCE1_N       (52)       /* used for pcmcia */
-#define H5000_GPIO_PCE2_N       (53)       /* used for pcmcia */
-#define H5000_GPIO_PSKTSEL      (54)       /* used for pcmcia */
-#define H5000_GPIO_PREG_N       (55)       /* used for pcmcia */
-#define H5000_GPIO_PWAIT_N      (56)       /* used for pcmcia */
-#define H5000_GPIO_IOIS16_N     (57)       /* used for pcmcia */
-
-#define H5000_GPIO_IRDA_SD      (58)       /* to hsdl3002 sd */
-/*(59) not connected */
-#define H5000_GPIO_POWER_SD_N   (60)       /* controls power to SD */
-#define H5000_GPIO_POWER_RS232_N       (61)       /* inverted FORCEON to rs232 transceiver */
-#define H5000_GPIO_POWER_ACCEL_N       (62)       /* controls power to accel */
-/*(63) is not connected */
-#define H5000_GPIO_OPT_NVRAM    (64)       /* controls power to expansion pack */
-#define H5000_GPIO_CHG_EN       (65)       /* to sc801 en */
-#define H5000_GPIO_USB_PULLUP   (66)       /* USB d+ pullup via 1.5K resistor */
-#define H5000_GPIO_BT_2V8_N     (67)       /* 2.8V used by bluetooth */
-#define H5000_GPIO_EXT_CHG_RATE (68)       /* enables external charging rate */
-/*(69) is not connected */
-#define H5000_GPIO_CIR_RESET    (70)       /* consumer IR reset */
-#define H5000_GPIO_POWER_LIGHT_SENSOR_N        (71)
-#define H5000_GPIO_BT_M_RESET   (72)
-#define H5000_GPIO_STD_CHG_RATE (73)
-#define H5000_GPIO_SD_WP_N      (74)
-#define H5000_GPIO_MOTOR_ON_N   (75)       /* external pullup on this */
-#define H5000_GPIO_HEADPHONE_DETECT    (76)
-#define H5000_GPIO_USB_CHG_RATE (77)       /* select rate for charging via usb */
-/*(78) is CS2# */
-/*(79) is CS3# */
-/*(80) is CS4# */
-
-#endif /* __ASM_ARCH_H5000_H */
diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h
deleted file mode 100644 (file)
index 7e63f46..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- *  arch/arm/mach-pxa/include/mach/idp.h
- *
- * 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.
- *
- * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
- *
- * 2001-09-13: Cliff Brake <cbrake@accelent.com>
- *             Initial code
- *
- * 2005-02-15: Cliff Brake <cliff.brake@gmail.com>
- *             <http://www.vibren.com> <http://bec-systems.com>
- *             Changes for 2.6 kernel.
- */
-
-
-/*
- * Note: this file must be safe to include in assembly files
- *
- * Support for the Vibren PXA255 IDP requires rev04 or later
- * IDP hardware.
- */
-
-#include "irqs.h" /* PXA_GPIO_TO_IRQ */
-
-#define IDP_FLASH_PHYS         (PXA_CS0_PHYS)
-#define IDP_ALT_FLASH_PHYS     (PXA_CS1_PHYS)
-#define IDP_MEDIAQ_PHYS                (PXA_CS3_PHYS)
-#define IDP_IDE_PHYS           (PXA_CS5_PHYS + 0x03000000)
-#define IDP_ETH_PHYS           (PXA_CS5_PHYS + 0x03400000)
-#define IDP_COREVOLT_PHYS      (PXA_CS5_PHYS + 0x03800000)
-#define IDP_CPLD_PHYS          (PXA_CS5_PHYS + 0x03C00000)
-
-
-/*
- * virtual memory map
- */
-
-#define IDP_COREVOLT_VIRT      (0xf0000000)
-#define IDP_COREVOLT_SIZE      (1*1024*1024)
-
-#define IDP_CPLD_VIRT          (IDP_COREVOLT_VIRT + IDP_COREVOLT_SIZE)
-#define IDP_CPLD_SIZE          (1*1024*1024)
-
-#if (IDP_CPLD_VIRT + IDP_CPLD_SIZE) > 0xfc000000
-#error Your custom IO space is getting a bit large !!
-#endif
-
-#define CPLD_P2V(x)            ((x) - IDP_CPLD_PHYS + IDP_CPLD_VIRT)
-#define CPLD_V2P(x)            ((x) - IDP_CPLD_VIRT + IDP_CPLD_PHYS)
-
-#ifndef __ASSEMBLY__
-#  define __CPLD_REG(x)                (*((volatile unsigned long *)CPLD_P2V(x)))
-#else
-#  define __CPLD_REG(x)                CPLD_P2V(x)
-#endif
-
-/* board level registers in the CPLD: (offsets from CPLD_VIRT) */
-
-#define _IDP_CPLD_REV                  (IDP_CPLD_PHYS + 0x00)
-#define _IDP_CPLD_PERIPH_PWR           (IDP_CPLD_PHYS + 0x04)
-#define _IDP_CPLD_LED_CONTROL          (IDP_CPLD_PHYS + 0x08)
-#define _IDP_CPLD_KB_COL_HIGH          (IDP_CPLD_PHYS + 0x0C)
-#define _IDP_CPLD_KB_COL_LOW           (IDP_CPLD_PHYS + 0x10)
-#define _IDP_CPLD_PCCARD_EN            (IDP_CPLD_PHYS + 0x14)
-#define _IDP_CPLD_GPIOH_DIR            (IDP_CPLD_PHYS + 0x18)
-#define _IDP_CPLD_GPIOH_VALUE          (IDP_CPLD_PHYS + 0x1C)
-#define _IDP_CPLD_GPIOL_DIR            (IDP_CPLD_PHYS + 0x20)
-#define _IDP_CPLD_GPIOL_VALUE          (IDP_CPLD_PHYS + 0x24)
-#define _IDP_CPLD_PCCARD_PWR           (IDP_CPLD_PHYS + 0x28)
-#define _IDP_CPLD_MISC_CTRL            (IDP_CPLD_PHYS + 0x2C)
-#define _IDP_CPLD_LCD                  (IDP_CPLD_PHYS + 0x30)
-#define _IDP_CPLD_FLASH_WE             (IDP_CPLD_PHYS + 0x34)
-
-#define _IDP_CPLD_KB_ROW               (IDP_CPLD_PHYS + 0x50)
-#define _IDP_CPLD_PCCARD0_STATUS       (IDP_CPLD_PHYS + 0x54)
-#define _IDP_CPLD_PCCARD1_STATUS       (IDP_CPLD_PHYS + 0x58)
-#define _IDP_CPLD_MISC_STATUS          (IDP_CPLD_PHYS + 0x5C)
-
-/* FPGA register virtual addresses */
-
-#define IDP_CPLD_REV                   __CPLD_REG(_IDP_CPLD_REV)
-#define IDP_CPLD_PERIPH_PWR            __CPLD_REG(_IDP_CPLD_PERIPH_PWR)
-#define IDP_CPLD_LED_CONTROL           __CPLD_REG(_IDP_CPLD_LED_CONTROL)
-#define IDP_CPLD_KB_COL_HIGH           __CPLD_REG(_IDP_CPLD_KB_COL_HIGH)
-#define IDP_CPLD_KB_COL_LOW            __CPLD_REG(_IDP_CPLD_KB_COL_LOW)
-#define IDP_CPLD_PCCARD_EN             __CPLD_REG(_IDP_CPLD_PCCARD_EN)
-#define IDP_CPLD_GPIOH_DIR             __CPLD_REG(_IDP_CPLD_GPIOH_DIR)
-#define IDP_CPLD_GPIOH_VALUE           __CPLD_REG(_IDP_CPLD_GPIOH_VALUE)
-#define IDP_CPLD_GPIOL_DIR             __CPLD_REG(_IDP_CPLD_GPIOL_DIR)
-#define IDP_CPLD_GPIOL_VALUE           __CPLD_REG(_IDP_CPLD_GPIOL_VALUE)
-#define IDP_CPLD_PCCARD_PWR            __CPLD_REG(_IDP_CPLD_PCCARD_PWR)
-#define IDP_CPLD_MISC_CTRL             __CPLD_REG(_IDP_CPLD_MISC_CTRL)
-#define IDP_CPLD_LCD                   __CPLD_REG(_IDP_CPLD_LCD)
-#define IDP_CPLD_FLASH_WE              __CPLD_REG(_IDP_CPLD_FLASH_WE)
-
-#define IDP_CPLD_KB_ROW                        __CPLD_REG(_IDP_CPLD_KB_ROW)
-#define IDP_CPLD_PCCARD0_STATUS                __CPLD_REG(_IDP_CPLD_PCCARD0_STATUS)
-#define IDP_CPLD_PCCARD1_STATUS                __CPLD_REG(_IDP_CPLD_PCCARD1_STATUS)
-#define IDP_CPLD_MISC_STATUS           __CPLD_REG(_IDP_CPLD_MISC_STATUS)
-
-
-/*
- * Bit masks for various registers
- */
-
-// IDP_CPLD_PCCARD_PWR
-#define PCC0_PWR0      (1 << 0)
-#define PCC0_PWR1      (1 << 1)
-#define PCC0_PWR2      (1 << 2)
-#define PCC0_PWR3      (1 << 3)
-#define PCC1_PWR0      (1 << 4)
-#define PCC1_PWR1      (1 << 5)
-#define PCC1_PWR2      (1 << 6)
-#define PCC1_PWR3      (1 << 7)
-
-// IDP_CPLD_PCCARD_EN
-#define PCC0_RESET     (1 << 6)
-#define PCC1_RESET     (1 << 7)
-#define PCC0_ENABLE    (1 << 0)
-#define PCC1_ENABLE    (1 << 1)
-
-// IDP_CPLD_PCCARDx_STATUS
-#define _PCC_WRPROT    (1 << 7) // 7-4 read as low true
-#define _PCC_RESET     (1 << 6)
-#define _PCC_IRQ       (1 << 5)
-#define _PCC_INPACK    (1 << 4)
-#define PCC_BVD2       (1 << 3)
-#define PCC_BVD1       (1 << 2)
-#define PCC_VS2                (1 << 1)
-#define PCC_VS1                (1 << 0)
-
-/* A listing of interrupts used by external hardware devices */
-
-#define TOUCH_PANEL_IRQ                        PXA_GPIO_TO_IRQ(5)
-#define IDE_IRQ                                PXA_GPIO_TO_IRQ(21)
-
-#define TOUCH_PANEL_IRQ_EDGE           IRQ_TYPE_EDGE_FALLING
-
-#define ETHERNET_IRQ                   PXA_GPIO_TO_IRQ(4)
-#define ETHERNET_IRQ_EDGE              IRQ_TYPE_EDGE_RISING
-
-#define IDE_IRQ_EDGE                   IRQ_TYPE_EDGE_RISING
-
-#define PCMCIA_S0_CD_VALID             PXA_GPIO_TO_IRQ(7)
-#define PCMCIA_S0_CD_VALID_EDGE                IRQ_TYPE_EDGE_BOTH
-
-#define PCMCIA_S1_CD_VALID             PXA_GPIO_TO_IRQ(8)
-#define PCMCIA_S1_CD_VALID_EDGE                IRQ_TYPE_EDGE_BOTH
-
-#define PCMCIA_S0_RDYINT               PXA_GPIO_TO_IRQ(19)
-#define PCMCIA_S1_RDYINT               PXA_GPIO_TO_IRQ(22)
-
-
-/*
- * Macros for LED Driver
- */
-
-/* leds 0 = ON */
-#define IDP_HB_LED     (1<<5)
-#define IDP_BUSY_LED   (1<<6)
-
-#define IDP_LEDS_MASK  (IDP_HB_LED | IDP_BUSY_LED)
-
-/*
- * macros for MTD driver
- */
-
-#define FLASH_WRITE_PROTECT_DISABLE()  ((IDP_CPLD_FLASH_WE) &= ~(0x1))
-#define FLASH_WRITE_PROTECT_ENABLE()   ((IDP_CPLD_FLASH_WE) |= (0x1))
-
-/*
- * macros for matrix keyboard driver
- */
-
-#define KEYBD_MATRIX_NUMBER_INPUTS     7
-#define KEYBD_MATRIX_NUMBER_OUTPUTS    14
-
-#define KEYBD_MATRIX_INVERT_OUTPUT_LOGIC       FALSE
-#define KEYBD_MATRIX_INVERT_INPUT_LOGIC                FALSE
-
-#define KEYBD_MATRIX_SETTLING_TIME_US                  100
-#define KEYBD_MATRIX_KEYSTATE_DEBOUNCE_CONSTANT                2
-
-#define KEYBD_MATRIX_SET_OUTPUTS(outputs) \
-{\
-       IDP_CPLD_KB_COL_LOW = outputs;\
-       IDP_CPLD_KB_COL_HIGH = outputs >> 7;\
-}
-
-#define KEYBD_MATRIX_GET_INPUTS(inputs) \
-{\
-       inputs = (IDP_CPLD_KB_ROW & 0x7f);\
-}
-
-
diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h
deleted file mode 100644 (file)
index 8066be5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ASM_ARCH_LITTLETON_H
-#define __ASM_ARCH_LITTLETON_H
-
-#define LITTLETON_ETH_PHYS     0x30000000
-
-#define LITTLETON_GPIO_LCD_CS  (17)
-
-#define EXT0_GPIO_BASE (PXA_NR_BUILTIN_GPIO)
-#define EXT0_GPIO(x)   (EXT0_GPIO_BASE + (x))
-
-#define LITTLETON_NR_IRQS      (IRQ_BOARD_START + 8)
-
-#endif /* __ASM_ARCH_LITTLETON_H */
diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/include/mach/lpd270.h
deleted file mode 100644 (file)
index 4edc712..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/lpd270.h
- *
- * Author:     Lennert Buytenhek
- * Created:    Feb 10, 2006
- *
- * 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_LPD270_H
-#define __ASM_ARCH_LPD270_H
-
-#define LPD270_CPLD_PHYS       PXA_CS2_PHYS
-#define LPD270_CPLD_VIRT       IOMEM(0xf0000000)
-#define LPD270_CPLD_SIZE       0x00100000
-
-#define LPD270_ETH_PHYS                (PXA_CS2_PHYS + 0x01000000)
-
-/* CPLD registers  */
-#define LPD270_CPLD_REG(x)     (LPD270_CPLD_VIRT + (x))
-#define LPD270_CONTROL         LPD270_CPLD_REG(0x00)
-#define LPD270_PERIPHERAL0     LPD270_CPLD_REG(0x04)
-#define LPD270_PERIPHERAL1     LPD270_CPLD_REG(0x08)
-#define LPD270_CPLD_REVISION   LPD270_CPLD_REG(0x14)
-#define LPD270_EEPROM_SPI_ITF  LPD270_CPLD_REG(0x20)
-#define LPD270_MODE_PINS       LPD270_CPLD_REG(0x24)
-#define LPD270_EGPIO           LPD270_CPLD_REG(0x30)
-#define LPD270_INT_MASK                LPD270_CPLD_REG(0x40)
-#define LPD270_INT_STATUS      LPD270_CPLD_REG(0x50)
-
-#define LPD270_INT_AC97                (1 << 4)  /* AC'97 CODEC IRQ */
-#define LPD270_INT_ETHERNET    (1 << 3)  /* Ethernet controller IRQ */
-#define LPD270_INT_USBC                (1 << 2)  /* USB client cable detection IRQ */
-
-#define LPD270_IRQ(x)          (IRQ_BOARD_START + (x))
-#define LPD270_USBC_IRQ                LPD270_IRQ(2)
-#define LPD270_ETHERNET_IRQ    LPD270_IRQ(3)
-#define LPD270_AC97_IRQ                LPD270_IRQ(4)
-#define LPD270_NR_IRQS         (IRQ_BOARD_START + 5)
-
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
deleted file mode 100644 (file)
index cafadc3..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-#ifndef __ASM_ARCH_MFP_PXA25X_H
-#define __ASM_ARCH_MFP_PXA25X_H
-
-#include <mach/mfp-pxa2xx.h>
-
-/* GPIO */
-#define GPIO2_GPIO             MFP_CFG_IN(GPIO2, AF0)
-#define GPIO3_GPIO             MFP_CFG_IN(GPIO3, AF0)
-#define GPIO4_GPIO             MFP_CFG_IN(GPIO4, AF0)
-#define GPIO5_GPIO             MFP_CFG_IN(GPIO5, AF0)
-#define GPIO6_GPIO             MFP_CFG_IN(GPIO6, AF0)
-#define GPIO7_GPIO             MFP_CFG_IN(GPIO7, AF0)
-#define GPIO8_GPIO             MFP_CFG_IN(GPIO8, AF0)
-
-#define GPIO1_RST              MFP_CFG_IN(GPIO1, AF1)
-
-/* Crystal and Clock Signals */
-#define GPIO10_RTCCLK          MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
-#define GPIO70_RTCCLK          MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
-#define GPIO7_48MHz            MFP_CFG_OUT(GPIO7,  AF1, DRIVE_LOW)
-#define GPIO11_3_6MHz          MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
-#define GPIO71_3_6MHz          MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW)
-#define GPIO12_32KHz           MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
-#define GPIO72_32kHz           MFP_CFG_OUT(GPIO72, AF1, DRIVE_LOW)
-
-/* SDRAM and Static Memory I/O Signals */
-#define GPIO15_nCS_1           MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
-#define GPIO78_nCS_2           MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
-#define GPIO79_nCS_3           MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
-#define GPIO80_nCS_4           MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
-#define GPIO33_nCS_5           MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
-
-/* Miscellaneous I/O and DMA Signals */
-#define GPIO18_RDY             MFP_CFG_IN(GPIO18, AF1)
-#define GPIO20_DREQ_0          MFP_CFG_IN(GPIO20, AF1)
-#define GPIO19_DREQ_1          MFP_CFG_IN(GPIO19, AF1)
-
-/* Alternate Bus Master Mode I/O Signals */
-#define GPIO13_MBGNT           MFP_CFG_OUT(GPIO13, AF2, DRIVE_LOW)
-#define GPIO73_MBGNT           MFP_CFG_OUT(GPIO73, AF1, DRIVE_LOW)
-#define GPIO14_MBREQ           MFP_CFG_IN(GPIO14, AF1)
-#define GPIO66_MBREQ           MFP_CFG_IN(GPIO66, AF1)
-
-/* PC CARD */
-#define GPIO52_nPCE_1          MFP_CFG_OUT(GPIO52, AF2, DRIVE_HIGH)
-#define GPIO53_nPCE_2          MFP_CFG_OUT(GPIO53, AF2, DRIVE_HIGH)
-#define GPIO55_nPREG           MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
-#define GPIO50_nPIOR           MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
-#define GPIO51_nPIOW           MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
-#define GPIO49_nPWE            MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
-#define GPIO48_nPOE            MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
-#define GPIO57_nIOIS16         MFP_CFG_IN(GPIO57, AF1)
-#define GPIO56_nPWAIT          MFP_CFG_IN(GPIO56, AF1)
-#define GPIO54_nPSKTSEL                MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
-
-/* FFUART */
-#define GPIO34_FFUART_RXD      MFP_CFG_IN(GPIO34, AF1)
-#define GPIO35_FFUART_CTS      MFP_CFG_IN(GPIO35, AF1)
-#define GPIO36_FFUART_DCD      MFP_CFG_IN(GPIO36, AF1)
-#define GPIO37_FFUART_DSR      MFP_CFG_IN(GPIO37, AF1)
-#define GPIO38_FFUART_RI       MFP_CFG_IN(GPIO38, AF1)
-#define GPIO39_FFUART_TXD      MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
-#define GPIO40_FFUART_DTR      MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
-#define GPIO41_FFUART_RTS      MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
-
-/* BTUART */
-#define GPIO42_BTUART_RXD      MFP_CFG_IN(GPIO42, AF1)
-#define GPIO43_BTUART_TXD      MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
-#define GPIO44_BTUART_CTS      MFP_CFG_IN(GPIO44, AF1)
-#define GPIO45_BTUART_RTS      MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
-
-/* STUART */
-#define GPIO46_STUART_RXD      MFP_CFG_IN(GPIO46, AF2)
-#define GPIO47_STUART_TXD      MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
-
-/* HWUART */
-#define GPIO42_HWUART_RXD      MFP_CFG_IN(GPIO42, AF3)
-#define GPIO43_HWUART_TXD      MFP_CFG_OUT(GPIO43, AF3, DRIVE_HIGH)
-#define GPIO44_HWUART_CTS      MFP_CFG_IN(GPIO44, AF3)
-#define GPIO45_HWUART_RTS      MFP_CFG_OUT(GPIO45, AF3, DRIVE_HIGH)
-#define GPIO48_HWUART_TXD      MFP_CFG_OUT(GPIO48, AF1, DRIVE_HIGH)
-#define GPIO49_HWUART_RXD      MFP_CFG_IN(GPIO49, AF1)
-#define GPIO50_HWUART_CTS      MFP_CFG_IN(GPIO50, AF1)
-#define GPIO51_HWUART_RTS      MFP_CFG_OUT(GPIO51, AF1, DRIVE_HIGH)
-
-/* FICP */
-#define GPIO46_FICP_RXD                MFP_CFG_IN(GPIO46, AF1)
-#define GPIO47_FICP_TXD                MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
-
-/* PWM 0/1 */
-#define GPIO16_PWM0_OUT                MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
-#define GPIO17_PWM1_OUT                MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
-
-/* AC97 */
-#define GPIO28_AC97_BITCLK     MFP_CFG_IN(GPIO28, AF1)
-#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
-#define GPIO30_AC97_SDATA_OUT  MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
-#define GPIO31_AC97_SYNC       MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
-#define GPIO32_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO32, AF1)
-
-/* I2S */
-#define GPIO28_I2S_BITCLK_IN   MFP_CFG_IN(GPIO28, AF2)
-#define GPIO28_I2S_BITCLK_OUT  MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
-#define GPIO29_I2S_SDATA_IN    MFP_CFG_IN(GPIO29, AF2)
-#define GPIO30_I2S_SDATA_OUT   MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
-#define GPIO31_I2S_SYNC                MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
-#define GPIO32_I2S_SYSCLK      MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
-
-/* SSP 1 */
-#define GPIO23_SSP1_SCLK       MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
-#define GPIO24_SSP1_SFRM       MFP_CFG_OUT(GPIO24, AF2, DRIVE_LOW)
-#define GPIO25_SSP1_TXD                MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
-#define GPIO26_SSP1_RXD                MFP_CFG_IN(GPIO26, AF1)
-#define GPIO27_SSP1_EXTCLK     MFP_CFG_IN(GPIO27, AF1)
-
-/* SSP 2 - NSSP */
-#define GPIO81_SSP2_CLK_OUT    MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
-#define GPIO81_SSP2_CLK_IN     MFP_CFG_IN(GPIO81, AF1)
-#define GPIO82_SSP2_FRM_OUT    MFP_CFG_OUT(GPIO82, AF1, DRIVE_LOW)
-#define GPIO82_SSP2_FRM_IN     MFP_CFG_IN(GPIO82, AF1)
-#define GPIO83_SSP2_TXD        MFP_CFG_OUT(GPIO83, AF1, DRIVE_LOW)
-#define GPIO83_SSP2_RXD        MFP_CFG_IN(GPIO83, AF2)
-#define GPIO84_SSP2_TXD        MFP_CFG_OUT(GPIO84, AF1, DRIVE_LOW)
-#define GPIO84_SSP2_RXD        MFP_CFG_IN(GPIO84, AF2)
-
-/* MMC */
-#define GPIO6_MMC_CLK          MFP_CFG_OUT(GPIO6, AF1, DRIVE_LOW)
-#define GPIO8_MMC_CS0          MFP_CFG_OUT(GPIO8, AF1, DRIVE_LOW)
-#define GPIO9_MMC_CS1          MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
-#define GPIO34_MMC_CS0         MFP_CFG_OUT(GPIO34, AF2, DRIVE_LOW)
-#define GPIO39_MMC_CS1         MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
-#define GPIO53_MMC_CLK         MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
-#define GPIO54_MMC_CLK         MFP_CFG_OUT(GPIO54, AF1, DRIVE_LOW)
-#define GPIO69_MMC_CLK         MFP_CFG_OUT(GPIO69, AF1, DRIVE_LOW)
-#define GPIO67_MMC_CS0         MFP_CFG_OUT(GPIO67, AF1, DRIVE_LOW)
-#define GPIO68_MMC_CS1         MFP_CFG_OUT(GPIO68, AF1, DRIVE_LOW)
-
-/* LCD */
-#define GPIO58_LCD_LDD_0       MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
-#define GPIO59_LCD_LDD_1       MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
-#define GPIO60_LCD_LDD_2       MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
-#define GPIO61_LCD_LDD_3       MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
-#define GPIO62_LCD_LDD_4       MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
-#define GPIO63_LCD_LDD_5       MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
-#define GPIO64_LCD_LDD_6       MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
-#define GPIO65_LCD_LDD_7       MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
-#define GPIO66_LCD_LDD_8       MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
-#define GPIO67_LCD_LDD_9       MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
-#define GPIO68_LCD_LDD_10      MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
-#define GPIO69_LCD_LDD_11      MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
-#define GPIO70_LCD_LDD_12      MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
-#define GPIO71_LCD_LDD_13      MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
-#define GPIO72_LCD_LDD_14      MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
-#define GPIO73_LCD_LDD_15      MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
-#define GPIO74_LCD_FCLK                MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
-#define GPIO75_LCD_LCLK                MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
-#define GPIO76_LCD_PCLK                MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
-#define GPIO77_LCD_BIAS                MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
-
-#ifdef CONFIG_CPU_PXA26x
-/* GPIO */
-#define GPIO85_GPIO            MFP_CFG_IN(GPIO85, AF0)
-#define GPIO86_GPIO            MFP_CFG_IN(GPIO86, AF1)
-#define GPIO87_GPIO            MFP_CFG_IN(GPIO87, AF1)
-#define GPIO88_GPIO            MFP_CFG_IN(GPIO88, AF1)
-#define GPIO89_GPIO            MFP_CFG_IN(GPIO89, AF1)
-
-/* SDRAM */
-#define GPIO86_nSDCS2          MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
-#define GPIO87_nSDCS3          MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
-#define GPIO88_RDnWR           MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
-
-/* USB */
-#define GPIO9_USB_RCV          MFP_CFG_IN(GPIO9, AF1)
-#define GPIO32_USB_VP          MFP_CFG_IN(GPIO32, AF2)
-#define GPIO34_USB_VM          MFP_CFG_IN(GPIO34, AF2)
-#define GPIO39_USB_VPO         MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
-#define GPIO56_USB_VMO         MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
-#define GPIO57_USB_nOE         MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)
-
-/* ASSP */
-#define GPIO28_ASSP_BITCLK_IN  MFP_CFG_IN(GPIO28, AF3)
-#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
-#define GPIO29_ASSP_RXD                MFP_CFG_IN(GPIO29, AF3)
-#define GPIO30_ASSP_TXD                MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
-#define GPIO31_ASSP_SFRM_IN    MFP_CFG_IN(GPIO31, AF1)
-#define GPIO31_ASSP_SFRM_OUT   MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
-
-/* AC97 */
-#define GPIO89_AC97_nRESET     MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
-#endif /* CONFIG_CPU_PXA26x */
-
-/* commonly used pin configurations */
-#define GPIOxx_LCD_16BPP       \
-       GPIO58_LCD_LDD_0,       \
-       GPIO59_LCD_LDD_1,       \
-       GPIO60_LCD_LDD_2,       \
-       GPIO61_LCD_LDD_3,       \
-       GPIO62_LCD_LDD_4,       \
-       GPIO63_LCD_LDD_5,       \
-       GPIO64_LCD_LDD_6,       \
-       GPIO65_LCD_LDD_7,       \
-       GPIO66_LCD_LDD_8,       \
-       GPIO67_LCD_LDD_9,       \
-       GPIO68_LCD_LDD_10,      \
-       GPIO69_LCD_LDD_11,      \
-       GPIO70_LCD_LDD_12,      \
-       GPIO71_LCD_LDD_13,      \
-       GPIO72_LCD_LDD_14,      \
-       GPIO73_LCD_LDD_15
-
-#define GPIOxx_LCD_DSTN_16BPP  \
-       GPIOxx_LCD_16BPP,       \
-       GPIO74_LCD_FCLK,        \
-       GPIO75_LCD_LCLK,        \
-       GPIO76_LCD_PCLK
-
-#define GPIOxx_LCD_TFT_16BPP   \
-       GPIOxx_LCD_16BPP,       \
-       GPIO74_LCD_FCLK,        \
-       GPIO75_LCD_LCLK,        \
-       GPIO76_LCD_PCLK,        \
-       GPIO77_LCD_BIAS
-
-#endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
deleted file mode 100644 (file)
index b6132aa..0000000
+++ /dev/null
@@ -1,471 +0,0 @@
-#ifndef __ASM_ARCH_MFP_PXA27X_H
-#define __ASM_ARCH_MFP_PXA27X_H
-
-/*
- * NOTE:  for those special-function bidirectional GPIOs, as described
- * in the "PXA27x Developer's Manual" Section 24.4.2.1, only its input
- * alternative is preserved, the direction is actually selected by the
- * specific controller, and this should work in most cases.
- */
-
-#include <mach/mfp-pxa2xx.h>
-
-/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
- * bit is set, regardless of the GPIO configuration
- */
-#define GPIO3_GPIO             MFP_CFG_IN(GPIO3, AF0)
-#define GPIO4_GPIO             MFP_CFG_IN(GPIO4, AF0)
-
-/* GPIO */
-#define GPIO85_GPIO            MFP_CFG_IN(GPIO85, AF0)
-#define GPIO86_GPIO            MFP_CFG_IN(GPIO86, AF0)
-#define GPIO87_GPIO            MFP_CFG_IN(GPIO87, AF0)
-#define GPIO88_GPIO            MFP_CFG_IN(GPIO88, AF0)
-#define GPIO89_GPIO            MFP_CFG_IN(GPIO89, AF0)
-#define GPIO90_GPIO            MFP_CFG_IN(GPIO90, AF0)
-#define GPIO91_GPIO            MFP_CFG_IN(GPIO91, AF0)
-#define GPIO92_GPIO            MFP_CFG_IN(GPIO92, AF0)
-#define GPIO93_GPIO            MFP_CFG_IN(GPIO93, AF0)
-#define GPIO94_GPIO            MFP_CFG_IN(GPIO94, AF0)
-#define GPIO95_GPIO            MFP_CFG_IN(GPIO95, AF0)
-#define GPIO96_GPIO            MFP_CFG_IN(GPIO96, AF0)
-#define GPIO97_GPIO            MFP_CFG_IN(GPIO97, AF0)
-#define GPIO98_GPIO            MFP_CFG_IN(GPIO98, AF0)
-#define GPIO99_GPIO            MFP_CFG_IN(GPIO99, AF0)
-#define GPIO100_GPIO           MFP_CFG_IN(GPIO100, AF0)
-#define GPIO101_GPIO           MFP_CFG_IN(GPIO101, AF0)
-#define GPIO102_GPIO           MFP_CFG_IN(GPIO102, AF0)
-#define GPIO103_GPIO           MFP_CFG_IN(GPIO103, AF0)
-#define GPIO104_GPIO           MFP_CFG_IN(GPIO104, AF0)
-#define GPIO105_GPIO           MFP_CFG_IN(GPIO105, AF0)
-#define GPIO106_GPIO           MFP_CFG_IN(GPIO106, AF0)
-#define GPIO107_GPIO           MFP_CFG_IN(GPIO107, AF0)
-#define GPIO108_GPIO           MFP_CFG_IN(GPIO108, AF0)
-#define GPIO109_GPIO           MFP_CFG_IN(GPIO109, AF0)
-#define GPIO110_GPIO           MFP_CFG_IN(GPIO110, AF0)
-#define GPIO111_GPIO           MFP_CFG_IN(GPIO111, AF0)
-#define GPIO112_GPIO           MFP_CFG_IN(GPIO112, AF0)
-#define GPIO113_GPIO           MFP_CFG_IN(GPIO113, AF0)
-#define GPIO114_GPIO           MFP_CFG_IN(GPIO114, AF0)
-#define GPIO115_GPIO           MFP_CFG_IN(GPIO115, AF0)
-#define GPIO116_GPIO           MFP_CFG_IN(GPIO116, AF0)
-#define GPIO117_GPIO           MFP_CFG_IN(GPIO117, AF0)
-#define GPIO118_GPIO           MFP_CFG_IN(GPIO118, AF0)
-#define GPIO119_GPIO           MFP_CFG_IN(GPIO119, AF0)
-#define GPIO120_GPIO           MFP_CFG_IN(GPIO120, AF0)
-
-/* Crystal and Clock Signals */
-#define GPIO9_HZ_CLK           MFP_CFG_OUT(GPIO9,  AF1, DRIVE_LOW)
-#define GPIO10_HZ_CLK          MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
-#define GPIO11_48_MHz          MFP_CFG_OUT(GPIO11, AF3, DRIVE_LOW)
-#define GPIO12_48_MHz          MFP_CFG_OUT(GPIO12, AF3, DRIVE_LOW)
-#define GPIO13_CLK_EXT         MFP_CFG_IN(GPIO13, AF1)
-
-/* OS Timer Signals */
-#define GPIO11_EXT_SYNC_0      MFP_CFG_IN(GPIO11, AF1)
-#define GPIO12_EXT_SYNC_1      MFP_CFG_IN(GPIO12, AF1)
-#define GPIO9_CHOUT_0          MFP_CFG_OUT(GPIO9,  AF3, DRIVE_LOW)
-#define GPIO10_CHOUT_1         MFP_CFG_OUT(GPIO10, AF3, DRIVE_LOW)
-#define GPIO11_CHOUT_0         MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
-#define GPIO12_CHOUT_1         MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
-
-/* SDRAM and Static Memory I/O Signals */
-#define GPIO20_nSDCS_2         MFP_CFG_OUT(GPIO20, AF1, DRIVE_HIGH)
-#define GPIO21_nSDCS_3         MFP_CFG_OUT(GPIO21, AF1, DRIVE_HIGH)
-#define GPIO15_nCS_1           MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
-#define GPIO78_nCS_2           MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
-#define GPIO79_nCS_3           MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
-#define GPIO80_nCS_4           MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
-#define GPIO33_nCS_5           MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
-
-/* Miscellaneous I/O and DMA Signals */
-#define GPIO21_DVAL_0          MFP_CFG_OUT(GPIO21, AF2, DRIVE_HIGH)
-#define GPIO116_DVAL_0         MFP_CFG_OUT(GPIO116, AF1, DRIVE_HIGH)
-#define GPIO33_DVAL_1          MFP_CFG_OUT(GPIO33, AF1, DRIVE_HIGH)
-#define GPIO96_DVAL_1          MFP_CFG_OUT(GPIO96, AF2, DRIVE_HIGH)
-#define GPIO18_RDY             MFP_CFG_IN(GPIO18, AF1)
-#define GPIO20_DREQ_0          MFP_CFG_IN(GPIO20, AF1)
-#define GPIO115_DREQ_0         MFP_CFG_IN(GPIO115, AF1)
-#define GPIO80_DREQ_1          MFP_CFG_IN(GPIO80, AF1)
-#define GPIO97_DREQ_1          MFP_CFG_IN(GPIO97, AF2)
-#define GPIO85_DREQ_2          MFP_CFG_IN(GPIO85, AF2)
-#define GPIO100_DREQ_2         MFP_CFG_IN(GPIO100, AF2)
-
-/* Alternate Bus Master Mode I/O Signals */
-#define GPIO20_MBREQ           MFP_CFG_IN(GPIO20, AF2)
-#define GPIO80_MBREQ           MFP_CFG_IN(GPIO80, AF2)
-#define GPIO96_MBREQ           MFP_CFG_IN(GPIO96, AF2)
-#define GPIO115_MBREQ          MFP_CFG_IN(GPIO115, AF3)
-#define GPIO21_MBGNT           MFP_CFG_OUT(GPIO21, AF3, DRIVE_LOW)
-#define GPIO33_MBGNT           MFP_CFG_OUT(GPIO33, AF3, DRIVE_LOW)
-#define GPIO97_MBGNT           MFP_CFG_OUT(GPIO97, AF2, DRIVE_LOW)
-#define GPIO116_MBGNT          MFP_CFG_OUT(GPIO116, AF3, DRIVE_LOW)
-
-/* PC CARD */
-#define GPIO15_nPCE_1          MFP_CFG_OUT(GPIO15, AF1, DRIVE_HIGH)
-#define GPIO85_nPCE_1          MFP_CFG_OUT(GPIO85, AF1, DRIVE_HIGH)
-#define GPIO86_nPCE_1          MFP_CFG_OUT(GPIO86, AF1, DRIVE_HIGH)
-#define GPIO102_nPCE_1         MFP_CFG_OUT(GPIO102, AF1, DRIVE_HIGH)
-#define GPIO54_nPCE_2          MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
-#define GPIO78_nPCE_2          MFP_CFG_OUT(GPIO78, AF1, DRIVE_HIGH)
-#define GPIO87_nPCE_2          MFP_CFG_IN(GPIO87, AF1)
-#define GPIO55_nPREG           MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
-#define GPIO50_nPIOR           MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
-#define GPIO51_nPIOW           MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
-#define GPIO49_nPWE            MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
-#define GPIO48_nPOE            MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
-#define GPIO57_nIOIS16         MFP_CFG_IN(GPIO57, AF1)
-#define GPIO56_nPWAIT          MFP_CFG_IN(GPIO56, AF1)
-#define GPIO79_PSKTSEL         MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH)
-#define GPIO104_PSKTSEL                MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH)
-
-/* I2C */
-#define GPIO117_I2C_SCL                MFP_CFG_IN(GPIO117, AF1)
-#define GPIO118_I2C_SDA                MFP_CFG_IN(GPIO118, AF1)
-
-/* FFUART */
-#define GPIO9_FFUART_CTS       MFP_CFG_IN(GPIO9, AF3)
-#define GPIO26_FFUART_CTS      MFP_CFG_IN(GPIO26, AF3)
-#define GPIO35_FFUART_CTS      MFP_CFG_IN(GPIO35, AF1)
-#define GPIO100_FFUART_CTS     MFP_CFG_IN(GPIO100, AF3)
-#define GPIO10_FFUART_DCD      MFP_CFG_IN(GPIO10, AF1)
-#define GPIO36_FFUART_DCD      MFP_CFG_IN(GPIO36, AF1)
-#define GPIO33_FFUART_DSR      MFP_CFG_IN(GPIO33, AF2)
-#define GPIO37_FFUART_DSR      MFP_CFG_IN(GPIO37, AF1)
-#define GPIO38_FFUART_RI       MFP_CFG_IN(GPIO38, AF1)
-#define GPIO89_FFUART_RI       MFP_CFG_IN(GPIO89, AF3)
-#define GPIO19_FFUART_RXD      MFP_CFG_IN(GPIO19, AF3)
-#define GPIO33_FFUART_RXD      MFP_CFG_IN(GPIO33, AF1)
-#define GPIO34_FFUART_RXD      MFP_CFG_IN(GPIO34, AF1)
-#define GPIO41_FFUART_RXD      MFP_CFG_IN(GPIO41, AF1)
-#define GPIO53_FFUART_RXD      MFP_CFG_IN(GPIO53, AF1)
-#define GPIO85_FFUART_RXD      MFP_CFG_IN(GPIO85, AF1)
-#define GPIO96_FFUART_RXD      MFP_CFG_IN(GPIO96, AF3)
-#define GPIO102_FFUART_RXD     MFP_CFG_IN(GPIO102, AF3)
-#define GPIO16_FFUART_TXD      MFP_CFG_OUT(GPIO16, AF3, DRIVE_HIGH)
-#define GPIO37_FFUART_TXD      MFP_CFG_OUT(GPIO37, AF3, DRIVE_HIGH)
-#define GPIO39_FFUART_TXD      MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
-#define GPIO83_FFUART_TXD      MFP_CFG_OUT(GPIO83, AF2, DRIVE_HIGH)
-#define GPIO99_FFUART_TXD      MFP_CFG_OUT(GPIO99, AF3, DRIVE_HIGH)
-#define GPIO27_FFUART_RTS      MFP_CFG_OUT(GPIO27, AF3, DRIVE_HIGH)
-#define GPIO41_FFUART_RTS      MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
-#define GPIO83_FFUART_RTS      MFP_CFG_OUT(GPIO83, AF3, DRIVE_HIGH)
-#define GPIO98_FFUART_RTS      MFP_CFG_OUT(GPIO98, AF3, DRIVE_HIGH)
-#define GPIO40_FFUART_DTR      MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
-#define GPIO82_FFUART_DTR      MFP_CFG_OUT(GPIO82, AF3, DRIVE_HIGH)
-
-/* BTUART */
-#define GPIO44_BTUART_CTS      MFP_CFG_IN(GPIO44, AF1)
-#define GPIO42_BTUART_RXD      MFP_CFG_IN(GPIO42, AF1)
-#define GPIO45_BTUART_RTS      MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
-#define GPIO45_BTUART_RTS_LPM_LOW      MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW)
-#define GPIO43_BTUART_TXD      MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
-#define GPIO43_BTUART_TXD_LPM_LOW      MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW)
-
-/* STUART */
-#define GPIO46_STUART_RXD      MFP_CFG_IN(GPIO46, AF2)
-#define GPIO47_STUART_TXD      MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
-
-/* FICP */
-#define GPIO42_FICP_RXD                MFP_CFG_IN(GPIO42, AF2)
-#define GPIO46_FICP_RXD                MFP_CFG_IN(GPIO46, AF1)
-#define GPIO43_FICP_TXD                MFP_CFG_OUT(GPIO43, AF1, DRIVE_HIGH)
-#define GPIO47_FICP_TXD                MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
-
-/* PWM 0/1/2/3 */
-#define GPIO11_PWM2_OUT                MFP_CFG_OUT(GPIO11, AF2, DRIVE_LOW)
-#define GPIO12_PWM3_OUT                MFP_CFG_OUT(GPIO12, AF2, DRIVE_LOW)
-#define GPIO16_PWM0_OUT                MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
-#define GPIO17_PWM1_OUT                MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
-#define GPIO38_PWM1_OUT                MFP_CFG_OUT(GPIO38, AF3, DRIVE_LOW)
-#define GPIO46_PWM2_OUT                MFP_CFG_OUT(GPIO46, AF2, DRIVE_LOW)
-#define GPIO47_PWM3_OUT                MFP_CFG_OUT(GPIO47, AF3, DRIVE_LOW)
-#define GPIO79_PWM2_OUT                MFP_CFG_OUT(GPIO79, AF3, DRIVE_LOW)
-#define GPIO80_PWM3_OUT                MFP_CFG_OUT(GPIO80, AF3, DRIVE_LOW)
-#define GPIO115_PWM1_OUT       MFP_CFG_OUT(GPIO115, AF3, DRIVE_LOW)
-
-/* AC97 */
-#define GPIO31_AC97_SYNC       MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
-#define GPIO94_AC97_SYNC       MFP_CFG_OUT(GPIO94, AF1, DRIVE_LOW)
-#define GPIO30_AC97_SDATA_OUT  MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
-#define GPIO93_AC97_SDATA_OUT  MFP_CFG_OUT(GPIO93, AF1, DRIVE_LOW)
-#define GPIO45_AC97_SYSCLK     MFP_CFG_OUT(GPIO45, AF1, DRIVE_LOW)
-#define GPIO89_AC97_SYSCLK     MFP_CFG_OUT(GPIO89, AF1, DRIVE_LOW)
-#define GPIO98_AC97_SYSCLK     MFP_CFG_OUT(GPIO98, AF1, DRIVE_LOW)
-#define GPIO95_AC97_nRESET     MFP_CFG_OUT(GPIO95, AF1, DRIVE_LOW)
-#define GPIO113_AC97_nRESET    MFP_CFG_OUT(GPIO113, AF2, DRIVE_LOW)
-#define GPIO28_AC97_BITCLK     MFP_CFG_IN(GPIO28, AF1)
-#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
-#define GPIO116_AC97_SDATA_IN_0        MFP_CFG_IN(GPIO116, AF2)
-#define GPIO99_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO99, AF2)
-
-/* I2S */
-#define GPIO28_I2S_BITCLK_IN   MFP_CFG_IN(GPIO28, AF2)
-#define GPIO28_I2S_BITCLK_OUT  MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
-#define GPIO29_I2S_SDATA_IN    MFP_CFG_IN(GPIO29, AF2)
-#define GPIO30_I2S_SDATA_OUT   MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
-#define GPIO31_I2S_SYNC                MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
-#define GPIO113_I2S_SYSCLK     MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW)
-
-/* SSP 1 */
-#define GPIO23_SSP1_SCLK_IN    MFP_CFG_IN(GPIO23, AF2)
-#define GPIO23_SSP1_SCLK       MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
-#define GPIO29_SSP1_SCLK       MFP_CFG_IN(GPIO29, AF3)
-#define GPIO27_SSP1_SYSCLK     MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW)
-#define GPIO53_SSP1_SYSCLK     MFP_CFG_OUT(GPIO53, AF3, DRIVE_LOW)
-#define GPIO24_SSP1_SFRM       MFP_CFG_IN(GPIO24, AF2)
-#define GPIO28_SSP1_SFRM       MFP_CFG_IN(GPIO28, AF3)
-#define GPIO25_SSP1_TXD                MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
-#define GPIO57_SSP1_TXD                MFP_CFG_OUT(GPIO57, AF3, DRIVE_LOW)
-#define GPIO26_SSP1_RXD                MFP_CFG_IN(GPIO26, AF1)
-#define GPIO27_SSP1_SCLKEN     MFP_CFG_IN(GPIO27, AF2)
-
-/* SSP 2 */
-#define GPIO19_SSP2_SCLK       MFP_CFG_IN(GPIO19, AF1)
-#define GPIO22_SSP2_SCLK       MFP_CFG_IN(GPIO22, AF3)
-#define GPIO29_SSP2_SCLK       MFP_CFG_OUT(GPIO29, AF3, DRIVE_LOW)
-#define GPIO36_SSP2_SCLK       MFP_CFG_IN(GPIO36, AF2)
-#define GPIO50_SSP2_SCLK       MFP_CFG_IN(GPIO50, AF3)
-#define GPIO22_SSP2_SYSCLK     MFP_CFG_OUT(GPIO22, AF2, DRIVE_LOW)
-#define GPIO14_SSP2_SFRM       MFP_CFG_IN(GPIO14, AF2)
-#define GPIO37_SSP2_SFRM       MFP_CFG_IN(GPIO37, AF2)
-#define GPIO87_SSP2_SFRM       MFP_CFG_OUT(GPIO87, AF3, DRIVE_LOW)
-#define GPIO88_SSP2_SFRM       MFP_CFG_IN(GPIO88, AF3)
-#define GPIO13_SSP2_TXD                MFP_CFG_OUT(GPIO13, AF1, DRIVE_LOW)
-#define GPIO38_SSP2_TXD                MFP_CFG_OUT(GPIO38, AF2, DRIVE_LOW)
-#define GPIO87_SSP2_TXD                MFP_CFG_OUT(GPIO87, AF1, DRIVE_LOW)
-#define GPIO89_SSP2_TXD                MFP_CFG_OUT(GPIO89, AF3, DRIVE_LOW)
-#define GPIO11_SSP2_RXD                MFP_CFG_IN(GPIO11, AF2)
-#define GPIO29_SSP2_RXD                MFP_CFG_OUT(GPIO29, AF1, DRIVE_LOW)
-#define GPIO40_SSP2_RXD                MFP_CFG_IN(GPIO40, AF1)
-#define GPIO86_SSP2_RXD                MFP_CFG_IN(GPIO86, AF1)
-#define GPIO88_SSP2_RXD                MFP_CFG_IN(GPIO88, AF2)
-#define GPIO22_SSP2_EXTCLK     MFP_CFG_IN(GPIO22, AF1)
-#define GPIO27_SSP2_EXTCLK     MFP_CFG_IN(GPIO27, AF1)
-#define GPIO22_SSP2_SCLKEN     MFP_CFG_IN(GPIO22, AF2)
-#define GPIO23_SSP2_SCLKEN     MFP_CFG_IN(GPIO23, AF2)
-
-/* SSP 3 */
-#define GPIO34_SSP3_SCLK       MFP_CFG_IN(GPIO34, AF3)
-#define GPIO40_SSP3_SCLK       MFP_CFG_OUT(GPIO40, AF3, DRIVE_LOW)
-#define GPIO52_SSP3_SCLK       MFP_CFG_IN(GPIO52, AF2)
-#define GPIO84_SSP3_SCLK       MFP_CFG_IN(GPIO84, AF1)
-#define GPIO45_SSP3_SYSCLK     MFP_CFG_OUT(GPIO45, AF3, DRIVE_LOW)
-#define GPIO35_SSP3_SFRM       MFP_CFG_IN(GPIO35, AF3)
-#define GPIO39_SSP3_SFRM       MFP_CFG_IN(GPIO39, AF3)
-#define GPIO83_SSP3_SFRM       MFP_CFG_IN(GPIO83, AF1)
-#define GPIO35_SSP3_TXD                MFP_CFG_OUT(GPIO35, AF3, DRIVE_LOW)
-#define GPIO38_SSP3_TXD                MFP_CFG_OUT(GPIO38, AF1, DRIVE_LOW)
-#define GPIO81_SSP3_TXD                MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
-#define GPIO41_SSP3_RXD                MFP_CFG_IN(GPIO41, AF3)
-#define GPIO82_SSP3_RXD                MFP_CFG_IN(GPIO82, AF1)
-#define GPIO89_SSP3_RXD                MFP_CFG_IN(GPIO89, AF1)
-
-/* MMC */
-#define GPIO32_MMC_CLK         MFP_CFG_OUT(GPIO32, AF2, DRIVE_LOW)
-#define GPIO92_MMC_DAT_0       MFP_CFG_IN(GPIO92, AF1)
-#define GPIO109_MMC_DAT_1      MFP_CFG_IN(GPIO109, AF1)
-#define GPIO110_MMC_DAT_2      MFP_CFG_IN(GPIO110, AF1)
-#define GPIO111_MMC_DAT_3      MFP_CFG_IN(GPIO111, AF1)
-#define GPIO112_MMC_CMD                MFP_CFG_IN(GPIO112, AF1)
-
-/* LCD */
-#define GPIO58_LCD_LDD_0       MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
-#define GPIO59_LCD_LDD_1       MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
-#define GPIO60_LCD_LDD_2       MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
-#define GPIO61_LCD_LDD_3       MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
-#define GPIO62_LCD_LDD_4       MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
-#define GPIO63_LCD_LDD_5       MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
-#define GPIO64_LCD_LDD_6       MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
-#define GPIO65_LCD_LDD_7       MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
-#define GPIO66_LCD_LDD_8       MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
-#define GPIO67_LCD_LDD_9       MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
-#define GPIO68_LCD_LDD_10      MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
-#define GPIO69_LCD_LDD_11      MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
-#define GPIO70_LCD_LDD_12      MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
-#define GPIO71_LCD_LDD_13      MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
-#define GPIO72_LCD_LDD_14      MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
-#define GPIO73_LCD_LDD_15      MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
-#define GPIO86_LCD_LDD_16      MFP_CFG_OUT(GPIO86, AF2, DRIVE_LOW)
-#define GPIO87_LCD_LDD_17      MFP_CFG_OUT(GPIO87, AF2, DRIVE_LOW)
-#define GPIO74_LCD_FCLK                MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
-#define GPIO75_LCD_LCLK                MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
-#define GPIO76_LCD_PCLK                MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
-#define GPIO77_LCD_BIAS                MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
-#define GPIO14_LCD_VSYNC       MFP_CFG_IN(GPIO14, AF1)
-#define GPIO19_LCD_CS          MFP_CFG_OUT(GPIO19, AF2, DRIVE_LOW)
-
-/* Keypad */
-#define GPIO93_KP_DKIN_0       MFP_CFG_IN(GPIO93, AF1)
-#define GPIO94_KP_DKIN_1       MFP_CFG_IN(GPIO94, AF1)
-#define GPIO95_KP_DKIN_2       MFP_CFG_IN(GPIO95, AF1)
-#define GPIO96_KP_DKIN_3       MFP_CFG_IN(GPIO96, AF1)
-#define GPIO97_KP_DKIN_4       MFP_CFG_IN(GPIO97, AF1)
-#define GPIO98_KP_DKIN_5       MFP_CFG_IN(GPIO98, AF1)
-#define GPIO99_KP_DKIN_6       MFP_CFG_IN(GPIO99, AF1)
-#define GPIO13_KP_KDIN_7       MFP_CFG_IN(GPIO13, AF2)
-#define GPIO100_KP_MKIN_0      MFP_CFG_IN(GPIO100, AF1)
-#define GPIO101_KP_MKIN_1      MFP_CFG_IN(GPIO101, AF1)
-#define GPIO102_KP_MKIN_2      MFP_CFG_IN(GPIO102, AF1)
-#define GPIO34_KP_MKIN_3       MFP_CFG_IN(GPIO34, AF2)
-#define GPIO37_KP_MKIN_3       MFP_CFG_IN(GPIO37, AF3)
-#define GPIO97_KP_MKIN_3       MFP_CFG_IN(GPIO97, AF3)
-#define GPIO98_KP_MKIN_4       MFP_CFG_IN(GPIO98, AF3)
-#define GPIO38_KP_MKIN_4       MFP_CFG_IN(GPIO38, AF2)
-#define GPIO39_KP_MKIN_4       MFP_CFG_IN(GPIO39, AF1)
-#define GPIO16_KP_MKIN_5       MFP_CFG_IN(GPIO16, AF1)
-#define GPIO90_KP_MKIN_5       MFP_CFG_IN(GPIO90, AF1)
-#define GPIO99_KP_MKIN_5       MFP_CFG_IN(GPIO99, AF3)
-#define GPIO17_KP_MKIN_6       MFP_CFG_IN(GPIO17, AF1)
-#define GPIO91_KP_MKIN_6       MFP_CFG_IN(GPIO91, AF1)
-#define GPIO95_KP_MKIN_6       MFP_CFG_IN(GPIO95, AF3)
-#define GPIO13_KP_MKIN_7       MFP_CFG_IN(GPIO13, AF3)
-#define GPIO36_KP_MKIN_7       MFP_CFG_IN(GPIO36, AF3)
-#define GPIO103_KP_MKOUT_0     MFP_CFG_OUT(GPIO103, AF2, DRIVE_HIGH)
-#define GPIO104_KP_MKOUT_1     MFP_CFG_OUT(GPIO104, AF2, DRIVE_HIGH)
-#define GPIO105_KP_MKOUT_2     MFP_CFG_OUT(GPIO105, AF2, DRIVE_HIGH)
-#define GPIO106_KP_MKOUT_3     MFP_CFG_OUT(GPIO106, AF2, DRIVE_HIGH)
-#define GPIO107_KP_MKOUT_4     MFP_CFG_OUT(GPIO107, AF2, DRIVE_HIGH)
-#define GPIO108_KP_MKOUT_5     MFP_CFG_OUT(GPIO108, AF2, DRIVE_HIGH)
-#define GPIO35_KP_MKOUT_6      MFP_CFG_OUT(GPIO35, AF2, DRIVE_HIGH)
-#define GPIO22_KP_MKOUT_7      MFP_CFG_OUT(GPIO22, AF1, DRIVE_HIGH)
-#define GPIO40_KP_MKOUT_6      MFP_CFG_OUT(GPIO40, AF1, DRIVE_HIGH)
-#define GPIO41_KP_MKOUT_7      MFP_CFG_OUT(GPIO41, AF1, DRIVE_HIGH)
-#define GPIO96_KP_MKOUT_6      MFP_CFG_OUT(GPIO96, AF3, DRIVE_HIGH)
-
-/* USB P3 */
-#define GPIO10_USB_P3_5                MFP_CFG_IN(GPIO10, AF3)
-#define GPIO11_USB_P3_1                MFP_CFG_IN(GPIO11, AF3)
-#define GPIO30_USB_P3_2                MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
-#define GPIO31_USB_P3_6                MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
-#define GPIO56_USB_P3_4                MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
-#define GPIO86_USB_P3_5                MFP_CFG_IN(GPIO86, AF3)
-#define GPIO87_USB_P3_1                MFP_CFG_IN(GPIO87, AF3)
-#define GPIO90_USB_P3_5                MFP_CFG_IN(GPIO90, AF2)
-#define GPIO91_USB_P3_1                MFP_CFG_IN(GPIO91, AF2)
-#define GPIO113_USB_P3_3       MFP_CFG_IN(GPIO113, AF3)
-
-/* USB P2 */
-#define GPIO34_USB_P2_2                MFP_CFG_OUT(GPIO34, AF1, DRIVE_LOW)
-#define GPIO35_USB_P2_1                MFP_CFG_IN(GPIO35, AF2)
-#define GPIO36_USB_P2_4                MFP_CFG_OUT(GPIO36, AF1, DRIVE_LOW)
-#define GPIO37_USB_P2_8                MFP_CFG_OUT(GPIO37, AF1, DRIVE_LOW)
-#define GPIO38_USB_P2_3                MFP_CFG_IN(GPIO38, AF3)
-#define GPIO39_USB_P2_6                MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
-#define GPIO40_USB_P2_5                MFP_CFG_IN(GPIO40, AF3)
-#define GPIO41_USB_P2_7                MFP_CFG_IN(GPIO41, AF2)
-#define GPIO53_USB_P2_3                MFP_CFG_IN(GPIO53, AF2)
-
-/* USB Host Port 1/2 */
-#define GPIO88_USBH1_PWR       MFP_CFG_IN(GPIO88, AF1)
-#define GPIO89_USBH1_PEN       MFP_CFG_OUT(GPIO89, AF2, DRIVE_LOW)
-#define GPIO119_USBH2_PWR      MFP_CFG_IN(GPIO119, AF1)
-#define GPIO120_USBH2_PEN      MFP_CFG_OUT(GPIO120, AF2, DRIVE_LOW)
-
-/* QCI - default to Master Mode: CIF_FV/CIF_LV Direction In */
-#define GPIO115_CIF_DD_3       MFP_CFG_IN(GPIO115, AF2)
-#define GPIO116_CIF_DD_2       MFP_CFG_IN(GPIO116, AF1)
-#define GPIO12_CIF_DD_7                MFP_CFG_IN(GPIO12, AF2)
-#define GPIO17_CIF_DD_6                MFP_CFG_IN(GPIO17, AF2)
-#define GPIO23_CIF_MCLK                MFP_CFG_OUT(GPIO23, AF1, DRIVE_LOW)
-#define GPIO24_CIF_FV          MFP_CFG_IN(GPIO24, AF1)
-#define GPIO25_CIF_LV          MFP_CFG_IN(GPIO25, AF1)
-#define GPIO26_CIF_PCLK                MFP_CFG_IN(GPIO26, AF2)
-#define GPIO27_CIF_DD_0                MFP_CFG_IN(GPIO27, AF3)
-#define GPIO42_CIF_MCLK                MFP_CFG_OUT(GPIO42, AF3, DRIVE_LOW)
-#define GPIO43_CIF_FV          MFP_CFG_IN(GPIO43, AF3)
-#define GPIO44_CIF_LV          MFP_CFG_IN(GPIO44, AF3)
-#define GPIO45_CIF_PCLK                MFP_CFG_IN(GPIO45, AF3)
-#define GPIO47_CIF_DD_0                MFP_CFG_IN(GPIO47, AF1)
-#define GPIO48_CIF_DD_5                MFP_CFG_IN(GPIO48, AF1)
-#define GPIO50_CIF_DD_3                MFP_CFG_IN(GPIO50, AF1)
-#define GPIO51_CIF_DD_2                MFP_CFG_IN(GPIO51, AF1)
-#define GPIO52_CIF_DD_4                MFP_CFG_IN(GPIO52, AF1)
-#define GPIO53_CIF_MCLK                MFP_CFG_OUT(GPIO53, AF2, DRIVE_LOW)
-#define GPIO54_CIF_PCLK                MFP_CFG_IN(GPIO54, AF3)
-#define GPIO55_CIF_DD_1                MFP_CFG_IN(GPIO55, AF1)
-#define GPIO81_CIF_DD_0                MFP_CFG_IN(GPIO81, AF2)
-#define GPIO82_CIF_DD_5                MFP_CFG_IN(GPIO82, AF3)
-#define GPIO83_CIF_DD_4                MFP_CFG_IN(GPIO83, AF3)
-#define GPIO84_CIF_FV          MFP_CFG_IN(GPIO84, AF3)
-#define GPIO85_CIF_LV          MFP_CFG_IN(GPIO85, AF3)
-#define GPIO90_CIF_DD_4                MFP_CFG_IN(GPIO90, AF3)
-#define GPIO91_CIF_DD_5                MFP_CFG_IN(GPIO91, AF3)
-#define GPIO93_CIF_DD_6                MFP_CFG_IN(GPIO93, AF2)
-#define GPIO94_CIF_DD_5                MFP_CFG_IN(GPIO94, AF2)
-#define GPIO95_CIF_DD_4                MFP_CFG_IN(GPIO95, AF2)
-#define GPIO98_CIF_DD_0                MFP_CFG_IN(GPIO98, AF2)
-#define GPIO103_CIF_DD_3       MFP_CFG_IN(GPIO103, AF1)
-#define GPIO104_CIF_DD_2       MFP_CFG_IN(GPIO104, AF1)
-#define GPIO105_CIF_DD_1       MFP_CFG_IN(GPIO105, AF1)
-#define GPIO106_CIF_DD_9       MFP_CFG_IN(GPIO106, AF1)
-#define GPIO107_CIF_DD_8       MFP_CFG_IN(GPIO107, AF1)
-#define GPIO108_CIF_DD_7       MFP_CFG_IN(GPIO108, AF1)
-#define GPIO114_CIF_DD_1       MFP_CFG_IN(GPIO114, AF1)
-
-/* Universal Subscriber ID Interface */
-#define GPIO114_UVS0           MFP_CFG_OUT(GPIO114, AF2, DRIVE_LOW)
-#define GPIO115_nUVS1          MFP_CFG_OUT(GPIO115, AF2, DRIVE_LOW)
-#define GPIO116_nUVS2          MFP_CFG_OUT(GPIO116, AF2, DRIVE_LOW)
-#define GPIO14_UCLK            MFP_CFG_OUT(GPIO14, AF3, DRIVE_LOW)
-#define GPIO91_UCLK            MFP_CFG_OUT(GPIO91, AF2, DRIVE_LOW)
-#define GPIO19_nURST           MFP_CFG_OUT(GPIO19, AF3, DRIVE_LOW)
-#define GPIO90_nURST           MFP_CFG_OUT(GPIO90, AF2, DRIVE_LOW)
-#define GPIO116_UDET           MFP_CFG_IN(GPIO116, AF3)
-#define GPIO114_UEN            MFP_CFG_OUT(GPIO114, AF1, DRIVE_LOW)
-#define GPIO115_UEN            MFP_CFG_OUT(GPIO115, AF1, DRIVE_LOW)
-
-/* Mobile Scalable Link (MSL) Interface */
-#define GPIO81_BB_OB_DAT_0     MFP_CFG_OUT(GPIO81, AF2, DRIVE_LOW)
-#define GPIO48_BB_OB_DAT_1     MFP_CFG_OUT(GPIO48, AF1, DRIVE_LOW)
-#define GPIO50_BB_OB_DAT_2     MFP_CFG_OUT(GPIO50, AF1, DRIVE_LOW)
-#define GPIO51_BB_OB_DAT_3     MFP_CFG_OUT(GPIO51, AF1, DRIVE_LOW)
-#define GPIO52_BB_OB_CLK       MFP_CFG_OUT(GPIO52, AF1, DRIVE_LOW)
-#define GPIO53_BB_OB_STB       MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
-#define GPIO54_BB_OB_WAIT      MFP_CFG_IN(GPIO54, AF2)
-#define GPIO82_BB_IB_DAT_0     MFP_CFG_IN(GPIO82, AF2)
-#define GPIO55_BB_IB_DAT_1     MFP_CFG_IN(GPIO55, AF2)
-#define GPIO56_BB_IB_DAT_2     MFP_CFG_IN(GPIO56, AF2)
-#define GPIO57_BB_IB_DAT_3     MFP_CFG_IN(GPIO57, AF2)
-#define GPIO83_BB_IB_CLK       MFP_CFG_IN(GPIO83, AF2)
-#define GPIO84_BB_IB_STB       MFP_CFG_IN(GPIO84, AF2)
-#define GPIO85_BB_IB_WAIT      MFP_CFG_OUT(GPIO85, AF2, DRIVE_LOW)
-
-/* Memory Stick Host Controller */
-#define GPIO92_MSBS            MFP_CFG_OUT(GPIO92, AF2, DRIVE_LOW)
-#define GPIO109_MSSDIO         MFP_CFG_IN(GPIO109, AF2)
-#define GPIO112_nMSINS         MFP_CFG_IN(GPIO112, AF2)
-#define GPIO32_MSSCLK          MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
-
-/* commonly used pin configurations */
-#define GPIOxx_LCD_16BPP       \
-       GPIO58_LCD_LDD_0,       \
-       GPIO59_LCD_LDD_1,       \
-       GPIO60_LCD_LDD_2,       \
-       GPIO61_LCD_LDD_3,       \
-       GPIO62_LCD_LDD_4,       \
-       GPIO63_LCD_LDD_5,       \
-       GPIO64_LCD_LDD_6,       \
-       GPIO65_LCD_LDD_7,       \
-       GPIO66_LCD_LDD_8,       \
-       GPIO67_LCD_LDD_9,       \
-       GPIO68_LCD_LDD_10,      \
-       GPIO69_LCD_LDD_11,      \
-       GPIO70_LCD_LDD_12,      \
-       GPIO71_LCD_LDD_13,      \
-       GPIO72_LCD_LDD_14,      \
-       GPIO73_LCD_LDD_15
-
-#define GPIOxx_LCD_TFT_16BPP   \
-       GPIOxx_LCD_16BPP,       \
-       GPIO74_LCD_FCLK,        \
-       GPIO75_LCD_LCLK,        \
-       GPIO76_LCD_PCLK,        \
-       GPIO77_LCD_BIAS
-
-/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */
-#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT)
-#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT)
-
-extern int keypad_set_wake(unsigned int on);
-#endif /* __ASM_ARCH_MFP_PXA27X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
deleted file mode 100644 (file)
index cbf51ae..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef __ASM_ARCH_MFP_PXA2XX_H
-#define __ASM_ARCH_MFP_PXA2XX_H
-
-#include <plat/mfp.h>
-
-/*
- * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
- *
- *  MFP_PIN(x)
- *  MFP_AFx
- *  MFP_LPM_DRIVE_{LOW, HIGH}
- *  MFP_LPM_EDGE_x
- *
- * other MFP_x bit definitions will be ignored
- *
- * and adds the below two bits specifically for pxa2xx:
- *
- * bit     23 - Input/Output (PXA2xx specific)
- * bit     24 - Wakeup Enable(PXA2xx specific)
- * bit     25 - Keep Output  (PXA2xx specific)
- */
-
-#define MFP_DIR_IN             (0x0 << 23)
-#define MFP_DIR_OUT            (0x1 << 23)
-#define MFP_DIR_MASK           (0x1 << 23)
-#define MFP_DIR(x)             (((x) >> 23) & 0x1)
-
-#define MFP_LPM_CAN_WAKEUP     (0x1 << 24)
-
-/*
- * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to
- * retain their last output level (low or high).
- * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input.
- */
-#define MFP_LPM_KEEP_OUTPUT    (0x1 << 25)
-
-#define WAKEUP_ON_EDGE_RISE    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
-#define WAKEUP_ON_EDGE_FALL    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL)
-#define WAKEUP_ON_EDGE_BOTH    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH)
-
-/* specifically for enabling wakeup on keypad GPIOs */
-#define WAKEUP_ON_LEVEL_HIGH   (MFP_LPM_CAN_WAKEUP)
-
-#define MFP_CFG_IN(pin, af)            \
-       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
-        (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_IN))
-
-/* NOTE:  pins configured as output _must_ provide a low power state,
- * and this state should help to minimize the power dissipation.
- */
-#define MFP_CFG_OUT(pin, af, state)    \
-       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
-        (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
-
-/* Common configurations for pxa25x and pxa27x
- *
- * Note: pins configured as GPIO are always initialized to input
- * so not to cause any side effect
- */
-#define GPIO0_GPIO     MFP_CFG_IN(GPIO0, AF0)
-#define GPIO1_GPIO     MFP_CFG_IN(GPIO1, AF0)
-#define GPIO9_GPIO     MFP_CFG_IN(GPIO9, AF0)
-#define GPIO10_GPIO    MFP_CFG_IN(GPIO10, AF0)
-#define GPIO11_GPIO    MFP_CFG_IN(GPIO11, AF0)
-#define GPIO12_GPIO    MFP_CFG_IN(GPIO12, AF0)
-#define GPIO13_GPIO    MFP_CFG_IN(GPIO13, AF0)
-#define GPIO14_GPIO    MFP_CFG_IN(GPIO14, AF0)
-#define GPIO15_GPIO    MFP_CFG_IN(GPIO15, AF0)
-#define GPIO16_GPIO    MFP_CFG_IN(GPIO16, AF0)
-#define GPIO17_GPIO    MFP_CFG_IN(GPIO17, AF0)
-#define GPIO18_GPIO    MFP_CFG_IN(GPIO18, AF0)
-#define GPIO19_GPIO    MFP_CFG_IN(GPIO19, AF0)
-#define GPIO20_GPIO    MFP_CFG_IN(GPIO20, AF0)
-#define GPIO21_GPIO    MFP_CFG_IN(GPIO21, AF0)
-#define GPIO22_GPIO    MFP_CFG_IN(GPIO22, AF0)
-#define GPIO23_GPIO    MFP_CFG_IN(GPIO23, AF0)
-#define GPIO24_GPIO    MFP_CFG_IN(GPIO24, AF0)
-#define GPIO25_GPIO    MFP_CFG_IN(GPIO25, AF0)
-#define GPIO26_GPIO    MFP_CFG_IN(GPIO26, AF0)
-#define GPIO27_GPIO    MFP_CFG_IN(GPIO27, AF0)
-#define GPIO28_GPIO    MFP_CFG_IN(GPIO28, AF0)
-#define GPIO29_GPIO    MFP_CFG_IN(GPIO29, AF0)
-#define GPIO30_GPIO    MFP_CFG_IN(GPIO30, AF0)
-#define GPIO31_GPIO    MFP_CFG_IN(GPIO31, AF0)
-#define GPIO32_GPIO    MFP_CFG_IN(GPIO32, AF0)
-#define GPIO33_GPIO    MFP_CFG_IN(GPIO33, AF0)
-#define GPIO34_GPIO    MFP_CFG_IN(GPIO34, AF0)
-#define GPIO35_GPIO    MFP_CFG_IN(GPIO35, AF0)
-#define GPIO36_GPIO    MFP_CFG_IN(GPIO36, AF0)
-#define GPIO37_GPIO    MFP_CFG_IN(GPIO37, AF0)
-#define GPIO38_GPIO    MFP_CFG_IN(GPIO38, AF0)
-#define GPIO39_GPIO    MFP_CFG_IN(GPIO39, AF0)
-#define GPIO40_GPIO    MFP_CFG_IN(GPIO40, AF0)
-#define GPIO41_GPIO    MFP_CFG_IN(GPIO41, AF0)
-#define GPIO42_GPIO    MFP_CFG_IN(GPIO42, AF0)
-#define GPIO43_GPIO    MFP_CFG_IN(GPIO43, AF0)
-#define GPIO44_GPIO    MFP_CFG_IN(GPIO44, AF0)
-#define GPIO45_GPIO    MFP_CFG_IN(GPIO45, AF0)
-#define GPIO46_GPIO    MFP_CFG_IN(GPIO46, AF0)
-#define GPIO47_GPIO    MFP_CFG_IN(GPIO47, AF0)
-#define GPIO48_GPIO    MFP_CFG_IN(GPIO48, AF0)
-#define GPIO49_GPIO    MFP_CFG_IN(GPIO49, AF0)
-#define GPIO50_GPIO    MFP_CFG_IN(GPIO50, AF0)
-#define GPIO51_GPIO    MFP_CFG_IN(GPIO51, AF0)
-#define GPIO52_GPIO    MFP_CFG_IN(GPIO52, AF0)
-#define GPIO53_GPIO    MFP_CFG_IN(GPIO53, AF0)
-#define GPIO54_GPIO    MFP_CFG_IN(GPIO54, AF0)
-#define GPIO55_GPIO    MFP_CFG_IN(GPIO55, AF0)
-#define GPIO56_GPIO    MFP_CFG_IN(GPIO56, AF0)
-#define GPIO57_GPIO    MFP_CFG_IN(GPIO57, AF0)
-#define GPIO58_GPIO    MFP_CFG_IN(GPIO58, AF0)
-#define GPIO59_GPIO    MFP_CFG_IN(GPIO59, AF0)
-#define GPIO60_GPIO    MFP_CFG_IN(GPIO60, AF0)
-#define GPIO61_GPIO    MFP_CFG_IN(GPIO61, AF0)
-#define GPIO62_GPIO    MFP_CFG_IN(GPIO62, AF0)
-#define GPIO63_GPIO    MFP_CFG_IN(GPIO63, AF0)
-#define GPIO64_GPIO    MFP_CFG_IN(GPIO64, AF0)
-#define GPIO65_GPIO    MFP_CFG_IN(GPIO65, AF0)
-#define GPIO66_GPIO    MFP_CFG_IN(GPIO66, AF0)
-#define GPIO67_GPIO    MFP_CFG_IN(GPIO67, AF0)
-#define GPIO68_GPIO    MFP_CFG_IN(GPIO68, AF0)
-#define GPIO69_GPIO    MFP_CFG_IN(GPIO69, AF0)
-#define GPIO70_GPIO    MFP_CFG_IN(GPIO70, AF0)
-#define GPIO71_GPIO    MFP_CFG_IN(GPIO71, AF0)
-#define GPIO72_GPIO    MFP_CFG_IN(GPIO72, AF0)
-#define GPIO73_GPIO    MFP_CFG_IN(GPIO73, AF0)
-#define GPIO74_GPIO    MFP_CFG_IN(GPIO74, AF0)
-#define GPIO75_GPIO    MFP_CFG_IN(GPIO75, AF0)
-#define GPIO76_GPIO    MFP_CFG_IN(GPIO76, AF0)
-#define GPIO77_GPIO    MFP_CFG_IN(GPIO77, AF0)
-#define GPIO78_GPIO    MFP_CFG_IN(GPIO78, AF0)
-#define GPIO79_GPIO    MFP_CFG_IN(GPIO79, AF0)
-#define GPIO80_GPIO    MFP_CFG_IN(GPIO80, AF0)
-#define GPIO81_GPIO    MFP_CFG_IN(GPIO81, AF0)
-#define GPIO82_GPIO    MFP_CFG_IN(GPIO82, AF0)
-#define GPIO83_GPIO    MFP_CFG_IN(GPIO83, AF0)
-#define GPIO84_GPIO    MFP_CFG_IN(GPIO84, AF0)
-
-extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num);
-extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm);
-extern int gpio_set_wake(unsigned int gpio, unsigned int on);
-#endif /* __ASM_ARCH_MFP_PXA2XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
deleted file mode 100644 (file)
index 4e12870..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/mfp-pxa300.h
- *
- * PXA300/PXA310 specific MFP configuration definitions
- *
- * Copyright (C) 2007 Marvell International Ltd.
- * 2007-08-21: eric miao <eric.miao@marvell.com>
- *             initial version
- *
- *  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_MFP_PXA300_H
-#define __ASM_ARCH_MFP_PXA300_H
-
-#include <mach/mfp-pxa3xx.h>
-
-/* GPIO */
-#define GPIO46_GPIO            MFP_CFG(GPIO46, AF1)
-#define GPIO49_GPIO            MFP_CFG(GPIO49, AF3)
-#define GPIO50_GPIO            MFP_CFG(GPIO50, AF2)
-#define GPIO51_GPIO            MFP_CFG(GPIO51, AF3)
-#define GPIO52_GPIO            MFP_CFG(GPIO52, AF3)
-#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
-#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
-#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
-#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
-#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
-#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
-
-#ifdef CONFIG_CPU_PXA310
-#define GPIO7_2_GPIO           MFP_CFG(GPIO7_2, AF0)
-#define GPIO8_2_GPIO           MFP_CFG(GPIO8_2, AF0)
-#define GPIO9_2_GPIO           MFP_CFG(GPIO9_2, AF0)
-#define GPIO10_2_GPIO          MFP_CFG(GPIO10_2, AF0)
-#define GPIO11_2_GPIO          MFP_CFG(GPIO11_2, AF0)
-#define GPIO12_2_GPIO          MFP_CFG(GPIO12_2, AF0)
-#endif
-
-/* Chip Select */
-#define GPIO1_nCS2             MFP_CFG(GPIO1,  AF1)
-#define GPIO2_nCS3             MFP_CFG(GPIO2,  AF1)
-
-/* AC97 */
-#define GPIO23_AC97_nACRESET   MFP_CFG(GPIO23, AF1)
-#define GPIO24_AC97_SYSCLK     MFP_CFG(GPIO24, AF1)
-#define GPIO29_AC97_BITCLK     MFP_CFG(GPIO29, AF1)
-#define GPIO25_AC97_SDATA_IN_0 MFP_CFG(GPIO25, AF1)
-#define GPIO26_AC97_SDATA_IN_1 MFP_CFG(GPIO26, AF1)
-#define GPIO17_AC97_SDATA_IN_2 MFP_CFG(GPIO17, AF3)
-#define GPIO21_AC97_SDATA_IN_2 MFP_CFG(GPIO21, AF2)
-#define GPIO18_AC97_SDATA_IN_3 MFP_CFG(GPIO18, AF3)
-#define GPIO22_AC97_SDATA_IN_3 MFP_CFG(GPIO22, AF2)
-#define GPIO27_AC97_SDATA_OUT  MFP_CFG(GPIO27, AF1)
-#define GPIO28_AC97_SYNC       MFP_CFG(GPIO28, AF1)
-
-/* I2C */
-#define GPIO21_I2C_SCL         MFP_CFG_LPM(GPIO21, AF1, PULL_HIGH)
-#define GPIO22_I2C_SDA         MFP_CFG_LPM(GPIO22, AF1, PULL_HIGH)
-
-/* QCI */
-#define GPIO39_CI_DD_0         MFP_CFG_DRV(GPIO39, AF1, DS04X)
-#define GPIO40_CI_DD_1         MFP_CFG_DRV(GPIO40, AF1, DS04X)
-#define GPIO41_CI_DD_2         MFP_CFG_DRV(GPIO41, AF1, DS04X)
-#define GPIO42_CI_DD_3         MFP_CFG_DRV(GPIO42, AF1, DS04X)
-#define GPIO43_CI_DD_4         MFP_CFG_DRV(GPIO43, AF1, DS04X)
-#define GPIO44_CI_DD_5         MFP_CFG_DRV(GPIO44, AF1, DS04X)
-#define GPIO45_CI_DD_6         MFP_CFG_DRV(GPIO45, AF1, DS04X)
-#define GPIO46_CI_DD_7         MFP_CFG_DRV(GPIO46, AF0, DS04X)
-#define GPIO47_CI_DD_8         MFP_CFG_DRV(GPIO47, AF1, DS04X)
-#define GPIO48_CI_DD_9         MFP_CFG_DRV(GPIO48, AF1, DS04X)
-#define GPIO49_CI_MCLK         MFP_CFG_DRV(GPIO49, AF0, DS04X)
-#define GPIO50_CI_PCLK         MFP_CFG_DRV(GPIO50, AF0, DS04X)
-#define GPIO51_CI_HSYNC                MFP_CFG_DRV(GPIO51, AF0, DS04X)
-#define GPIO52_CI_VSYNC                MFP_CFG_DRV(GPIO52, AF0, DS04X)
-
-/* KEYPAD */
-#define GPIO3_KP_DKIN_6                MFP_CFG_LPM(GPIO3,   AF2, FLOAT)
-#define GPIO4_KP_DKIN_7                MFP_CFG_LPM(GPIO4,   AF2, FLOAT)
-#define GPIO16_KP_DKIN_6       MFP_CFG_LPM(GPIO16,  AF6, FLOAT)
-#define GPIO83_KP_DKIN_2       MFP_CFG_LPM(GPIO83,  AF5, FLOAT)
-#define GPIO84_KP_DKIN_1       MFP_CFG_LPM(GPIO84,  AF5, FLOAT)
-#define GPIO85_KP_DKIN_0       MFP_CFG_LPM(GPIO85,  AF3, FLOAT)
-#define GPIO86_KP_DKIN_1       MFP_CFG_LPM(GPIO86,  AF3, FLOAT)
-#define GPIO87_KP_DKIN_2       MFP_CFG_LPM(GPIO87,  AF3, FLOAT)
-#define GPIO88_KP_DKIN_3       MFP_CFG_LPM(GPIO88,  AF3, FLOAT)
-#define GPIO89_KP_DKIN_3       MFP_CFG_LPM(GPIO89,  AF3, FLOAT)
-#define GPIO107_KP_DKIN_0      MFP_CFG_LPM(GPIO107, AF2, FLOAT)
-#define GPIO108_KP_DKIN_1      MFP_CFG_LPM(GPIO108, AF2, FLOAT)
-#define GPIO109_KP_DKIN_2      MFP_CFG_LPM(GPIO109, AF2, FLOAT)
-#define GPIO110_KP_DKIN_3      MFP_CFG_LPM(GPIO110, AF2, FLOAT)
-#define GPIO111_KP_DKIN_4      MFP_CFG_LPM(GPIO111, AF2, FLOAT)
-#define GPIO112_KP_DKIN_5      MFP_CFG_LPM(GPIO112, AF2, FLOAT)
-#define GPIO113_KP_DKIN_6      MFP_CFG_LPM(GPIO113, AF2, FLOAT)
-#define GPIO114_KP_DKIN_7      MFP_CFG_LPM(GPIO114, AF2, FLOAT)
-#define GPIO115_KP_DKIN_0      MFP_CFG_LPM(GPIO115, AF2, FLOAT)
-#define GPIO116_KP_DKIN_1      MFP_CFG_LPM(GPIO116, AF2, FLOAT)
-#define GPIO117_KP_DKIN_2      MFP_CFG_LPM(GPIO117, AF2, FLOAT)
-#define GPIO118_KP_DKIN_3      MFP_CFG_LPM(GPIO118, AF2, FLOAT)
-#define GPIO119_KP_DKIN_4      MFP_CFG_LPM(GPIO119, AF2, FLOAT)
-#define GPIO120_KP_DKIN_5      MFP_CFG_LPM(GPIO120, AF2, FLOAT)
-#define GPIO121_KP_DKIN_6      MFP_CFG_LPM(GPIO121, AF2, FLOAT)
-#define GPIO122_KP_DKIN_5      MFP_CFG_LPM(GPIO122, AF2, FLOAT)
-#define GPIO123_KP_DKIN_4      MFP_CFG_LPM(GPIO123, AF2, FLOAT)
-#define GPIO124_KP_DKIN_3      MFP_CFG_LPM(GPIO124, AF2, FLOAT)
-#define GPIO127_KP_DKIN_0      MFP_CFG_LPM(GPIO127, AF5, FLOAT)
-#define GPIO0_2_KP_DKIN_0      MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
-#define GPIO1_2_KP_DKIN_1      MFP_CFG_LPM(GPIO1_2, AF2, FLOAT)
-#define GPIO2_2_KP_DKIN_6      MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
-#define GPIO3_2_KP_DKIN_7      MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
-#define GPIO4_2_KP_DKIN_1      MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
-#define GPIO5_2_KP_DKIN_0      MFP_CFG_LPM(GPIO5_2, AF2, FLOAT)
-
-#define GPIO5_KP_MKIN_0                MFP_CFG_LPM(GPIO5,   AF2, FLOAT)
-#define GPIO6_KP_MKIN_1                MFP_CFG_LPM(GPIO6,   AF2, FLOAT)
-#define GPIO9_KP_MKIN_6                MFP_CFG_LPM(GPIO9,   AF3, FLOAT)
-#define GPIO10_KP_MKIN_7       MFP_CFG_LPM(GPIO10,  AF3, FLOAT)
-#define GPIO70_KP_MKIN_6       MFP_CFG_LPM(GPIO70,  AF3, FLOAT)
-#define GPIO71_KP_MKIN_7       MFP_CFG_LPM(GPIO71,  AF3, FLOAT)
-#define GPIO100_KP_MKIN_6      MFP_CFG_LPM(GPIO100, AF7, FLOAT)
-#define GPIO101_KP_MKIN_7      MFP_CFG_LPM(GPIO101, AF7, FLOAT)
-#define GPIO112_KP_MKIN_6      MFP_CFG_LPM(GPIO112, AF4, FLOAT)
-#define GPIO113_KP_MKIN_7      MFP_CFG_LPM(GPIO113, AF4, FLOAT)
-#define GPIO115_KP_MKIN_0      MFP_CFG_LPM(GPIO115, AF1, FLOAT)
-#define GPIO116_KP_MKIN_1      MFP_CFG_LPM(GPIO116, AF1, FLOAT)
-#define GPIO117_KP_MKIN_2      MFP_CFG_LPM(GPIO117, AF1, FLOAT)
-#define GPIO118_KP_MKIN_3      MFP_CFG_LPM(GPIO118, AF1, FLOAT)
-#define GPIO119_KP_MKIN_4      MFP_CFG_LPM(GPIO119, AF1, FLOAT)
-#define GPIO120_KP_MKIN_5      MFP_CFG_LPM(GPIO120, AF1, FLOAT)
-#define GPIO125_KP_MKIN_2      MFP_CFG_LPM(GPIO125, AF2, FLOAT)
-#define GPIO2_2_KP_MKIN_6      MFP_CFG_LPM(GPIO2_2, AF1, FLOAT)
-#define GPIO3_2_KP_MKIN_7      MFP_CFG_LPM(GPIO3_2, AF1, FLOAT)
-
-#define GPIO7_KP_MKOUT_5       MFP_CFG_LPM(GPIO7,   AF1, DRIVE_HIGH)
-#define GPIO11_KP_MKOUT_5      MFP_CFG_LPM(GPIO11,  AF3, DRIVE_HIGH)
-#define GPIO12_KP_MKOUT_6      MFP_CFG_LPM(GPIO12,  AF3, DRIVE_HIGH)
-#define GPIO13_KP_MKOUT_7      MFP_CFG_LPM(GPIO13,  AF3, DRIVE_HIGH)
-#define GPIO19_KP_MKOUT_4      MFP_CFG_LPM(GPIO19,  AF3, DRIVE_HIGH)
-#define GPIO20_KP_MKOUT_5      MFP_CFG_LPM(GPIO20,  AF3, DRIVE_HIGH)
-#define GPIO38_KP_MKOUT_5      MFP_CFG_LPM(GPIO38,  AF5, DRIVE_HIGH)
-#define GPIO53_KP_MKOUT_6      MFP_CFG_LPM(GPIO53,  AF5, DRIVE_HIGH)
-#define GPIO78_KP_MKOUT_7      MFP_CFG_LPM(GPIO78,  AF5, DRIVE_HIGH)
-#define GPIO85_KP_MKOUT_0      MFP_CFG_LPM(GPIO85,  AF2, DRIVE_HIGH)
-#define GPIO86_KP_MKOUT_1      MFP_CFG_LPM(GPIO86,  AF2, DRIVE_HIGH)
-#define GPIO87_KP_MKOUT_2      MFP_CFG_LPM(GPIO87,  AF2, DRIVE_HIGH)
-#define GPIO88_KP_MKOUT_3      MFP_CFG_LPM(GPIO88,  AF2, DRIVE_HIGH)
-#define GPIO104_KP_MKOUT_6     MFP_CFG_LPM(GPIO104, AF5, DRIVE_HIGH)
-#define GPIO105_KP_MKOUT_7     MFP_CFG_LPM(GPIO105, AF5, DRIVE_HIGH)
-#define GPIO121_KP_MKOUT_0     MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
-#define GPIO122_KP_MKOUT_1     MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
-#define GPIO123_KP_MKOUT_2     MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
-#define GPIO124_KP_MKOUT_3     MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
-#define GPIO125_KP_MKOUT_4     MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
-#define GPIO126_KP_MKOUT_7     MFP_CFG_LPM(GPIO126, AF4, DRIVE_HIGH)
-#define GPIO5_2_KP_MKOUT_6     MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
-#define GPIO4_2_KP_MKOUT_5     MFP_CFG_LPM(GPIO4_2, AF1, DRIVE_HIGH)
-#define GPIO6_2_KP_MKOUT_7     MFP_CFG_LPM(GPIO6_2, AF1, DRIVE_HIGH)
-
-/* LCD */
-#define GPIO54_LCD_LDD_0       MFP_CFG_DRV(GPIO54, AF1, DS01X)
-#define GPIO55_LCD_LDD_1       MFP_CFG_DRV(GPIO55, AF1, DS01X)
-#define GPIO56_LCD_LDD_2       MFP_CFG_DRV(GPIO56, AF1, DS01X)
-#define GPIO57_LCD_LDD_3       MFP_CFG_DRV(GPIO57, AF1, DS01X)
-#define GPIO58_LCD_LDD_4       MFP_CFG_DRV(GPIO58, AF1, DS01X)
-#define GPIO59_LCD_LDD_5       MFP_CFG_DRV(GPIO59, AF1, DS01X)
-#define GPIO60_LCD_LDD_6       MFP_CFG_DRV(GPIO60, AF1, DS01X)
-#define GPIO61_LCD_LDD_7       MFP_CFG_DRV(GPIO61, AF1, DS01X)
-#define GPIO62_LCD_LDD_8       MFP_CFG_DRV(GPIO62, AF1, DS01X)
-#define GPIO63_LCD_LDD_9       MFP_CFG_DRV(GPIO63, AF1, DS01X)
-#define GPIO64_LCD_LDD_10      MFP_CFG_DRV(GPIO64, AF1, DS01X)
-#define GPIO65_LCD_LDD_11      MFP_CFG_DRV(GPIO65, AF1, DS01X)
-#define GPIO66_LCD_LDD_12      MFP_CFG_DRV(GPIO66, AF1, DS01X)
-#define GPIO67_LCD_LDD_13      MFP_CFG_DRV(GPIO67, AF1, DS01X)
-#define GPIO68_LCD_LDD_14      MFP_CFG_DRV(GPIO68, AF1, DS01X)
-#define GPIO69_LCD_LDD_15      MFP_CFG_DRV(GPIO69, AF1, DS01X)
-#define GPIO70_LCD_LDD_16      MFP_CFG_DRV(GPIO70, AF1, DS01X)
-#define GPIO71_LCD_LDD_17      MFP_CFG_DRV(GPIO71, AF1, DS01X)
-#define GPIO62_LCD_CS_N                MFP_CFG_DRV(GPIO62, AF2, DS01X)
-#define GPIO72_LCD_FCLK                MFP_CFG_DRV(GPIO72, AF1, DS01X)
-#define GPIO73_LCD_LCLK                MFP_CFG_DRV(GPIO73, AF1, DS01X)
-#define GPIO74_LCD_PCLK                MFP_CFG_DRV(GPIO74, AF1, DS02X)
-#define GPIO75_LCD_BIAS                MFP_CFG_DRV(GPIO75, AF1, DS01X)
-#define GPIO76_LCD_VSYNC       MFP_CFG_DRV(GPIO76, AF2, DS01X)
-
-#define GPIO15_LCD_CS_N                MFP_CFG_DRV(GPIO15,  AF2, DS01X)
-#define GPIO127_LCD_CS_N       MFP_CFG_DRV(GPIO127, AF1, DS01X)
-#define GPIO63_LCD_VSYNC       MFP_CFG_DRV(GPIO63,  AF2, DS01X)
-
-/* Mini-LCD */
-#define GPIO72_MLCD_FCLK       MFP_CFG_DRV(GPIO72, AF7, DS08X)
-#define GPIO73_MLCD_LCLK       MFP_CFG_DRV(GPIO73, AF7, DS08X)
-#define GPIO54_MLCD_LDD_0      MFP_CFG_DRV(GPIO54, AF7, DS08X)
-#define GPIO55_MLCD_LDD_1      MFP_CFG_DRV(GPIO55, AF7, DS08X)
-#define GPIO56_MLCD_LDD_2      MFP_CFG_DRV(GPIO56, AF7, DS08X)
-#define GPIO57_MLCD_LDD_3      MFP_CFG_DRV(GPIO57, AF7, DS08X)
-#define GPIO58_MLCD_LDD_4      MFP_CFG_DRV(GPIO58, AF7, DS08X)
-#define GPIO59_MLCD_LDD_5      MFP_CFG_DRV(GPIO59, AF7, DS08X)
-#define GPIO60_MLCD_LDD_6      MFP_CFG_DRV(GPIO60, AF7, DS08X)
-#define GPIO61_MLCD_LDD_7      MFP_CFG_DRV(GPIO61, AF7, DS08X)
-#define GPIO62_MLCD_LDD_8      MFP_CFG_DRV(GPIO62, AF7, DS08X)
-#define GPIO63_MLCD_LDD_9      MFP_CFG_DRV(GPIO63, AF7, DS08X)
-#define GPIO64_MLCD_LDD_10     MFP_CFG_DRV(GPIO64, AF7, DS08X)
-#define GPIO65_MLCD_LDD_11     MFP_CFG_DRV(GPIO65, AF7, DS08X)
-#define GPIO66_MLCD_LDD_12     MFP_CFG_DRV(GPIO66, AF7, DS08X)
-#define GPIO67_MLCD_LDD_13     MFP_CFG_DRV(GPIO67, AF7, DS08X)
-#define GPIO68_MLCD_LDD_14     MFP_CFG_DRV(GPIO68, AF7, DS08X)
-#define GPIO69_MLCD_LDD_15     MFP_CFG_DRV(GPIO69, AF7, DS08X)
-#define GPIO74_MLCD_PCLK       MFP_CFG_DRV(GPIO74, AF7, DS08X)
-#define GPIO75_MLCD_BIAS       MFP_CFG_DRV(GPIO75, AF2, DS08X)
-
-/* MMC1 */
-#define GPIO7_MMC1_CLK         MFP_CFG_LPM(GPIO7,  AF4, DRIVE_HIGH)
-#define GPIO8_MMC1_CMD         MFP_CFG_LPM(GPIO8,  AF4, DRIVE_HIGH)
-#define GPIO14_MMC1_CMD                MFP_CFG_LPM(GPIO14, AF5, DRIVE_HIGH)
-#define GPIO15_MMC1_CMD                MFP_CFG_LPM(GPIO15, AF5, DRIVE_HIGH)
-#define GPIO3_MMC1_DAT0                MFP_CFG_LPM(GPIO3,  AF4, DRIVE_HIGH)
-#define GPIO4_MMC1_DAT1                MFP_CFG_LPM(GPIO4,  AF4, DRIVE_HIGH)
-#define GPIO5_MMC1_DAT2                MFP_CFG_LPM(GPIO5,  AF4, DRIVE_HIGH)
-#define GPIO6_MMC1_DAT3                MFP_CFG_LPM(GPIO6,  AF4, DRIVE_HIGH)
-
-/* MMC2 */
-#define GPIO9_MMC2_DAT0                MFP_CFG_LPM(GPIO9,  AF4, PULL_HIGH)
-#define GPIO10_MMC2_DAT1       MFP_CFG_LPM(GPIO10, AF4, PULL_HIGH)
-#define GPIO11_MMC2_DAT2       MFP_CFG_LPM(GPIO11, AF4, PULL_HIGH)
-#define GPIO12_MMC2_DAT3       MFP_CFG_LPM(GPIO12, AF4, PULL_HIGH)
-#define GPIO13_MMC2_CLK                MFP_CFG_LPM(GPIO13, AF4, PULL_HIGH)
-#define GPIO14_MMC2_CMD                MFP_CFG_LPM(GPIO14, AF4, PULL_HIGH)
-#define GPIO77_MMC2_DAT0       MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
-#define GPIO78_MMC2_DAT1       MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
-#define GPIO79_MMC2_DAT2       MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
-#define GPIO80_MMC2_DAT3       MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
-#define GPIO81_MMC2_CLK                MFP_CFG_LPM(GPIO81, AF4, PULL_HIGH)
-#define GPIO82_MMC2_CMD                MFP_CFG_LPM(GPIO82, AF4, PULL_HIGH)
-
-/* SSP1 */
-#define GPIO89_SSP1_EXTCLK     MFP_CFG(GPIO89, AF1)
-#define GPIO90_SSP1_SYSCLK     MFP_CFG(GPIO90, AF1)
-#define GPIO15_SSP1_SCLK       MFP_CFG(GPIO15, AF6)
-#define GPIO16_SSP1_FRM                MFP_CFG(GPIO16, AF2)
-#define GPIO33_SSP1_SCLK       MFP_CFG(GPIO33, AF5)
-#define GPIO34_SSP1_FRM                MFP_CFG(GPIO34, AF5)
-#define GPIO85_SSP1_SCLK       MFP_CFG(GPIO85, AF1)
-#define GPIO86_SSP1_FRM                MFP_CFG(GPIO86, AF1)
-#define GPIO18_SSP1_TXD                MFP_CFG(GPIO18, AF7)
-#define GPIO18_SSP1_RXD                MFP_CFG(GPIO18, AF2)
-#define GPIO20_SSP1_TXD                MFP_CFG(GPIO20, AF2)
-#define GPIO20_SSP1_RXD                MFP_CFG(GPIO20, AF7)
-#define GPIO35_SSP1_TXD                MFP_CFG(GPIO35, AF5)
-#define GPIO35_SSP1_RXD                MFP_CFG(GPIO35, AF4)
-#define GPIO36_SSP1_TXD                MFP_CFG(GPIO36, AF5)
-#define GPIO36_SSP1_RXD                MFP_CFG(GPIO36, AF6)
-#define GPIO87_SSP1_TXD                MFP_CFG(GPIO87, AF1)
-#define GPIO87_SSP1_RXD                MFP_CFG(GPIO87, AF6)
-#define GPIO88_SSP1_TXD                MFP_CFG(GPIO88, AF6)
-#define GPIO88_SSP1_RXD                MFP_CFG(GPIO88, AF1)
-
-/* SSP2 */
-#define GPIO29_SSP2_EXTCLK     MFP_CFG(GPIO29, AF2)
-#define GPIO23_SSP2_SCLK       MFP_CFG(GPIO23, AF2)
-#define GPIO17_SSP2_FRM                MFP_CFG(GPIO17, AF2)
-#define GPIO25_SSP2_SCLK       MFP_CFG(GPIO25, AF2)
-#define GPIO26_SSP2_FRM                MFP_CFG(GPIO26, AF2)
-#define GPIO33_SSP2_SCLK       MFP_CFG(GPIO33, AF6)
-#define GPIO34_SSP2_FRM                MFP_CFG(GPIO34, AF6)
-#define GPIO64_SSP2_SCLK       MFP_CFG(GPIO64, AF2)
-#define GPIO65_SSP2_FRM                MFP_CFG(GPIO65, AF2)
-#define GPIO19_SSP2_TXD                MFP_CFG(GPIO19, AF2)
-#define GPIO19_SSP2_RXD                MFP_CFG(GPIO19, AF7)
-#define GPIO24_SSP2_TXD                MFP_CFG(GPIO24, AF5)
-#define GPIO24_SSP2_RXD                MFP_CFG(GPIO24, AF4)
-#define GPIO27_SSP2_TXD                MFP_CFG(GPIO27, AF2)
-#define GPIO27_SSP2_RXD                MFP_CFG(GPIO27, AF5)
-#define GPIO28_SSP2_TXD                MFP_CFG(GPIO28, AF5)
-#define GPIO28_SSP2_RXD                MFP_CFG(GPIO28, AF2)
-#define GPIO35_SSP2_TXD                MFP_CFG(GPIO35, AF7)
-#define GPIO35_SSP2_RXD                MFP_CFG(GPIO35, AF6)
-#define GPIO66_SSP2_TXD                MFP_CFG(GPIO66, AF4)
-#define GPIO66_SSP2_RXD                MFP_CFG(GPIO66, AF2)
-#define GPIO67_SSP2_TXD                MFP_CFG(GPIO67, AF2)
-#define GPIO67_SSP2_RXD                MFP_CFG(GPIO67, AF4)
-#define GPIO36_SSP2_TXD                MFP_CFG(GPIO36, AF7)
-
-/* SSP3 */
-#define GPIO69_SSP3_FRM                MFP_CFG_X(GPIO69, AF2, DS08X, DRIVE_LOW)
-#define GPIO68_SSP3_SCLK       MFP_CFG_X(GPIO68, AF2, DS08X, FLOAT)
-#define GPIO92_SSP3_FRM                MFP_CFG_X(GPIO92, AF1, DS08X, DRIVE_LOW)
-#define GPIO91_SSP3_SCLK       MFP_CFG_X(GPIO91, AF1, DS08X, FLOAT)
-#define GPIO70_SSP3_TXD                MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
-#define GPIO70_SSP3_RXD                MFP_CFG_X(GPIO70, AF5, DS08X, FLOAT)
-#define GPIO71_SSP3_TXD                MFP_CFG_X(GPIO71, AF5, DS08X, DRIVE_LOW)
-#define GPIO71_SSP3_RXD                MFP_CFG_X(GPIO71, AF2, DS08X, FLOAT)
-#define GPIO93_SSP3_TXD                MFP_CFG_X(GPIO93, AF1, DS08X, DRIVE_LOW)
-#define GPIO93_SSP3_RXD                MFP_CFG_X(GPIO93, AF5, DS08X, FLOAT)
-#define GPIO94_SSP3_TXD                MFP_CFG_X(GPIO94, AF5, DS08X, DRIVE_LOW)
-#define GPIO94_SSP3_RXD                MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)
-
-/* SSP4 */
-#define GPIO95_SSP4_SCLK       MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
-#define GPIO96_SSP4_FRM                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
-#define GPIO97_SSP4_TXD                MFP_CFG_LPM(GPIO97, AF1, PULL_HIGH)
-#define GPIO97_SSP4_RXD                MFP_CFG_LPM(GPIO97, AF5, PULL_HIGH)
-#define GPIO98_SSP4_TXD                MFP_CFG_LPM(GPIO98, AF5, PULL_HIGH)
-#define GPIO98_SSP4_RXD                MFP_CFG_LPM(GPIO98, AF1, PULL_HIGH)
-
-/* UART1 */
-#define GPIO32_UART1_CTS       MFP_CFG_LPM(GPIO32,  AF2, FLOAT)
-#define GPIO37_UART1_CTS       MFP_CFG_LPM(GPIO37,  AF4, FLOAT)
-#define GPIO79_UART1_CTS       MFP_CFG_LPM(GPIO79,  AF1, FLOAT)
-#define GPIO84_UART1_CTS       MFP_CFG_LPM(GPIO84,  AF3, FLOAT)
-#define GPIO101_UART1_CTS      MFP_CFG_LPM(GPIO101, AF1, FLOAT)
-#define GPIO106_UART1_CTS      MFP_CFG_LPM(GPIO106, AF6, FLOAT)
-
-#define GPIO32_UART1_RTS       MFP_CFG_LPM(GPIO32,  AF4, FLOAT)
-#define GPIO37_UART1_RTS       MFP_CFG_LPM(GPIO37,  AF2, FLOAT)
-#define GPIO79_UART1_RTS       MFP_CFG_LPM(GPIO79,  AF3, FLOAT)
-#define GPIO84_UART1_RTS       MFP_CFG_LPM(GPIO84,  AF1, FLOAT)
-#define GPIO101_UART1_RTS      MFP_CFG_LPM(GPIO101, AF6, FLOAT)
-#define GPIO106_UART1_RTS      MFP_CFG_LPM(GPIO106, AF1, FLOAT)
-
-#define GPIO34_UART1_DSR       MFP_CFG_LPM(GPIO34,  AF2, FLOAT)
-#define GPIO36_UART1_DSR       MFP_CFG_LPM(GPIO36,  AF4, FLOAT)
-#define GPIO81_UART1_DSR       MFP_CFG_LPM(GPIO81,  AF1, FLOAT)
-#define GPIO83_UART1_DSR       MFP_CFG_LPM(GPIO83,  AF3, FLOAT)
-#define GPIO103_UART1_DSR      MFP_CFG_LPM(GPIO103, AF1, FLOAT)
-#define GPIO105_UART1_DSR      MFP_CFG_LPM(GPIO105, AF6, FLOAT)
-
-#define GPIO34_UART1_DTR       MFP_CFG_LPM(GPIO34,  AF4, FLOAT)
-#define GPIO36_UART1_DTR       MFP_CFG_LPM(GPIO36,  AF2, FLOAT)
-#define GPIO81_UART1_DTR       MFP_CFG_LPM(GPIO81,  AF3, FLOAT)
-#define GPIO83_UART1_DTR       MFP_CFG_LPM(GPIO83,  AF1, FLOAT)
-#define GPIO103_UART1_DTR      MFP_CFG_LPM(GPIO103, AF6, FLOAT)
-#define GPIO105_UART1_DTR      MFP_CFG_LPM(GPIO105, AF1, FLOAT)
-
-#define GPIO35_UART1_RI                MFP_CFG_LPM(GPIO35,  AF2, FLOAT)
-#define GPIO82_UART1_RI                MFP_CFG_LPM(GPIO82,  AF1, FLOAT)
-#define GPIO104_UART1_RI       MFP_CFG_LPM(GPIO104, AF1, FLOAT)
-
-#define GPIO33_UART1_DCD       MFP_CFG_LPM(GPIO33,  AF2, FLOAT)
-#define GPIO80_UART1_DCD       MFP_CFG_LPM(GPIO80,  AF1, FLOAT)
-#define GPIO102_UART1_DCD      MFP_CFG_LPM(GPIO102, AF1, FLOAT)
-
-#define GPIO30_UART1_RXD       MFP_CFG_LPM(GPIO30,  AF2, FLOAT)
-#define GPIO31_UART1_RXD       MFP_CFG_LPM(GPIO31,  AF4, FLOAT)
-#define GPIO77_UART1_RXD       MFP_CFG_LPM(GPIO77,  AF1, FLOAT)
-#define GPIO78_UART1_RXD       MFP_CFG_LPM(GPIO78,  AF3, FLOAT)
-#define GPIO99_UART1_RXD       MFP_CFG_LPM(GPIO99,  AF1, FLOAT)
-#define GPIO100_UART1_RXD      MFP_CFG_LPM(GPIO100, AF6, FLOAT)
-#define GPIO102_UART1_RXD      MFP_CFG_LPM(GPIO102, AF6, FLOAT)
-#define GPIO104_UART1_RXD      MFP_CFG_LPM(GPIO104, AF4, FLOAT)
-
-#define GPIO30_UART1_TXD       MFP_CFG_LPM(GPIO30,  AF4, FLOAT)
-#define GPIO31_UART1_TXD       MFP_CFG_LPM(GPIO31,  AF2, FLOAT)
-#define GPIO77_UART1_TXD       MFP_CFG_LPM(GPIO77,  AF3, FLOAT)
-#define GPIO78_UART1_TXD       MFP_CFG_LPM(GPIO78,  AF1, FLOAT)
-#define GPIO99_UART1_TXD       MFP_CFG_LPM(GPIO99,  AF6, FLOAT)
-#define GPIO100_UART1_TXD      MFP_CFG_LPM(GPIO100, AF1, FLOAT)
-#define GPIO102_UART1_TXD      MFP_CFG_LPM(GPIO102, AF4, FLOAT)
-
-/* UART2 */
-#define GPIO15_UART2_CTS       MFP_CFG_LPM(GPIO15,  AF3, FLOAT)
-#define GPIO16_UART2_CTS       MFP_CFG_LPM(GPIO16,  AF5, FLOAT)
-#define GPIO111_UART2_CTS      MFP_CFG_LPM(GPIO111, AF3, FLOAT)
-#define GPIO114_UART2_CTS      MFP_CFG_LPM(GPIO114, AF1, FLOAT)
-
-#define GPIO15_UART2_RTS       MFP_CFG_LPM(GPIO15,  AF4, FLOAT)
-#define GPIO16_UART2_RTS       MFP_CFG_LPM(GPIO16,  AF4, FLOAT)
-#define GPIO114_UART2_RTS      MFP_CFG_LPM(GPIO114, AF3, FLOAT)
-#define GPIO111_UART2_RTS      MFP_CFG_LPM(GPIO111, AF1, FLOAT)
-
-#define GPIO18_UART2_RXD       MFP_CFG_LPM(GPIO18,  AF5, FLOAT)
-#define GPIO19_UART2_RXD       MFP_CFG_LPM(GPIO19,  AF4, FLOAT)
-#define GPIO112_UART2_RXD      MFP_CFG_LPM(GPIO112, AF1, FLOAT)
-#define GPIO113_UART2_RXD      MFP_CFG_LPM(GPIO113, AF3, FLOAT)
-
-#define GPIO18_UART2_TXD       MFP_CFG_LPM(GPIO18,  AF4, FLOAT)
-#define GPIO19_UART2_TXD       MFP_CFG_LPM(GPIO19,  AF5, FLOAT)
-#define GPIO112_UART2_TXD      MFP_CFG_LPM(GPIO112, AF3, FLOAT)
-#define GPIO113_UART2_TXD      MFP_CFG_LPM(GPIO113, AF1, FLOAT)
-
-/* UART3 */
-#define GPIO91_UART3_CTS       MFP_CFG_LPM(GPIO91,  AF2, FLOAT)
-#define GPIO92_UART3_CTS       MFP_CFG_LPM(GPIO92,  AF4, FLOAT)
-#define GPIO107_UART3_CTS      MFP_CFG_LPM(GPIO107, AF1, FLOAT)
-#define GPIO108_UART3_CTS      MFP_CFG_LPM(GPIO108, AF3, FLOAT)
-
-#define GPIO91_UART3_RTS       MFP_CFG_LPM(GPIO91,  AF4, FLOAT)
-#define GPIO92_UART3_RTS       MFP_CFG_LPM(GPIO92,  AF2, FLOAT)
-#define GPIO107_UART3_RTS      MFP_CFG_LPM(GPIO107, AF3, FLOAT)
-#define GPIO108_UART3_RTS      MFP_CFG_LPM(GPIO108, AF1, FLOAT)
-
-#define GPIO7_UART3_RXD                MFP_CFG_LPM(GPIO7,   AF2, FLOAT)
-#define GPIO8_UART3_RXD                MFP_CFG_LPM(GPIO8,   AF6, FLOAT)
-#define GPIO93_UART3_RXD       MFP_CFG_LPM(GPIO93,  AF4, FLOAT)
-#define GPIO94_UART3_RXD       MFP_CFG_LPM(GPIO94,  AF2, FLOAT)
-#define GPIO109_UART3_RXD      MFP_CFG_LPM(GPIO109, AF3, FLOAT)
-#define GPIO110_UART3_RXD      MFP_CFG_LPM(GPIO110, AF1, FLOAT)
-
-#define GPIO7_UART3_TXD                MFP_CFG_LPM(GPIO7,   AF6, FLOAT)
-#define GPIO8_UART3_TXD                MFP_CFG_LPM(GPIO8,   AF2, FLOAT)
-#define GPIO93_UART3_TXD       MFP_CFG_LPM(GPIO93,  AF2, FLOAT)
-#define GPIO94_UART3_TXD       MFP_CFG_LPM(GPIO94,  AF4, FLOAT)
-#define GPIO109_UART3_TXD      MFP_CFG_LPM(GPIO109, AF1, FLOAT)
-#define GPIO110_UART3_TXD      MFP_CFG_LPM(GPIO110, AF3, FLOAT)
-
-/* USB Host */
-#define GPIO0_2_USBH_PEN       MFP_CFG(GPIO0_2, AF1)
-#define GPIO1_2_USBH_PWR       MFP_CFG(GPIO1_2, AF1)
-
-/* USB P3 */
-#define GPIO77_USB_P3_1                MFP_CFG(GPIO77,  AF2)
-#define GPIO78_USB_P3_2                MFP_CFG(GPIO78,  AF2)
-#define GPIO79_USB_P3_3                MFP_CFG(GPIO79,  AF2)
-#define GPIO80_USB_P3_4                MFP_CFG(GPIO80,  AF2)
-#define GPIO81_USB_P3_5                MFP_CFG(GPIO81,  AF2)
-#define GPIO82_USB_P3_6                MFP_CFG(GPIO82,  AF2)
-
-/* PWM */
-#define GPIO17_PWM0_OUT                MFP_CFG(GPIO17, AF1)
-#define GPIO18_PWM1_OUT                MFP_CFG(GPIO18, AF1)
-#define GPIO19_PWM2_OUT                MFP_CFG(GPIO19, AF1)
-#define GPIO20_PWM3_OUT                MFP_CFG(GPIO20, AF1)
-
-/* CIR */
-#define GPIO8_CIR_OUT          MFP_CFG(GPIO8, AF5)
-#define GPIO16_CIR_OUT         MFP_CFG(GPIO16, AF3)
-
-#define GPIO20_OW_DQ_IN                MFP_CFG(GPIO20, AF5)
-#define GPIO126_OW_DQ          MFP_CFG(GPIO126, AF2)
-
-#define GPIO0_DF_RDY           MFP_CFG(GPIO0, AF1)
-#define GPIO7_CLK_BYPASS_XSC   MFP_CFG(GPIO7, AF7)
-#define GPIO17_EXT_SYNC_MVT_0  MFP_CFG(GPIO17, AF6)
-#define GPIO18_EXT_SYNC_MVT_1  MFP_CFG(GPIO18, AF6)
-#define GPIO19_OST_CHOUT_MVT_0 MFP_CFG(GPIO19, AF6)
-#define GPIO20_OST_CHOUT_MVT_1 MFP_CFG(GPIO20, AF6)
-#define GPIO49_48M_CLK         MFP_CFG(GPIO49, AF2)
-#define GPIO126_EXT_CLK                MFP_CFG(GPIO126, AF3)
-#define GPIO127_CLK_BYPASS_GB  MFP_CFG(GPIO127, AF7)
-#define GPIO71_EXT_MATCH_MVT   MFP_CFG(GPIO71, AF6)
-
-#define GPIO3_uIO_IN           MFP_CFG(GPIO3, AF1)
-
-#define GPIO4_uSIM_CARD_STATE  MFP_CFG(GPIO4, AF1)
-#define GPIO5_uSIM_uCLK                MFP_CFG(GPIO5, AF1)
-#define GPIO6_uSIM_uRST                MFP_CFG(GPIO6, AF1)
-#define GPIO16_uSIM_UVS_0      MFP_CFG(GPIO16, AF1)
-
-#define GPIO9_SCIO             MFP_CFG(GPIO9, AF1)
-#define GPIO20_RTC_MVT         MFP_CFG(GPIO20, AF4)
-#define GPIO126_RTC_MVT                MFP_CFG(GPIO126, AF1)
-
-/*
- * PXA300 specific MFP configurations
- */
-#ifdef CONFIG_CPU_PXA300
-#define GPIO99_USB_P2_2                MFP_CFG(GPIO99, AF2)
-#define GPIO99_USB_P2_5                MFP_CFG(GPIO99, AF3)
-#define GPIO99_USB_P2_6                MFP_CFG(GPIO99, AF4)
-#define GPIO100_USB_P2_2       MFP_CFG(GPIO100, AF4)
-#define GPIO100_USB_P2_5       MFP_CFG(GPIO100, AF5)
-#define GPIO101_USB_P2_1       MFP_CFG(GPIO101, AF2)
-#define GPIO102_USB_P2_4       MFP_CFG(GPIO102, AF2)
-#define GPIO104_USB_P2_3       MFP_CFG(GPIO104, AF2)
-#define GPIO105_USB_P2_5       MFP_CFG(GPIO105, AF2)
-#define GPIO100_USB_P2_6       MFP_CFG(GPIO100, AF2)
-#define GPIO106_USB_P2_7       MFP_CFG(GPIO106, AF2)
-#define GPIO103_USB_P2_8       MFP_CFG(GPIO103, AF2)
-
-/* U2D UTMI */
-#define GPIO38_UTM_CLK         MFP_CFG(GPIO38,  AF1)
-#define GPIO26_U2D_RXERROR     MFP_CFG(GPIO26,  AF3)
-#define GPIO50_U2D_RXERROR     MFP_CFG(GPIO50,  AF1)
-#define GPIO89_U2D_RXERROR     MFP_CFG(GPIO89,  AF5)
-#define GPIO24_UTM_RXVALID     MFP_CFG(GPIO24,  AF3)
-#define GPIO48_UTM_RXVALID     MFP_CFG(GPIO48,  AF2)
-#define GPIO87_UTM_RXVALID     MFP_CFG(GPIO87,  AF5)
-#define GPIO25_UTM_RXACTIVE    MFP_CFG(GPIO25,  AF3)
-#define GPIO47_UTM_RXACTIVE    MFP_CFG(GPIO47,  AF2)
-#define GPIO49_UTM_RXACTIVE    MFP_CFG(GPIO49,  AF1)
-#define GPIO88_UTM_RXACTIVE    MFP_CFG(GPIO88,  AF5)
-#define GPIO53_UTM_TXREADY     MFP_CFG(GPIO53,  AF1)
-#define GPIO67_UTM_LINESTATE_0 MFP_CFG(GPIO67,  AF3)
-#define GPIO92_UTM_LINESTATE_0 MFP_CFG(GPIO92,  AF3)
-#define GPIO104_UTM_LINESTATE_0        MFP_CFG(GPIO104, AF3)
-#define GPIO109_UTM_LINESTATE_0        MFP_CFG(GPIO109, AF4)
-#define GPIO68_UTM_LINESTATE_1 MFP_CFG(GPIO68,  AF3)
-#define GPIO93_UTM_LINESTATE_1 MFP_CFG(GPIO93,  AF3)
-#define GPIO105_UTM_LINESTATE_1        MFP_CFG(GPIO105, AF3)
-#define GPIO27_U2D_OPMODE_0    MFP_CFG(GPIO27,  AF4)
-#define GPIO51_U2D_OPMODE_0    MFP_CFG(GPIO51,  AF2)
-#define GPIO90_U2D_OPMODE_0    MFP_CFG(GPIO90,  AF7)
-#define GPIO28_U2D_OPMODE_1    MFP_CFG(GPIO28,  AF4)
-#define GPIO52_U2D_OPMODE_1    MFP_CFG(GPIO52,  AF2)
-#define GPIO106_U2D_OPMODE_1   MFP_CFG(GPIO106, AF3)
-#define GPIO110_U2D_OPMODE_1   MFP_CFG(GPIO110, AF5)
-#define GPIO76_U2D_RESET       MFP_CFG(GPIO76,  AF1)
-#define GPIO95_U2D_RESET       MFP_CFG(GPIO95,  AF2)
-#define GPIO100_U2D_RESET      MFP_CFG(GPIO100, AF3)
-#define GPIO66_U2D_SUSPEND     MFP_CFG(GPIO66,  AF3)
-#define GPIO98_U2D_SUSPEND     MFP_CFG(GPIO98,  AF2)
-#define GPIO103_U2D_SUSPEND    MFP_CFG(GPIO103, AF3)
-#define GPIO65_U2D_TERM_SEL    MFP_CFG(GPIO65,  AF5)
-#define GPIO97_U2D_TERM_SEL    MFP_CFG(GPIO97,  AF3)
-#define GPIO102_U2D_TERM_SEL   MFP_CFG(GPIO102, AF5)
-#define GPIO29_U2D_TXVALID     MFP_CFG(GPIO29,  AF3)
-#define GPIO52_U2D_TXVALID     MFP_CFG(GPIO52,  AF4)
-#define GPIO69_U2D_TXVALID     MFP_CFG(GPIO69,  AF3)
-#define GPIO85_U2D_TXVALID     MFP_CFG(GPIO85,  AF7)
-#define GPIO64_U2D_XCVR_SEL    MFP_CFG(GPIO64,  AF5)
-#define GPIO96_U2D_XCVR_SEL    MFP_CFG(GPIO96,  AF3)
-#define GPIO101_U2D_XCVR_SEL   MFP_CFG(GPIO101, AF5)
-#define GPIO30_UTM_PHYDATA_0   MFP_CFG(GPIO30,  AF3)
-#define GPIO31_UTM_PHYDATA_1   MFP_CFG(GPIO31,  AF3)
-#define GPIO32_UTM_PHYDATA_2   MFP_CFG(GPIO32,  AF3)
-#define GPIO33_UTM_PHYDATA_3   MFP_CFG(GPIO33,  AF3)
-#define GPIO34_UTM_PHYDATA_4   MFP_CFG(GPIO34,  AF3)
-#define GPIO35_UTM_PHYDATA_5   MFP_CFG(GPIO35,  AF3)
-#define GPIO36_UTM_PHYDATA_6   MFP_CFG(GPIO36,  AF3)
-#define GPIO37_UTM_PHYDATA_7   MFP_CFG(GPIO37,  AF3)
-#define GPIO39_UTM_PHYDATA_0   MFP_CFG(GPIO39,  AF3)
-#define GPIO40_UTM_PHYDATA_1   MFP_CFG(GPIO40,  AF3)
-#define GPIO41_UTM_PHYDATA_2   MFP_CFG(GPIO41,  AF3)
-#define GPIO42_UTM_PHYDATA_3   MFP_CFG(GPIO42,  AF3)
-#define GPIO43_UTM_PHYDATA_4   MFP_CFG(GPIO43,  AF3)
-#define GPIO44_UTM_PHYDATA_5   MFP_CFG(GPIO44,  AF3)
-#define GPIO45_UTM_PHYDATA_6   MFP_CFG(GPIO45,  AF3)
-#define GPIO46_UTM_PHYDATA_7   MFP_CFG(GPIO46,  AF3)
-#endif /* CONFIG_CPU_PXA300 */
-
-/*
- * PXA310 specific MFP configurations
- */
-#ifdef CONFIG_CPU_PXA310
-/* USB P2 */
-#define GPIO36_USB_P2_1                MFP_CFG(GPIO36, AF1)
-#define GPIO30_USB_P2_2                MFP_CFG(GPIO30, AF1)
-#define GPIO35_USB_P2_3                MFP_CFG(GPIO35, AF1)
-#define GPIO32_USB_P2_4                MFP_CFG(GPIO32, AF1)
-#define GPIO34_USB_P2_5                MFP_CFG(GPIO34, AF1)
-#define GPIO31_USB_P2_6                MFP_CFG(GPIO31, AF1)
-
-/* MMC1 */
-#define GPIO24_MMC1_CMD                MFP_CFG(GPIO24, AF3)
-#define GPIO29_MMC1_DAT0       MFP_CFG(GPIO29, AF3)
-
-/* MMC3 */
-#define GPIO103_MMC3_CLK       MFP_CFG(GPIO103, AF2)
-#define GPIO105_MMC3_CMD       MFP_CFG(GPIO105, AF2)
-#define GPIO11_2_MMC3_CLK      MFP_CFG(GPIO11_2, AF1)
-#define GPIO12_2_MMC3_CMD      MFP_CFG(GPIO12_2, AF1)
-#define GPIO7_2_MMC3_DAT0      MFP_CFG(GPIO7_2, AF1)
-#define GPIO8_2_MMC3_DAT1      MFP_CFG(GPIO8_2, AF1)
-#define GPIO9_2_MMC3_DAT2      MFP_CFG(GPIO9_2, AF1)
-#define GPIO10_2_MMC3_DAT3     MFP_CFG(GPIO10_2, AF1)
-
-/* ULPI */
-#define GPIO38_ULPI_CLK                MFP_CFG(GPIO38, AF1)
-#define GPIO30_ULPI_DATA_OUT_0 MFP_CFG(GPIO30, AF3)
-#define GPIO31_ULPI_DATA_OUT_1 MFP_CFG(GPIO31, AF3)
-#define GPIO32_ULPI_DATA_OUT_2 MFP_CFG(GPIO32, AF3)
-#define GPIO33_ULPI_DATA_OUT_3 MFP_CFG(GPIO33, AF3)
-#define GPIO34_ULPI_DATA_OUT_4 MFP_CFG(GPIO34, AF3)
-#define GPIO35_ULPI_DATA_OUT_5 MFP_CFG(GPIO35, AF3)
-#define GPIO36_ULPI_DATA_OUT_6 MFP_CFG(GPIO36, AF3)
-#define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3)
-#define GPIO33_ULPI_OTG_INTR   MFP_CFG(GPIO33, AF1)
-
-#define ULPI_DIR       MFP_CFG_DRV(ULPI_DIR, AF0, DS01X)
-#define ULPI_NXT       MFP_CFG_DRV(ULPI_NXT, AF0, DS01X)
-#define ULPI_STP       MFP_CFG_DRV(ULPI_STP, AF0, DS01X)
-#endif /* CONFIG_CPU_PXA310 */
-
-#endif /* __ASM_ARCH_MFP_PXA300_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
deleted file mode 100644 (file)
index 3ce4682..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/mfp-pxa320.h
- *
- * PXA320 specific MFP configuration definitions
- *
- * Copyright (C) 2007 Marvell International Ltd.
- * 2007-08-21: eric miao <eric.miao@marvell.com>
- *             initial version
- *
- *  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_MFP_PXA320_H
-#define __ASM_ARCH_MFP_PXA320_H
-
-#include <mach/mfp-pxa3xx.h>
-
-/* GPIO */
-#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
-#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
-#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
-#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
-#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
-
-#define GPIO7_2_GPIO           MFP_CFG(GPIO7_2, AF0)
-#define GPIO8_2_GPIO           MFP_CFG(GPIO8_2, AF0)
-#define GPIO9_2_GPIO           MFP_CFG(GPIO9_2, AF0)
-#define GPIO10_2_GPIO          MFP_CFG(GPIO10_2, AF0)
-#define GPIO11_2_GPIO          MFP_CFG(GPIO11_2, AF0)
-#define GPIO12_2_GPIO          MFP_CFG(GPIO12_2, AF0)
-#define GPIO13_2_GPIO          MFP_CFG(GPIO13_2, AF0)
-#define GPIO14_2_GPIO          MFP_CFG(GPIO14_2, AF0)
-#define GPIO15_2_GPIO          MFP_CFG(GPIO15_2, AF0)
-#define GPIO16_2_GPIO          MFP_CFG(GPIO16_2, AF0)
-#define GPIO17_2_GPIO          MFP_CFG(GPIO17_2, AF0)
-
-/* Chip Select */
-#define GPIO3_nCS2             MFP_CFG(GPIO3, AF1)
-#define GPIO4_nCS3             MFP_CFG(GPIO4, AF1)
-
-/* AC97 */
-#define GPIO34_AC97_SYSCLK     MFP_CFG(GPIO34, AF1)
-#define GPIO39_AC97_BITCLK     MFP_CFG(GPIO39, AF1)
-#define GPIO40_AC97_nACRESET   MFP_CFG(GPIO40, AF1)
-#define GPIO35_AC97_SDATA_IN_0 MFP_CFG(GPIO35, AF1)
-#define GPIO36_AC97_SDATA_IN_1 MFP_CFG(GPIO36, AF1)
-#define GPIO32_AC97_SDATA_IN_2 MFP_CFG(GPIO32, AF2)
-#define GPIO33_AC97_SDATA_IN_3 MFP_CFG(GPIO33, AF2)
-#define GPIO11_AC97_SDATA_IN_2 MFP_CFG(GPIO11, AF3)
-#define GPIO12_AC97_SDATA_IN_3 MFP_CFG(GPIO12, AF3)
-#define GPIO37_AC97_SDATA_OUT  MFP_CFG(GPIO37, AF1)
-#define GPIO38_AC97_SYNC       MFP_CFG(GPIO38, AF1)
-
-/* I2C */
-#define GPIO32_I2C_SCL         MFP_CFG_LPM(GPIO32, AF1, PULL_HIGH)
-#define GPIO33_I2C_SDA         MFP_CFG_LPM(GPIO33, AF1, PULL_HIGH)
-
-/* QCI */
-#define GPIO49_CI_DD_0         MFP_CFG_DRV(GPIO49, AF1, DS04X)
-#define GPIO50_CI_DD_1         MFP_CFG_DRV(GPIO50, AF1, DS04X)
-#define GPIO51_CI_DD_2         MFP_CFG_DRV(GPIO51, AF1, DS04X)
-#define GPIO52_CI_DD_3         MFP_CFG_DRV(GPIO52, AF1, DS04X)
-#define GPIO53_CI_DD_4         MFP_CFG_DRV(GPIO53, AF1, DS04X)
-#define GPIO54_CI_DD_5         MFP_CFG_DRV(GPIO54, AF1, DS04X)
-#define GPIO55_CI_DD_6         MFP_CFG_DRV(GPIO55, AF1, DS04X)
-#define GPIO56_CI_DD_7         MFP_CFG_DRV(GPIO56, AF0, DS04X)
-#define GPIO57_CI_DD_8         MFP_CFG_DRV(GPIO57, AF1, DS04X)
-#define GPIO58_CI_DD_9         MFP_CFG_DRV(GPIO58, AF1, DS04X)
-#define GPIO59_CI_MCLK         MFP_CFG_DRV(GPIO59, AF0, DS04X)
-#define GPIO60_CI_PCLK         MFP_CFG_DRV(GPIO60, AF0, DS04X)
-#define GPIO61_CI_HSYNC                MFP_CFG_DRV(GPIO61, AF0, DS04X)
-#define GPIO62_CI_VSYNC                MFP_CFG_DRV(GPIO62, AF0, DS04X)
-
-#define GPIO31_CIR_OUT         MFP_CFG(GPIO31, AF5)
-
-#define GPIO0_2_CLK_EXT                MFP_CFG(GPIO0_2, AF3)
-#define GPIO0_DRQ              MFP_CFG(GPIO0, AF2)
-#define GPIO11_EXT_SYNC0       MFP_CFG(GPIO11, AF5)
-#define GPIO12_EXT_SYNC1       MFP_CFG(GPIO12, AF6)
-#define GPIO0_2_HZ_CLK         MFP_CFG(GPIO0_2, AF1)
-#define GPIO14_HZ_CLK          MFP_CFG(GPIO14, AF4)
-#define GPIO30_ICP_RXD         MFP_CFG(GPIO30, AF1)
-#define GPIO31_ICP_TXD         MFP_CFG(GPIO31, AF1)
-
-#define GPIO83_KP_DKIN_0       MFP_CFG_LPM(GPIO83, AF3, FLOAT)
-#define GPIO84_KP_DKIN_1       MFP_CFG_LPM(GPIO84, AF3, FLOAT)
-#define GPIO85_KP_DKIN_2       MFP_CFG_LPM(GPIO85, AF3, FLOAT)
-#define GPIO86_KP_DKIN_3       MFP_CFG_LPM(GPIO86, AF3, FLOAT)
-
-#define GPIO105_KP_DKIN_0      MFP_CFG_LPM(GPIO105, AF2, FLOAT)
-#define GPIO106_KP_DKIN_1      MFP_CFG_LPM(GPIO106, AF2, FLOAT)
-#define GPIO107_KP_DKIN_2      MFP_CFG_LPM(GPIO107, AF2, FLOAT)
-#define GPIO108_KP_DKIN_3      MFP_CFG_LPM(GPIO108, AF2, FLOAT)
-#define GPIO109_KP_DKIN_4      MFP_CFG_LPM(GPIO109, AF2, FLOAT)
-#define GPIO110_KP_DKIN_5      MFP_CFG_LPM(GPIO110, AF2, FLOAT)
-#define GPIO111_KP_DKIN_6      MFP_CFG_LPM(GPIO111, AF2, FLOAT)
-#define GPIO112_KP_DKIN_7      MFP_CFG_LPM(GPIO112, AF2, FLOAT)
-
-#define GPIO113_KP_DKIN_0      MFP_CFG_LPM(GPIO113, AF2, FLOAT)
-#define GPIO114_KP_DKIN_1      MFP_CFG_LPM(GPIO114, AF2, FLOAT)
-#define GPIO115_KP_DKIN_2      MFP_CFG_LPM(GPIO115, AF2, FLOAT)
-#define GPIO116_KP_DKIN_3      MFP_CFG_LPM(GPIO116, AF2, FLOAT)
-#define GPIO117_KP_DKIN_4      MFP_CFG_LPM(GPIO117, AF2, FLOAT)
-#define GPIO118_KP_DKIN_5      MFP_CFG_LPM(GPIO118, AF2, FLOAT)
-#define GPIO119_KP_DKIN_6      MFP_CFG_LPM(GPIO119, AF2, FLOAT)
-#define GPIO120_KP_DKIN_7      MFP_CFG_LPM(GPIO120, AF2, FLOAT)
-
-#define GPIO127_KP_DKIN_0      MFP_CFG_LPM(GPIO127, AF2, FLOAT)
-#define GPIO126_KP_DKIN_1      MFP_CFG_LPM(GPIO126, AF2, FLOAT)
-
-#define GPIO2_2_KP_DKIN_0      MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
-#define GPIO3_2_KP_DKIN_1      MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
-#define GPIO125_KP_DKIN_2      MFP_CFG_LPM(GPIO125, AF2, FLOAT)
-#define GPIO124_KP_DKIN_3      MFP_CFG_LPM(GPIO124, AF2, FLOAT)
-#define GPIO123_KP_DKIN_4      MFP_CFG_LPM(GPIO123, AF2, FLOAT)
-#define GPIO122_KP_DKIN_5      MFP_CFG_LPM(GPIO122, AF2, FLOAT)
-#define GPIO121_KP_DKIN_6      MFP_CFG_LPM(GPIO121, AF2, FLOAT)
-#define GPIO4_2_KP_DKIN_7      MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
-
-#define GPIO113_KP_MKIN_0      MFP_CFG_LPM(GPIO113, AF1, FLOAT)
-#define GPIO114_KP_MKIN_1      MFP_CFG_LPM(GPIO114, AF1, FLOAT)
-#define GPIO115_KP_MKIN_2      MFP_CFG_LPM(GPIO115, AF1, FLOAT)
-#define GPIO116_KP_MKIN_3      MFP_CFG_LPM(GPIO116, AF1, FLOAT)
-#define GPIO117_KP_MKIN_4      MFP_CFG_LPM(GPIO117, AF1, FLOAT)
-#define GPIO118_KP_MKIN_5      MFP_CFG_LPM(GPIO118, AF1, FLOAT)
-#define GPIO119_KP_MKIN_6      MFP_CFG_LPM(GPIO119, AF1, FLOAT)
-#define GPIO120_KP_MKIN_7      MFP_CFG_LPM(GPIO120, AF1, FLOAT)
-
-#define GPIO83_KP_MKOUT_0      MFP_CFG_LPM(GPIO83, AF2, DRIVE_HIGH)
-#define GPIO84_KP_MKOUT_1      MFP_CFG_LPM(GPIO84, AF2, DRIVE_HIGH)
-#define GPIO85_KP_MKOUT_2      MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
-#define GPIO86_KP_MKOUT_3      MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
-#define GPIO13_KP_MKOUT_4      MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
-#define GPIO14_KP_MKOUT_5      MFP_CFG_LPM(GPIO14, AF3, DRIVE_HIGH)
-
-#define GPIO121_KP_MKOUT_0     MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
-#define GPIO122_KP_MKOUT_1     MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
-#define GPIO123_KP_MKOUT_2     MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
-#define GPIO124_KP_MKOUT_3     MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
-#define GPIO125_KP_MKOUT_4     MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
-#define GPIO126_KP_MKOUT_5     MFP_CFG_LPM(GPIO126, AF1, DRIVE_HIGH)
-#define GPIO127_KP_MKOUT_6     MFP_CFG_LPM(GPIO127, AF1, DRIVE_HIGH)
-#define GPIO5_2_KP_MKOUT_7     MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
-
-/* LCD */
-#define GPIO6_2_LCD_LDD_0      MFP_CFG_DRV(GPIO6_2, AF1, DS01X)
-#define GPIO7_2_LCD_LDD_1      MFP_CFG_DRV(GPIO7_2, AF1, DS01X)
-#define GPIO8_2_LCD_LDD_2      MFP_CFG_DRV(GPIO8_2, AF1, DS01X)
-#define GPIO9_2_LCD_LDD_3      MFP_CFG_DRV(GPIO9_2, AF1, DS01X)
-#define GPIO10_2_LCD_LDD_4     MFP_CFG_DRV(GPIO10_2, AF1, DS01X)
-#define GPIO11_2_LCD_LDD_5     MFP_CFG_DRV(GPIO11_2, AF1, DS01X)
-#define GPIO12_2_LCD_LDD_6     MFP_CFG_DRV(GPIO12_2, AF1, DS01X)
-#define GPIO13_2_LCD_LDD_7     MFP_CFG_DRV(GPIO13_2, AF1, DS01X)
-#define GPIO63_LCD_LDD_8       MFP_CFG_DRV(GPIO63, AF1, DS01X)
-#define GPIO64_LCD_LDD_9       MFP_CFG_DRV(GPIO64, AF1, DS01X)
-#define GPIO65_LCD_LDD_10      MFP_CFG_DRV(GPIO65, AF1, DS01X)
-#define GPIO66_LCD_LDD_11      MFP_CFG_DRV(GPIO66, AF1, DS01X)
-#define GPIO67_LCD_LDD_12      MFP_CFG_DRV(GPIO67, AF1, DS01X)
-#define GPIO68_LCD_LDD_13      MFP_CFG_DRV(GPIO68, AF1, DS01X)
-#define GPIO69_LCD_LDD_14      MFP_CFG_DRV(GPIO69, AF1, DS01X)
-#define GPIO70_LCD_LDD_15      MFP_CFG_DRV(GPIO70, AF1, DS01X)
-#define GPIO71_LCD_LDD_16      MFP_CFG_DRV(GPIO71, AF1, DS01X)
-#define GPIO72_LCD_LDD_17      MFP_CFG_DRV(GPIO72, AF1, DS01X)
-#define GPIO73_LCD_CS_N                MFP_CFG_DRV(GPIO73, AF2, DS01X)
-#define GPIO74_LCD_VSYNC       MFP_CFG_DRV(GPIO74, AF2, DS01X)
-#define GPIO14_2_LCD_FCLK      MFP_CFG_DRV(GPIO14_2, AF1, DS01X)
-#define GPIO15_2_LCD_LCLK      MFP_CFG_DRV(GPIO15_2, AF1, DS01X)
-#define GPIO16_2_LCD_PCLK      MFP_CFG_DRV(GPIO16_2, AF1, DS01X)
-#define GPIO17_2_LCD_BIAS      MFP_CFG_DRV(GPIO17_2, AF1, DS01X)
-#define GPIO64_LCD_VSYNC       MFP_CFG_DRV(GPIO64, AF2, DS01X)
-#define GPIO63_LCD_CS_N                MFP_CFG_DRV(GPIO63, AF2, DS01X)
-
-#define GPIO6_2_MLCD_DD_0      MFP_CFG_DRV(GPIO6_2, AF7, DS08X)
-#define GPIO7_2_MLCD_DD_1      MFP_CFG_DRV(GPIO7_2, AF7, DS08X)
-#define GPIO8_2_MLCD_DD_2      MFP_CFG_DRV(GPIO8_2, AF7, DS08X)
-#define GPIO9_2_MLCD_DD_3      MFP_CFG_DRV(GPIO9_2, AF7, DS08X)
-#define GPIO10_2_MLCD_DD_4     MFP_CFG_DRV(GPIO10_2, AF7, DS08X)
-#define GPIO11_2_MLCD_DD_5     MFP_CFG_DRV(GPIO11_2, AF7, DS08X)
-#define GPIO12_2_MLCD_DD_6     MFP_CFG_DRV(GPIO12_2, AF7, DS08X)
-#define GPIO13_2_MLCD_DD_7     MFP_CFG_DRV(GPIO13_2, AF7, DS08X)
-#define GPIO63_MLCD_DD_8       MFP_CFG_DRV(GPIO63, AF7, DS08X)
-#define GPIO64_MLCD_DD_9       MFP_CFG_DRV(GPIO64, AF7, DS08X)
-#define GPIO65_MLCD_DD_10      MFP_CFG_DRV(GPIO65, AF7, DS08X)
-#define GPIO66_MLCD_DD_11      MFP_CFG_DRV(GPIO66, AF7, DS08X)
-#define GPIO67_MLCD_DD_12      MFP_CFG_DRV(GPIO67, AF7, DS08X)
-#define GPIO68_MLCD_DD_13      MFP_CFG_DRV(GPIO68, AF7, DS08X)
-#define GPIO69_MLCD_DD_14      MFP_CFG_DRV(GPIO69, AF7, DS08X)
-#define GPIO70_MLCD_DD_15      MFP_CFG_DRV(GPIO70, AF7, DS08X)
-#define GPIO71_MLCD_DD_16      MFP_CFG_DRV(GPIO71, AF7, DS08X)
-#define GPIO72_MLCD_DD_17      MFP_CFG_DRV(GPIO72, AF7, DS08X)
-#define GPIO73_MLCD_CS         MFP_CFG_DRV(GPIO73, AF7, DS08X)
-#define GPIO74_MLCD_VSYNC      MFP_CFG_DRV(GPIO74, AF7, DS08X)
-#define GPIO14_2_MLCD_FCLK     MFP_CFG_DRV(GPIO14_2, AF7, DS08X)
-#define GPIO15_2_MLCD_LCLK     MFP_CFG_DRV(GPIO15_2, AF7, DS08X)
-#define GPIO16_2_MLCD_PCLK     MFP_CFG_DRV(GPIO16_2, AF7, DS08X)
-#define GPIO17_2_MLCD_BIAS     MFP_CFG_DRV(GPIO17_2, AF7, DS08X)
-
-/* MMC1 */
-#define GPIO9_MMC1_CMD         MFP_CFG_LPM(GPIO9,  AF4, DRIVE_HIGH)
-#define GPIO22_MMC1_CLK                MFP_CFG_LPM(GPIO22, AF4, DRIVE_HIGH)
-#define GPIO23_MMC1_CMD                MFP_CFG_LPM(GPIO23, AF4, DRIVE_HIGH)
-#define GPIO30_MMC1_CLK                MFP_CFG_LPM(GPIO30, AF4, DRIVE_HIGH)
-#define GPIO31_MMC1_CMD                MFP_CFG_LPM(GPIO31, AF4, DRIVE_HIGH)
-#define GPIO5_MMC1_DAT0                MFP_CFG_LPM(GPIO5,  AF4, DRIVE_HIGH)
-#define GPIO6_MMC1_DAT1                MFP_CFG_LPM(GPIO6,  AF4, DRIVE_HIGH)
-#define GPIO7_MMC1_DAT2                MFP_CFG_LPM(GPIO7,  AF4, DRIVE_HIGH)
-#define GPIO8_MMC1_DAT3                MFP_CFG_LPM(GPIO8,  AF4, DRIVE_HIGH)
-#define GPIO18_MMC1_DAT0       MFP_CFG_LPM(GPIO18, AF4, DRIVE_HIGH)
-#define GPIO19_MMC1_DAT1       MFP_CFG_LPM(GPIO19, AF4, DRIVE_HIGH)
-#define GPIO20_MMC1_DAT2       MFP_CFG_LPM(GPIO20, AF4, DRIVE_HIGH)
-#define GPIO21_MMC1_DAT3       MFP_CFG_LPM(GPIO21, AF4, DRIVE_HIGH)
-
-#define GPIO28_MMC2_CLK                MFP_CFG_LPM(GPIO28, AF4, PULL_HIGH)
-#define GPIO29_MMC2_CMD                MFP_CFG_LPM(GPIO29, AF4, PULL_HIGH)
-#define GPIO30_MMC2_CLK                MFP_CFG_LPM(GPIO30, AF3, PULL_HIGH)
-#define GPIO31_MMC2_CMD                MFP_CFG_LPM(GPIO31, AF3, PULL_HIGH)
-#define GPIO79_MMC2_CLK                MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
-#define GPIO80_MMC2_CMD                MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
-
-#define GPIO5_MMC2_DAT0                MFP_CFG_LPM(GPIO5, AF2, PULL_HIGH)
-#define GPIO6_MMC2_DAT1                MFP_CFG_LPM(GPIO6, AF2, PULL_HIGH)
-#define GPIO7_MMC2_DAT2                MFP_CFG_LPM(GPIO7, AF2, PULL_HIGH)
-#define GPIO8_MMC2_DAT3                MFP_CFG_LPM(GPIO8, AF2, PULL_HIGH)
-#define GPIO24_MMC2_DAT0       MFP_CFG_LPM(GPIO24, AF4, PULL_HIGH)
-#define GPIO75_MMC2_DAT0       MFP_CFG_LPM(GPIO75, AF4, PULL_HIGH)
-#define GPIO25_MMC2_DAT1       MFP_CFG_LPM(GPIO25, AF4, PULL_HIGH)
-#define GPIO76_MMC2_DAT1       MFP_CFG_LPM(GPIO76, AF4, PULL_HIGH)
-#define GPIO26_MMC2_DAT2       MFP_CFG_LPM(GPIO26, AF4, PULL_HIGH)
-#define GPIO77_MMC2_DAT2       MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
-#define GPIO27_MMC2_DAT3       MFP_CFG_LPM(GPIO27, AF4, PULL_HIGH)
-#define GPIO78_MMC2_DAT3       MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
-
-/* 1-Wire */
-#define GPIO14_ONE_WIRE                MFP_CFG_LPM(GPIO14,  AF5, FLOAT)
-#define GPIO0_2_ONE_WIRE       MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
-
-/* SSP1 */
-#define GPIO87_SSP1_EXTCLK     MFP_CFG(GPIO87, AF1)
-#define GPIO88_SSP1_SYSCLK     MFP_CFG(GPIO88, AF1)
-#define GPIO83_SSP1_SCLK       MFP_CFG(GPIO83, AF1)
-#define GPIO84_SSP1_SFRM       MFP_CFG(GPIO84, AF1)
-#define GPIO85_SSP1_RXD                MFP_CFG(GPIO85, AF6)
-#define GPIO85_SSP1_TXD                MFP_CFG(GPIO85, AF1)
-#define GPIO86_SSP1_RXD                MFP_CFG(GPIO86, AF1)
-#define GPIO86_SSP1_TXD                MFP_CFG(GPIO86, AF6)
-
-/* SSP2 */
-#define GPIO39_SSP2_EXTCLK     MFP_CFG(GPIO39, AF2)
-#define GPIO40_SSP2_SYSCLK     MFP_CFG(GPIO40, AF2)
-#define GPIO12_SSP2_SCLK       MFP_CFG(GPIO12, AF2)
-#define GPIO35_SSP2_SCLK       MFP_CFG(GPIO35, AF2)
-#define GPIO36_SSP2_SFRM       MFP_CFG(GPIO36, AF2)
-#define GPIO37_SSP2_RXD                MFP_CFG(GPIO37, AF5)
-#define GPIO37_SSP2_TXD                MFP_CFG(GPIO37, AF2)
-#define GPIO38_SSP2_RXD                MFP_CFG(GPIO38, AF2)
-#define GPIO38_SSP2_TXD                MFP_CFG(GPIO38, AF5)
-
-#define GPIO69_SSP3_SCLK       MFP_CFG_X(GPIO69, AF2, DS08X, FLOAT)
-#define GPIO70_SSP3_FRM                MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
-#define GPIO89_SSP3_SCLK       MFP_CFG_X(GPIO89, AF1, DS08X, FLOAT)
-#define GPIO90_SSP3_FRM                MFP_CFG_X(GPIO90, AF1, DS08X, DRIVE_LOW)
-#define GPIO71_SSP3_RXD                MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT)
-#define GPIO71_SSP3_TXD                MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW)
-#define GPIO72_SSP3_RXD                MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT)
-#define GPIO72_SSP3_TXD                MFP_CFG_X(GPIO72, AF5, DS08X, DRIVE_LOW)
-#define GPIO91_SSP3_RXD                MFP_CFG_X(GPIO91, AF5, DS08X, FLOAT)
-#define GPIO91_SSP3_TXD                MFP_CFG_X(GPIO91, AF1, DS08X, DRIVE_LOW)
-#define GPIO92_SSP3_RXD                MFP_CFG_X(GPIO92, AF1, DS08X, FLOAT)
-#define GPIO92_SSP3_TXD                MFP_CFG_X(GPIO92, AF5, DS08X, DRIVE_LOW)
-
-#define GPIO93_SSP4_SCLK       MFP_CFG_LPM(GPIO93, AF1, PULL_HIGH)
-#define GPIO94_SSP4_FRM                MFP_CFG_LPM(GPIO94, AF1, PULL_HIGH)
-#define GPIO94_SSP4_RXD                MFP_CFG_LPM(GPIO94, AF5, PULL_HIGH)
-#define GPIO95_SSP4_RXD                MFP_CFG_LPM(GPIO95, AF5, PULL_HIGH)
-#define GPIO95_SSP4_TXD                MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
-#define GPIO96_SSP4_RXD                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
-#define GPIO96_SSP4_TXD                MFP_CFG_LPM(GPIO96, AF5, PULL_HIGH)
-
-/* UART1 */
-#define GPIO41_UART1_RXD       MFP_CFG_LPM(GPIO41, AF2, FLOAT)
-#define GPIO41_UART1_TXD       MFP_CFG_LPM(GPIO41, AF4, FLOAT)
-#define GPIO42_UART1_RXD       MFP_CFG_LPM(GPIO42, AF4, FLOAT)
-#define GPIO42_UART1_TXD       MFP_CFG_LPM(GPIO42, AF2, FLOAT)
-#define GPIO75_UART1_RXD       MFP_CFG_LPM(GPIO75, AF1, FLOAT)
-#define GPIO76_UART1_RXD       MFP_CFG_LPM(GPIO76, AF3, FLOAT)
-#define GPIO76_UART1_TXD       MFP_CFG_LPM(GPIO76, AF1, FLOAT)
-#define GPIO97_UART1_RXD       MFP_CFG_LPM(GPIO97, AF1, FLOAT)
-#define GPIO97_UART1_TXD       MFP_CFG_LPM(GPIO97, AF6, FLOAT)
-#define GPIO98_UART1_RXD       MFP_CFG_LPM(GPIO98, AF6, FLOAT)
-#define GPIO98_UART1_TXD       MFP_CFG_LPM(GPIO98, AF1, FLOAT)
-#define GPIO43_UART1_CTS       MFP_CFG_LPM(GPIO43, AF2, FLOAT)
-#define GPIO43_UART1_RTS       MFP_CFG_LPM(GPIO43, AF4, FLOAT)
-#define GPIO48_UART1_CTS       MFP_CFG_LPM(GPIO48, AF4, FLOAT)
-#define GPIO48_UART1_RTS       MFP_CFG_LPM(GPIO48, AF2, FLOAT)
-#define GPIO77_UART1_CTS       MFP_CFG_LPM(GPIO77, AF1, FLOAT)
-#define GPIO82_UART1_RTS       MFP_CFG_LPM(GPIO82, AF1, FLOAT)
-#define GPIO82_UART1_CTS       MFP_CFG_LPM(GPIO82, AF3, FLOAT)
-#define GPIO99_UART1_CTS       MFP_CFG_LPM(GPIO99, AF1, FLOAT)
-#define GPIO99_UART1_RTS       MFP_CFG_LPM(GPIO99, AF6, FLOAT)
-#define GPIO104_UART1_CTS      MFP_CFG_LPM(GPIO104, AF6, FLOAT)
-#define GPIO104_UART1_RTS      MFP_CFG_LPM(GPIO104, AF1, FLOAT)
-#define GPIO45_UART1_DTR       MFP_CFG_LPM(GPIO45, AF4, FLOAT)
-#define GPIO45_UART1_DSR       MFP_CFG_LPM(GPIO45, AF2, FLOAT)
-#define GPIO47_UART1_DTR       MFP_CFG_LPM(GPIO47, AF2, FLOAT)
-#define GPIO47_UART1_DSR       MFP_CFG_LPM(GPIO47, AF4, FLOAT)
-#define GPIO79_UART1_DSR       MFP_CFG_LPM(GPIO79, AF1, FLOAT)
-#define GPIO81_UART1_DTR       MFP_CFG_LPM(GPIO81, AF1, FLOAT)
-#define GPIO81_UART1_DSR       MFP_CFG_LPM(GPIO81, AF3, FLOAT)
-#define GPIO101_UART1_DTR      MFP_CFG_LPM(GPIO101, AF6, FLOAT)
-#define GPIO101_UART1_DSR      MFP_CFG_LPM(GPIO101, AF1, FLOAT)
-#define GPIO103_UART1_DTR      MFP_CFG_LPM(GPIO103, AF1, FLOAT)
-#define GPIO103_UART1_DSR      MFP_CFG_LPM(GPIO103, AF6, FLOAT)
-#define GPIO44_UART1_DCD       MFP_CFG_LPM(GPIO44, AF2, FLOAT)
-#define GPIO78_UART1_DCD       MFP_CFG_LPM(GPIO78, AF1, FLOAT)
-#define GPIO100_UART1_DCD      MFP_CFG_LPM(GPIO100, AF1, FLOAT)
-#define GPIO46_UART1_RI                MFP_CFG_LPM(GPIO46, AF2, FLOAT)
-#define GPIO80_UART1_RI                MFP_CFG_LPM(GPIO80, AF1, FLOAT)
-#define GPIO102_UART1_RI       MFP_CFG_LPM(GPIO102, AF1, FLOAT)
-
-/* UART2 */
-#define GPIO109_UART2_CTS      MFP_CFG_LPM(GPIO109, AF3, FLOAT)
-#define GPIO109_UART2_RTS      MFP_CFG_LPM(GPIO109, AF1, FLOAT)
-#define GPIO112_UART2_CTS      MFP_CFG_LPM(GPIO112, AF1, FLOAT)
-#define GPIO112_UART2_RTS      MFP_CFG_LPM(GPIO112, AF3, FLOAT)
-#define GPIO110_UART2_RXD      MFP_CFG_LPM(GPIO110, AF1, FLOAT)
-#define GPIO110_UART2_TXD      MFP_CFG_LPM(GPIO110, AF3, FLOAT)
-#define GPIO111_UART2_RXD      MFP_CFG_LPM(GPIO111, AF3, FLOAT)
-#define GPIO111_UART2_TXD      MFP_CFG_LPM(GPIO111, AF1, FLOAT)
-
-/* UART3 */
-#define GPIO89_UART3_CTS       MFP_CFG_LPM(GPIO89, AF2, FLOAT)
-#define GPIO89_UART3_RTS       MFP_CFG_LPM(GPIO89, AF4, FLOAT)
-#define GPIO90_UART3_CTS       MFP_CFG_LPM(GPIO90, AF4, FLOAT)
-#define GPIO90_UART3_RTS       MFP_CFG_LPM(GPIO90, AF2, FLOAT)
-#define GPIO105_UART3_CTS      MFP_CFG_LPM(GPIO105, AF1, FLOAT)
-#define GPIO105_UART3_RTS      MFP_CFG_LPM(GPIO105, AF3, FLOAT)
-#define GPIO106_UART3_CTS      MFP_CFG_LPM(GPIO106, AF3, FLOAT)
-#define GPIO106_UART3_RTS      MFP_CFG_LPM(GPIO106, AF1, FLOAT)
-#define GPIO30_UART3_RXD       MFP_CFG_LPM(GPIO30, AF2, FLOAT)
-#define GPIO30_UART3_TXD       MFP_CFG_LPM(GPIO30, AF6, FLOAT)
-#define GPIO31_UART3_RXD       MFP_CFG_LPM(GPIO31, AF6, FLOAT)
-#define GPIO31_UART3_TXD       MFP_CFG_LPM(GPIO31, AF2, FLOAT)
-#define GPIO91_UART3_RXD       MFP_CFG_LPM(GPIO91, AF4, FLOAT)
-#define GPIO91_UART3_TXD       MFP_CFG_LPM(GPIO91, AF2, FLOAT)
-#define GPIO92_UART3_RXD       MFP_CFG_LPM(GPIO92, AF2, FLOAT)
-#define GPIO92_UART3_TXD       MFP_CFG_LPM(GPIO92, AF4, FLOAT)
-#define GPIO107_UART3_RXD      MFP_CFG_LPM(GPIO107, AF3, FLOAT)
-#define GPIO107_UART3_TXD      MFP_CFG_LPM(GPIO107, AF1, FLOAT)
-#define GPIO108_UART3_RXD      MFP_CFG_LPM(GPIO108, AF1, FLOAT)
-#define GPIO108_UART3_TXD      MFP_CFG_LPM(GPIO108, AF3, FLOAT)
-
-
-/* USB 2.0 UTMI */
-#define GPIO10_UTM_CLK         MFP_CFG(GPIO10, AF1)
-#define GPIO36_U2D_RXERROR     MFP_CFG(GPIO36, AF3)
-#define GPIO60_U2D_RXERROR     MFP_CFG(GPIO60, AF1)
-#define GPIO87_U2D_RXERROR     MFP_CFG(GPIO87, AF5)
-#define GPIO34_UTM_RXVALID     MFP_CFG(GPIO34, AF3)
-#define GPIO58_UTM_RXVALID     MFP_CFG(GPIO58, AF2)
-#define GPIO85_UTM_RXVALID     MFP_CFG(GPIO85, AF5)
-#define GPIO35_UTM_RXACTIVE    MFP_CFG(GPIO35, AF3)
-#define GPIO59_UTM_RXACTIVE    MFP_CFG(GPIO59, AF1)
-#define GPIO86_UTM_RXACTIVE    MFP_CFG(GPIO86, AF5)
-#define GPIO73_UTM_TXREADY     MFP_CFG(GPIO73, AF1)
-#define GPIO68_UTM_LINESTATE_0 MFP_CFG(GPIO68, AF3)
-#define GPIO90_UTM_LINESTATE_0 MFP_CFG(GPIO90, AF3)
-#define GPIO102_UTM_LINESTATE_0        MFP_CFG(GPIO102, AF3)
-#define GPIO107_UTM_LINESTATE_0        MFP_CFG(GPIO107, AF4)
-#define GPIO69_UTM_LINESTATE_1 MFP_CFG(GPIO69, AF3)
-#define GPIO91_UTM_LINESTATE_1 MFP_CFG(GPIO91, AF3)
-#define GPIO103_UTM_LINESTATE_1        MFP_CFG(GPIO103, AF3)
-
-#define GPIO41_U2D_PHYDATA_0   MFP_CFG(GPIO41, AF3)
-#define GPIO42_U2D_PHYDATA_1   MFP_CFG(GPIO42, AF3)
-#define GPIO43_U2D_PHYDATA_2   MFP_CFG(GPIO43, AF3)
-#define GPIO44_U2D_PHYDATA_3   MFP_CFG(GPIO44, AF3)
-#define GPIO45_U2D_PHYDATA_4   MFP_CFG(GPIO45, AF3)
-#define GPIO46_U2D_PHYDATA_5   MFP_CFG(GPIO46, AF3)
-#define GPIO47_U2D_PHYDATA_6   MFP_CFG(GPIO47, AF3)
-#define GPIO48_U2D_PHYDATA_7   MFP_CFG(GPIO48, AF3)
-
-#define GPIO49_U2D_PHYDATA_0   MFP_CFG(GPIO49, AF3)
-#define GPIO50_U2D_PHYDATA_1   MFP_CFG(GPIO50, AF3)
-#define GPIO51_U2D_PHYDATA_2   MFP_CFG(GPIO51, AF3)
-#define GPIO52_U2D_PHYDATA_3   MFP_CFG(GPIO52, AF3)
-#define GPIO53_U2D_PHYDATA_4   MFP_CFG(GPIO53, AF3)
-#define GPIO54_U2D_PHYDATA_5   MFP_CFG(GPIO54, AF3)
-#define GPIO55_U2D_PHYDATA_6   MFP_CFG(GPIO55, AF3)
-#define GPIO56_U2D_PHYDATA_7   MFP_CFG(GPIO56, AF3)
-
-#define GPIO37_U2D_OPMODE0     MFP_CFG(GPIO37, AF4)
-#define GPIO61_U2D_OPMODE0     MFP_CFG(GPIO61, AF2)
-#define GPIO88_U2D_OPMODE0     MFP_CFG(GPIO88, AF7)
-
-#define GPIO38_U2D_OPMODE1     MFP_CFG(GPIO38, AF4)
-#define GPIO62_U2D_OPMODE1     MFP_CFG(GPIO62, AF2)
-#define GPIO104_U2D_OPMODE1    MFP_CFG(GPIO104, AF4)
-#define GPIO108_U2D_OPMODE1    MFP_CFG(GPIO108, AF5)
-
-#define GPIO74_U2D_RESET       MFP_CFG(GPIO74, AF1)
-#define GPIO93_U2D_RESET       MFP_CFG(GPIO93, AF2)
-#define GPIO98_U2D_RESET       MFP_CFG(GPIO98, AF3)
-
-#define GPIO67_U2D_SUSPEND     MFP_CFG(GPIO67, AF3)
-#define GPIO96_U2D_SUSPEND     MFP_CFG(GPIO96, AF2)
-#define GPIO101_U2D_SUSPEND    MFP_CFG(GPIO101, AF3)
-
-#define GPIO66_U2D_TERM_SEL    MFP_CFG(GPIO66, AF5)
-#define GPIO95_U2D_TERM_SEL    MFP_CFG(GPIO95, AF3)
-#define GPIO97_U2D_TERM_SEL    MFP_CFG(GPIO97, AF7)
-#define GPIO100_U2D_TERM_SEL   MFP_CFG(GPIO100, AF5)
-
-#define GPIO39_U2D_TXVALID     MFP_CFG(GPIO39, AF4)
-#define GPIO70_U2D_TXVALID     MFP_CFG(GPIO70, AF5)
-#define GPIO83_U2D_TXVALID     MFP_CFG(GPIO83, AF7)
-
-#define GPIO65_U2D_XCVR_SEL    MFP_CFG(GPIO65, AF5)
-#define GPIO94_U2D_XCVR_SEL    MFP_CFG(GPIO94, AF3)
-#define GPIO99_U2D_XCVR_SEL    MFP_CFG(GPIO99, AF5)
-
-/* USB Host 1.1 */
-#define GPIO2_2_USBH_PEN       MFP_CFG(GPIO2_2, AF1)
-#define GPIO3_2_USBH_PWR       MFP_CFG(GPIO3_2, AF1)
-
-/* USB P2 */
-#define GPIO97_USB_P2_2                MFP_CFG(GPIO97, AF2)
-#define GPIO97_USB_P2_6                MFP_CFG(GPIO97, AF4)
-#define GPIO98_USB_P2_2                MFP_CFG(GPIO98, AF4)
-#define GPIO98_USB_P2_6                MFP_CFG(GPIO98, AF2)
-#define GPIO99_USB_P2_1                MFP_CFG(GPIO99, AF2)
-#define GPIO100_USB_P2_4       MFP_CFG(GPIO100, AF2)
-#define GPIO101_USB_P2_8       MFP_CFG(GPIO101, AF2)
-#define GPIO102_USB_P2_3       MFP_CFG(GPIO102, AF2)
-#define GPIO103_USB_P2_5       MFP_CFG(GPIO103, AF2)
-#define GPIO104_USB_P2_7       MFP_CFG(GPIO104, AF2)
-
-/* USB P3 */
-#define GPIO75_USB_P3_1                MFP_CFG(GPIO75, AF2)
-#define GPIO76_USB_P3_2                MFP_CFG(GPIO76, AF2)
-#define GPIO77_USB_P3_3                MFP_CFG(GPIO77, AF2)
-#define GPIO78_USB_P3_4                MFP_CFG(GPIO78, AF2)
-#define GPIO79_USB_P3_5                MFP_CFG(GPIO79, AF2)
-#define GPIO80_USB_P3_6                MFP_CFG(GPIO80, AF2)
-
-#define GPIO13_CHOUT0          MFP_CFG(GPIO13, AF6)
-#define GPIO14_CHOUT1          MFP_CFG(GPIO14, AF6)
-
-#define GPIO2_RDY              MFP_CFG(GPIO2, AF1)
-#define GPIO5_NPIOR            MFP_CFG(GPIO5, AF3)
-#define GPIO6_NPIOW            MFP_CFG(GPIO6, AF3)
-#define GPIO7_NPIOS16          MFP_CFG(GPIO7, AF3)
-#define GPIO8_NPWAIT           MFP_CFG(GPIO8, AF3)
-
-#define GPIO11_PWM0_OUT                MFP_CFG(GPIO11, AF1)
-#define GPIO12_PWM1_OUT                MFP_CFG(GPIO12, AF1)
-#define GPIO13_PWM2_OUT                MFP_CFG(GPIO13, AF1)
-#define GPIO14_PWM3_OUT                MFP_CFG(GPIO14, AF1)
-
-#endif /* __ASM_ARCH_MFP_PXA320_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
deleted file mode 100644 (file)
index d375195..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef __ASM_ARCH_MFP_PXA3XX_H
-#define __ASM_ARCH_MFP_PXA3XX_H
-
-#include <plat/mfp.h>
-
-#define MFPR_BASE      (0x40e10000)
-
-/* PXA3xx common MFP configurations - processor specific ones defined
- * in mfp-pxa300.h and mfp-pxa320.h
- */
-#define GPIO0_GPIO             MFP_CFG(GPIO0, AF0)
-#define GPIO1_GPIO             MFP_CFG(GPIO1, AF0)
-#define GPIO2_GPIO             MFP_CFG(GPIO2, AF0)
-#define GPIO3_GPIO             MFP_CFG(GPIO3, AF0)
-#define GPIO4_GPIO             MFP_CFG(GPIO4, AF0)
-#define GPIO5_GPIO             MFP_CFG(GPIO5, AF0)
-#define GPIO6_GPIO             MFP_CFG(GPIO6, AF0)
-#define GPIO7_GPIO             MFP_CFG(GPIO7, AF0)
-#define GPIO8_GPIO             MFP_CFG(GPIO8, AF0)
-#define GPIO9_GPIO             MFP_CFG(GPIO9, AF0)
-#define GPIO10_GPIO            MFP_CFG(GPIO10, AF0)
-#define GPIO11_GPIO            MFP_CFG(GPIO11, AF0)
-#define GPIO12_GPIO            MFP_CFG(GPIO12, AF0)
-#define GPIO13_GPIO            MFP_CFG(GPIO13, AF0)
-#define GPIO14_GPIO            MFP_CFG(GPIO14, AF0)
-#define GPIO15_GPIO            MFP_CFG(GPIO15, AF0)
-#define GPIO16_GPIO            MFP_CFG(GPIO16, AF0)
-#define GPIO17_GPIO            MFP_CFG(GPIO17, AF0)
-#define GPIO18_GPIO            MFP_CFG(GPIO18, AF0)
-#define GPIO19_GPIO            MFP_CFG(GPIO19, AF0)
-#define GPIO20_GPIO            MFP_CFG(GPIO20, AF0)
-#define GPIO21_GPIO            MFP_CFG(GPIO21, AF0)
-#define GPIO22_GPIO            MFP_CFG(GPIO22, AF0)
-#define GPIO23_GPIO            MFP_CFG(GPIO23, AF0)
-#define GPIO24_GPIO            MFP_CFG(GPIO24, AF0)
-#define GPIO25_GPIO            MFP_CFG(GPIO25, AF0)
-#define GPIO26_GPIO            MFP_CFG(GPIO26, AF0)
-#define GPIO27_GPIO            MFP_CFG(GPIO27, AF0)
-#define GPIO28_GPIO            MFP_CFG(GPIO28, AF0)
-#define GPIO29_GPIO            MFP_CFG(GPIO29, AF0)
-#define GPIO30_GPIO            MFP_CFG(GPIO30, AF0)
-#define GPIO31_GPIO            MFP_CFG(GPIO31, AF0)
-#define GPIO32_GPIO            MFP_CFG(GPIO32, AF0)
-#define GPIO33_GPIO            MFP_CFG(GPIO33, AF0)
-#define GPIO34_GPIO            MFP_CFG(GPIO34, AF0)
-#define GPIO35_GPIO            MFP_CFG(GPIO35, AF0)
-#define GPIO36_GPIO            MFP_CFG(GPIO36, AF0)
-#define GPIO37_GPIO            MFP_CFG(GPIO37, AF0)
-#define GPIO38_GPIO            MFP_CFG(GPIO38, AF0)
-#define GPIO39_GPIO            MFP_CFG(GPIO39, AF0)
-#define GPIO40_GPIO            MFP_CFG(GPIO40, AF0)
-#define GPIO41_GPIO            MFP_CFG(GPIO41, AF0)
-#define GPIO42_GPIO            MFP_CFG(GPIO42, AF0)
-#define GPIO43_GPIO            MFP_CFG(GPIO43, AF0)
-#define GPIO44_GPIO            MFP_CFG(GPIO44, AF0)
-#define GPIO45_GPIO            MFP_CFG(GPIO45, AF0)
-
-#define GPIO47_GPIO            MFP_CFG(GPIO47, AF0)
-#define GPIO48_GPIO            MFP_CFG(GPIO48, AF0)
-
-#define GPIO53_GPIO            MFP_CFG(GPIO53, AF0)
-#define GPIO54_GPIO            MFP_CFG(GPIO54, AF0)
-#define GPIO55_GPIO            MFP_CFG(GPIO55, AF0)
-
-#define GPIO57_GPIO            MFP_CFG(GPIO57, AF0)
-
-#define GPIO63_GPIO            MFP_CFG(GPIO63, AF0)
-#define GPIO64_GPIO            MFP_CFG(GPIO64, AF0)
-#define GPIO65_GPIO            MFP_CFG(GPIO65, AF0)
-#define GPIO66_GPIO            MFP_CFG(GPIO66, AF0)
-#define GPIO67_GPIO            MFP_CFG(GPIO67, AF0)
-#define GPIO68_GPIO            MFP_CFG(GPIO68, AF0)
-#define GPIO69_GPIO            MFP_CFG(GPIO69, AF0)
-#define GPIO70_GPIO            MFP_CFG(GPIO70, AF0)
-#define GPIO71_GPIO            MFP_CFG(GPIO71, AF0)
-#define GPIO72_GPIO            MFP_CFG(GPIO72, AF0)
-#define GPIO73_GPIO            MFP_CFG(GPIO73, AF0)
-#define GPIO74_GPIO            MFP_CFG(GPIO74, AF0)
-#define GPIO75_GPIO            MFP_CFG(GPIO75, AF0)
-#define GPIO76_GPIO            MFP_CFG(GPIO76, AF0)
-#define GPIO77_GPIO            MFP_CFG(GPIO77, AF0)
-#define GPIO78_GPIO            MFP_CFG(GPIO78, AF0)
-#define GPIO79_GPIO            MFP_CFG(GPIO79, AF0)
-#define GPIO80_GPIO            MFP_CFG(GPIO80, AF0)
-#define GPIO81_GPIO            MFP_CFG(GPIO81, AF0)
-#define GPIO82_GPIO            MFP_CFG(GPIO82, AF0)
-#define GPIO83_GPIO            MFP_CFG(GPIO83, AF0)
-#define GPIO84_GPIO            MFP_CFG(GPIO84, AF0)
-#define GPIO85_GPIO            MFP_CFG(GPIO85, AF0)
-#define GPIO86_GPIO            MFP_CFG(GPIO86, AF0)
-#define GPIO87_GPIO            MFP_CFG(GPIO87, AF0)
-#define GPIO88_GPIO            MFP_CFG(GPIO88, AF0)
-#define GPIO89_GPIO            MFP_CFG(GPIO89, AF0)
-#define GPIO90_GPIO            MFP_CFG(GPIO90, AF0)
-#define GPIO91_GPIO            MFP_CFG(GPIO91, AF0)
-#define GPIO92_GPIO            MFP_CFG(GPIO92, AF0)
-#define GPIO93_GPIO            MFP_CFG(GPIO93, AF0)
-#define GPIO94_GPIO            MFP_CFG(GPIO94, AF0)
-#define GPIO95_GPIO            MFP_CFG(GPIO95, AF0)
-#define GPIO96_GPIO            MFP_CFG(GPIO96, AF0)
-#define GPIO97_GPIO            MFP_CFG(GPIO97, AF0)
-#define GPIO98_GPIO            MFP_CFG(GPIO98, AF0)
-#define GPIO99_GPIO            MFP_CFG(GPIO99, AF0)
-#define GPIO100_GPIO           MFP_CFG(GPIO100, AF0)
-#define GPIO101_GPIO           MFP_CFG(GPIO101, AF0)
-#define GPIO102_GPIO           MFP_CFG(GPIO102, AF0)
-#define GPIO103_GPIO           MFP_CFG(GPIO103, AF0)
-#define GPIO104_GPIO           MFP_CFG(GPIO104, AF0)
-#define GPIO105_GPIO           MFP_CFG(GPIO105, AF0)
-#define GPIO106_GPIO           MFP_CFG(GPIO106, AF0)
-#define GPIO107_GPIO           MFP_CFG(GPIO107, AF0)
-#define GPIO108_GPIO           MFP_CFG(GPIO108, AF0)
-#define GPIO109_GPIO           MFP_CFG(GPIO109, AF0)
-#define GPIO110_GPIO           MFP_CFG(GPIO110, AF0)
-#define GPIO111_GPIO           MFP_CFG(GPIO111, AF0)
-#define GPIO112_GPIO           MFP_CFG(GPIO112, AF0)
-#define GPIO113_GPIO           MFP_CFG(GPIO113, AF0)
-#define GPIO114_GPIO           MFP_CFG(GPIO114, AF0)
-#define GPIO115_GPIO           MFP_CFG(GPIO115, AF0)
-#define GPIO116_GPIO           MFP_CFG(GPIO116, AF0)
-#define GPIO117_GPIO           MFP_CFG(GPIO117, AF0)
-#define GPIO118_GPIO           MFP_CFG(GPIO118, AF0)
-#define GPIO119_GPIO           MFP_CFG(GPIO119, AF0)
-#define GPIO120_GPIO           MFP_CFG(GPIO120, AF0)
-#define GPIO121_GPIO           MFP_CFG(GPIO121, AF0)
-#define GPIO122_GPIO           MFP_CFG(GPIO122, AF0)
-#define GPIO123_GPIO           MFP_CFG(GPIO123, AF0)
-#define GPIO124_GPIO           MFP_CFG(GPIO124, AF0)
-#define GPIO125_GPIO           MFP_CFG(GPIO125, AF0)
-#define GPIO126_GPIO           MFP_CFG(GPIO126, AF0)
-#define GPIO127_GPIO           MFP_CFG(GPIO127, AF0)
-
-#define GPIO0_2_GPIO           MFP_CFG(GPIO0_2, AF0)
-#define GPIO1_2_GPIO           MFP_CFG(GPIO1_2, AF0)
-#define GPIO2_2_GPIO           MFP_CFG(GPIO2_2, AF0)
-#define GPIO3_2_GPIO           MFP_CFG(GPIO3_2, AF0)
-#define GPIO4_2_GPIO           MFP_CFG(GPIO4_2, AF0)
-#define GPIO5_2_GPIO           MFP_CFG(GPIO5_2, AF0)
-#define GPIO6_2_GPIO           MFP_CFG(GPIO6_2, AF0)
-
-/* NOTE: usage of these two functions is not recommended,
- * use pxa3xx_mfp_config() instead.
- */
-static inline unsigned long pxa3xx_mfp_read(int mfp)
-{
-       return mfp_read(mfp);
-}
-
-static inline void pxa3xx_mfp_write(int mfp, unsigned long val)
-{
-       mfp_write(mfp, val);
-}
-
-static inline void pxa3xx_mfp_config(unsigned long *mfp_cfg, int num)
-{
-       mfp_config(mfp_cfg, num);
-}
-#endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
deleted file mode 100644 (file)
index 04f7c97..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/mfp-pxa930.h
- *
- * PXA930 specific MFP configuration definitions
- *
- * Copyright (C) 2007-2008 Marvell International 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.
- */
-
-#ifndef __ASM_ARCH_MFP_PXA9xx_H
-#define __ASM_ARCH_MFP_PXA9xx_H
-
-#include <mach/mfp-pxa3xx.h>
-
-/* GPIO */
-#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
-#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
-#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
-#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
-#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
-#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
-#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
-#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
-#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
-#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
-#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
-
-#define GSIM_UCLK_GPIO_79      MFP_CFG(GSIM_UCLK, AF0)
-#define GSIM_UIO_GPIO_80       MFP_CFG(GSIM_UIO, AF0)
-#define GSIM_nURST_GPIO_81     MFP_CFG(GSIM_nURST, AF0)
-#define GSIM_UDET_GPIO_82      MFP_CFG(GSIM_UDET, AF0)
-
-#define DF_IO15_GPIO_28                MFP_CFG(DF_IO15, AF0)
-#define DF_IO14_GPIO_29                MFP_CFG(DF_IO14, AF0)
-#define DF_IO13_GPIO_30                MFP_CFG(DF_IO13, AF0)
-#define DF_IO12_GPIO_31                MFP_CFG(DF_IO12, AF0)
-#define DF_IO11_GPIO_32                MFP_CFG(DF_IO11, AF0)
-#define DF_IO10_GPIO_33                MFP_CFG(DF_IO10, AF0)
-#define DF_IO9_GPIO_34         MFP_CFG(DF_IO9, AF0)
-#define DF_IO8_GPIO_35         MFP_CFG(DF_IO8, AF0)
-#define DF_IO7_GPIO_36         MFP_CFG(DF_IO7, AF0)
-#define DF_IO6_GPIO_37         MFP_CFG(DF_IO6, AF0)
-#define DF_IO5_GPIO_38         MFP_CFG(DF_IO5, AF0)
-#define DF_IO4_GPIO_39         MFP_CFG(DF_IO4, AF0)
-#define DF_IO3_GPIO_40         MFP_CFG(DF_IO3, AF0)
-#define DF_IO2_GPIO_41         MFP_CFG(DF_IO2, AF0)
-#define DF_IO1_GPIO_42         MFP_CFG(DF_IO1, AF0)
-#define DF_IO0_GPIO_43         MFP_CFG(DF_IO0, AF0)
-#define DF_nCS0_GPIO_44                MFP_CFG(DF_nCS0, AF0)
-#define DF_nCS1_GPIO_45                MFP_CFG(DF_nCS1, AF0)
-#define DF_nWE_GPIO_46         MFP_CFG(DF_nWE, AF0)
-#define DF_nRE_nOE_GPIO_47     MFP_CFG(DF_nRE_nOE, AF0)
-#define DF_CLE_nOE_GPIO_48     MFP_CFG(DF_CLE_nOE, AF0)
-#define DF_nADV1_ALE_GPIO_49   MFP_CFG(DF_nADV1_ALE, AF0)
-#define DF_nADV2_ALE_GPIO_50   MFP_CFG(DF_nADV2_ALE, AF0)
-#define DF_INT_RnB_GPIO_51     MFP_CFG(DF_INT_RnB, AF0)
-#define DF_SCLK_E_GPIO_52      MFP_CFG(DF_SCLK_E, AF0)
-
-#define DF_ADDR0_GPIO_53       MFP_CFG(DF_ADDR0, AF0)
-#define DF_ADDR1_GPIO_54       MFP_CFG(DF_ADDR1, AF0)
-#define DF_ADDR2_GPIO_55       MFP_CFG(DF_ADDR2, AF0)
-#define DF_ADDR3_GPIO_56       MFP_CFG(DF_ADDR3, AF0)
-#define nXCVREN_GPIO_57                MFP_CFG(nXCVREN, AF0)
-#define nLUA_GPIO_58           MFP_CFG(nLUA, AF0)
-#define nLLA_GPIO_59           MFP_CFG(nLLA, AF0)
-#define nBE0_GPIO_60           MFP_CFG(nBE0, AF0)
-#define nBE1_GPIO_61           MFP_CFG(nBE1, AF0)
-#define RDY_GPIO_62            MFP_CFG(RDY, AF0)
-#define PMIC_INT_GPIO83                MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH)
-
-/* Chip Select */
-#define DF_nCS0_nCS2           MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
-#define DF_nCS1_nCS3           MFP_CFG_LPM(DF_nCS1, AF3, PULL_HIGH)
-
-/* AC97 */
-#define GPIO83_BAC97_SYSCLK    MFP_CFG(GPIO83, AF3)
-#define GPIO84_BAC97_SDATA_IN0 MFP_CFG(GPIO84, AF3)
-#define GPIO85_BAC97_BITCLK    MFP_CFG(GPIO85, AF3)
-#define GPIO86_BAC97_nRESET    MFP_CFG(GPIO86, AF3)
-#define GPIO87_BAC97_SYNC      MFP_CFG(GPIO87, AF3)
-#define GPIO88_BAC97_SDATA_OUT MFP_CFG(GPIO88, AF3)
-
-/* I2C */
-#define GPIO39_CI2C_SCL                MFP_CFG_LPM(GPIO39, AF3, PULL_HIGH)
-#define GPIO40_CI2C_SDA                MFP_CFG_LPM(GPIO40, AF3, PULL_HIGH)
-
-#define GPIO51_CI2C_SCL                MFP_CFG_LPM(GPIO51, AF3, PULL_HIGH)
-#define GPIO52_CI2C_SDA                MFP_CFG_LPM(GPIO52, AF3, PULL_HIGH)
-
-#define GPIO63_CI2C_SCL                MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
-#define GPIO64_CI2C_SDA                MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
-
-#define GPIO73_CI2C_SCL                MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH)
-#define GPIO74_CI2C_SDA                MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH)
-
-#define GPIO77_CI2C_SCL                MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
-#define GPIO78_CI2C_SDA                MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
-
-#define GPIO89_CI2C_SCL                MFP_CFG_LPM(GPIO89, AF1, PULL_HIGH)
-#define GPIO90_CI2C_SDA                MFP_CFG_LPM(GPIO90, AF1, PULL_HIGH)
-
-#define GPIO95_CI2C_SCL                MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
-#define GPIO96_CI2C_SDA                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
-
-#define GPIO97_CI2C_SCL                MFP_CFG_LPM(GPIO97, AF3, PULL_HIGH)
-#define GPIO98_CI2C_SDA                MFP_CFG_LPM(GPIO98, AF3, PULL_HIGH)
-
-/* QCI */
-#define GPIO63_CI_DD_9         MFP_CFG_LPM(GPIO63, AF1, PULL_LOW)
-#define GPIO64_CI_DD_8         MFP_CFG_LPM(GPIO64, AF1, PULL_LOW)
-#define GPIO65_CI_DD_7         MFP_CFG_LPM(GPIO65, AF1, PULL_LOW)
-#define GPIO66_CI_DD_6         MFP_CFG_LPM(GPIO66, AF1, PULL_LOW)
-#define GPIO67_CI_DD_5         MFP_CFG_LPM(GPIO67, AF1, PULL_LOW)
-#define GPIO68_CI_DD_4         MFP_CFG_LPM(GPIO68, AF1, PULL_LOW)
-#define GPIO69_CI_DD_3         MFP_CFG_LPM(GPIO69, AF1, PULL_LOW)
-#define GPIO70_CI_DD_2         MFP_CFG_LPM(GPIO70, AF1, PULL_LOW)
-#define GPIO71_CI_DD_1         MFP_CFG_LPM(GPIO71, AF1, PULL_LOW)
-#define GPIO72_CI_DD_0         MFP_CFG_LPM(GPIO72, AF1, PULL_LOW)
-#define GPIO73_CI_HSYNC                MFP_CFG_LPM(GPIO73, AF1, PULL_LOW)
-#define GPIO74_CI_VSYNC                MFP_CFG_LPM(GPIO74, AF1, PULL_LOW)
-#define GPIO75_CI_MCLK         MFP_CFG_LPM(GPIO75, AF1, PULL_LOW)
-#define GPIO76_CI_PCLK         MFP_CFG_LPM(GPIO76, AF1, PULL_LOW)
-
-/* KEYPAD */
-#define GPIO4_KP_DKIN_4                MFP_CFG_LPM(GPIO4, AF3, FLOAT)
-#define GPIO5_KP_DKIN_5                MFP_CFG_LPM(GPIO5, AF3, FLOAT)
-#define GPIO6_KP_DKIN_6                MFP_CFG_LPM(GPIO6, AF3, FLOAT)
-#define GPIO7_KP_DKIN_7                MFP_CFG_LPM(GPIO7, AF3, FLOAT)
-#define GPIO8_KP_DKIN_4                MFP_CFG_LPM(GPIO8, AF3, FLOAT)
-#define GPIO9_KP_DKIN_5                MFP_CFG_LPM(GPIO9, AF3, FLOAT)
-#define GPIO10_KP_DKIN_6       MFP_CFG_LPM(GPIO10, AF3, FLOAT)
-#define GPIO11_KP_DKIN_7       MFP_CFG_LPM(GPIO11, AF3, FLOAT)
-
-#define GPIO12_KP_DKIN_0       MFP_CFG_LPM(GPIO12, AF2, FLOAT)
-#define GPIO13_KP_DKIN_1       MFP_CFG_LPM(GPIO13, AF2, FLOAT)
-#define GPIO14_KP_DKIN_2       MFP_CFG_LPM(GPIO14, AF2, FLOAT)
-#define GPIO15_KP_DKIN_3       MFP_CFG_LPM(GPIO15, AF2, FLOAT)
-
-#define GPIO41_KP_DKIN_0       MFP_CFG_LPM(GPIO41, AF2, FLOAT)
-#define GPIO42_KP_DKIN_1       MFP_CFG_LPM(GPIO42, AF2, FLOAT)
-#define GPIO43_KP_DKIN_2       MFP_CFG_LPM(GPIO43, AF2, FLOAT)
-#define GPIO44_KP_DKIN_3       MFP_CFG_LPM(GPIO44, AF2, FLOAT)
-#define GPIO41_KP_DKIN_4       MFP_CFG_LPM(GPIO41, AF4, FLOAT)
-#define GPIO42_KP_DKIN_5       MFP_CFG_LPM(GPIO42, AF4, FLOAT)
-
-#define GPIO0_KP_MKIN_0                MFP_CFG_LPM(GPIO0, AF1, FLOAT)
-#define GPIO2_KP_MKIN_1                MFP_CFG_LPM(GPIO2, AF1, FLOAT)
-#define GPIO4_KP_MKIN_2                MFP_CFG_LPM(GPIO4, AF1, FLOAT)
-#define GPIO6_KP_MKIN_3                MFP_CFG_LPM(GPIO6, AF1, FLOAT)
-#define GPIO8_KP_MKIN_4                MFP_CFG_LPM(GPIO8, AF1, FLOAT)
-#define GPIO10_KP_MKIN_5       MFP_CFG_LPM(GPIO10, AF1, FLOAT)
-#define GPIO12_KP_MKIN_6       MFP_CFG_LPM(GPIO12, AF1, FLOAT)
-#define GPIO14_KP_MKIN_7       MFP_CFG(GPIO14, AF1)
-#define GPIO35_KP_MKIN_5       MFP_CFG(GPIO35, AF4)
-
-#define GPIO1_KP_MKOUT_0       MFP_CFG_LPM(GPIO1, AF1, DRIVE_HIGH)
-#define GPIO3_KP_MKOUT_1       MFP_CFG_LPM(GPIO3, AF1, DRIVE_HIGH)
-#define GPIO5_KP_MKOUT_2       MFP_CFG_LPM(GPIO5, AF1, DRIVE_HIGH)
-#define GPIO7_KP_MKOUT_3       MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
-#define GPIO9_KP_MKOUT_4       MFP_CFG_LPM(GPIO9, AF1, DRIVE_HIGH)
-#define GPIO11_KP_MKOUT_5      MFP_CFG_LPM(GPIO11, AF1, DRIVE_HIGH)
-#define GPIO13_KP_MKOUT_6      MFP_CFG_LPM(GPIO13, AF1, DRIVE_HIGH)
-#define GPIO15_KP_MKOUT_7      MFP_CFG_LPM(GPIO15, AF1, DRIVE_HIGH)
-#define GPIO36_KP_MKOUT_5      MFP_CFG_LPM(GPIO36, AF4, DRIVE_HIGH)
-
-/* LCD */
-#define GPIO17_LCD_FCLK_RD     MFP_CFG(GPIO17, AF1)
-#define GPIO18_LCD_LCLK_A0     MFP_CFG(GPIO18, AF1)
-#define GPIO19_LCD_PCLK_WR     MFP_CFG(GPIO19, AF1)
-#define GPIO20_LCD_BIAS                MFP_CFG(GPIO20, AF1)
-#define GPIO21_LCD_CS          MFP_CFG(GPIO21, AF1)
-#define GPIO22_LCD_CS2         MFP_CFG(GPIO22, AF2)
-#define GPIO22_LCD_VSYNC       MFP_CFG(GPIO22, AF1)
-#define GPIO23_LCD_DD0         MFP_CFG(GPIO23, AF1)
-#define GPIO24_LCD_DD1         MFP_CFG(GPIO24, AF1)
-#define GPIO25_LCD_DD2         MFP_CFG(GPIO25, AF1)
-#define GPIO26_LCD_DD3         MFP_CFG(GPIO26, AF1)
-#define GPIO27_LCD_DD4         MFP_CFG(GPIO27, AF1)
-#define GPIO28_LCD_DD5         MFP_CFG(GPIO28, AF1)
-#define GPIO29_LCD_DD6         MFP_CFG(GPIO29, AF1)
-#define GPIO30_LCD_DD7         MFP_CFG(GPIO30, AF1)
-#define GPIO31_LCD_DD8         MFP_CFG(GPIO31, AF1)
-#define GPIO32_LCD_DD9         MFP_CFG(GPIO32, AF1)
-#define GPIO33_LCD_DD10                MFP_CFG(GPIO33, AF1)
-#define GPIO34_LCD_DD11                MFP_CFG(GPIO34, AF1)
-#define GPIO35_LCD_DD12                MFP_CFG(GPIO35, AF1)
-#define GPIO36_LCD_DD13                MFP_CFG(GPIO36, AF1)
-#define GPIO37_LCD_DD14                MFP_CFG(GPIO37, AF1)
-#define GPIO38_LCD_DD15                MFP_CFG(GPIO38, AF1)
-#define GPIO39_LCD_DD16                MFP_CFG(GPIO39, AF1)
-#define GPIO40_LCD_DD17                MFP_CFG(GPIO40, AF1)
-#define GPIO41_LCD_CS2         MFP_CFG(GPIO41, AF3)
-#define GPIO42_LCD_VSYNC2      MFP_CFG(GPIO42, AF3)
-#define GPIO44_LCD_DD7         MFP_CFG(GPIO44, AF1)
-
-/* Mini-LCD */
-#define GPIO17_MLCD_FCLK       MFP_CFG(GPIO17, AF3)
-#define GPIO18_MLCD_LCLK       MFP_CFG(GPIO18, AF3)
-#define GPIO19_MLCD_PCLK       MFP_CFG(GPIO19, AF3)
-#define GPIO20_MLCD_BIAS       MFP_CFG(GPIO20, AF3)
-#define GPIO23_MLCD_DD0                MFP_CFG(GPIO23, AF3)
-#define GPIO24_MLCD_DD1                MFP_CFG(GPIO24, AF3)
-#define GPIO25_MLCD_DD2                MFP_CFG(GPIO25, AF3)
-#define GPIO26_MLCD_DD3                MFP_CFG(GPIO26, AF3)
-#define GPIO27_MLCD_DD4                MFP_CFG(GPIO27, AF3)
-#define GPIO28_MLCD_DD5                MFP_CFG(GPIO28, AF3)
-#define GPIO29_MLCD_DD6                MFP_CFG(GPIO29, AF3)
-#define GPIO30_MLCD_DD7                MFP_CFG(GPIO30, AF3)
-#define GPIO31_MLCD_DD8                MFP_CFG(GPIO31, AF3)
-#define GPIO32_MLCD_DD9                MFP_CFG(GPIO32, AF3)
-#define GPIO33_MLCD_DD10       MFP_CFG(GPIO33, AF3)
-#define GPIO34_MLCD_DD11       MFP_CFG(GPIO34, AF3)
-#define GPIO35_MLCD_DD12       MFP_CFG(GPIO35, AF3)
-#define GPIO36_MLCD_DD13       MFP_CFG(GPIO36, AF3)
-#define GPIO37_MLCD_DD14       MFP_CFG(GPIO37, AF3)
-#define GPIO38_MLCD_DD15       MFP_CFG(GPIO38, AF3)
-#define GPIO44_MLCD_DD7                MFP_CFG(GPIO44, AF5)
-
-/* MMC1 */
-#define GPIO10_MMC1_DAT3       MFP_CFG(GPIO10, AF4)
-#define GPIO11_MMC1_DAT2       MFP_CFG(GPIO11, AF4)
-#define GPIO12_MMC1_DAT1       MFP_CFG(GPIO12, AF4)
-#define GPIO13_MMC1_DAT0       MFP_CFG(GPIO13, AF4)
-#define GPIO14_MMC1_CMD                MFP_CFG(GPIO14, AF4)
-#define GPIO15_MMC1_CLK                MFP_CFG(GPIO15, AF4)
-#define GPIO55_MMC1_CMD                MFP_CFG(GPIO55, AF3)
-#define GPIO56_MMC1_CLK                MFP_CFG(GPIO56, AF3)
-#define GPIO57_MMC1_DAT0       MFP_CFG(GPIO57, AF3)
-#define GPIO58_MMC1_DAT1       MFP_CFG(GPIO58, AF3)
-#define GPIO59_MMC1_DAT2       MFP_CFG(GPIO59, AF3)
-#define GPIO60_MMC1_DAT3       MFP_CFG(GPIO60, AF3)
-
-#define DF_ADDR0_MMC1_CLK      MFP_CFG(DF_ADDR0, AF2)
-#define DF_ADDR1_MMC1_CMD      MFP_CFG(DF_ADDR1, AF2)
-#define DF_ADDR2_MMC1_DAT0     MFP_CFG(DF_ADDR2, AF2)
-#define DF_ADDR3_MMC1_DAT1     MFP_CFG(DF_ADDR3, AF3)
-#define nXCVREN_MMC1_DAT2      MFP_CFG(nXCVREN, AF2)
-
-/* MMC2 */
-#define GPIO31_MMC2_CMD                MFP_CFG(GPIO31, AF7)
-#define GPIO32_MMC2_CLK                MFP_CFG(GPIO32, AF7)
-#define GPIO33_MMC2_DAT0       MFP_CFG(GPIO33, AF7)
-#define GPIO34_MMC2_DAT1       MFP_CFG(GPIO34, AF7)
-#define GPIO35_MMC2_DAT2       MFP_CFG(GPIO35, AF7)
-#define GPIO36_MMC2_DAT3       MFP_CFG(GPIO36, AF7)
-
-#define GPIO101_MMC2_DAT3      MFP_CFG(GPIO101, AF1)
-#define GPIO102_MMC2_DAT2      MFP_CFG(GPIO102, AF1)
-#define GPIO103_MMC2_DAT1      MFP_CFG(GPIO103, AF1)
-#define GPIO104_MMC2_DAT0      MFP_CFG(GPIO104, AF1)
-#define GPIO105_MMC2_CMD       MFP_CFG(GPIO105, AF1)
-#define GPIO106_MMC2_CLK       MFP_CFG(GPIO106, AF1)
-
-#define DF_IO10_MMC2_DAT3      MFP_CFG(DF_IO10, AF3)
-#define DF_IO11_MMC2_DAT2      MFP_CFG(DF_IO11, AF3)
-#define DF_IO12_MMC2_DAT1      MFP_CFG(DF_IO12, AF3)
-#define DF_IO13_MMC2_DAT0      MFP_CFG(DF_IO13, AF3)
-#define DF_IO14_MMC2_CLK       MFP_CFG(DF_IO14, AF3)
-#define DF_IO15_MMC2_CMD       MFP_CFG(DF_IO15, AF3)
-
-/* BSSP1 */
-#define GPIO12_BSSP1_CLK       MFP_CFG(GPIO12, AF3)
-#define GPIO13_BSSP1_FRM       MFP_CFG(GPIO13, AF3)
-#define GPIO14_BSSP1_RXD       MFP_CFG(GPIO14, AF3)
-#define GPIO15_BSSP1_TXD       MFP_CFG(GPIO15, AF3)
-#define GPIO97_BSSP1_CLK       MFP_CFG(GPIO97, AF5)
-#define GPIO98_BSSP1_FRM       MFP_CFG(GPIO98, AF5)
-
-/* BSSP2 */
-#define GPIO84_BSSP2_SDATA_IN  MFP_CFG(GPIO84, AF1)
-#define GPIO85_BSSP2_BITCLK    MFP_CFG(GPIO85, AF1)
-#define GPIO86_BSSP2_SYSCLK    MFP_CFG(GPIO86, AF1)
-#define GPIO87_BSSP2_SYNC      MFP_CFG(GPIO87, AF1)
-#define GPIO88_BSSP2_DATA_OUT  MFP_CFG(GPIO88, AF1)
-#define GPIO86_BSSP2_SDATA_IN  MFP_CFG(GPIO86, AF4)
-
-/* BSSP3 */
-#define GPIO79_BSSP3_CLK       MFP_CFG(GPIO79, AF1)
-#define GPIO80_BSSP3_FRM       MFP_CFG(GPIO80, AF1)
-#define GPIO81_BSSP3_TXD       MFP_CFG(GPIO81, AF1)
-#define GPIO82_BSSP3_RXD       MFP_CFG(GPIO82, AF1)
-#define GPIO83_BSSP3_SYSCLK    MFP_CFG(GPIO83, AF1)
-
-/* BSSP4 */
-#define GPIO43_BSSP4_CLK       MFP_CFG(GPIO43, AF4)
-#define GPIO44_BSSP4_FRM       MFP_CFG(GPIO44, AF4)
-#define GPIO45_BSSP4_TXD       MFP_CFG(GPIO45, AF4)
-#define GPIO46_BSSP4_RXD       MFP_CFG(GPIO46, AF4)
-
-#define GPIO51_BSSP4_CLK       MFP_CFG(GPIO51, AF4)
-#define GPIO52_BSSP4_FRM       MFP_CFG(GPIO52, AF4)
-#define GPIO53_BSSP4_TXD       MFP_CFG(GPIO53, AF4)
-#define GPIO54_BSSP4_RXD       MFP_CFG(GPIO54, AF4)
-
-/* GSSP1 */
-#define GPIO79_GSSP1_CLK       MFP_CFG(GPIO79, AF2)
-#define GPIO80_GSSP1_FRM       MFP_CFG(GPIO80, AF2)
-#define GPIO81_GSSP1_TXD       MFP_CFG(GPIO81, AF2)
-#define GPIO82_GSSP1_RXD       MFP_CFG(GPIO82, AF2)
-#define GPIO83_GSSP1_SYSCLK    MFP_CFG(GPIO83, AF2)
-
-#define GPIO93_GSSP1_CLK       MFP_CFG(GPIO93, AF4)
-#define GPIO94_GSSP1_FRM       MFP_CFG(GPIO94, AF4)
-#define GPIO95_GSSP1_TXD       MFP_CFG(GPIO95, AF4)
-#define GPIO96_GSSP1_RXD       MFP_CFG(GPIO96, AF4)
-
-/* GSSP2 */
-#define GPIO47_GSSP2_CLK       MFP_CFG(GPIO47, AF4)
-#define GPIO48_GSSP2_FRM       MFP_CFG(GPIO48, AF4)
-#define GPIO49_GSSP2_RXD       MFP_CFG(GPIO49, AF4)
-#define GPIO50_GSSP2_TXD       MFP_CFG(GPIO50, AF4)
-
-#define GPIO69_GSSP2_CLK       MFP_CFG(GPIO69, AF4)
-#define GPIO70_GSSP2_FRM       MFP_CFG(GPIO70, AF4)
-#define GPIO71_GSSP2_RXD       MFP_CFG(GPIO71, AF4)
-#define GPIO72_GSSP2_TXD       MFP_CFG(GPIO72, AF4)
-
-#define GPIO84_GSSP2_RXD       MFP_CFG(GPIO84, AF2)
-#define GPIO85_GSSP2_CLK       MFP_CFG(GPIO85, AF2)
-#define GPIO86_GSSP2_SYSCLK    MFP_CFG(GPIO86, AF2)
-#define GPIO87_GSSP2_FRM       MFP_CFG(GPIO87, AF2)
-#define GPIO88_GSSP2_TXD       MFP_CFG(GPIO88, AF2)
-#define GPIO86_GSSP2_RXD       MFP_CFG(GPIO86, AF5)
-
-#define GPIO103_GSSP2_CLK      MFP_CFG(GPIO103, AF2)
-#define GPIO104_GSSP2_FRM      MFP_CFG(GPIO104, AF2)
-#define GPIO105_GSSP2_RXD      MFP_CFG(GPIO105, AF2)
-#define GPIO106_GSSP2_TXD      MFP_CFG(GPIO106, AF2)
-
-/* UART1 - FFUART */
-#define GPIO47_UART1_DSR_N     MFP_CFG(GPIO47, AF1)
-#define GPIO48_UART1_DTR_N     MFP_CFG(GPIO48, AF1)
-#define GPIO49_UART1_RI                MFP_CFG(GPIO49, AF1)
-#define GPIO50_UART1_DCD       MFP_CFG(GPIO50, AF1)
-#define GPIO51_UART1_CTS       MFP_CFG(GPIO51, AF1)
-#define GPIO52_UART1_RTS       MFP_CFG(GPIO52, AF1)
-#define GPIO53_UART1_RXD       MFP_CFG(GPIO53, AF1)
-#define GPIO54_UART1_TXD       MFP_CFG(GPIO54, AF1)
-
-#define GPIO63_UART1_TXD       MFP_CFG(GPIO63, AF2)
-#define GPIO64_UART1_RXD       MFP_CFG(GPIO64, AF2)
-#define GPIO65_UART1_DSR       MFP_CFG(GPIO65, AF2)
-#define GPIO66_UART1_DTR       MFP_CFG(GPIO66, AF2)
-#define GPIO67_UART1_RI                MFP_CFG(GPIO67, AF2)
-#define GPIO68_UART1_DCD       MFP_CFG(GPIO68, AF2)
-#define GPIO69_UART1_CTS       MFP_CFG(GPIO69, AF2)
-#define GPIO70_UART1_RTS       MFP_CFG(GPIO70, AF2)
-
-#define GPIO53_UART1_TXD       MFP_CFG(GPIO53, AF2)
-#define GPIO54_UART1_RXD       MFP_CFG(GPIO54, AF2)
-
-/* UART2 - BTUART */
-#define GPIO91_UART2_RXD       MFP_CFG(GPIO91, AF1)
-#define GPIO92_UART2_TXD       MFP_CFG(GPIO92, AF1)
-#define GPIO93_UART2_CTS       MFP_CFG(GPIO93, AF1)
-#define GPIO94_UART2_RTS       MFP_CFG(GPIO94, AF1)
-
-/* UART3 - STUART */
-#define GPIO43_UART3_RTS       MFP_CFG(GPIO43, AF3)
-#define GPIO44_UART3_CTS       MFP_CFG(GPIO44, AF3)
-#define GPIO45_UART3_RXD       MFP_CFG(GPIO45, AF3)
-#define GPIO46_UART3_TXD       MFP_CFG(GPIO46, AF3)
-
-#define GPIO75_UART3_RTS       MFP_CFG(GPIO75, AF5)
-#define GPIO76_UART3_CTS       MFP_CFG(GPIO76, AF5)
-#define GPIO77_UART3_TXD       MFP_CFG(GPIO77, AF5)
-#define GPIO78_UART3_RXD       MFP_CFG(GPIO78, AF5)
-
-/* DFI */
-#define DF_IO0_DF_IO0          MFP_CFG(DF_IO0, AF2)
-#define DF_IO1_DF_IO1          MFP_CFG(DF_IO1, AF2)
-#define DF_IO2_DF_IO2          MFP_CFG(DF_IO2, AF2)
-#define DF_IO3_DF_IO3          MFP_CFG(DF_IO3, AF2)
-#define DF_IO4_DF_IO4          MFP_CFG(DF_IO4, AF2)
-#define DF_IO5_DF_IO5          MFP_CFG(DF_IO5, AF2)
-#define DF_IO6_DF_IO6          MFP_CFG(DF_IO6, AF2)
-#define DF_IO7_DF_IO7          MFP_CFG(DF_IO7, AF2)
-#define DF_IO8_DF_IO8          MFP_CFG(DF_IO8, AF2)
-#define DF_IO9_DF_IO9          MFP_CFG(DF_IO9, AF2)
-#define DF_IO10_DF_IO10                MFP_CFG(DF_IO10, AF2)
-#define DF_IO11_DF_IO11                MFP_CFG(DF_IO11, AF2)
-#define DF_IO12_DF_IO12                MFP_CFG(DF_IO12, AF2)
-#define DF_IO13_DF_IO13                MFP_CFG(DF_IO13, AF2)
-#define DF_IO14_DF_IO14                MFP_CFG(DF_IO14, AF2)
-#define DF_IO15_DF_IO15                MFP_CFG(DF_IO15, AF2)
-#define DF_nADV1_ALE_DF_nADV1  MFP_CFG(DF_nADV1_ALE, AF2)
-#define DF_nADV2_ALE_DF_nADV2  MFP_CFG(DF_nADV2_ALE, AF2)
-#define DF_nCS0_DF_nCS0                MFP_CFG(DF_nCS0, AF2)
-#define DF_nCS1_DF_nCS1                MFP_CFG(DF_nCS1, AF2)
-#define DF_nRE_nOE_DF_nOE      MFP_CFG(DF_nRE_nOE, AF2)
-#define DF_nWE_DF_nWE          MFP_CFG(DF_nWE, AF2)
-
-/* DFI - NAND */
-#define DF_CLE_nOE_ND_CLE      MFP_CFG_LPM(DF_CLE_nOE, AF1, PULL_HIGH)
-#define DF_INT_RnB_ND_INT_RnB  MFP_CFG_LPM(DF_INT_RnB, AF1, PULL_LOW)
-#define DF_IO0_ND_IO0          MFP_CFG_LPM(DF_IO0, AF1, PULL_LOW)
-#define DF_IO1_ND_IO1          MFP_CFG_LPM(DF_IO1, AF1, PULL_LOW)
-#define DF_IO2_ND_IO2          MFP_CFG_LPM(DF_IO2, AF1, PULL_LOW)
-#define DF_IO3_ND_IO3          MFP_CFG_LPM(DF_IO3, AF1, PULL_LOW)
-#define DF_IO4_ND_IO4          MFP_CFG_LPM(DF_IO4, AF1, PULL_LOW)
-#define DF_IO5_ND_IO5          MFP_CFG_LPM(DF_IO5, AF1, PULL_LOW)
-#define DF_IO6_ND_IO6          MFP_CFG_LPM(DF_IO6, AF1, PULL_LOW)
-#define DF_IO7_ND_IO7          MFP_CFG_LPM(DF_IO7, AF1, PULL_LOW)
-#define DF_IO8_ND_IO8          MFP_CFG_LPM(DF_IO8, AF1, PULL_LOW)
-#define DF_IO9_ND_IO9          MFP_CFG_LPM(DF_IO9, AF1, PULL_LOW)
-#define DF_IO10_ND_IO10                MFP_CFG_LPM(DF_IO10, AF1, PULL_LOW)
-#define DF_IO11_ND_IO11                MFP_CFG_LPM(DF_IO11, AF1, PULL_LOW)
-#define DF_IO12_ND_IO12                MFP_CFG_LPM(DF_IO12, AF1, PULL_LOW)
-#define DF_IO13_ND_IO13                MFP_CFG_LPM(DF_IO13, AF1, PULL_LOW)
-#define DF_IO14_ND_IO14                MFP_CFG_LPM(DF_IO14, AF1, PULL_LOW)
-#define DF_IO15_ND_IO15                MFP_CFG_LPM(DF_IO15, AF1, PULL_LOW)
-#define DF_nADV1_ALE_ND_ALE    MFP_CFG_LPM(DF_nADV1_ALE, AF1, PULL_HIGH)
-#define DF_nADV2_ALE_ND_ALE    MFP_CFG_LPM(DF_nADV2_ALE, AF1, PULL_HIGH)
-#define        DF_nADV2_ALE_nCS3       MFP_CFG_LPM(DF_nADV2_ALE, AF3, PULL_HIGH)
-#define DF_nCS0_ND_nCS0                MFP_CFG_LPM(DF_nCS0, AF1, PULL_HIGH)
-#define DF_nCS1_ND_nCS1                MFP_CFG_LPM(DF_nCS1, AF1, PULL_HIGH)
-#define DF_nRE_nOE_ND_nRE      MFP_CFG_LPM(DF_nRE_nOE, AF1, PULL_HIGH)
-#define DF_nWE_ND_nWE          MFP_CFG_LPM(DF_nWE, AF1, PULL_HIGH)
-
-/* PWM */
-#define GPIO41_PWM0            MFP_CFG_LPM(GPIO41, AF1, PULL_LOW)
-#define GPIO42_PWM1            MFP_CFG_LPM(GPIO42, AF1, PULL_LOW)
-#define GPIO43_PWM3            MFP_CFG_LPM(GPIO43, AF1, PULL_LOW)
-#define GPIO20_PWM0            MFP_CFG_LPM(GPIO20, AF2, PULL_LOW)
-#define GPIO21_PWM2            MFP_CFG_LPM(GPIO21, AF3, PULL_LOW)
-#define GPIO22_PWM3            MFP_CFG_LPM(GPIO22, AF3, PULL_LOW)
-#define GPIO32_PWM0            MFP_CFG_LPM(GPIO32, AF4, PULL_LOW)
-
-/* CIR */
-#define GPIO46_CIR_OUT         MFP_CFG(GPIO46, AF1)
-#define GPIO77_CIR_OUT         MFP_CFG(GPIO77, AF3)
-
-/* USB P2 */
-#define GPIO0_USB_P2_7         MFP_CFG(GPIO0, AF3)
-#define GPIO15_USB_P2_7                MFP_CFG(GPIO15, AF5)
-#define GPIO16_USB_P2_7                MFP_CFG(GPIO16, AF2)
-#define GPIO48_USB_P2_7                MFP_CFG(GPIO48, AF7)
-#define GPIO49_USB_P2_7                MFP_CFG(GPIO49, AF6)
-#define DF_IO9_USB_P2_7                MFP_CFG(DF_IO9, AF3)
-
-#define GPIO48_USB_P2_8                MFP_CFG(GPIO48, AF2)
-#define GPIO50_USB_P2_7                MFP_CFG_X(GPIO50, AF2, DS02X, FLOAT)
-#define GPIO51_USB_P2_5                MFP_CFG(GPIO51, AF2)
-#define GPIO47_USB_P2_4                MFP_CFG(GPIO47, AF2)
-#define GPIO53_USB_P2_3                MFP_CFG(GPIO53, AF2)
-#define GPIO54_USB_P2_6                MFP_CFG(GPIO54, AF2)
-#define GPIO49_USB_P2_2                MFP_CFG(GPIO49, AF2)
-#define GPIO52_USB_P2_1                MFP_CFG(GPIO52, AF2)
-
-#define GPIO63_USB_P2_8                MFP_CFG(GPIO63, AF3)
-#define GPIO64_USB_P2_7                MFP_CFG(GPIO64, AF3)
-#define GPIO65_USB_P2_6                MFP_CFG(GPIO65, AF3)
-#define GPIO66_USG_P2_5                MFP_CFG(GPIO66, AF3)
-#define GPIO67_USB_P2_4                MFP_CFG(GPIO67, AF3)
-#define GPIO68_USB_P2_3                MFP_CFG(GPIO68, AF3)
-#define GPIO69_USB_P2_2                MFP_CFG(GPIO69, AF3)
-#define GPIO70_USB_P2_1                MFP_CFG(GPIO70, AF3)
-
-/* ULPI */
-#define GPIO31_USB_ULPI_D0     MFP_CFG(GPIO31, AF4)
-#define GPIO30_USB_ULPI_D1     MFP_CFG(GPIO30, AF7)
-#define GPIO33_USB_ULPI_D2     MFP_CFG(GPIO33, AF5)
-#define GPIO34_USB_ULPI_D3     MFP_CFG(GPIO34, AF5)
-#define GPIO35_USB_ULPI_D4     MFP_CFG(GPIO35, AF5)
-#define GPIO36_USB_ULPI_D5     MFP_CFG(GPIO36, AF5)
-#define GPIO41_USB_ULPI_D6     MFP_CFG(GPIO41, AF5)
-#define GPIO42_USB_ULPI_D7     MFP_CFG(GPIO42, AF5)
-#define GPIO37_USB_ULPI_DIR    MFP_CFG(GPIO37, AF4)
-#define GPIO38_USB_ULPI_CLK    MFP_CFG(GPIO38, AF4)
-#define GPIO39_USB_ULPI_STP    MFP_CFG(GPIO39, AF4)
-#define GPIO40_USB_ULPI_NXT    MFP_CFG(GPIO40, AF4)
-
-#define GPIO3_CLK26MOUTDMD     MFP_CFG(GPIO3, AF3)
-#define GPIO40_CLK26MOUTDMD    MFP_CFG(GPIO40, AF7)
-#define GPIO94_CLK26MOUTDMD    MFP_CFG(GPIO94, AF5)
-#define GPIO104_CLK26MOUTDMD   MFP_CFG(GPIO104, AF4)
-#define DF_ADDR1_CLK26MOUTDMD  MFP_CFG(DF_ADDR2, AF3)
-#define DF_ADDR3_CLK26MOUTDMD  MFP_CFG(DF_ADDR3, AF3)
-
-#define GPIO14_CLK26MOUT       MFP_CFG(GPIO14, AF5)
-#define GPIO38_CLK26MOUT       MFP_CFG(GPIO38, AF7)
-#define GPIO92_CLK26MOUT       MFP_CFG(GPIO92, AF5)
-#define GPIO105_CLK26MOUT      MFP_CFG(GPIO105, AF4)
-
-#define GPIO2_CLK13MOUTDMD     MFP_CFG(GPIO2, AF3)
-#define GPIO39_CLK13MOUTDMD    MFP_CFG(GPIO39, AF7)
-#define GPIO50_CLK13MOUTDMD    MFP_CFG(GPIO50, AF3)
-#define GPIO93_CLK13MOUTDMD    MFP_CFG(GPIO93, AF5)
-#define GPIO103_CLK13MOUTDMD   MFP_CFG(GPIO103, AF4)
-#define DF_ADDR2_CLK13MOUTDMD  MFP_CFG(DF_ADDR2, AF3)
-
-/* 1 wire */
-#define GPIO95_OW_DQ_IN                MFP_CFG(GPIO95, AF5)
-
-#endif /* __ASM_ARCH_MFP_PXA9xx_H */
diff --git a/arch/arm/mach-pxa/include/mach/mioa701.h b/arch/arm/mach-pxa/include/mach/mioa701.h
deleted file mode 100644 (file)
index e57f5c7..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef _MIOA701_H_
-#define _MIOA701_H_
-
-#define MIO_CFG_IN(pin, af)            \
-       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
-        (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN))
-
-#define MIO_CFG_OUT(pin, af, state)    \
-       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
-        (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
-
-/* Global GPIOs */
-#define GPIO9_CHARGE_EN                                9
-#define GPIO18_POWEROFF                                18
-#define GPIO87_LCD_POWER                       87
-#define GPIO96_AC_DETECT                       96
-#define GPIO80_MAYBE_CHARGE_VDROP              80      /* Drop of 88mV */
-
-/* USB */
-#define GPIO13_nUSB_DETECT                     13
-#define GPIO22_USB_ENABLE                      22
-
-/* SDIO bits */
-#define GPIO78_SDIO_RO                         78
-#define GPIO15_SDIO_INSERT                     15
-#define GPIO91_SDIO_EN                         91
-
-/* Bluetooth */
-#define GPIO14_BT_nACTIVITY                    14
-#define GPIO83_BT_ON                           83
-#define GPIO77_BT_UNKNOWN1                     77
-#define GPIO86_BT_MAYBE_nRESET                 86
-
-/* GPS */
-#define GPIO23_GPS_UNKNOWN1                    23
-#define GPIO26_GPS_ON                          26
-#define GPIO27_GPS_RESET                       27
-#define GPIO106_GPS_UNKNOWN2                   106
-#define GPIO107_GPS_UNKNOWN3                   107
-
-/* GSM */
-#define GPIO24_GSM_MOD_RESET_CMD               24
-#define GPIO88_GSM_nMOD_ON_CMD                 88
-#define GPIO90_GSM_nMOD_OFF_CMD                        90
-#define GPIO114_GSM_nMOD_DTE_UART_STATE        114
-#define GPIO25_GSM_MOD_ON_STATE                        25
-#define GPIO113_GSM_EVENT                      113
-
-/* SOUND */
-#define GPIO12_HPJACK_INSERT                   12
-
-/* LEDS */
-#define GPIO10_LED_nCharging                   10
-#define GPIO97_LED_nBlue                       97
-#define GPIO98_LED_nOrange                     98
-#define GPIO82_LED_nVibra                      82
-#define GPIO115_LED_nKeyboard                  115
-
-/* Keyboard */
-#define GPIO0_KEY_POWER                                0
-#define GPIO93_KEY_VOLUME_UP                   93
-#define GPIO94_KEY_VOLUME_DOWN                 94
-
-/* Camera */
-#define GPIO56_MT9M111_nOE                     56
-
-extern struct input_dev *mioa701_evdev;
-extern void mioa701_gpio_lpm_set(unsigned long mfp_pin);
-
-/* Assembler externals mioa701_bootresume.S */
-extern u32 mioa701_bootstrap;
-extern u32 mioa701_jumpaddr;
-extern u32 mioa701_bootstrap_lg;
-
-#endif /* _MIOA701_H */
diff --git a/arch/arm/mach-pxa/include/mach/mxm8x10.h b/arch/arm/mach-pxa/include/mach/mxm8x10.h
deleted file mode 100644 (file)
index ffa1566..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __MACH_MXM_8X10_H
-#define __MACH_MXM_8X10_H
-
-#define MXM_8X10_ETH_PHYS      0x13000000
-
-#if defined(CONFIG_MMC)
-
-#define MXM_8X10_SD_nCD (72)
-#define MXM_8X10_SD_WP (84)
-
-extern void mxm_8x10_mmc_init(void);
-#else
-static inline void mxm_8x10_mmc_init(void) {}
-#endif
-
-extern void mxm_8x10_usb_host_init(void);
-extern void mxm_8x10_ac97_init(void);
-
-extern void mxm_8x10_barebones_init(void);
-
-#endif /* __MACH_MXM_8X10_H */
diff --git a/arch/arm/mach-pxa/include/mach/palm27x.h b/arch/arm/mach-pxa/include/mach/palm27x.h
deleted file mode 100644 (file)
index d4eac3d..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Common functions for Palm LD, T5, TX, Z72
- *
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.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        __INCLUDE_MACH_PALM27X__
-#define        __INCLUDE_MACH_PALM27X__
-
-#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
-extern void __init palm27x_mmc_init(int detect, int ro, int power,
-                                       int power_inverted);
-#else
-static inline void palm27x_mmc_init(int detect, int ro, int power,
-                                       int power_inverted)
-{}
-#endif
-
-#if defined(CONFIG_SUSPEND)
-extern void __init palm27x_pm_init(unsigned long str_base);
-#else
-static inline void palm27x_pm_init(unsigned long str_base) {}
-#endif
-
-#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
-extern struct pxafb_mode_info palm_320x480_lcd_mode;
-extern struct pxafb_mode_info palm_320x320_lcd_mode;
-extern struct pxafb_mode_info palm_320x320_new_lcd_mode;
-extern void __init palm27x_lcd_init(int power,
-                                       struct pxafb_mode_info *mode);
-#else
-#define palm27x_lcd_init(power, mode)  do {} while (0)
-#endif
-
-#if    defined(CONFIG_USB_PXA27X) || \
-       defined(CONFIG_USB_PXA27X_MODULE)
-extern void __init palm27x_udc_init(int vbus, int pullup,
-                                       int vbus_inverted);
-#else
-static inline void palm27x_udc_init(int vbus, int pullup, int vbus_inverted) {}
-#endif
-
-#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
-extern void __init palm27x_irda_init(int pwdn);
-#else
-static inline void palm27x_irda_init(int pwdn) {}
-#endif
-
-#if    defined(CONFIG_TOUCHSCREEN_WM97XX) || \
-       defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE)
-extern void __init palm27x_ac97_init(int minv, int maxv, int jack,
-                                       int reset);
-#else
-static inline void palm27x_ac97_init(int minv, int maxv, int jack, int reset) {}
-#endif
-
-#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
-extern void __init palm27x_pwm_init(int bl, int lcd);
-#else
-static inline void palm27x_pwm_init(int bl, int lcd) {}
-#endif
-
-#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE)
-extern void __init palm27x_power_init(int ac, int usb);
-#else
-static inline void palm27x_power_init(int ac, int usb) {}
-#endif
-
-#if defined(CONFIG_REGULATOR_MAX1586) || \
-    defined(CONFIG_REGULATOR_MAX1586_MODULE)
-extern void __init palm27x_pmic_init(void);
-#else
-static inline void palm27x_pmic_init(void) {}
-#endif
-
-#endif /* __INCLUDE_MACH_PALM27X__ */
diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
deleted file mode 100644 (file)
index e342c59..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer
- *
- * Authors:    Ales Snuparek <snuparek@atlas.cz>
- *             Marek Vasut <marek.vasut@gmail.com>
- *             Justin Kendrick <twilightsentry@gmail.com>
- *             RichardT5 <richard_t5@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef _INCLUDE_PALMT5_H_
-#define _INCLUDE_PALMT5_H_
-
-#include "irqs.h" /* PXA_GPIO_TO_IRQ */
-
-/** HERE ARE GPIOs **/
-
-/* GPIOs */
-#define GPIO_NR_PALMT5_GPIO_RESET              1
-
-#define GPIO_NR_PALMT5_POWER_DETECT            90
-#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N                10
-#define GPIO_NR_PALMT5_EARPHONE_DETECT         107
-
-/* SD/MMC */
-#define GPIO_NR_PALMT5_SD_DETECT_N             14
-#define GPIO_NR_PALMT5_SD_POWER                        114
-#define GPIO_NR_PALMT5_SD_READONLY             115
-
-/* TOUCHSCREEN */
-#define GPIO_NR_PALMT5_WM9712_IRQ              27
-
-/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
-#define GPIO_NR_PALMT5_IR_DISABLE              40
-
-/* USB */
-#define GPIO_NR_PALMT5_USB_DETECT_N            15
-#define GPIO_NR_PALMT5_USB_PULLUP              93
-
-/* LCD/BACKLIGHT */
-#define GPIO_NR_PALMT5_BL_POWER                        84
-#define GPIO_NR_PALMT5_LCD_POWER               96
-
-/* BLUETOOTH */
-#define GPIO_NR_PALMT5_BT_POWER                        17
-#define GPIO_NR_PALMT5_BT_RESET                        83
-
-/* INTERRUPTS */
-#define IRQ_GPIO_PALMT5_SD_DETECT_N    PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N)
-#define IRQ_GPIO_PALMT5_WM9712_IRQ     PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ)
-#define IRQ_GPIO_PALMT5_USB_DETECT     PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT)
-#define IRQ_GPIO_PALMT5_GPIO_RESET     PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_GPIO_RESET)
-
-/** HERE ARE INIT VALUES **/
-
-/* Various addresses  */
-#define PALMT5_PHYS_RAM_START  0xa0000000
-#define PALMT5_PHYS_IO_START   0x40000000
-#define PALMT5_STR_BASE                0xa0200000
-
-/* TOUCHSCREEN */
-#define AC97_LINK_FRAME                21
-
-/* BATTERY */
-#define PALMT5_BAT_MAX_VOLTAGE         4000    /* 4.00v current voltage */
-#define PALMT5_BAT_MIN_VOLTAGE         3550    /* 3.55v critical voltage */
-#define PALMT5_BAT_MAX_CURRENT         0       /* unknown */
-#define PALMT5_BAT_MIN_CURRENT         0       /* unknown */
-#define PALMT5_BAT_MAX_CHARGE          1       /* unknown */
-#define PALMT5_BAT_MIN_CHARGE          1       /* unknown */
-#define PALMT5_MAX_LIFE_MINS           360    /* on-life in minutes */
-
-#define PALMT5_BAT_MEASURE_DELAY       (HZ * 1)
-
-/* BACKLIGHT */
-#define PALMT5_MAX_INTENSITY           0xFE
-#define PALMT5_DEFAULT_INTENSITY       0x7E
-#define PALMT5_LIMIT_MASK              0x7F
-#define PALMT5_PRESCALER               0x3F
-#define PALMT5_PERIOD_NS               3500
-
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h
deleted file mode 100644 (file)
index f89e989..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer
- *
- * Author:
- *             Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.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 _INCLUDE_PALMTE2_H_
-#define _INCLUDE_PALMTE2_H_
-
-/** HERE ARE GPIOs **/
-
-/* GPIOs */
-#define GPIO_NR_PALMTE2_POWER_DETECT           9
-#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N       4
-#define GPIO_NR_PALMTE2_EARPHONE_DETECT                15
-
-/* SD/MMC */
-#define GPIO_NR_PALMTE2_SD_DETECT_N            10
-#define GPIO_NR_PALMTE2_SD_POWER               55
-#define GPIO_NR_PALMTE2_SD_READONLY            51
-
-/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
-#define GPIO_NR_PALMTE2_IR_DISABLE             48
-
-/* USB */
-#define GPIO_NR_PALMTE2_USB_DETECT_N           35
-#define GPIO_NR_PALMTE2_USB_PULLUP             53
-
-/* LCD/BACKLIGHT */
-#define GPIO_NR_PALMTE2_BL_POWER               56
-#define GPIO_NR_PALMTE2_LCD_POWER              37
-
-/* KEYS */
-#define GPIO_NR_PALMTE2_KEY_NOTES      5
-#define GPIO_NR_PALMTE2_KEY_TASKS      7
-#define GPIO_NR_PALMTE2_KEY_CALENDAR   11
-#define GPIO_NR_PALMTE2_KEY_CONTACTS   13
-#define GPIO_NR_PALMTE2_KEY_CENTER     14
-#define GPIO_NR_PALMTE2_KEY_LEFT       19
-#define GPIO_NR_PALMTE2_KEY_RIGHT      20
-#define GPIO_NR_PALMTE2_KEY_DOWN       21
-#define GPIO_NR_PALMTE2_KEY_UP         22
-
-/** HERE ARE INIT VALUES **/
-
-/* BACKLIGHT */
-#define PALMTE2_MAX_INTENSITY          0xFE
-#define PALMTE2_DEFAULT_INTENSITY      0x7E
-#define PALMTE2_LIMIT_MASK             0x7F
-#define PALMTE2_PRESCALER              0x3F
-#define PALMTE2_PERIOD_NS              3500
-
-/* BATTERY */
-#define PALMTE2_BAT_MAX_VOLTAGE                4000    /* 4.00v current voltage */
-#define PALMTE2_BAT_MIN_VOLTAGE                3550    /* 3.55v critical voltage */
-#define PALMTE2_BAT_MAX_CURRENT                0       /* unknown */
-#define PALMTE2_BAT_MIN_CURRENT                0       /* unknown */
-#define PALMTE2_BAT_MAX_CHARGE         1       /* unknown */
-#define PALMTE2_BAT_MIN_CHARGE         1       /* unknown */
-#define PALMTE2_MAX_LIFE_MINS          360     /* on-life in minutes */
-
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmtreo.h b/arch/arm/mach-pxa/include/mach/palmtreo.h
deleted file mode 100644 (file)
index 714b657..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * GPIOs and interrupts for Palm Treo smartphones
- *
- * currently supported:
- *     Palm Treo 680 (GSM)
- *     Palm Centro 685 (GSM)
- *
- * Author:     Tomas Cech <sleep_walker@suse.cz>
- *
- * 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.
- *
- * find more info at www.hackndev.com
- *
- */
-
-#ifndef _INCLUDE_TREO_H_
-#define _INCLUDE_TREO_H_
-
-/* GPIOs */
-#define GPIO_NR_TREO_POWER_DETECT      0
-#define GPIO_NR_TREO_AMP_EN            27
-#define GPIO_NR_TREO_GREEN_LED 20
-#define GPIO_NR_TREO_RED_LED           79
-#define GPIO_NR_TREO_SD_DETECT_N       113
-#define GPIO_NR_TREO_EP_DETECT_N       116
-#define GPIO_NR_TREO_USB_DETECT        1
-#define GPIO_NR_TREO_USB_PULLUP        114
-#define GPIO_NR_TREO_GSM_POWER 40
-#define GPIO_NR_TREO_GSM_RESET 87
-#define GPIO_NR_TREO_GSM_WAKE  57
-#define GPIO_NR_TREO_GSM_HOST_WAKE     14
-#define GPIO_NR_TREO_GSM_TRIGGER       10
-#define GPIO_NR_TREO_IR_EN             115
-#define GPIO_NR_TREO_IR_TXD            47
-#define GPIO_NR_TREO_BL_POWER  38
-#define GPIO_NR_TREO_LCD_POWER 25
-
-/* Treo680 specific GPIOs */
-#define GPIO_NR_TREO680_SD_READONLY    33
-#define GPIO_NR_TREO680_SD_POWER       42
-#define GPIO_NR_TREO680_VIBRATE_EN     44
-#define GPIO_NR_TREO680_KEYB_BL                24
-#define GPIO_NR_TREO680_BT_EN          43
-#define GPIO_NR_TREO680_LCD_POWER      77
-#define GPIO_NR_TREO680_LCD_EN         86
-#define GPIO_NR_TREO680_LCD_EN_N       25
-
-/* Centro685 specific GPIOs */
-#define GPIO_NR_CENTRO_SD_POWER                21
-#define GPIO_NR_CENTRO_VIBRATE_EN      22
-#define GPIO_NR_CENTRO_KEYB_BL         33
-#define GPIO_NR_CENTRO_BT_EN           80
-
-/* Various addresses  */
-#define TREO_PHYS_RAM_START    0xa0000000
-#define TREO_PHYS_IO_START     0x40000000
-#define TREO_STR_BASE  0xa2000000
-
-/* BACKLIGHT */
-#define TREO_MAX_INTENSITY             254
-#define TREO_DEFAULT_INTENSITY 160
-#define TREO_LIMIT_MASK                0x7F
-#define TREO_PRESCALER         63
-#define TREO_PERIOD_NS         3500
-
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
deleted file mode 100644 (file)
index 0d4700a..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * GPIOs and interrupts for Palm Zire72 Handheld Computer
- *
- * Authors:    Alex Osborne <bobofdoom@gmail.com>
- *             Jan Herman <2hp@seznam.cz>
- *             Sergey Lapin <slapin@ossfans.org>
- *
- * 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 _INCLUDE_PALMZ72_H_
-#define _INCLUDE_PALMZ72_H_
-
-/* Power and control */
-#define GPIO_NR_PALMZ72_GPIO_RESET             1
-#define GPIO_NR_PALMZ72_POWER_DETECT           0
-
-/* SD/MMC */
-#define GPIO_NR_PALMZ72_SD_DETECT_N            14
-#define GPIO_NR_PALMZ72_SD_POWER_N             98
-#define GPIO_NR_PALMZ72_SD_RO                  115
-
-/* Touchscreen */
-#define GPIO_NR_PALMZ72_WM9712_IRQ             27
-
-/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
-#define GPIO_NR_PALMZ72_IR_DISABLE             49
-
-/* USB */
-#define GPIO_NR_PALMZ72_USB_DETECT_N           15
-#define GPIO_NR_PALMZ72_USB_PULLUP             95
-
-/* LCD/Backlight */
-#define GPIO_NR_PALMZ72_BL_POWER               20
-#define GPIO_NR_PALMZ72_LCD_POWER              96
-
-/* LED */
-#define GPIO_NR_PALMZ72_LED_GREEN              88
-
-/* Bluetooth */
-#define GPIO_NR_PALMZ72_BT_POWER               17
-#define GPIO_NR_PALMZ72_BT_RESET               83
-
-/* Camera */
-#define GPIO_NR_PALMZ72_CAM_PWDN               56
-#define GPIO_NR_PALMZ72_CAM_RESET              57
-#define GPIO_NR_PALMZ72_CAM_POWER              91
-
-/** Initial values **/
-
-/* Battery */
-#define PALMZ72_BAT_MAX_VOLTAGE                4000    /* 4.00v current voltage */
-#define PALMZ72_BAT_MIN_VOLTAGE                3550    /* 3.55v critical voltage */
-#define PALMZ72_BAT_MAX_CURRENT                0       /* unknown */
-#define PALMZ72_BAT_MIN_CURRENT                0       /* unknown */
-#define PALMZ72_BAT_MAX_CHARGE         1       /* unknown */
-#define PALMZ72_BAT_MIN_CHARGE         1       /* unknown */
-#define PALMZ72_MAX_LIFE_MINS          360     /* on-life in minutes */
-
-/* Backlight */
-#define PALMZ72_MAX_INTENSITY          0xFE
-#define PALMZ72_DEFAULT_INTENSITY      0x7E
-#define PALMZ72_LIMIT_MASK             0x7F
-#define PALMZ72_PRESCALER              0x3F
-#define PALMZ72_PERIOD_NS              3500
-
-#ifdef CONFIG_PM
-struct palmz72_resume_info {
-       u32 magic0;             /* 0x0 */
-       u32 magic1;             /* 0x4 */
-       u32 resume_addr;        /* 0x8 */
-       u32 pad[11];            /* 0xc..0x37 */
-       u32 arm_control;        /* 0x38 */
-       u32 aux_control;        /* 0x3c */
-       u32 ttb;                /* 0x40 */
-       u32 domain_access;      /* 0x44 */
-       u32 process_id;         /* 0x48 */
-};
-#endif
-#endif
-
diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
deleted file mode 100644 (file)
index 86ebd7b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/pcm027.h
- *
- * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
- * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
- *
- * This program is free software; 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
- */
-
-/*
- * Definitions of CPU card resources only
- */
-
-#include "irqs.h" /* PXA_GPIO_TO_IRQ */
-
-/* phyCORE-PXA270 (PCM027) Interrupts */
-#define PCM027_IRQ(x)          (IRQ_BOARD_START + (x))
-#define PCM027_BTDET_IRQ       PCM027_IRQ(0)
-#define PCM027_FF_RI_IRQ       PCM027_IRQ(1)
-#define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
-#define PCM027_PM_5V_IRQ       PCM027_IRQ(3)
-
-#define PCM027_NR_IRQS         (IRQ_BOARD_START + 32)
-
-/* I2C RTC */
-#define PCM027_RTC_IRQ_GPIO    0
-#define PCM027_RTC_IRQ         PXA_GPIO_TO_IRQ(PCM027_RTC_IRQ_GPIO)
-#define PCM027_RTC_IRQ_EDGE    IRQ_TYPE_EDGE_FALLING
-#define ADR_PCM027_RTC         0x51    /* I2C address */
-
-/* I2C EEPROM */
-#define ADR_PCM027_EEPROM      0x54    /* I2C address */
-
-/* Ethernet chip (SMSC91C111) */
-#define PCM027_ETH_IRQ_GPIO    52
-#define PCM027_ETH_IRQ         PXA_GPIO_TO_IRQ(PCM027_ETH_IRQ_GPIO)
-#define PCM027_ETH_IRQ_EDGE    IRQ_TYPE_EDGE_RISING
-#define PCM027_ETH_PHYS                PXA_CS5_PHYS
-#define PCM027_ETH_SIZE                (1*1024*1024)
-
-/* CAN controller SJA1000 (unsupported yet) */
-#define PCM027_CAN_IRQ_GPIO    114
-#define PCM027_CAN_IRQ         PXA_GPIO_TO_IRQ(PCM027_CAN_IRQ_GPIO)
-#define PCM027_CAN_IRQ_EDGE    IRQ_TYPE_EDGE_FALLING
-#define PCM027_CAN_PHYS                0x22000000
-#define PCM027_CAN_SIZE                0x100
-
-/* SPI GPIO expander (unsupported yet) */
-#define PCM027_EGPIO_IRQ_GPIO  27
-#define PCM027_EGPIO_IRQ       PXA_GPIO_TO_IRQ(PCM027_EGPIO_IRQ_GPIO)
-#define PCM027_EGPIO_IRQ_EDGE  IRQ_TYPE_EDGE_FALLING
-#define PCM027_EGPIO_CS                24
-/*
- * TODO: Switch this pin from dedicated usage to GPIO if
- * more than the MAX7301 device is connected to this SPI bus
- */
-#define PCM027_EGPIO_CS_MODE   GPIO24_SFRM_MD
-
-/* Flash memory */
-#define PCM027_FLASH_PHYS      0x00000000
-#define PCM027_FLASH_SIZE      0x02000000
-
-/* onboard LEDs connected to GPIO */
-#define PCM027_LED_CPU         90
-#define PCM027_LED_HEARD_BEAT  91
-
-/*
- * This CPU module needs a baseboard to work. After basic initializing
- * its own devices, it calls baseboard's init function.
- * TODO: Add your own basebaord init function and call it from
- * inside pcm027_init(). This example here is for the developmen board.
- * Refer pcm990-baseboard.c
- */
-extern void pcm990_baseboard_init(void);
diff --git a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
deleted file mode 100644 (file)
index 7e544c1..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
- *
- * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
- * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <mach/pcm027.h>
-#include "irqs.h" /* PXA_GPIO_TO_IRQ */
-
-/*
- * definitions relevant only when the PCM-990
- * development base board is in use
- */
-
-/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
-#define PCM990_CTRL_INT_IRQ_GPIO       9
-#define PCM990_CTRL_INT_IRQ            PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO)
-#define PCM990_CTRL_INT_IRQ_EDGE       IRQ_TYPE_EDGE_RISING
-#define PCM990_CTRL_PHYS               PXA_CS1_PHYS    /* 16-Bit */
-#define PCM990_CTRL_SIZE               (1*1024*1024)
-
-#define PCM990_CTRL_PWR_IRQ_GPIO       14
-#define PCM990_CTRL_PWR_IRQ            PXA_GPIO_TO_IRQ(PCM990_CTRL_PWR_IRQ_GPIO)
-#define PCM990_CTRL_PWR_IRQ_EDGE       IRQ_TYPE_EDGE_RISING
-
-/* visible CPLD (U7) registers */
-#define PCM990_CTRL_REG0       0x0000  /* RESET REGISTER */
-#define PCM990_CTRL_SYSRES     0x0001  /* System RESET REGISTER */
-#define PCM990_CTRL_RESOUT     0x0002  /* RESETOUT Enable REGISTER */
-#define PCM990_CTRL_RESGPIO    0x0004  /* RESETGPIO Enable REGISTER */
-
-#define PCM990_CTRL_REG1       0x0002  /* Power REGISTER */
-#define PCM990_CTRL_5VOFF      0x0001  /* Disable  5V Regulators */
-#define PCM990_CTRL_CANPWR     0x0004  /* Enable CANPWR ADUM */
-#define PCM990_CTRL_PM_5V      0x0008  /* Read 5V OK */
-
-#define PCM990_CTRL_REG2       0x0004  /* LED REGISTER */
-#define PCM990_CTRL_LEDPWR     0x0001  /* POWER LED enable */
-#define PCM990_CTRL_LEDBAS     0x0002  /* BASIS LED enable */
-#define PCM990_CTRL_LEDUSR     0x0004  /* USER LED enable */
-
-#define PCM990_CTRL_REG3       0x0006  /* LCD CTRL REGISTER 3 */
-#define PCM990_CTRL_LCDPWR     0x0001  /* RW LCD Power on */
-#define PCM990_CTRL_LCDON      0x0002  /* RW LCD Latch on */
-#define PCM990_CTRL_LCDPOS1    0x0004  /* RW POS 1 */
-#define PCM990_CTRL_LCDPOS2    0x0008  /* RW POS 2 */
-
-#define PCM990_CTRL_REG4       0x0008  /* MMC1 CTRL REGISTER 4 */
-#define PCM990_CTRL_MMC1PWR    0x0001 /* RW MMC1 Power on */
-
-#define PCM990_CTRL_REG5       0x000A  /* MMC2 CTRL REGISTER 5 */
-#define PCM990_CTRL_MMC2PWR    0x0001  /* RW MMC2 Power on */
-#define PCM990_CTRL_MMC2LED    0x0002  /* RW MMC2 LED */
-#define PCM990_CTRL_MMC2DE     0x0004  /* R MMC2 Card detect */
-#define PCM990_CTRL_MMC2WP     0x0008  /* R MMC2 Card write protect */
-
-#define PCM990_CTRL_INTSETCLR  0x000C  /* Interrupt Clear REGISTER */
-#define PCM990_CTRL_INTC0      0x0001  /* Clear Reg BT Detect */
-#define PCM990_CTRL_INTC1      0x0002  /* Clear Reg FR RI */
-#define PCM990_CTRL_INTC2      0x0004  /* Clear Reg MMC1 Detect */
-#define PCM990_CTRL_INTC3      0x0008  /* Clear Reg PM_5V off */
-
-#define PCM990_CTRL_INTMSKENA  0x000E  /* Interrupt Enable REGISTER */
-#define PCM990_CTRL_ENAINT0    0x0001  /* Enable Int BT Detect */
-#define PCM990_CTRL_ENAINT1    0x0002  /* Enable Int FR RI */
-#define PCM990_CTRL_ENAINT2    0x0004  /* Enable Int MMC1 Detect */
-#define PCM990_CTRL_ENAINT3    0x0008  /* Enable Int PM_5V off */
-
-#define PCM990_CTRL_REG8       0x0014  /* Uart REGISTER */
-#define PCM990_CTRL_FFSD       0x0001  /* BT Uart Enable */
-#define PCM990_CTRL_BTSD       0x0002  /* FF Uart Enable */
-#define PCM990_CTRL_FFRI       0x0004  /* FF Uart RI detect */
-#define PCM990_CTRL_BTRX       0x0008  /* BT Uart Rx detect */
-
-#define PCM990_CTRL_REG9       0x0010  /* AC97 Flash REGISTER */
-#define PCM990_CTRL_FLWP       0x0001  /* pC Flash Write Protect */
-#define PCM990_CTRL_FLDIS      0x0002  /* pC Flash Disable */
-#define PCM990_CTRL_AC97ENA    0x0004  /* Enable AC97 Expansion */
-
-#define PCM990_CTRL_REG10      0x0012  /* GPS-REGISTER */
-#define PCM990_CTRL_GPSPWR     0x0004  /* GPS-Modul Power on */
-#define PCM990_CTRL_GPSENA     0x0008  /* GPS-Modul Enable */
-
-#define PCM990_CTRL_REG11      0x0014  /* Accu REGISTER */
-#define PCM990_CTRL_ACENA      0x0001  /* Charge Enable */
-#define PCM990_CTRL_ACSEL      0x0002  /* Charge Akku -> DC Enable */
-#define PCM990_CTRL_ACPRES     0x0004  /* DC Present */
-#define PCM990_CTRL_ACALARM    0x0008  /* Error Akku */
-
-/*
- * IDE
- */
-#define PCM990_IDE_IRQ_GPIO    13
-#define PCM990_IDE_IRQ         PXA_GPIO_TO_IRQ(PCM990_IDE_IRQ_GPIO)
-#define PCM990_IDE_IRQ_EDGE    IRQ_TYPE_EDGE_RISING
-#define PCM990_IDE_PLD_PHYS    0x20000000      /* 16 bit wide */
-#define PCM990_IDE_PLD_BASE    0xee000000
-#define PCM990_IDE_PLD_SIZE    (1*1024*1024)
-
-/* visible CPLD (U6) registers */
-#define PCM990_IDE_PLD_REG0    0x1000  /* OFFSET IDE REGISTER 0 */
-#define PCM990_IDE_PM5V                0x0004  /* R System VCC_5V */
-#define PCM990_IDE_STBY                0x0008  /* R System StandBy */
-
-#define PCM990_IDE_PLD_REG1    0x1002  /* OFFSET IDE REGISTER 1 */
-#define PCM990_IDE_IDEMODE     0x0001  /* R TrueIDE Mode */
-#define PCM990_IDE_DMAENA      0x0004  /* RW DMA Enable */
-#define PCM990_IDE_DMA1_0      0x0008  /* RW 1=DREQ1 0=DREQ0 */
-
-#define PCM990_IDE_PLD_REG2    0x1004  /* OFFSET IDE REGISTER 2 */
-#define PCM990_IDE_RESENA      0x0001  /* RW IDE Reset Bit enable */
-#define PCM990_IDE_RES         0x0002  /* RW IDE Reset Bit */
-#define PCM990_IDE_RDY         0x0008  /* RDY */
-
-#define PCM990_IDE_PLD_REG3    0x1006  /* OFFSET IDE REGISTER 3 */
-#define PCM990_IDE_IDEOE       0x0001  /* RW Latch on Databus */
-#define PCM990_IDE_IDEON       0x0002  /* RW Latch on Control Address */
-#define PCM990_IDE_IDEIN       0x0004  /* RW Latch on Interrupt usw. */
-
-#define PCM990_IDE_PLD_REG4    0x1008  /* OFFSET IDE REGISTER 4 */
-#define PCM990_IDE_PWRENA      0x0001  /* RW IDE Power enable */
-#define PCM990_IDE_5V          0x0002  /* R IDE Power 5V */
-#define PCM990_IDE_PWG         0x0008  /* R IDE Power is on */
-
-#define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
-#define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)
-
-/*
- * Compact Flash
- */
-#define PCM990_CF_IRQ_GPIO     11
-#define PCM990_CF_IRQ          PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO)
-#define PCM990_CF_IRQ_EDGE     IRQ_TYPE_EDGE_RISING
-
-#define PCM990_CF_CD_GPIO      12
-#define PCM990_CF_CD           PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO)
-#define PCM990_CF_CD_EDGE      IRQ_TYPE_EDGE_RISING
-
-#define PCM990_CF_PLD_PHYS     0x30000000      /* 16 bit wide */
-
-/* visible CPLD (U6) registers */
-#define PCM990_CF_PLD_REG0     0x1000  /* OFFSET CF REGISTER 0 */
-#define PCM990_CF_REG0_LED     0x0001  /* RW LED on */
-#define PCM990_CF_REG0_BLK     0x0002  /* RW LED flash when access */
-#define PCM990_CF_REG0_PM5V    0x0004  /* R System VCC_5V enable */
-#define PCM990_CF_REG0_STBY    0x0008  /* R System StandBy */
-
-#define PCM990_CF_PLD_REG1     0x1002  /* OFFSET CF REGISTER 1 */
-#define PCM990_CF_REG1_IDEMODE 0x0001  /* RW CF card run as TrueIDE */
-#define PCM990_CF_REG1_CF0     0x0002  /* RW CF card at ADDR 0x28000000 */
-
-#define PCM990_CF_PLD_REG2     0x1004  /* OFFSET CF REGISTER 2 */
-#define PCM990_CF_REG2_RES     0x0002  /* RW CF RESET BIT */
-#define PCM990_CF_REG2_RDYENA  0x0004  /* RW Enable CF_RDY */
-#define PCM990_CF_REG2_RDY     0x0008  /* R CF_RDY auf PWAIT */
-
-#define PCM990_CF_PLD_REG3     0x1006  /* OFFSET CF REGISTER 3 */
-#define PCM990_CF_REG3_CFOE    0x0001  /* RW Latch on Databus */
-#define PCM990_CF_REG3_CFON    0x0002  /* RW Latch on Control Address */
-#define PCM990_CF_REG3_CFIN    0x0004  /* RW Latch on Interrupt usw. */
-#define PCM990_CF_REG3_CFCD    0x0008  /* RW Latch on CD1/2 VS1/2 usw */
-
-#define PCM990_CF_PLD_REG4     0x1008  /* OFFSET CF REGISTER 4 */
-#define PCM990_CF_REG4_PWRENA  0x0001  /* RW CF Power on (CD1/2 = "00") */
-#define PCM990_CF_REG4_5_3V    0x0002  /* RW 1 = 5V CF_VCC 0 = 3 V CF_VCC */
-#define PCM990_CF_REG4_3B      0x0004  /* RW 3.0V Backup from VCC (5_3V=0) */
-#define PCM990_CF_REG4_PWG     0x0008  /* R CF-Power is on */
-
-#define PCM990_CF_PLD_REG5     0x100A  /* OFFSET CF REGISTER 5 */
-#define PCM990_CF_REG5_BVD1    0x0001  /* R CF /BVD1 */
-#define PCM990_CF_REG5_BVD2    0x0002  /* R CF /BVD2 */
-#define PCM990_CF_REG5_VS1     0x0004  /* R CF /VS1 */
-#define PCM990_CF_REG5_VS2     0x0008  /* R CF /VS2 */
-
-#define PCM990_CF_PLD_REG6     0x100C  /* OFFSET CF REGISTER 6 */
-#define PCM990_CF_REG6_CD1     0x0001  /* R CF Card_Detect1 */
-#define PCM990_CF_REG6_CD2     0x0002  /* R CF Card_Detect2 */
-
-/*
- * Wolfson AC97 Touch
- */
-#define PCM990_AC97_IRQ_GPIO   10
-#define PCM990_AC97_IRQ                PXA_GPIO_TO_IRQ(PCM990_AC97_IRQ_GPIO)
-#define PCM990_AC97_IRQ_EDGE   IRQ_TYPE_EDGE_RISING
-
-/*
- * MMC phyCORE
- */
-#define PCM990_MMC0_IRQ_GPIO   9
-#define PCM990_MMC0_IRQ                PXA_GPIO_TO_IRQ(PCM990_MMC0_IRQ_GPIO)
-#define PCM990_MMC0_IRQ_EDGE   IRQ_TYPE_EDGE_FALLING
-
-/*
- * USB phyCore
- */
-#define PCM990_USB_OVERCURRENT (88 | GPIO_ALT_FN_1_IN)
-#define PCM990_USB_PWR_EN (89 | GPIO_ALT_FN_2_OUT)
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h
deleted file mode 100644 (file)
index 51558bc..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2005 Richard Purdie
- *
- * 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/suspend.h>
-
-struct pxa_cpu_pm_fns {
-       int     save_count;
-       void    (*save)(unsigned long *);
-       void    (*restore)(unsigned long *);
-       int     (*valid)(suspend_state_t state);
-       void    (*enter)(suspend_state_t state);
-       int     (*prepare)(void);
-       void    (*finish)(void);
-};
-
-extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
-
-/* sleep.S */
-extern int pxa25x_finish_suspend(unsigned long);
-extern int pxa27x_finish_suspend(unsigned long);
-
-extern int pxa_pm_enter(suspend_state_t state);
-extern int pxa_pm_prepare(void);
-extern void pxa_pm_finish(void);
-
-/* NOTE: this is for PM debugging on Lubbock,  it's really a big
- * ugly, but let's keep the crap minimum here, instead of direct
- * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c
- */
-#ifdef CONFIG_ARCH_LUBBOCK
-extern void lubbock_set_hexled(uint32_t value);
-#else
-#define lubbock_set_hexled(x)
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h
deleted file mode 100644 (file)
index 5a34175..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __MACH_PXA25x_H
-#define __MACH_PXA25x_H
-
-#include <mach/hardware.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/irqs.h>
-
-#endif /* __MACH_PXA25x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x-udc.h b/arch/arm/mach-pxa/include/mach/pxa27x-udc.h
deleted file mode 100644 (file)
index 4cf28f6..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-#ifndef _ASM_ARCH_PXA27X_UDC_H
-#define _ASM_ARCH_PXA27X_UDC_H
-
-#ifdef _ASM_ARCH_PXA25X_UDC_H
-#error You cannot include both PXA25x and PXA27x UDC support
-#endif
-
-#define UDCCR           __REG(0x40600000) /* UDC Control Register */
-#define UDCCR_OEN      (1 << 31)       /* On-the-Go Enable */
-#define UDCCR_AALTHNP  (1 << 30)       /* A-device Alternate Host Negotiation
-                                          Protocol Port Support */
-#define UDCCR_AHNP     (1 << 29)       /* A-device Host Negotiation Protocol
-                                          Support */
-#define UDCCR_BHNP     (1 << 28)       /* B-device Host Negotiation Protocol
-                                          Enable */
-#define UDCCR_DWRE     (1 << 16)       /* Device Remote Wake-up Enable */
-#define UDCCR_ACN      (0x03 << 11)    /* Active UDC configuration Number */
-#define UDCCR_ACN_S    11
-#define UDCCR_AIN      (0x07 << 8)     /* Active UDC interface Number */
-#define UDCCR_AIN_S    8
-#define UDCCR_AAISN    (0x07 << 5)     /* Active UDC Alternate Interface
-                                          Setting Number */
-#define UDCCR_AAISN_S  5
-#define UDCCR_SMAC     (1 << 4)        /* Switch Endpoint Memory to Active
-                                          Configuration */
-#define UDCCR_EMCE     (1 << 3)        /* Endpoint Memory Configuration
-                                          Error */
-#define UDCCR_UDR      (1 << 2)        /* UDC Resume */
-#define UDCCR_UDA      (1 << 1)        /* UDC Active */
-#define UDCCR_UDE      (1 << 0)        /* UDC Enable */
-
-#define UDCICR0         __REG(0x40600004) /* UDC Interrupt Control Register0 */
-#define UDCICR1         __REG(0x40600008) /* UDC Interrupt Control Register1 */
-#define UDCICR_FIFOERR (1 << 1)        /* FIFO Error interrupt for EP */
-#define UDCICR_PKTCOMPL (1 << 0)       /* Packet Complete interrupt for EP */
-
-#define UDC_INT_FIFOERROR  (0x2)
-#define UDC_INT_PACKETCMP  (0x1)
-
-#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
-#define UDCICR1_IECC   (1 << 31)       /* IntEn - Configuration Change */
-#define UDCICR1_IESOF  (1 << 30)       /* IntEn - Start of Frame */
-#define UDCICR1_IERU   (1 << 29)       /* IntEn - Resume */
-#define UDCICR1_IESU   (1 << 28)       /* IntEn - Suspend */
-#define UDCICR1_IERS   (1 << 27)       /* IntEn - Reset */
-
-#define UDCISR0         __REG(0x4060000C) /* UDC Interrupt Status Register 0 */
-#define UDCISR1         __REG(0x40600010) /* UDC Interrupt Status Register 1 */
-#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
-#define UDCISR1_IRCC   (1 << 31)       /* IntReq - Configuration Change */
-#define UDCISR1_IRSOF  (1 << 30)       /* IntReq - Start of Frame */
-#define UDCISR1_IRRU   (1 << 29)       /* IntReq - Resume */
-#define UDCISR1_IRSU   (1 << 28)       /* IntReq - Suspend */
-#define UDCISR1_IRRS   (1 << 27)       /* IntReq - Reset */
-
-#define UDCFNR          __REG(0x40600014) /* UDC Frame Number Register */
-#define UDCOTGICR      __REG(0x40600018) /* UDC On-The-Go interrupt control */
-#define UDCOTGICR_IESF (1 << 24)       /* OTG SET_FEATURE command recvd */
-#define UDCOTGICR_IEXR (1 << 17)       /* Extra Transceiver Interrupt
-                                          Rising Edge Interrupt Enable */
-#define UDCOTGICR_IEXF (1 << 16)       /* Extra Transceiver Interrupt
-                                          Falling Edge Interrupt Enable */
-#define UDCOTGICR_IEVV40R (1 << 9)     /* OTG Vbus Valid 4.0V Rising Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IEVV40F (1 << 8)     /* OTG Vbus Valid 4.0V Falling Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IEVV44R (1 << 7)     /* OTG Vbus Valid 4.4V Rising Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IEVV44F (1 << 6)     /* OTG Vbus Valid 4.4V Falling Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IESVR        (1 << 5)        /* OTG Session Valid Rising Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IESVF        (1 << 4)        /* OTG Session Valid Falling Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IESDR        (1 << 3)        /* OTG A-Device SRP Detect Rising
-                                          Edge Interrupt Enable */
-#define UDCOTGICR_IESDF        (1 << 2)        /* OTG A-Device SRP Detect Falling
-                                          Edge Interrupt Enable */
-#define UDCOTGICR_IEIDR        (1 << 1)        /* OTG ID Change Rising Edge
-                                          Interrupt Enable */
-#define UDCOTGICR_IEIDF        (1 << 0)        /* OTG ID Change Falling Edge
-                                          Interrupt Enable */
-
-#define UP2OCR           __REG(0x40600020)  /* USB Port 2 Output Control register */
-#define UP3OCR           __REG(0x40600024)  /* USB Port 2 Output Control register */
-
-#define UP2OCR_CPVEN   (1 << 0)        /* Charge Pump Vbus Enable */
-#define UP2OCR_CPVPE   (1 << 1)        /* Charge Pump Vbus Pulse Enable */
-#define UP2OCR_DPPDE   (1 << 2)        /* Host Port 2 Transceiver D+ Pull Down Enable */
-#define UP2OCR_DMPDE   (1 << 3)        /* Host Port 2 Transceiver D- Pull Down Enable */
-#define UP2OCR_DPPUE   (1 << 4)        /* Host Port 2 Transceiver D+ Pull Up Enable */
-#define UP2OCR_DMPUE   (1 << 5)        /* Host Port 2 Transceiver D- Pull Up Enable */
-#define UP2OCR_DPPUBE  (1 << 6)        /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */
-#define UP2OCR_DMPUBE  (1 << 7)        /* Host Port 2 Transceiver D- Pull Up Bypass Enable */
-#define UP2OCR_EXSP            (1 << 8)        /* External Transceiver Speed Control */
-#define UP2OCR_EXSUS   (1 << 9)        /* External Transceiver Speed Enable */
-#define UP2OCR_IDON            (1 << 10)       /* OTG ID Read Enable */
-#define UP2OCR_HXS             (1 << 16)       /* Host Port 2 Transceiver Output Select */
-#define UP2OCR_HXOE            (1 << 17)       /* Host Port 2 Transceiver Output Enable */
-#define UP2OCR_SEOS(x)         ((x & 7) << 24) /* Single-Ended Output Select */
-
-#define UDCCSN(x)      __REG2(0x40600100, (x) << 2)
-#define UDCCSR0         __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */
-#define UDCCSR0_SA     (1 << 7)        /* Setup Active */
-#define UDCCSR0_RNE    (1 << 6)        /* Receive FIFO Not Empty */
-#define UDCCSR0_FST    (1 << 5)        /* Force Stall */
-#define UDCCSR0_SST    (1 << 4)        /* Sent Stall */
-#define UDCCSR0_DME    (1 << 3)        /* DMA Enable */
-#define UDCCSR0_FTF    (1 << 2)        /* Flush Transmit FIFO */
-#define UDCCSR0_IPR    (1 << 1)        /* IN Packet Ready */
-#define UDCCSR0_OPC    (1 << 0)        /* OUT Packet Complete */
-
-#define UDCCSRA         __REG(0x40600104) /* UDC Control/Status register - Endpoint A */
-#define UDCCSRB         __REG(0x40600108) /* UDC Control/Status register - Endpoint B */
-#define UDCCSRC         __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */
-#define UDCCSRD         __REG(0x40600110) /* UDC Control/Status register - Endpoint D */
-#define UDCCSRE         __REG(0x40600114) /* UDC Control/Status register - Endpoint E */
-#define UDCCSRF         __REG(0x40600118) /* UDC Control/Status register - Endpoint F */
-#define UDCCSRG         __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */
-#define UDCCSRH         __REG(0x40600120) /* UDC Control/Status register - Endpoint H */
-#define UDCCSRI         __REG(0x40600124) /* UDC Control/Status register - Endpoint I */
-#define UDCCSRJ         __REG(0x40600128) /* UDC Control/Status register - Endpoint J */
-#define UDCCSRK         __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */
-#define UDCCSRL         __REG(0x40600130) /* UDC Control/Status register - Endpoint L */
-#define UDCCSRM         __REG(0x40600134) /* UDC Control/Status register - Endpoint M */
-#define UDCCSRN         __REG(0x40600138) /* UDC Control/Status register - Endpoint N */
-#define UDCCSRP         __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */
-#define UDCCSRQ         __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */
-#define UDCCSRR         __REG(0x40600144) /* UDC Control/Status register - Endpoint R */
-#define UDCCSRS         __REG(0x40600148) /* UDC Control/Status register - Endpoint S */
-#define UDCCSRT         __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */
-#define UDCCSRU         __REG(0x40600150) /* UDC Control/Status register - Endpoint U */
-#define UDCCSRV         __REG(0x40600154) /* UDC Control/Status register - Endpoint V */
-#define UDCCSRW         __REG(0x40600158) /* UDC Control/Status register - Endpoint W */
-#define UDCCSRX         __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */
-
-#define UDCCSR_DPE     (1 << 9)        /* Data Packet Error */
-#define UDCCSR_FEF     (1 << 8)        /* Flush Endpoint FIFO */
-#define UDCCSR_SP      (1 << 7)        /* Short Packet Control/Status */
-#define UDCCSR_BNE     (1 << 6)        /* Buffer Not Empty (IN endpoints) */
-#define UDCCSR_BNF     (1 << 6)        /* Buffer Not Full (OUT endpoints) */
-#define UDCCSR_FST     (1 << 5)        /* Force STALL */
-#define UDCCSR_SST     (1 << 4)        /* Sent STALL */
-#define UDCCSR_DME     (1 << 3)        /* DMA Enable */
-#define UDCCSR_TRN     (1 << 2)        /* Tx/Rx NAK */
-#define UDCCSR_PC      (1 << 1)        /* Packet Complete */
-#define UDCCSR_FS      (1 << 0)        /* FIFO needs service */
-
-#define UDCBCN(x)      __REG2(0x40600200, (x)<<2)
-#define UDCBCR0         __REG(0x40600200) /* Byte Count Register - EP0 */
-#define UDCBCRA         __REG(0x40600204) /* Byte Count Register - EPA */
-#define UDCBCRB         __REG(0x40600208) /* Byte Count Register - EPB */
-#define UDCBCRC         __REG(0x4060020C) /* Byte Count Register - EPC */
-#define UDCBCRD         __REG(0x40600210) /* Byte Count Register - EPD */
-#define UDCBCRE         __REG(0x40600214) /* Byte Count Register - EPE */
-#define UDCBCRF         __REG(0x40600218) /* Byte Count Register - EPF */
-#define UDCBCRG         __REG(0x4060021C) /* Byte Count Register - EPG */
-#define UDCBCRH         __REG(0x40600220) /* Byte Count Register - EPH */
-#define UDCBCRI         __REG(0x40600224) /* Byte Count Register - EPI */
-#define UDCBCRJ         __REG(0x40600228) /* Byte Count Register - EPJ */
-#define UDCBCRK         __REG(0x4060022C) /* Byte Count Register - EPK */
-#define UDCBCRL         __REG(0x40600230) /* Byte Count Register - EPL */
-#define UDCBCRM         __REG(0x40600234) /* Byte Count Register - EPM */
-#define UDCBCRN         __REG(0x40600238) /* Byte Count Register - EPN */
-#define UDCBCRP         __REG(0x4060023C) /* Byte Count Register - EPP */
-#define UDCBCRQ         __REG(0x40600240) /* Byte Count Register - EPQ */
-#define UDCBCRR         __REG(0x40600244) /* Byte Count Register - EPR */
-#define UDCBCRS         __REG(0x40600248) /* Byte Count Register - EPS */
-#define UDCBCRT         __REG(0x4060024C) /* Byte Count Register - EPT */
-#define UDCBCRU         __REG(0x40600250) /* Byte Count Register - EPU */
-#define UDCBCRV         __REG(0x40600254) /* Byte Count Register - EPV */
-#define UDCBCRW         __REG(0x40600258) /* Byte Count Register - EPW */
-#define UDCBCRX         __REG(0x4060025C) /* Byte Count Register - EPX */
-
-#define UDCDN(x)       __REG2(0x40600300, (x)<<2)
-#define PHYS_UDCDN(x)  (0x40600300 + ((x)<<2))
-#define PUDCDN(x)      (volatile u32 *)(io_p2v(PHYS_UDCDN((x))))
-#define UDCDR0          __REG(0x40600300) /* Data Register - EP0 */
-#define UDCDRA          __REG(0x40600304) /* Data Register - EPA */
-#define UDCDRB          __REG(0x40600308) /* Data Register - EPB */
-#define UDCDRC          __REG(0x4060030C) /* Data Register - EPC */
-#define UDCDRD          __REG(0x40600310) /* Data Register - EPD */
-#define UDCDRE          __REG(0x40600314) /* Data Register - EPE */
-#define UDCDRF          __REG(0x40600318) /* Data Register - EPF */
-#define UDCDRG          __REG(0x4060031C) /* Data Register - EPG */
-#define UDCDRH          __REG(0x40600320) /* Data Register - EPH */
-#define UDCDRI          __REG(0x40600324) /* Data Register - EPI */
-#define UDCDRJ          __REG(0x40600328) /* Data Register - EPJ */
-#define UDCDRK          __REG(0x4060032C) /* Data Register - EPK */
-#define UDCDRL          __REG(0x40600330) /* Data Register - EPL */
-#define UDCDRM          __REG(0x40600334) /* Data Register - EPM */
-#define UDCDRN          __REG(0x40600338) /* Data Register - EPN */
-#define UDCDRP          __REG(0x4060033C) /* Data Register - EPP */
-#define UDCDRQ          __REG(0x40600340) /* Data Register - EPQ */
-#define UDCDRR          __REG(0x40600344) /* Data Register - EPR */
-#define UDCDRS          __REG(0x40600348) /* Data Register - EPS */
-#define UDCDRT          __REG(0x4060034C) /* Data Register - EPT */
-#define UDCDRU          __REG(0x40600350) /* Data Register - EPU */
-#define UDCDRV          __REG(0x40600354) /* Data Register - EPV */
-#define UDCDRW          __REG(0x40600358) /* Data Register - EPW */
-#define UDCDRX          __REG(0x4060035C) /* Data Register - EPX */
-
-#define UDCCN(x)       __REG2(0x40600400, (x)<<2)
-#define UDCCRA          __REG(0x40600404) /* Configuration register EPA */
-#define UDCCRB          __REG(0x40600408) /* Configuration register EPB */
-#define UDCCRC          __REG(0x4060040C) /* Configuration register EPC */
-#define UDCCRD          __REG(0x40600410) /* Configuration register EPD */
-#define UDCCRE          __REG(0x40600414) /* Configuration register EPE */
-#define UDCCRF          __REG(0x40600418) /* Configuration register EPF */
-#define UDCCRG          __REG(0x4060041C) /* Configuration register EPG */
-#define UDCCRH          __REG(0x40600420) /* Configuration register EPH */
-#define UDCCRI          __REG(0x40600424) /* Configuration register EPI */
-#define UDCCRJ          __REG(0x40600428) /* Configuration register EPJ */
-#define UDCCRK          __REG(0x4060042C) /* Configuration register EPK */
-#define UDCCRL          __REG(0x40600430) /* Configuration register EPL */
-#define UDCCRM          __REG(0x40600434) /* Configuration register EPM */
-#define UDCCRN          __REG(0x40600438) /* Configuration register EPN */
-#define UDCCRP          __REG(0x4060043C) /* Configuration register EPP */
-#define UDCCRQ          __REG(0x40600440) /* Configuration register EPQ */
-#define UDCCRR          __REG(0x40600444) /* Configuration register EPR */
-#define UDCCRS          __REG(0x40600448) /* Configuration register EPS */
-#define UDCCRT          __REG(0x4060044C) /* Configuration register EPT */
-#define UDCCRU          __REG(0x40600450) /* Configuration register EPU */
-#define UDCCRV          __REG(0x40600454) /* Configuration register EPV */
-#define UDCCRW          __REG(0x40600458) /* Configuration register EPW */
-#define UDCCRX          __REG(0x4060045C) /* Configuration register EPX */
-
-#define UDCCONR_CN     (0x03 << 25)    /* Configuration Number */
-#define UDCCONR_CN_S   (25)
-#define UDCCONR_IN     (0x07 << 22)    /* Interface Number */
-#define UDCCONR_IN_S   (22)
-#define UDCCONR_AISN   (0x07 << 19)    /* Alternate Interface Number */
-#define UDCCONR_AISN_S (19)
-#define UDCCONR_EN     (0x0f << 15)    /* Endpoint Number */
-#define UDCCONR_EN_S   (15)
-#define UDCCONR_ET     (0x03 << 13)    /* Endpoint Type: */
-#define UDCCONR_ET_S   (13)
-#define UDCCONR_ET_INT (0x03 << 13)    /*   Interrupt */
-#define UDCCONR_ET_BULK        (0x02 << 13)    /*   Bulk */
-#define UDCCONR_ET_ISO (0x01 << 13)    /*   Isochronous */
-#define UDCCONR_ET_NU  (0x00 << 13)    /*   Not used */
-#define UDCCONR_ED     (1 << 12)       /* Endpoint Direction */
-#define UDCCONR_MPS    (0x3ff << 2)    /* Maximum Packet Size */
-#define UDCCONR_MPS_S  (2)
-#define UDCCONR_DE     (1 << 1)        /* Double Buffering Enable */
-#define UDCCONR_EE     (1 << 0)        /* Endpoint Enable */
-
-
-#define UDC_INT_FIFOERROR  (0x2)
-#define UDC_INT_PACKETCMP  (0x1)
-
-#define UDC_FNR_MASK     (0x7ff)
-
-#define UDCCSR_WR_MASK   (UDCCSR_DME|UDCCSR_FST)
-#define UDC_BCR_MASK    (0x3ff)
-
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h
deleted file mode 100644 (file)
index 1a42919..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __MACH_PXA27x_H
-#define __MACH_PXA27x_H
-
-#include <linux/suspend.h>
-#include <mach/hardware.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/irqs.h>
-
-#define ARB_CNTRL      __REG(0x48000048)  /* Arbiter Control Register */
-
-#define ARB_DMA_SLV_PARK       (1<<31)    /* Be parked with DMA slave when idle */
-#define ARB_CI_PARK            (1<<30)    /* Be parked with Camera Interface when idle */
-#define ARB_EX_MEM_PARK        (1<<29)    /* Be parked with external MEMC when idle */
-#define ARB_INT_MEM_PARK       (1<<28)    /* Be parked with internal MEMC when idle */
-#define ARB_USB_PARK           (1<<27)    /* Be parked with USB when idle */
-#define ARB_LCD_PARK           (1<<26)    /* Be parked with LCD when idle */
-#define ARB_DMA_PARK           (1<<25)    /* Be parked with DMA when idle */
-#define ARB_CORE_PARK          (1<<24)    /* Be parked with core when idle */
-#define ARB_LOCK_FLAG          (1<<23)    /* Only Locking masters gain access to the bus */
-
-extern int pxa27x_set_pwrmode(unsigned int mode);
-extern void pxa27x_cpu_pm_enter(suspend_state_t state);
-
-#endif /* __MACH_PXA27x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa300.h b/arch/arm/mach-pxa/include/mach/pxa300.h
deleted file mode 100644 (file)
index 733b641..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_PXA300_H
-#define __MACH_PXA300_H
-
-#include <mach/pxa3xx.h>
-#include <mach/mfp-pxa300.h>
-
-#endif /* __MACH_PXA300_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa320.h b/arch/arm/mach-pxa/include/mach/pxa320.h
deleted file mode 100644 (file)
index b6204e4..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __MACH_PXA320_H
-#define __MACH_PXA320_H
-
-#include <mach/pxa3xx.h>
-#include <mach/mfp-pxa320.h>
-
-#endif /* __MACH_PXA320_H */
-
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx.h b/arch/arm/mach-pxa/include/mach/pxa3xx.h
deleted file mode 100644 (file)
index b4143fb..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __MACH_PXA3XX_H        
-#define __MACH_PXA3XX_H
-
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/irqs.h>
-
-#endif /* __MACH_PXA3XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa930.h b/arch/arm/mach-pxa/include/mach/pxa930.h
deleted file mode 100644 (file)
index 190363b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_PXA930_H
-#define __MACH_PXA930_H
-
-#include <mach/pxa3xx.h>
-#include <mach/mfp-pxa930.h>
-
-#endif /* __MACH_PXA930_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-rtc.h b/arch/arm/mach-pxa/include/mach/regs-rtc.h
deleted file mode 100644 (file)
index f0e4a58..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __ASM_MACH_REGS_RTC_H
-#define __ASM_MACH_REGS_RTC_H
-
-#include <mach/hardware.h>
-
-/*
- * Real Time Clock
- */
-
-#define RCNR           __REG(0x40900000)  /* RTC Count Register */
-#define RTAR           __REG(0x40900004)  /* RTC Alarm Register */
-#define RTSR           __REG(0x40900008)  /* RTC Status Register */
-#define RTTR           __REG(0x4090000C)  /* RTC Timer Trim Register */
-#define PIAR           __REG(0x40900038)  /* Periodic Interrupt Alarm Register */
-
-#define RTSR_PICE      (1 << 15)       /* Periodic interrupt count enable */
-#define RTSR_PIALE     (1 << 14)       /* Periodic interrupt Alarm enable */
-#define RTSR_HZE       (1 << 3)        /* HZ interrupt enable */
-#define RTSR_ALE       (1 << 2)        /* RTC alarm interrupt enable */
-#define RTSR_HZ                (1 << 1)        /* HZ rising-edge detected */
-#define RTSR_AL                (1 << 0)        /* RTC alarm detected */
-
-#endif /* __ASM_MACH_REGS_RTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-u2d.h b/arch/arm/mach-pxa/include/mach/regs-u2d.h
deleted file mode 100644 (file)
index c15c0c5..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef __ASM_ARCH_PXA3xx_U2D_H
-#define __ASM_ARCH_PXA3xx_U2D_H
-
-#include <mach/bitfield.h>
-
-/*
- * USB2 device controller registers and bits definitions
- */
-#define U2DCR          (0x0000)        /* U2D Control Register */
-#define U2DCR_NDC      (1   << 31)     /* NAK During Config */
-#define U2DCR_HSTC     (0x7 << 28)     /* High Speed Timeout Calibration */
-#define U2DCR_SPEOREN  (1   << 27)     /* Short Packet EOR INTR generation Enable */
-#define U2DCR_FSTC     (0x7 << 24)     /* Full Speed Timeout Calibration */
-#define U2DCR_UCLKOVR  (1   << 22)     /* UTM Clock Override */
-#define U2DCR_ABP      (1   << 21)     /* Application Bus Power */
-#define U2DCR_ADD      (1   << 20)     /* Application Device Disconnect */
-#define U2DCR_CC       (1   << 19)     /* Configuration Change */
-#define U2DCR_HS       (1   << 18)     /* High Speed USB Detection */
-#define U2DCR_SMAC     (1   << 17)     /* Switch Endpoint Memory to Active Configuration */
-#define U2DCR_DWRE     (1   << 16)     /* Device Remote Wake-up Feature */
-#define U2DCR_ACN      (0xf << 12)     /* Active U2D Configuration Number */
-#define U2DCR_AIN      (0xf << 8)      /* Active U2D Interface Number */
-#define U2DCR_AAISN    (0xf << 4)      /* Active U2D Alternate Interface Setting Number */
-#define U2DCR_EMCE     (1   << 3)      /* Endpoint Memory Configuration Error */
-#define U2DCR_UDR      (1   << 2)      /* U2D Resume */
-#define U2DCR_UDA      (1   << 1)      /* U2D Active */
-#define U2DCR_UDE      (1   << 0)      /* U2D Enable */
-
-#define U2DICR                 (0x0004)        /* U2D Interrupt Control Register */
-#define U2DISR                 (0x000C)        /* U2D Interrupt Status Register */
-#define U2DINT_CC              (1 << 31)       /* Interrupt - Configuration Change */
-#define U2DINT_SOF             (1 << 30)       /* Interrupt - SOF */
-#define U2DINT_USOF            (1 << 29)       /* Interrupt - micro SOF */
-#define U2DINT_RU              (1 << 28)       /* Interrupt - Resume */
-#define U2DINT_SU              (1 << 27)       /* Interrupt - Suspend */
-#define U2DINT_RS              (1 << 26)       /* Interrupt - Reset */
-#define U2DINT_DPE             (1 << 25)       /* Interrupt - Data Packet Error */
-#define U2DINT_FIFOERR         (0x4)           /* Interrupt - endpoint FIFO error */
-#define U2DINT_PACKETCMP       (0x2)           /* Interrupt - endpoint packet complete */
-#define U2DINT_SPACKETCMP      (0x1)           /* Interrupt - endpoint short packet complete */
-
-#define U2DFNR                 (0x0014)        /* U2D Frame Number Register */
-
-#define U2DINT(n, intr)                (((intr) & 0x07) << (((n) & 0x07) * 3))
-#define U2DICR2                        (0x0008)        /* U2D Interrupt Control Register 2 */
-#define U2DISR2                        (0x0010)        /* U2D Interrupt Status Register 2 */
-
-#define U2DOTGCR               (0x0020)        /* U2D OTG Control Register */
-#define U2DOTGCR_OTGEN         (1 << 31)       /* On-The-Go Enable */
-#define U2DOTGCR_AALTHNP       (1 << 30)       /* A-device Alternate Host Negotiation Protocal Port Support */
-#define U2DOTGCR_AHNP          (1 << 29)       /* A-device Host Negotiation Protocal Support */
-#define U2DOTGCR_BHNP          (1 << 28)       /* B-device Host Negotiation Protocal Enable */
-
-#ifdef CONFIG_CPU_PXA930
-#define U2DOTGCR_LPA           (1 << 15)       /* ULPI low power mode active */
-#define U2DOTGCR_IESI          (1 << 13)       /* OTG interrupt Enable */
-#define U2DOTGCR_ISSI          (1 << 12)       /* OTG interrupt status */
-#endif
-
-#define U2DOTGCR_CKAF  (1 << 5)        /* Carkit Mode Alternate Function Select */
-#define U2DOTGCR_UTMID (1 << 4)        /* UTMI Interface Disable */
-#define U2DOTGCR_ULAF  (1 << 3)        /* ULPI Mode Alternate Function Select */
-#define U2DOTGCR_SMAF  (1 << 2)        /* Serial Mode Alternate Function Select */
-#define U2DOTGCR_RTSM  (1 << 1)        /* Return to Synchronous Mode (ULPI Mode) */
-#define U2DOTGCR_ULE   (1 << 0)        /* ULPI Wrapper Enable */
-
-#define U2DOTGICR      (0x0024)        /* U2D OTG Interrupt Control Register */
-#define U2DOTGISR      (0x0028)        /* U2D OTG Interrupt Status Register */
-
-#define U2DOTGINT_SF   (1 << 17)       /* OTG Set Feature Command Received */
-#define U2DOTGINT_SI   (1 << 16)       /* OTG Interrupt */
-#define U2DOTGINT_RLS1 (1 << 14)       /* RXCMD Linestate[1] Change Interrupt Rise */
-#define U2DOTGINT_RLS0 (1 << 13)       /* RXCMD Linestate[0] Change Interrupt Rise */
-#define U2DOTGINT_RID  (1 << 12)       /* RXCMD OTG ID Change Interrupt Rise */
-#define U2DOTGINT_RSE  (1 << 11)       /* RXCMD OTG Session End Interrupt Rise */
-#define U2DOTGINT_RSV  (1 << 10)       /* RXCMD OTG Session Valid Interrupt Rise */
-#define U2DOTGINT_RVV  (1 << 9)        /* RXCMD OTG Vbus Valid Interrupt Rise */
-#define U2DOTGINT_RCK  (1 << 8)        /* RXCMD Carkit Interrupt Rise */
-#define U2DOTGINT_FLS1 (1 << 6)        /* RXCMD Linestate[1] Change Interrupt Fall */
-#define U2DOTGINT_FLS0 (1 << 5)        /* RXCMD Linestate[0] Change Interrupt Fall */
-#define U2DOTGINT_FID  (1 << 4)        /* RXCMD OTG ID Change Interrupt Fall */
-#define U2DOTGINT_FSE  (1 << 3)        /* RXCMD OTG Session End Interrupt Fall */
-#define U2DOTGINT_FSV  (1 << 2)        /* RXCMD OTG Session Valid Interrupt Fall */
-#define U2DOTGINT_FVV  (1 << 1)        /* RXCMD OTG Vbus Valid Interrupt Fall */
-#define U2DOTGINT_FCK  (1 << 0)        /* RXCMD Carkit Interrupt Fall */
-
-#define U2DOTGUSR      (0x002C)        /* U2D OTG ULPI Status Register */
-#define U2DOTGUSR_LPA  (1 << 31)       /* ULPI Low Power Mode Active */
-#define U2DOTGUSR_S6A  (1 << 30)       /* ULPI Serial Mode (6-pin) Active */
-#define U2DOTGUSR_S3A  (1 << 29)       /* ULPI Serial Mode (3-pin) Active */
-#define U2DOTGUSR_CKA  (1 << 28)       /* ULPI Car Kit Mode Active */
-#define U2DOTGUSR_LS1  (1 << 6)        /* RXCMD Linestate 1 Status */
-#define U2DOTGUSR_LS0  (1 << 5)        /* RXCMD Linestate 0 Status */
-#define U2DOTGUSR_ID   (1 << 4)        /* OTG IDGnd Status */
-#define U2DOTGUSR_SE   (1 << 3)        /* OTG Session End Status */
-#define U2DOTGUSR_SV   (1 << 2)        /* OTG Session Valid Status */
-#define U2DOTGUSR_VV   (1 << 1)        /* OTG Vbus Valid Status */
-#define U2DOTGUSR_CK   (1 << 0)        /* Carkit Interrupt Status */
-
-#define U2DOTGUCR      (0x0030)        /* U2D OTG ULPI Control Register */
-#define U2DOTGUCR_RUN  (1    << 25)    /* RUN */
-#define U2DOTGUCR_RNW  (1    << 24)    /* Read or Write operation */
-#define U2DOTGUCR_ADDR (0x3f << 16)    /* Address of the ULPI PHY register */
-#define U2DOTGUCR_WDATA        (0xff << 8)     /* The data for a WRITE command */
-#define U2DOTGUCR_RDATA        (0xff << 0)     /* The data for a READ command */
-
-#define U2DP3CR                (0x0034)        /* U2D Port 3 Control Register */
-#define U2DP3CR_P2SS   (0x3 << 8)      /* Host Port 2 Serial Mode Select */
-#define U2DP3CR_P3SS   (0x7 << 4)      /* Host Port 3 Serial Mode Select */
-#define U2DP3CR_VPVMBEN        (0x1 << 2)      /* Host Port 3 Vp/Vm Block Enable */
-#define U2DP3CR_CFG    (0x3 << 0)      /* Host Port 3 Configuration */
-
-#define U2DCSR0                (0x0100)        /* U2D Control/Status Register - Endpoint 0 */
-#define U2DCSR0_IPA    (1 << 8)        /* IN Packet Adjusted */
-#define U2DCSR0_SA     (1 << 7)        /* SETUP Active */
-#define U2DCSR0_RNE    (1 << 6)        /* Receive FIFO Not Empty */
-#define U2DCSR0_FST    (1 << 5)        /* Force Stall */
-#define U2DCSR0_SST    (1 << 4)        /* Send Stall */
-#define U2DCSR0_DME    (1 << 3)        /* DMA Enable */
-#define U2DCSR0_FTF    (1 << 2)        /* Flush Transmit FIFO */
-#define U2DCSR0_IPR    (1 << 1)        /* IN Packet Ready */
-#define U2DCSR0_OPC    (1 << 0)        /* OUT Packet Complete */
-
-#define U2DCSR(x)      (0x0100 + ((x) << 2))   /* U2D Control/Status Register - Endpoint x */
-#define U2DCSR_BF      (1 << 10)       /* Buffer Full, for OUT eps */
-#define U2DCSR_BE      (1 << 10)       /* Buffer Empty, for IN eps */
-#define U2DCSR_DPE     (1 << 9)        /* Data Packet Error, for ISO eps only */
-#define U2DCSR_FEF     (1 << 8)        /* Flush Endpoint FIFO */
-#define U2DCSR_SP      (1 << 7)        /* Short Packet Control/Status, for OUT eps only, readonly */
-#define U2DCSR_BNE     (1 << 6)        /* Buffer Not Empty, for OUT eps */
-#define U2DCSR_BNF     (1 << 6)        /* Buffer Not Full, for IN eps */
-#define U2DCSR_FST     (1 << 5)        /* Force STALL, write 1 set */
-#define U2DCSR_SST     (1 << 4)        /* Sent STALL, write 1 clear */
-#define U2DCSR_DME     (1 << 3)        /* DMA Enable */
-#define U2DCSR_TRN     (1 << 2)        /* Tx/Rx NAK, write 1 clear */
-#define U2DCSR_PC      (1 << 1)        /* Packet Complete, write 1 clear */
-#define U2DCSR_FS      (1 << 0)        /* FIFO needs Service */
-
-#define U2DBCR0                (0x0200)                /* U2D Byte Count Register - Endpoint 0 */
-#define U2DBCR(x)      (0x0200 + ((x) << 2))   /* U2D Byte Count Register - Endpoint x */
-
-#define U2DDR0         (0x0300)                /* U2D Data Register - Endpoint 0 */
-
-#define U2DEPCR(x)     (0x0400 + ((x) << 2))   /* U2D Configuration Register - Endpoint x */
-#define U2DEPCR_EE     (1 << 0)                /* Endpoint Enable */
-#define U2DEPCR_BS_MASK        (0x3FE)                 /* Buffer Size, BS*8=FIFO size, max 8184B = 8KB */
-
-#define U2DSCA         (0x0500)                /* U2D Setup Command Address */
-#define U2DSCA_VALUE   (0x0120)
-
-#define U2DEN0         (0x0504)                /* U2D Endpoint Information Register - Endpoint 0 */
-#define U2DEN(x)       (0x0504 + ((x) << 2))   /* U2D Endpoint Information Register - Endpoint x */
-
-/* U2DMA registers */
-#define U2DMACSR0              (0x1000)        /* U2DMA Control/Status Register - Channel 0 */
-#define U2DMACSR(x)            (0x1000 + ((x) << 2))   /* U2DMA Control/Status Register - Channel x */
-#define U2DMACSR_RUN           (1 << 31)       /* Run Bit (read / write) */
-#define U2DMACSR_STOPIRQEN     (1 << 29)       /* Stop Interrupt Enable (read / write) */
-#define U2DMACSR_EORIRQEN      (1 << 28)       /* End of Receive Interrupt Enable (R/W) */
-#define U2DMACSR_EORJMPEN      (1 << 27)       /* Jump to next descriptor on EOR */
-#define U2DMACSR_EORSTOPEN     (1 << 26)       /* STOP on an EOR */
-#define U2DMACSR_RASIRQEN      (1 << 23)       /* Request After Cnannel Stopped Interrupt Enable */
-#define U2DMACSR_MASKRUN       (1 << 22)       /* Mask Run */
-#define U2DMACSR_SCEMC         (3 << 18)       /* System Bus Split Completion Error Message Class */
-#define U2DMACSR_SCEMI         (0x1f << 13)    /* System Bus Split Completion Error Message Index */
-#define U2DMACSR_BUSERRTYPE    (7 << 10)       /* PX Bus Error Type */
-#define U2DMACSR_EORINTR       (1 << 9)        /* End Of Receive */
-#define U2DMACSR_REQPEND       (1 << 8)        /* Request Pending */
-#define U2DMACSR_RASINTR       (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */
-#define U2DMACSR_STOPINTR      (1 << 3)        /* Stop Interrupt (read only) */
-#define U2DMACSR_ENDINTR       (1 << 2)        /* End Interrupt (read / write 1 clear) */
-#define U2DMACSR_STARTINTR     (1 << 1)        /* Start Interrupt (read / write 1 clear) */
-#define U2DMACSR_BUSERRINTR    (1 << 0)        /* Bus Error Interrupt (read / write 1 clear) */
-
-#define U2DMACR                (0x1080)                /* U2DMA Control Register */
-#define U2DMAINT       (0x10F0)                /* U2DMA Interrupt Register */
-
-#define U2DMABR0       (0x1100)                /* U2DMA Branch Register - Channel 0 */
-#define U2DMABR(x)      (0x1100 + (x) << 2)    /* U2DMA Branch Register - Channel x */
-
-#define U2DMADADR0      (0x1200)               /* U2DMA Descriptor Address Register - Channel 0 */
-#define U2DMADADR(x)    (0x1200 + (x) * 0x10)  /* U2DMA Descriptor Address Register - Channel x */
-
-#define U2DMADADR_STOP (1U << 0)
-
-#define U2DMASADR0     (0x1204)                /* U2DMA Source Address Register - Channel 0 */
-#define U2DMASADR(x)   (0x1204 + (x) * 0x10)   /* U2DMA Source Address Register - Channel x */
-#define U2DMATADR0     (0x1208)                /* U2DMA Target Address Register - Channel 0 */
-#define U2DMATADR(x)   (0x1208 + (x) * 0x10)   /* U2DMA Target Address Register - Channel x */
-
-#define U2DMACMDR0     (0x120C)                /* U2DMA Command Address Register - Channel 0 */
-#define U2DMACMDR(x)   (0x120C + (x) * 0x10)   /* U2DMA Command Address Register - Channel x */
-
-#define U2DMACMDR_XFRDIS       (1 << 31)       /* Transfer Direction */
-#define U2DMACMDR_STARTIRQEN   (1 << 22)       /* Start Interrupt Enable */
-#define U2DMACMDR_ENDIRQEN     (1 << 21)       /* End Interrupt Enable */
-#define U2DMACMDR_PACKCOMP     (1 << 13)       /* Packet Complete */
-#define U2DMACMDR_LEN          (0x07ff)        /* length mask (max = 2K - 1) */
-
-#endif /* __ASM_ARCH_PXA3xx_U2D_H */
diff --git a/arch/arm/mach-pxa/include/mach/sharpsl_pm.h b/arch/arm/mach-pxa/include/mach/sharpsl_pm.h
deleted file mode 100644 (file)
index 905be67..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SharpSL Battery/PM Driver
- *
- * Copyright (c) 2004-2005 Richard Purdie
- *
- * 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 _MACH_SHARPSL_PM
-#define _MACH_SHARPSL_PM
-
-struct sharpsl_charger_machinfo {
-       void (*init)(void);
-       void (*exit)(void);
-       int gpio_acin;
-       int gpio_batfull;
-       int batfull_irq;
-       int gpio_batlock;
-       int gpio_fatal;
-       void (*discharge)(int);
-       void (*discharge1)(int);
-       void (*charge)(int);
-       void (*measure_temp)(int);
-       void (*presuspend)(void);
-       void (*postsuspend)(void);
-       void (*earlyresume)(void);
-       unsigned long (*read_devdata)(int);
-#define SHARPSL_BATT_VOLT       1
-#define SHARPSL_BATT_TEMP       2
-#define SHARPSL_ACIN_VOLT       3
-#define SHARPSL_STATUS_ACIN     4
-#define SHARPSL_STATUS_LOCK     5
-#define SHARPSL_STATUS_CHRGFULL 6
-#define SHARPSL_STATUS_FATAL    7
-       unsigned long (*charger_wakeup)(void);
-       int (*should_wakeup)(unsigned int resume_on_alarm);
-       void (*backlight_limit)(int);
-       int (*backlight_get_status) (void);
-       int charge_on_volt;
-       int charge_on_temp;
-       int charge_acin_high;
-       int charge_acin_low;
-       int fatal_acin_volt;
-       int fatal_noacin_volt;
-       int bat_levels;
-       struct battery_thresh *bat_levels_noac;
-       struct battery_thresh *bat_levels_acin;
-       struct battery_thresh *bat_levels_noac_bl;
-       struct battery_thresh *bat_levels_acin_bl;
-       int status_high_acin;
-       int status_low_acin;
-       int status_high_noac;
-       int status_low_noac;
-};
-
-struct battery_thresh {
-       int voltage;
-       int percentage;
-};
-
-struct battery_stat {
-       int ac_status;         /* APM AC Present/Not Present */
-       int mainbat_status;    /* APM Main Battery Status */
-       int mainbat_percent;   /* Main Battery Percentage Charge */
-       int mainbat_voltage;   /* Main Battery Voltage */
-};
-
-struct sharpsl_pm_status {
-       struct device *dev;
-       struct timer_list ac_timer;
-       struct timer_list chrg_full_timer;
-
-       int charge_mode;
-#define CHRG_ERROR    (-1)
-#define CHRG_OFF      (0)
-#define CHRG_ON       (1)
-#define CHRG_DONE     (2)
-
-       unsigned int flags;
-#define SHARPSL_SUSPENDED       (1 << 0)  /* Device is Suspended */
-#define SHARPSL_ALARM_ACTIVE    (1 << 1)  /* Alarm is for charging event (not user) */
-#define SHARPSL_BL_LIMIT        (1 << 2)  /* Backlight Intensity Limited */
-#define SHARPSL_APM_QUEUED      (1 << 3)  /* APM Event Queued */
-#define SHARPSL_DO_OFFLINE_CHRG (1 << 4)  /* Trigger the offline charger */
-
-       int full_count;
-       unsigned long charge_start_time;
-       struct sharpsl_charger_machinfo *machinfo;
-       struct battery_stat battstat;
-};
-
-extern struct sharpsl_pm_status sharpsl_pm;
-
-extern struct battery_thresh sharpsl_battery_levels_acin[];
-extern struct battery_thresh sharpsl_battery_levels_noac[];
-
-#define SHARPSL_LED_ERROR  2
-#define SHARPSL_LED_ON     1
-#define SHARPSL_LED_OFF    0
-
-void sharpsl_battery_kick(void);
-void sharpsl_pm_led(int val);
-
-/* MAX1111 Channel Definitions */
-#define MAX1111_BATT_VOLT   4u
-#define MAX1111_BATT_TEMP   2u
-#define MAX1111_ACIN_VOLT   6u
-int sharpsl_pm_pxa_read_max1111(int channel);
-
-void corgi_lcd_limit_intensity(int limit);
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/tosa_bt.h b/arch/arm/mach-pxa/include/mach/tosa_bt.h
deleted file mode 100644 (file)
index efc3c3d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Tosa bluetooth built-in chip control.
- *
- * Later it may be shared with some other platforms.
- *
- * Copyright (c) 2008 Dmitry Baryshkov
- *
- * 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 TOSA_BT_H
-#define TOSA_BT_H
-
-struct tosa_bt_data {
-       int gpio_pwr;
-       int gpio_reset;
-};
-
-#endif
-
diff --git a/arch/arm/mach-pxa/include/mach/udc.h b/arch/arm/mach-pxa/include/mach/udc.h
deleted file mode 100644 (file)
index 9a827e3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/udc.h
- *
- */
-#include <linux/platform_data/pxa2xx_udc.h>
-
-extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
-
diff --git a/arch/arm/mach-pxa/include/mach/viper.h b/arch/arm/mach-pxa/include/mach/viper.h
deleted file mode 100644 (file)
index 5f5fbf1..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/viper.h
- *
- * Author:     Ian Campbell
- * Created:    Feb 03, 2003
- * Copyright:  Arcom Control Systems.
- *
- * Maintained by Marc Zyngier <maz@misterjones.org>
- *                           <marc.zyngier@altran.com>
- *
- * Created based on lubbock.h:
- *  Author:    Nicolas Pitre
- *  Created:   Jun 15, 2001
- *  Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef ARCH_VIPER_H
-#define ARCH_VIPER_H
-
-#define VIPER_BOOT_PHYS                PXA_CS0_PHYS
-#define VIPER_FLASH_PHYS       PXA_CS1_PHYS
-#define VIPER_ETH_PHYS         PXA_CS2_PHYS
-#define VIPER_USB_PHYS         PXA_CS3_PHYS
-#define VIPER_ETH_DATA_PHYS    PXA_CS4_PHYS
-#define VIPER_CPLD_PHYS                PXA_CS5_PHYS
-
-#define VIPER_CPLD_BASE                (0xf0000000)
-#define VIPER_PC104IO_BASE     (0xf1000000)
-#define VIPER_USB_BASE         (0xf1800000)
-
-#define VIPER_ETH_GPIO         (0)
-#define VIPER_CPLD_GPIO                (1)
-#define VIPER_USB_GPIO         (2)
-#define VIPER_UARTA_GPIO       (4)
-#define VIPER_UARTB_GPIO       (3)
-#define VIPER_CF_CD_GPIO       (32)
-#define VIPER_CF_RDY_GPIO      (8)
-#define VIPER_BCKLIGHT_EN_GPIO (9)
-#define VIPER_LCD_EN_GPIO      (10)
-#define VIPER_PSU_DATA_GPIO    (6)
-#define VIPER_PSU_CLK_GPIO     (11)
-#define VIPER_UART_SHDN_GPIO   (12)
-#define VIPER_BRIGHTNESS_GPIO  (16)
-#define VIPER_PSU_nCS_LD_GPIO  (19)
-#define VIPER_UPS_GPIO         (20)
-#define VIPER_CF_POWER_GPIO    (82)
-#define VIPER_TPM_I2C_SDA_GPIO (26)
-#define VIPER_TPM_I2C_SCL_GPIO (27)
-#define VIPER_RTC_I2C_SDA_GPIO (83)
-#define VIPER_RTC_I2C_SCL_GPIO (84)
-
-#define VIPER_CPLD_P2V(x)      ((x) - VIPER_CPLD_PHYS + VIPER_CPLD_BASE)
-#define VIPER_CPLD_V2P(x)      ((x) - VIPER_CPLD_BASE + VIPER_CPLD_PHYS)
-
-#ifndef __ASSEMBLY__
-#  define __VIPER_CPLD_REG(x)  (*((volatile u16 *)VIPER_CPLD_P2V(x)))
-#endif
-
-/* board level registers in the CPLD: (offsets from CPLD_BASE) ... */
-
-/* ... Physical addresses */
-#define _VIPER_LO_IRQ_STATUS   (VIPER_CPLD_PHYS + 0x100000)
-#define _VIPER_ICR_PHYS                (VIPER_CPLD_PHYS + 0x100002)
-#define _VIPER_HI_IRQ_STATUS   (VIPER_CPLD_PHYS + 0x100004)
-#define _VIPER_VERSION_PHYS    (VIPER_CPLD_PHYS + 0x100006)
-#define VIPER_UARTA_PHYS       (VIPER_CPLD_PHYS + 0x300010)
-#define VIPER_UARTB_PHYS       (VIPER_CPLD_PHYS + 0x300000)
-#define _VIPER_SRAM_BASE       (VIPER_CPLD_PHYS + 0x800000)
-
-/* ... Virtual addresses */
-#define VIPER_LO_IRQ_STATUS    __VIPER_CPLD_REG(_VIPER_LO_IRQ_STATUS)
-#define VIPER_HI_IRQ_STATUS    __VIPER_CPLD_REG(_VIPER_HI_IRQ_STATUS)
-#define VIPER_VERSION          __VIPER_CPLD_REG(_VIPER_VERSION_PHYS)
-#define VIPER_ICR              __VIPER_CPLD_REG(_VIPER_ICR_PHYS)
-
-/* Decode VIPER_VERSION register */
-#define VIPER_CPLD_REVISION(x) (((x) >> 5) & 0x7)
-#define VIPER_BOARD_VERSION(x) (((x) >> 3) & 0x3)
-#define VIPER_BOARD_ISSUE(x)   (((x) >> 0) & 0x7)
-
-/* Interrupt and Configuration Register (VIPER_ICR) */
-/* This is a write only register. Only CF_RST is used under Linux */
-
-#define VIPER_ICR_RETRIG       (1 << 0)
-#define VIPER_ICR_AUTO_CLR     (1 << 1)
-#define VIPER_ICR_R_DIS                (1 << 2)
-#define VIPER_ICR_CF_RST       (1 << 3)
-
-#endif
-
diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h
deleted file mode 100644 (file)
index 56024f8..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  arch/arm/mach-pxa/include/mach/zeus.h
- *
- *  Author:    David Vrabel
- *  Created:   Sept 28, 2005
- *  Copyright: Arcom Control Systems Ltd.
- *
- *  Maintained by: Marc Zyngier <maz@misterjones.org>
- *
- * 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 _MACH_ZEUS_H
-#define _MACH_ZEUS_H
-
-#define ZEUS_NR_IRQS           (IRQ_BOARD_START + 48)
-
-/* Physical addresses */
-#define ZEUS_FLASH_PHYS                PXA_CS0_PHYS
-#define ZEUS_ETH0_PHYS         PXA_CS1_PHYS
-#define ZEUS_ETH1_PHYS         PXA_CS2_PHYS
-#define ZEUS_CPLD_PHYS         (PXA_CS4_PHYS+0x2000000)
-#define ZEUS_SRAM_PHYS         PXA_CS5_PHYS
-#define ZEUS_PC104IO_PHYS      (0x30000000)
-
-#define ZEUS_CPLD_VERSION_PHYS (ZEUS_CPLD_PHYS + 0x00000000)
-#define ZEUS_CPLD_ISA_IRQ_PHYS (ZEUS_CPLD_PHYS + 0x00800000)
-#define ZEUS_CPLD_CONTROL_PHYS (ZEUS_CPLD_PHYS + 0x01000000)
-#define ZEUS_CPLD_EXTWDOG_PHYS (ZEUS_CPLD_PHYS + 0x01800000)
-
-/* GPIOs */
-#define ZEUS_AC97_GPIO         0
-#define ZEUS_WAKEUP_GPIO       1
-#define ZEUS_UARTA_GPIO                9
-#define ZEUS_UARTB_GPIO                10
-#define ZEUS_UARTC_GPIO                12
-#define ZEUS_UARTD_GPIO                11
-#define ZEUS_ETH0_GPIO         14
-#define ZEUS_ISA_GPIO          17
-#define ZEUS_BKLEN_GPIO                19
-#define ZEUS_USB2_PWREN_GPIO   22
-#define ZEUS_PTT_GPIO          27
-#define ZEUS_CF_CD_GPIO         35
-#define ZEUS_MMC_WP_GPIO        52
-#define ZEUS_MMC_CD_GPIO        53
-#define ZEUS_EXTGPIO_GPIO      91
-#define ZEUS_CF_PWEN_GPIO       97
-#define ZEUS_CF_RDY_GPIO        99
-#define ZEUS_LCD_EN_GPIO       101
-#define ZEUS_ETH1_GPIO         113
-#define ZEUS_CAN_GPIO          116
-
-#define ZEUS_EXT0_GPIO_BASE    128
-#define ZEUS_EXT1_GPIO_BASE    160
-#define ZEUS_USER_GPIO_BASE    192
-
-#define ZEUS_EXT0_GPIO(x)      (ZEUS_EXT0_GPIO_BASE + (x))
-#define ZEUS_EXT1_GPIO(x)      (ZEUS_EXT1_GPIO_BASE + (x))
-#define ZEUS_USER_GPIO(x)      (ZEUS_USER_GPIO_BASE + (x))
-
-#define        ZEUS_CAN_SHDN_GPIO      ZEUS_EXT1_GPIO(2)
-
-/*
- * CPLD registers:
- * Only 4 registers, but spread over a 32MB address space.
- * Be gentle, and remap that over 32kB...
- */
-
-#define ZEUS_CPLD              IOMEM(0xf0000000)
-#define ZEUS_CPLD_VERSION      (ZEUS_CPLD + 0x0000)
-#define ZEUS_CPLD_ISA_IRQ      (ZEUS_CPLD + 0x1000)
-#define ZEUS_CPLD_CONTROL      (ZEUS_CPLD + 0x2000)
-
-/* CPLD register bits */
-#define ZEUS_CPLD_CONTROL_CF_RST        0x01
-
-#define ZEUS_PC104IO           IOMEM(0xf1000000)
-
-#define ZEUS_SRAM_SIZE         (256 * 1024)
-
-#endif
-
-
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h
deleted file mode 100644 (file)
index ecca976..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __ASM_ARCH_ZYLONITE_H
-#define __ASM_ARCH_ZYLONITE_H
-
-#define ZYLONITE_ETH_PHYS      0x14000000
-
-#define EXT_GPIO(x)            (128 + (x))
-
-#define ZYLONITE_NR_IRQS       (IRQ_BOARD_START + 32)
-
-/* the following variables are processor specific and initialized
- * by the corresponding zylonite_pxa3xx_init()
- */
-extern int gpio_eth_irq;
-extern int gpio_debug_led1;
-extern int gpio_debug_led2;
-
-extern int wm9713_irq;
-
-extern int lcd_id;
-extern int lcd_orientation;
-
-#ifdef CONFIG_MACH_ZYLONITE300
-extern void zylonite_pxa300_init(void);
-#else
-static inline void zylonite_pxa300_init(void)
-{
-       if (cpu_is_pxa300() || cpu_is_pxa310())
-               panic("%s: PXA300/PXA310 not supported\n", __func__);
-}
-#endif
-
-#ifdef CONFIG_MACH_ZYLONITE320
-extern void zylonite_pxa320_init(void);
-#else
-static inline void zylonite_pxa320_init(void)
-{
-       if (cpu_is_pxa320())
-               panic("%s: PXA320 not supported\n", __func__);
-}
-#endif
-
-#endif /* __ASM_ARCH_ZYLONITE_H */
index 5d66558..051c554 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa300.h>
+#include "pxa300.h"
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/littleton.h>
+#include "littleton.h"
 #include <linux/platform_data/mtd-nand-pxa3xx.h>
 
 #include "generic.h"
diff --git a/arch/arm/mach-pxa/littleton.h b/arch/arm/mach-pxa/littleton.h
new file mode 100644 (file)
index 0000000..8066be5
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __ASM_ARCH_LITTLETON_H
+#define __ASM_ARCH_LITTLETON_H
+
+#define LITTLETON_ETH_PHYS     0x30000000
+
+#define LITTLETON_GPIO_LCD_CS  (17)
+
+#define EXT0_GPIO_BASE (PXA_NR_BUILTIN_GPIO)
+#define EXT0_GPIO(x)   (EXT0_GPIO_BASE + (x))
+
+#define LITTLETON_NR_IRQS      (IRQ_BOARD_START + 8)
+
+#endif /* __ASM_ARCH_LITTLETON_H */
index 5fcd4f0..e9f401b 100644 (file)
@@ -40,8 +40,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa27x.h>
-#include <mach/lpd270.h>
+#include "pxa27x.h"
+#include "lpd270.h"
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
diff --git a/arch/arm/mach-pxa/lpd270.h b/arch/arm/mach-pxa/lpd270.h
new file mode 100644 (file)
index 0000000..4edc712
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-pxa/include/mach/lpd270.h
+ *
+ * Author:     Lennert Buytenhek
+ * Created:    Feb 10, 2006
+ *
+ * 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_LPD270_H
+#define __ASM_ARCH_LPD270_H
+
+#define LPD270_CPLD_PHYS       PXA_CS2_PHYS
+#define LPD270_CPLD_VIRT       IOMEM(0xf0000000)
+#define LPD270_CPLD_SIZE       0x00100000
+
+#define LPD270_ETH_PHYS                (PXA_CS2_PHYS + 0x01000000)
+
+/* CPLD registers  */
+#define LPD270_CPLD_REG(x)     (LPD270_CPLD_VIRT + (x))
+#define LPD270_CONTROL         LPD270_CPLD_REG(0x00)
+#define LPD270_PERIPHERAL0     LPD270_CPLD_REG(0x04)
+#define LPD270_PERIPHERAL1     LPD270_CPLD_REG(0x08)
+#define LPD270_CPLD_REVISION   LPD270_CPLD_REG(0x14)
+#define LPD270_EEPROM_SPI_ITF  LPD270_CPLD_REG(0x20)
+#define LPD270_MODE_PINS       LPD270_CPLD_REG(0x24)
+#define LPD270_EGPIO           LPD270_CPLD_REG(0x30)
+#define LPD270_INT_MASK                LPD270_CPLD_REG(0x40)
+#define LPD270_INT_STATUS      LPD270_CPLD_REG(0x50)
+
+#define LPD270_INT_AC97                (1 << 4)  /* AC'97 CODEC IRQ */
+#define LPD270_INT_ETHERNET    (1 << 3)  /* Ethernet controller IRQ */
+#define LPD270_INT_USBC                (1 << 2)  /* USB client cable detection IRQ */
+
+#define LPD270_IRQ(x)          (IRQ_BOARD_START + (x))
+#define LPD270_USBC_IRQ                LPD270_IRQ(2)
+#define LPD270_ETHERNET_IRQ    LPD270_IRQ(3)
+#define LPD270_AC97_IRQ                LPD270_IRQ(4)
+#define LPD270_NR_IRQS         (IRQ_BOARD_START + 5)
+
+#endif
index 6de32fa..7245f33 100644 (file)
 
 #include <asm/hardware/sa1111.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/audio.h>
 #include <mach/lubbock.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/pm.h>
+#include "pm.h"
 #include <mach/smemc.h>
 
 #include "generic.h"
index 896b268..abc9181 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/mach/arch.h>
 #include <asm/system_info.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/magician.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
@@ -48,9 +48,9 @@
 #include <linux/regulator/max1586.h>
 
 #include <linux/platform_data/pxa2xx_udc.h>
-#include <mach/udc.h>
-#include <mach/pxa27x-udc.h>
 
+#include "udc.h"
+#include "pxa27x-udc.h"
 #include "devices.h"
 #include "generic.h"
 
index c3a87c1..4096406 100644 (file)
@@ -46,7 +46,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/mainstone.h>
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
diff --git a/arch/arm/mach-pxa/mfp-pxa25x.h b/arch/arm/mach-pxa/mfp-pxa25x.h
new file mode 100644 (file)
index 0000000..1c59d4b
--- /dev/null
@@ -0,0 +1,225 @@
+#ifndef __ASM_ARCH_MFP_PXA25X_H
+#define __ASM_ARCH_MFP_PXA25X_H
+
+#include "mfp-pxa2xx.h"
+
+/* GPIO */
+#define GPIO2_GPIO             MFP_CFG_IN(GPIO2, AF0)
+#define GPIO3_GPIO             MFP_CFG_IN(GPIO3, AF0)
+#define GPIO4_GPIO             MFP_CFG_IN(GPIO4, AF0)
+#define GPIO5_GPIO             MFP_CFG_IN(GPIO5, AF0)
+#define GPIO6_GPIO             MFP_CFG_IN(GPIO6, AF0)
+#define GPIO7_GPIO             MFP_CFG_IN(GPIO7, AF0)
+#define GPIO8_GPIO             MFP_CFG_IN(GPIO8, AF0)
+
+#define GPIO1_RST              MFP_CFG_IN(GPIO1, AF1)
+
+/* Crystal and Clock Signals */
+#define GPIO10_RTCCLK          MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
+#define GPIO70_RTCCLK          MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
+#define GPIO7_48MHz            MFP_CFG_OUT(GPIO7,  AF1, DRIVE_LOW)
+#define GPIO11_3_6MHz          MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
+#define GPIO71_3_6MHz          MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW)
+#define GPIO12_32KHz           MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
+#define GPIO72_32kHz           MFP_CFG_OUT(GPIO72, AF1, DRIVE_LOW)
+
+/* SDRAM and Static Memory I/O Signals */
+#define GPIO15_nCS_1           MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
+#define GPIO78_nCS_2           MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
+#define GPIO79_nCS_3           MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
+#define GPIO80_nCS_4           MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
+#define GPIO33_nCS_5           MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
+
+/* Miscellaneous I/O and DMA Signals */
+#define GPIO18_RDY             MFP_CFG_IN(GPIO18, AF1)
+#define GPIO20_DREQ_0          MFP_CFG_IN(GPIO20, AF1)
+#define GPIO19_DREQ_1          MFP_CFG_IN(GPIO19, AF1)
+
+/* Alternate Bus Master Mode I/O Signals */
+#define GPIO13_MBGNT           MFP_CFG_OUT(GPIO13, AF2, DRIVE_LOW)
+#define GPIO73_MBGNT           MFP_CFG_OUT(GPIO73, AF1, DRIVE_LOW)
+#define GPIO14_MBREQ           MFP_CFG_IN(GPIO14, AF1)
+#define GPIO66_MBREQ           MFP_CFG_IN(GPIO66, AF1)
+
+/* PC CARD */
+#define GPIO52_nPCE_1          MFP_CFG_OUT(GPIO52, AF2, DRIVE_HIGH)
+#define GPIO53_nPCE_2          MFP_CFG_OUT(GPIO53, AF2, DRIVE_HIGH)
+#define GPIO55_nPREG           MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
+#define GPIO50_nPIOR           MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
+#define GPIO51_nPIOW           MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
+#define GPIO49_nPWE            MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
+#define GPIO48_nPOE            MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
+#define GPIO57_nIOIS16         MFP_CFG_IN(GPIO57, AF1)
+#define GPIO56_nPWAIT          MFP_CFG_IN(GPIO56, AF1)
+#define GPIO54_nPSKTSEL                MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
+
+/* FFUART */
+#define GPIO34_FFUART_RXD      MFP_CFG_IN(GPIO34, AF1)
+#define GPIO35_FFUART_CTS      MFP_CFG_IN(GPIO35, AF1)
+#define GPIO36_FFUART_DCD      MFP_CFG_IN(GPIO36, AF1)
+#define GPIO37_FFUART_DSR      MFP_CFG_IN(GPIO37, AF1)
+#define GPIO38_FFUART_RI       MFP_CFG_IN(GPIO38, AF1)
+#define GPIO39_FFUART_TXD      MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
+#define GPIO40_FFUART_DTR      MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
+#define GPIO41_FFUART_RTS      MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
+
+/* BTUART */
+#define GPIO42_BTUART_RXD      MFP_CFG_IN(GPIO42, AF1)
+#define GPIO43_BTUART_TXD      MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+#define GPIO44_BTUART_CTS      MFP_CFG_IN(GPIO44, AF1)
+#define GPIO45_BTUART_RTS      MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
+
+/* STUART */
+#define GPIO46_STUART_RXD      MFP_CFG_IN(GPIO46, AF2)
+#define GPIO47_STUART_TXD      MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
+
+/* HWUART */
+#define GPIO42_HWUART_RXD      MFP_CFG_IN(GPIO42, AF3)
+#define GPIO43_HWUART_TXD      MFP_CFG_OUT(GPIO43, AF3, DRIVE_HIGH)
+#define GPIO44_HWUART_CTS      MFP_CFG_IN(GPIO44, AF3)
+#define GPIO45_HWUART_RTS      MFP_CFG_OUT(GPIO45, AF3, DRIVE_HIGH)
+#define GPIO48_HWUART_TXD      MFP_CFG_OUT(GPIO48, AF1, DRIVE_HIGH)
+#define GPIO49_HWUART_RXD      MFP_CFG_IN(GPIO49, AF1)
+#define GPIO50_HWUART_CTS      MFP_CFG_IN(GPIO50, AF1)
+#define GPIO51_HWUART_RTS      MFP_CFG_OUT(GPIO51, AF1, DRIVE_HIGH)
+
+/* FICP */
+#define GPIO46_FICP_RXD                MFP_CFG_IN(GPIO46, AF1)
+#define GPIO47_FICP_TXD                MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
+
+/* PWM 0/1 */
+#define GPIO16_PWM0_OUT                MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
+#define GPIO17_PWM1_OUT                MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO28_AC97_BITCLK     MFP_CFG_IN(GPIO28, AF1)
+#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
+#define GPIO30_AC97_SDATA_OUT  MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
+#define GPIO31_AC97_SYNC       MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
+#define GPIO32_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO32, AF1)
+
+/* I2S */
+#define GPIO28_I2S_BITCLK_IN   MFP_CFG_IN(GPIO28, AF2)
+#define GPIO28_I2S_BITCLK_OUT  MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
+#define GPIO29_I2S_SDATA_IN    MFP_CFG_IN(GPIO29, AF2)
+#define GPIO30_I2S_SDATA_OUT   MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
+#define GPIO31_I2S_SYNC                MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
+#define GPIO32_I2S_SYSCLK      MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
+
+/* SSP 1 */
+#define GPIO23_SSP1_SCLK       MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
+#define GPIO24_SSP1_SFRM       MFP_CFG_OUT(GPIO24, AF2, DRIVE_LOW)
+#define GPIO25_SSP1_TXD                MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
+#define GPIO26_SSP1_RXD                MFP_CFG_IN(GPIO26, AF1)
+#define GPIO27_SSP1_EXTCLK     MFP_CFG_IN(GPIO27, AF1)
+
+/* SSP 2 - NSSP */
+#define GPIO81_SSP2_CLK_OUT    MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
+#define GPIO81_SSP2_CLK_IN     MFP_CFG_IN(GPIO81, AF1)
+#define GPIO82_SSP2_FRM_OUT    MFP_CFG_OUT(GPIO82, AF1, DRIVE_LOW)
+#define GPIO82_SSP2_FRM_IN     MFP_CFG_IN(GPIO82, AF1)
+#define GPIO83_SSP2_TXD        MFP_CFG_OUT(GPIO83, AF1, DRIVE_LOW)
+#define GPIO83_SSP2_RXD        MFP_CFG_IN(GPIO83, AF2)
+#define GPIO84_SSP2_TXD        MFP_CFG_OUT(GPIO84, AF1, DRIVE_LOW)
+#define GPIO84_SSP2_RXD        MFP_CFG_IN(GPIO84, AF2)
+
+/* MMC */
+#define GPIO6_MMC_CLK          MFP_CFG_OUT(GPIO6, AF1, DRIVE_LOW)
+#define GPIO8_MMC_CS0          MFP_CFG_OUT(GPIO8, AF1, DRIVE_LOW)
+#define GPIO9_MMC_CS1          MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
+#define GPIO34_MMC_CS0         MFP_CFG_OUT(GPIO34, AF2, DRIVE_LOW)
+#define GPIO39_MMC_CS1         MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
+#define GPIO53_MMC_CLK         MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
+#define GPIO54_MMC_CLK         MFP_CFG_OUT(GPIO54, AF1, DRIVE_LOW)
+#define GPIO69_MMC_CLK         MFP_CFG_OUT(GPIO69, AF1, DRIVE_LOW)
+#define GPIO67_MMC_CS0         MFP_CFG_OUT(GPIO67, AF1, DRIVE_LOW)
+#define GPIO68_MMC_CS1         MFP_CFG_OUT(GPIO68, AF1, DRIVE_LOW)
+
+/* LCD */
+#define GPIO58_LCD_LDD_0       MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
+#define GPIO59_LCD_LDD_1       MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
+#define GPIO60_LCD_LDD_2       MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
+#define GPIO61_LCD_LDD_3       MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
+#define GPIO62_LCD_LDD_4       MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
+#define GPIO63_LCD_LDD_5       MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
+#define GPIO64_LCD_LDD_6       MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
+#define GPIO65_LCD_LDD_7       MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
+#define GPIO66_LCD_LDD_8       MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
+#define GPIO67_LCD_LDD_9       MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
+#define GPIO68_LCD_LDD_10      MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
+#define GPIO69_LCD_LDD_11      MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
+#define GPIO70_LCD_LDD_12      MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
+#define GPIO71_LCD_LDD_13      MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
+#define GPIO72_LCD_LDD_14      MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
+#define GPIO73_LCD_LDD_15      MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
+#define GPIO74_LCD_FCLK                MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
+#define GPIO75_LCD_LCLK                MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
+#define GPIO76_LCD_PCLK                MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
+#define GPIO77_LCD_BIAS                MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
+
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO */
+#define GPIO85_GPIO            MFP_CFG_IN(GPIO85, AF0)
+#define GPIO86_GPIO            MFP_CFG_IN(GPIO86, AF1)
+#define GPIO87_GPIO            MFP_CFG_IN(GPIO87, AF1)
+#define GPIO88_GPIO            MFP_CFG_IN(GPIO88, AF1)
+#define GPIO89_GPIO            MFP_CFG_IN(GPIO89, AF1)
+
+/* SDRAM */
+#define GPIO86_nSDCS2          MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
+#define GPIO87_nSDCS3          MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
+#define GPIO88_RDnWR           MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
+
+/* USB */
+#define GPIO9_USB_RCV          MFP_CFG_IN(GPIO9, AF1)
+#define GPIO32_USB_VP          MFP_CFG_IN(GPIO32, AF2)
+#define GPIO34_USB_VM          MFP_CFG_IN(GPIO34, AF2)
+#define GPIO39_USB_VPO         MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
+#define GPIO56_USB_VMO         MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
+#define GPIO57_USB_nOE         MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)
+
+/* ASSP */
+#define GPIO28_ASSP_BITCLK_IN  MFP_CFG_IN(GPIO28, AF3)
+#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
+#define GPIO29_ASSP_RXD                MFP_CFG_IN(GPIO29, AF3)
+#define GPIO30_ASSP_TXD                MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
+#define GPIO31_ASSP_SFRM_IN    MFP_CFG_IN(GPIO31, AF1)
+#define GPIO31_ASSP_SFRM_OUT   MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO89_AC97_nRESET     MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
+#endif /* CONFIG_CPU_PXA26x */
+
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP       \
+       GPIO58_LCD_LDD_0,       \
+       GPIO59_LCD_LDD_1,       \
+       GPIO60_LCD_LDD_2,       \
+       GPIO61_LCD_LDD_3,       \
+       GPIO62_LCD_LDD_4,       \
+       GPIO63_LCD_LDD_5,       \
+       GPIO64_LCD_LDD_6,       \
+       GPIO65_LCD_LDD_7,       \
+       GPIO66_LCD_LDD_8,       \
+       GPIO67_LCD_LDD_9,       \
+       GPIO68_LCD_LDD_10,      \
+       GPIO69_LCD_LDD_11,      \
+       GPIO70_LCD_LDD_12,      \
+       GPIO71_LCD_LDD_13,      \
+       GPIO72_LCD_LDD_14,      \
+       GPIO73_LCD_LDD_15
+
+#define GPIOxx_LCD_DSTN_16BPP  \
+       GPIOxx_LCD_16BPP,       \
+       GPIO74_LCD_FCLK,        \
+       GPIO75_LCD_LCLK,        \
+       GPIO76_LCD_PCLK
+
+#define GPIOxx_LCD_TFT_16BPP   \
+       GPIOxx_LCD_16BPP,       \
+       GPIO74_LCD_FCLK,        \
+       GPIO75_LCD_LCLK,        \
+       GPIO76_LCD_PCLK,        \
+       GPIO77_LCD_BIAS
+
+#endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa27x.h b/arch/arm/mach-pxa/mfp-pxa27x.h
new file mode 100644 (file)
index 0000000..9fe5601
--- /dev/null
@@ -0,0 +1,471 @@
+#ifndef __ASM_ARCH_MFP_PXA27X_H
+#define __ASM_ARCH_MFP_PXA27X_H
+
+/*
+ * NOTE:  for those special-function bidirectional GPIOs, as described
+ * in the "PXA27x Developer's Manual" Section 24.4.2.1, only its input
+ * alternative is preserved, the direction is actually selected by the
+ * specific controller, and this should work in most cases.
+ */
+
+#include "mfp-pxa2xx.h"
+
+/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
+ * bit is set, regardless of the GPIO configuration
+ */
+#define GPIO3_GPIO             MFP_CFG_IN(GPIO3, AF0)
+#define GPIO4_GPIO             MFP_CFG_IN(GPIO4, AF0)
+
+/* GPIO */
+#define GPIO85_GPIO            MFP_CFG_IN(GPIO85, AF0)
+#define GPIO86_GPIO            MFP_CFG_IN(GPIO86, AF0)
+#define GPIO87_GPIO            MFP_CFG_IN(GPIO87, AF0)
+#define GPIO88_GPIO            MFP_CFG_IN(GPIO88, AF0)
+#define GPIO89_GPIO            MFP_CFG_IN(GPIO89, AF0)
+#define GPIO90_GPIO            MFP_CFG_IN(GPIO90, AF0)
+#define GPIO91_GPIO            MFP_CFG_IN(GPIO91, AF0)
+#define GPIO92_GPIO            MFP_CFG_IN(GPIO92, AF0)
+#define GPIO93_GPIO            MFP_CFG_IN(GPIO93, AF0)
+#define GPIO94_GPIO            MFP_CFG_IN(GPIO94, AF0)
+#define GPIO95_GPIO            MFP_CFG_IN(GPIO95, AF0)
+#define GPIO96_GPIO            MFP_CFG_IN(GPIO96, AF0)
+#define GPIO97_GPIO            MFP_CFG_IN(GPIO97, AF0)
+#define GPIO98_GPIO            MFP_CFG_IN(GPIO98, AF0)
+#define GPIO99_GPIO            MFP_CFG_IN(GPIO99, AF0)
+#define GPIO100_GPIO           MFP_CFG_IN(GPIO100, AF0)
+#define GPIO101_GPIO           MFP_CFG_IN(GPIO101, AF0)
+#define GPIO102_GPIO           MFP_CFG_IN(GPIO102, AF0)
+#define GPIO103_GPIO           MFP_CFG_IN(GPIO103, AF0)
+#define GPIO104_GPIO           MFP_CFG_IN(GPIO104, AF0)
+#define GPIO105_GPIO           MFP_CFG_IN(GPIO105, AF0)
+#define GPIO106_GPIO           MFP_CFG_IN(GPIO106, AF0)
+#define GPIO107_GPIO           MFP_CFG_IN(GPIO107, AF0)
+#define GPIO108_GPIO           MFP_CFG_IN(GPIO108, AF0)
+#define GPIO109_GPIO           MFP_CFG_IN(GPIO109, AF0)
+#define GPIO110_GPIO           MFP_CFG_IN(GPIO110, AF0)
+#define GPIO111_GPIO           MFP_CFG_IN(GPIO111, AF0)
+#define GPIO112_GPIO           MFP_CFG_IN(GPIO112, AF0)
+#define GPIO113_GPIO           MFP_CFG_IN(GPIO113, AF0)
+#define GPIO114_GPIO           MFP_CFG_IN(GPIO114, AF0)
+#define GPIO115_GPIO           MFP_CFG_IN(GPIO115, AF0)
+#define GPIO116_GPIO           MFP_CFG_IN(GPIO116, AF0)
+#define GPIO117_GPIO           MFP_CFG_IN(GPIO117, AF0)
+#define GPIO118_GPIO           MFP_CFG_IN(GPIO118, AF0)
+#define GPIO119_GPIO           MFP_CFG_IN(GPIO119, AF0)
+#define GPIO120_GPIO           MFP_CFG_IN(GPIO120, AF0)
+
+/* Crystal and Clock Signals */
+#define GPIO9_HZ_CLK           MFP_CFG_OUT(GPIO9,  AF1, DRIVE_LOW)
+#define GPIO10_HZ_CLK          MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
+#define GPIO11_48_MHz          MFP_CFG_OUT(GPIO11, AF3, DRIVE_LOW)
+#define GPIO12_48_MHz          MFP_CFG_OUT(GPIO12, AF3, DRIVE_LOW)
+#define GPIO13_CLK_EXT         MFP_CFG_IN(GPIO13, AF1)
+
+/* OS Timer Signals */
+#define GPIO11_EXT_SYNC_0      MFP_CFG_IN(GPIO11, AF1)
+#define GPIO12_EXT_SYNC_1      MFP_CFG_IN(GPIO12, AF1)
+#define GPIO9_CHOUT_0          MFP_CFG_OUT(GPIO9,  AF3, DRIVE_LOW)
+#define GPIO10_CHOUT_1         MFP_CFG_OUT(GPIO10, AF3, DRIVE_LOW)
+#define GPIO11_CHOUT_0         MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
+#define GPIO12_CHOUT_1         MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
+
+/* SDRAM and Static Memory I/O Signals */
+#define GPIO20_nSDCS_2         MFP_CFG_OUT(GPIO20, AF1, DRIVE_HIGH)
+#define GPIO21_nSDCS_3         MFP_CFG_OUT(GPIO21, AF1, DRIVE_HIGH)
+#define GPIO15_nCS_1           MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
+#define GPIO78_nCS_2           MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
+#define GPIO79_nCS_3           MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
+#define GPIO80_nCS_4           MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
+#define GPIO33_nCS_5           MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
+
+/* Miscellaneous I/O and DMA Signals */
+#define GPIO21_DVAL_0          MFP_CFG_OUT(GPIO21, AF2, DRIVE_HIGH)
+#define GPIO116_DVAL_0         MFP_CFG_OUT(GPIO116, AF1, DRIVE_HIGH)
+#define GPIO33_DVAL_1          MFP_CFG_OUT(GPIO33, AF1, DRIVE_HIGH)
+#define GPIO96_DVAL_1          MFP_CFG_OUT(GPIO96, AF2, DRIVE_HIGH)
+#define GPIO18_RDY             MFP_CFG_IN(GPIO18, AF1)
+#define GPIO20_DREQ_0          MFP_CFG_IN(GPIO20, AF1)
+#define GPIO115_DREQ_0         MFP_CFG_IN(GPIO115, AF1)
+#define GPIO80_DREQ_1          MFP_CFG_IN(GPIO80, AF1)
+#define GPIO97_DREQ_1          MFP_CFG_IN(GPIO97, AF2)
+#define GPIO85_DREQ_2          MFP_CFG_IN(GPIO85, AF2)
+#define GPIO100_DREQ_2         MFP_CFG_IN(GPIO100, AF2)
+
+/* Alternate Bus Master Mode I/O Signals */
+#define GPIO20_MBREQ           MFP_CFG_IN(GPIO20, AF2)
+#define GPIO80_MBREQ           MFP_CFG_IN(GPIO80, AF2)
+#define GPIO96_MBREQ           MFP_CFG_IN(GPIO96, AF2)
+#define GPIO115_MBREQ          MFP_CFG_IN(GPIO115, AF3)
+#define GPIO21_MBGNT           MFP_CFG_OUT(GPIO21, AF3, DRIVE_LOW)
+#define GPIO33_MBGNT           MFP_CFG_OUT(GPIO33, AF3, DRIVE_LOW)
+#define GPIO97_MBGNT           MFP_CFG_OUT(GPIO97, AF2, DRIVE_LOW)
+#define GPIO116_MBGNT          MFP_CFG_OUT(GPIO116, AF3, DRIVE_LOW)
+
+/* PC CARD */
+#define GPIO15_nPCE_1          MFP_CFG_OUT(GPIO15, AF1, DRIVE_HIGH)
+#define GPIO85_nPCE_1          MFP_CFG_OUT(GPIO85, AF1, DRIVE_HIGH)
+#define GPIO86_nPCE_1          MFP_CFG_OUT(GPIO86, AF1, DRIVE_HIGH)
+#define GPIO102_nPCE_1         MFP_CFG_OUT(GPIO102, AF1, DRIVE_HIGH)
+#define GPIO54_nPCE_2          MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
+#define GPIO78_nPCE_2          MFP_CFG_OUT(GPIO78, AF1, DRIVE_HIGH)
+#define GPIO87_nPCE_2          MFP_CFG_IN(GPIO87, AF1)
+#define GPIO55_nPREG           MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
+#define GPIO50_nPIOR           MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
+#define GPIO51_nPIOW           MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
+#define GPIO49_nPWE            MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
+#define GPIO48_nPOE            MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
+#define GPIO57_nIOIS16         MFP_CFG_IN(GPIO57, AF1)
+#define GPIO56_nPWAIT          MFP_CFG_IN(GPIO56, AF1)
+#define GPIO79_PSKTSEL         MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH)
+#define GPIO104_PSKTSEL                MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH)
+
+/* I2C */
+#define GPIO117_I2C_SCL                MFP_CFG_IN(GPIO117, AF1)
+#define GPIO118_I2C_SDA                MFP_CFG_IN(GPIO118, AF1)
+
+/* FFUART */
+#define GPIO9_FFUART_CTS       MFP_CFG_IN(GPIO9, AF3)
+#define GPIO26_FFUART_CTS      MFP_CFG_IN(GPIO26, AF3)
+#define GPIO35_FFUART_CTS      MFP_CFG_IN(GPIO35, AF1)
+#define GPIO100_FFUART_CTS     MFP_CFG_IN(GPIO100, AF3)
+#define GPIO10_FFUART_DCD      MFP_CFG_IN(GPIO10, AF1)
+#define GPIO36_FFUART_DCD      MFP_CFG_IN(GPIO36, AF1)
+#define GPIO33_FFUART_DSR      MFP_CFG_IN(GPIO33, AF2)
+#define GPIO37_FFUART_DSR      MFP_CFG_IN(GPIO37, AF1)
+#define GPIO38_FFUART_RI       MFP_CFG_IN(GPIO38, AF1)
+#define GPIO89_FFUART_RI       MFP_CFG_IN(GPIO89, AF3)
+#define GPIO19_FFUART_RXD      MFP_CFG_IN(GPIO19, AF3)
+#define GPIO33_FFUART_RXD      MFP_CFG_IN(GPIO33, AF1)
+#define GPIO34_FFUART_RXD      MFP_CFG_IN(GPIO34, AF1)
+#define GPIO41_FFUART_RXD      MFP_CFG_IN(GPIO41, AF1)
+#define GPIO53_FFUART_RXD      MFP_CFG_IN(GPIO53, AF1)
+#define GPIO85_FFUART_RXD      MFP_CFG_IN(GPIO85, AF1)
+#define GPIO96_FFUART_RXD      MFP_CFG_IN(GPIO96, AF3)
+#define GPIO102_FFUART_RXD     MFP_CFG_IN(GPIO102, AF3)
+#define GPIO16_FFUART_TXD      MFP_CFG_OUT(GPIO16, AF3, DRIVE_HIGH)
+#define GPIO37_FFUART_TXD      MFP_CFG_OUT(GPIO37, AF3, DRIVE_HIGH)
+#define GPIO39_FFUART_TXD      MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
+#define GPIO83_FFUART_TXD      MFP_CFG_OUT(GPIO83, AF2, DRIVE_HIGH)
+#define GPIO99_FFUART_TXD      MFP_CFG_OUT(GPIO99, AF3, DRIVE_HIGH)
+#define GPIO27_FFUART_RTS      MFP_CFG_OUT(GPIO27, AF3, DRIVE_HIGH)
+#define GPIO41_FFUART_RTS      MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
+#define GPIO83_FFUART_RTS      MFP_CFG_OUT(GPIO83, AF3, DRIVE_HIGH)
+#define GPIO98_FFUART_RTS      MFP_CFG_OUT(GPIO98, AF3, DRIVE_HIGH)
+#define GPIO40_FFUART_DTR      MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
+#define GPIO82_FFUART_DTR      MFP_CFG_OUT(GPIO82, AF3, DRIVE_HIGH)
+
+/* BTUART */
+#define GPIO44_BTUART_CTS      MFP_CFG_IN(GPIO44, AF1)
+#define GPIO42_BTUART_RXD      MFP_CFG_IN(GPIO42, AF1)
+#define GPIO45_BTUART_RTS      MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
+#define GPIO45_BTUART_RTS_LPM_LOW      MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW)
+#define GPIO43_BTUART_TXD      MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+#define GPIO43_BTUART_TXD_LPM_LOW      MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW)
+
+/* STUART */
+#define GPIO46_STUART_RXD      MFP_CFG_IN(GPIO46, AF2)
+#define GPIO47_STUART_TXD      MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
+
+/* FICP */
+#define GPIO42_FICP_RXD                MFP_CFG_IN(GPIO42, AF2)
+#define GPIO46_FICP_RXD                MFP_CFG_IN(GPIO46, AF1)
+#define GPIO43_FICP_TXD                MFP_CFG_OUT(GPIO43, AF1, DRIVE_HIGH)
+#define GPIO47_FICP_TXD                MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
+
+/* PWM 0/1/2/3 */
+#define GPIO11_PWM2_OUT                MFP_CFG_OUT(GPIO11, AF2, DRIVE_LOW)
+#define GPIO12_PWM3_OUT                MFP_CFG_OUT(GPIO12, AF2, DRIVE_LOW)
+#define GPIO16_PWM0_OUT                MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
+#define GPIO17_PWM1_OUT                MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
+#define GPIO38_PWM1_OUT                MFP_CFG_OUT(GPIO38, AF3, DRIVE_LOW)
+#define GPIO46_PWM2_OUT                MFP_CFG_OUT(GPIO46, AF2, DRIVE_LOW)
+#define GPIO47_PWM3_OUT                MFP_CFG_OUT(GPIO47, AF3, DRIVE_LOW)
+#define GPIO79_PWM2_OUT                MFP_CFG_OUT(GPIO79, AF3, DRIVE_LOW)
+#define GPIO80_PWM3_OUT                MFP_CFG_OUT(GPIO80, AF3, DRIVE_LOW)
+#define GPIO115_PWM1_OUT       MFP_CFG_OUT(GPIO115, AF3, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO31_AC97_SYNC       MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
+#define GPIO94_AC97_SYNC       MFP_CFG_OUT(GPIO94, AF1, DRIVE_LOW)
+#define GPIO30_AC97_SDATA_OUT  MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
+#define GPIO93_AC97_SDATA_OUT  MFP_CFG_OUT(GPIO93, AF1, DRIVE_LOW)
+#define GPIO45_AC97_SYSCLK     MFP_CFG_OUT(GPIO45, AF1, DRIVE_LOW)
+#define GPIO89_AC97_SYSCLK     MFP_CFG_OUT(GPIO89, AF1, DRIVE_LOW)
+#define GPIO98_AC97_SYSCLK     MFP_CFG_OUT(GPIO98, AF1, DRIVE_LOW)
+#define GPIO95_AC97_nRESET     MFP_CFG_OUT(GPIO95, AF1, DRIVE_LOW)
+#define GPIO113_AC97_nRESET    MFP_CFG_OUT(GPIO113, AF2, DRIVE_LOW)
+#define GPIO28_AC97_BITCLK     MFP_CFG_IN(GPIO28, AF1)
+#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
+#define GPIO116_AC97_SDATA_IN_0        MFP_CFG_IN(GPIO116, AF2)
+#define GPIO99_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO99, AF2)
+
+/* I2S */
+#define GPIO28_I2S_BITCLK_IN   MFP_CFG_IN(GPIO28, AF2)
+#define GPIO28_I2S_BITCLK_OUT  MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
+#define GPIO29_I2S_SDATA_IN    MFP_CFG_IN(GPIO29, AF2)
+#define GPIO30_I2S_SDATA_OUT   MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
+#define GPIO31_I2S_SYNC                MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
+#define GPIO113_I2S_SYSCLK     MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW)
+
+/* SSP 1 */
+#define GPIO23_SSP1_SCLK_IN    MFP_CFG_IN(GPIO23, AF2)
+#define GPIO23_SSP1_SCLK       MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
+#define GPIO29_SSP1_SCLK       MFP_CFG_IN(GPIO29, AF3)
+#define GPIO27_SSP1_SYSCLK     MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW)
+#define GPIO53_SSP1_SYSCLK     MFP_CFG_OUT(GPIO53, AF3, DRIVE_LOW)
+#define GPIO24_SSP1_SFRM       MFP_CFG_IN(GPIO24, AF2)
+#define GPIO28_SSP1_SFRM       MFP_CFG_IN(GPIO28, AF3)
+#define GPIO25_SSP1_TXD                MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
+#define GPIO57_SSP1_TXD                MFP_CFG_OUT(GPIO57, AF3, DRIVE_LOW)
+#define GPIO26_SSP1_RXD                MFP_CFG_IN(GPIO26, AF1)
+#define GPIO27_SSP1_SCLKEN     MFP_CFG_IN(GPIO27, AF2)
+
+/* SSP 2 */
+#define GPIO19_SSP2_SCLK       MFP_CFG_IN(GPIO19, AF1)
+#define GPIO22_SSP2_SCLK       MFP_CFG_IN(GPIO22, AF3)
+#define GPIO29_SSP2_SCLK       MFP_CFG_OUT(GPIO29, AF3, DRIVE_LOW)
+#define GPIO36_SSP2_SCLK       MFP_CFG_IN(GPIO36, AF2)
+#define GPIO50_SSP2_SCLK       MFP_CFG_IN(GPIO50, AF3)
+#define GPIO22_SSP2_SYSCLK     MFP_CFG_OUT(GPIO22, AF2, DRIVE_LOW)
+#define GPIO14_SSP2_SFRM       MFP_CFG_IN(GPIO14, AF2)
+#define GPIO37_SSP2_SFRM       MFP_CFG_IN(GPIO37, AF2)
+#define GPIO87_SSP2_SFRM       MFP_CFG_OUT(GPIO87, AF3, DRIVE_LOW)
+#define GPIO88_SSP2_SFRM       MFP_CFG_IN(GPIO88, AF3)
+#define GPIO13_SSP2_TXD                MFP_CFG_OUT(GPIO13, AF1, DRIVE_LOW)
+#define GPIO38_SSP2_TXD                MFP_CFG_OUT(GPIO38, AF2, DRIVE_LOW)
+#define GPIO87_SSP2_TXD                MFP_CFG_OUT(GPIO87, AF1, DRIVE_LOW)
+#define GPIO89_SSP2_TXD                MFP_CFG_OUT(GPIO89, AF3, DRIVE_LOW)
+#define GPIO11_SSP2_RXD                MFP_CFG_IN(GPIO11, AF2)
+#define GPIO29_SSP2_RXD                MFP_CFG_OUT(GPIO29, AF1, DRIVE_LOW)
+#define GPIO40_SSP2_RXD                MFP_CFG_IN(GPIO40, AF1)
+#define GPIO86_SSP2_RXD                MFP_CFG_IN(GPIO86, AF1)
+#define GPIO88_SSP2_RXD                MFP_CFG_IN(GPIO88, AF2)
+#define GPIO22_SSP2_EXTCLK     MFP_CFG_IN(GPIO22, AF1)
+#define GPIO27_SSP2_EXTCLK     MFP_CFG_IN(GPIO27, AF1)
+#define GPIO22_SSP2_SCLKEN     MFP_CFG_IN(GPIO22, AF2)
+#define GPIO23_SSP2_SCLKEN     MFP_CFG_IN(GPIO23, AF2)
+
+/* SSP 3 */
+#define GPIO34_SSP3_SCLK       MFP_CFG_IN(GPIO34, AF3)
+#define GPIO40_SSP3_SCLK       MFP_CFG_OUT(GPIO40, AF3, DRIVE_LOW)
+#define GPIO52_SSP3_SCLK       MFP_CFG_IN(GPIO52, AF2)
+#define GPIO84_SSP3_SCLK       MFP_CFG_IN(GPIO84, AF1)
+#define GPIO45_SSP3_SYSCLK     MFP_CFG_OUT(GPIO45, AF3, DRIVE_LOW)
+#define GPIO35_SSP3_SFRM       MFP_CFG_IN(GPIO35, AF3)
+#define GPIO39_SSP3_SFRM       MFP_CFG_IN(GPIO39, AF3)
+#define GPIO83_SSP3_SFRM       MFP_CFG_IN(GPIO83, AF1)
+#define GPIO35_SSP3_TXD                MFP_CFG_OUT(GPIO35, AF3, DRIVE_LOW)
+#define GPIO38_SSP3_TXD                MFP_CFG_OUT(GPIO38, AF1, DRIVE_LOW)
+#define GPIO81_SSP3_TXD                MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
+#define GPIO41_SSP3_RXD                MFP_CFG_IN(GPIO41, AF3)
+#define GPIO82_SSP3_RXD                MFP_CFG_IN(GPIO82, AF1)
+#define GPIO89_SSP3_RXD                MFP_CFG_IN(GPIO89, AF1)
+
+/* MMC */
+#define GPIO32_MMC_CLK         MFP_CFG_OUT(GPIO32, AF2, DRIVE_LOW)
+#define GPIO92_MMC_DAT_0       MFP_CFG_IN(GPIO92, AF1)
+#define GPIO109_MMC_DAT_1      MFP_CFG_IN(GPIO109, AF1)
+#define GPIO110_MMC_DAT_2      MFP_CFG_IN(GPIO110, AF1)
+#define GPIO111_MMC_DAT_3      MFP_CFG_IN(GPIO111, AF1)
+#define GPIO112_MMC_CMD                MFP_CFG_IN(GPIO112, AF1)
+
+/* LCD */
+#define GPIO58_LCD_LDD_0       MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
+#define GPIO59_LCD_LDD_1       MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
+#define GPIO60_LCD_LDD_2       MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
+#define GPIO61_LCD_LDD_3       MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
+#define GPIO62_LCD_LDD_4       MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
+#define GPIO63_LCD_LDD_5       MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
+#define GPIO64_LCD_LDD_6       MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
+#define GPIO65_LCD_LDD_7       MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
+#define GPIO66_LCD_LDD_8       MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
+#define GPIO67_LCD_LDD_9       MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
+#define GPIO68_LCD_LDD_10      MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
+#define GPIO69_LCD_LDD_11      MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
+#define GPIO70_LCD_LDD_12      MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
+#define GPIO71_LCD_LDD_13      MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
+#define GPIO72_LCD_LDD_14      MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
+#define GPIO73_LCD_LDD_15      MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
+#define GPIO86_LCD_LDD_16      MFP_CFG_OUT(GPIO86, AF2, DRIVE_LOW)
+#define GPIO87_LCD_LDD_17      MFP_CFG_OUT(GPIO87, AF2, DRIVE_LOW)
+#define GPIO74_LCD_FCLK                MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
+#define GPIO75_LCD_LCLK                MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
+#define GPIO76_LCD_PCLK                MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
+#define GPIO77_LCD_BIAS                MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
+#define GPIO14_LCD_VSYNC       MFP_CFG_IN(GPIO14, AF1)
+#define GPIO19_LCD_CS          MFP_CFG_OUT(GPIO19, AF2, DRIVE_LOW)
+
+/* Keypad */
+#define GPIO93_KP_DKIN_0       MFP_CFG_IN(GPIO93, AF1)
+#define GPIO94_KP_DKIN_1       MFP_CFG_IN(GPIO94, AF1)
+#define GPIO95_KP_DKIN_2       MFP_CFG_IN(GPIO95, AF1)
+#define GPIO96_KP_DKIN_3       MFP_CFG_IN(GPIO96, AF1)
+#define GPIO97_KP_DKIN_4       MFP_CFG_IN(GPIO97, AF1)
+#define GPIO98_KP_DKIN_5       MFP_CFG_IN(GPIO98, AF1)
+#define GPIO99_KP_DKIN_6       MFP_CFG_IN(GPIO99, AF1)
+#define GPIO13_KP_KDIN_7       MFP_CFG_IN(GPIO13, AF2)
+#define GPIO100_KP_MKIN_0      MFP_CFG_IN(GPIO100, AF1)
+#define GPIO101_KP_MKIN_1      MFP_CFG_IN(GPIO101, AF1)
+#define GPIO102_KP_MKIN_2      MFP_CFG_IN(GPIO102, AF1)
+#define GPIO34_KP_MKIN_3       MFP_CFG_IN(GPIO34, AF2)
+#define GPIO37_KP_MKIN_3       MFP_CFG_IN(GPIO37, AF3)
+#define GPIO97_KP_MKIN_3       MFP_CFG_IN(GPIO97, AF3)
+#define GPIO98_KP_MKIN_4       MFP_CFG_IN(GPIO98, AF3)
+#define GPIO38_KP_MKIN_4       MFP_CFG_IN(GPIO38, AF2)
+#define GPIO39_KP_MKIN_4       MFP_CFG_IN(GPIO39, AF1)
+#define GPIO16_KP_MKIN_5       MFP_CFG_IN(GPIO16, AF1)
+#define GPIO90_KP_MKIN_5       MFP_CFG_IN(GPIO90, AF1)
+#define GPIO99_KP_MKIN_5       MFP_CFG_IN(GPIO99, AF3)
+#define GPIO17_KP_MKIN_6       MFP_CFG_IN(GPIO17, AF1)
+#define GPIO91_KP_MKIN_6       MFP_CFG_IN(GPIO91, AF1)
+#define GPIO95_KP_MKIN_6       MFP_CFG_IN(GPIO95, AF3)
+#define GPIO13_KP_MKIN_7       MFP_CFG_IN(GPIO13, AF3)
+#define GPIO36_KP_MKIN_7       MFP_CFG_IN(GPIO36, AF3)
+#define GPIO103_KP_MKOUT_0     MFP_CFG_OUT(GPIO103, AF2, DRIVE_HIGH)
+#define GPIO104_KP_MKOUT_1     MFP_CFG_OUT(GPIO104, AF2, DRIVE_HIGH)
+#define GPIO105_KP_MKOUT_2     MFP_CFG_OUT(GPIO105, AF2, DRIVE_HIGH)
+#define GPIO106_KP_MKOUT_3     MFP_CFG_OUT(GPIO106, AF2, DRIVE_HIGH)
+#define GPIO107_KP_MKOUT_4     MFP_CFG_OUT(GPIO107, AF2, DRIVE_HIGH)
+#define GPIO108_KP_MKOUT_5     MFP_CFG_OUT(GPIO108, AF2, DRIVE_HIGH)
+#define GPIO35_KP_MKOUT_6      MFP_CFG_OUT(GPIO35, AF2, DRIVE_HIGH)
+#define GPIO22_KP_MKOUT_7      MFP_CFG_OUT(GPIO22, AF1, DRIVE_HIGH)
+#define GPIO40_KP_MKOUT_6      MFP_CFG_OUT(GPIO40, AF1, DRIVE_HIGH)
+#define GPIO41_KP_MKOUT_7      MFP_CFG_OUT(GPIO41, AF1, DRIVE_HIGH)
+#define GPIO96_KP_MKOUT_6      MFP_CFG_OUT(GPIO96, AF3, DRIVE_HIGH)
+
+/* USB P3 */
+#define GPIO10_USB_P3_5                MFP_CFG_IN(GPIO10, AF3)
+#define GPIO11_USB_P3_1                MFP_CFG_IN(GPIO11, AF3)
+#define GPIO30_USB_P3_2                MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
+#define GPIO31_USB_P3_6                MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
+#define GPIO56_USB_P3_4                MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
+#define GPIO86_USB_P3_5                MFP_CFG_IN(GPIO86, AF3)
+#define GPIO87_USB_P3_1                MFP_CFG_IN(GPIO87, AF3)
+#define GPIO90_USB_P3_5                MFP_CFG_IN(GPIO90, AF2)
+#define GPIO91_USB_P3_1                MFP_CFG_IN(GPIO91, AF2)
+#define GPIO113_USB_P3_3       MFP_CFG_IN(GPIO113, AF3)
+
+/* USB P2 */
+#define GPIO34_USB_P2_2                MFP_CFG_OUT(GPIO34, AF1, DRIVE_LOW)
+#define GPIO35_USB_P2_1                MFP_CFG_IN(GPIO35, AF2)
+#define GPIO36_USB_P2_4                MFP_CFG_OUT(GPIO36, AF1, DRIVE_LOW)
+#define GPIO37_USB_P2_8                MFP_CFG_OUT(GPIO37, AF1, DRIVE_LOW)
+#define GPIO38_USB_P2_3                MFP_CFG_IN(GPIO38, AF3)
+#define GPIO39_USB_P2_6                MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
+#define GPIO40_USB_P2_5                MFP_CFG_IN(GPIO40, AF3)
+#define GPIO41_USB_P2_7                MFP_CFG_IN(GPIO41, AF2)
+#define GPIO53_USB_P2_3                MFP_CFG_IN(GPIO53, AF2)
+
+/* USB Host Port 1/2 */
+#define GPIO88_USBH1_PWR       MFP_CFG_IN(GPIO88, AF1)
+#define GPIO89_USBH1_PEN       MFP_CFG_OUT(GPIO89, AF2, DRIVE_LOW)
+#define GPIO119_USBH2_PWR      MFP_CFG_IN(GPIO119, AF1)
+#define GPIO120_USBH2_PEN      MFP_CFG_OUT(GPIO120, AF2, DRIVE_LOW)
+
+/* QCI - default to Master Mode: CIF_FV/CIF_LV Direction In */
+#define GPIO115_CIF_DD_3       MFP_CFG_IN(GPIO115, AF2)
+#define GPIO116_CIF_DD_2       MFP_CFG_IN(GPIO116, AF1)
+#define GPIO12_CIF_DD_7                MFP_CFG_IN(GPIO12, AF2)
+#define GPIO17_CIF_DD_6                MFP_CFG_IN(GPIO17, AF2)
+#define GPIO23_CIF_MCLK                MFP_CFG_OUT(GPIO23, AF1, DRIVE_LOW)
+#define GPIO24_CIF_FV          MFP_CFG_IN(GPIO24, AF1)
+#define GPIO25_CIF_LV          MFP_CFG_IN(GPIO25, AF1)
+#define GPIO26_CIF_PCLK                MFP_CFG_IN(GPIO26, AF2)
+#define GPIO27_CIF_DD_0                MFP_CFG_IN(GPIO27, AF3)
+#define GPIO42_CIF_MCLK                MFP_CFG_OUT(GPIO42, AF3, DRIVE_LOW)
+#define GPIO43_CIF_FV          MFP_CFG_IN(GPIO43, AF3)
+#define GPIO44_CIF_LV          MFP_CFG_IN(GPIO44, AF3)
+#define GPIO45_CIF_PCLK                MFP_CFG_IN(GPIO45, AF3)
+#define GPIO47_CIF_DD_0                MFP_CFG_IN(GPIO47, AF1)
+#define GPIO48_CIF_DD_5                MFP_CFG_IN(GPIO48, AF1)
+#define GPIO50_CIF_DD_3                MFP_CFG_IN(GPIO50, AF1)
+#define GPIO51_CIF_DD_2                MFP_CFG_IN(GPIO51, AF1)
+#define GPIO52_CIF_DD_4                MFP_CFG_IN(GPIO52, AF1)
+#define GPIO53_CIF_MCLK                MFP_CFG_OUT(GPIO53, AF2, DRIVE_LOW)
+#define GPIO54_CIF_PCLK                MFP_CFG_IN(GPIO54, AF3)
+#define GPIO55_CIF_DD_1                MFP_CFG_IN(GPIO55, AF1)
+#define GPIO81_CIF_DD_0                MFP_CFG_IN(GPIO81, AF2)
+#define GPIO82_CIF_DD_5                MFP_CFG_IN(GPIO82, AF3)
+#define GPIO83_CIF_DD_4                MFP_CFG_IN(GPIO83, AF3)
+#define GPIO84_CIF_FV          MFP_CFG_IN(GPIO84, AF3)
+#define GPIO85_CIF_LV          MFP_CFG_IN(GPIO85, AF3)
+#define GPIO90_CIF_DD_4                MFP_CFG_IN(GPIO90, AF3)
+#define GPIO91_CIF_DD_5                MFP_CFG_IN(GPIO91, AF3)
+#define GPIO93_CIF_DD_6                MFP_CFG_IN(GPIO93, AF2)
+#define GPIO94_CIF_DD_5                MFP_CFG_IN(GPIO94, AF2)
+#define GPIO95_CIF_DD_4                MFP_CFG_IN(GPIO95, AF2)
+#define GPIO98_CIF_DD_0                MFP_CFG_IN(GPIO98, AF2)
+#define GPIO103_CIF_DD_3       MFP_CFG_IN(GPIO103, AF1)
+#define GPIO104_CIF_DD_2       MFP_CFG_IN(GPIO104, AF1)
+#define GPIO105_CIF_DD_1       MFP_CFG_IN(GPIO105, AF1)
+#define GPIO106_CIF_DD_9       MFP_CFG_IN(GPIO106, AF1)
+#define GPIO107_CIF_DD_8       MFP_CFG_IN(GPIO107, AF1)
+#define GPIO108_CIF_DD_7       MFP_CFG_IN(GPIO108, AF1)
+#define GPIO114_CIF_DD_1       MFP_CFG_IN(GPIO114, AF1)
+
+/* Universal Subscriber ID Interface */
+#define GPIO114_UVS0           MFP_CFG_OUT(GPIO114, AF2, DRIVE_LOW)
+#define GPIO115_nUVS1          MFP_CFG_OUT(GPIO115, AF2, DRIVE_LOW)
+#define GPIO116_nUVS2          MFP_CFG_OUT(GPIO116, AF2, DRIVE_LOW)
+#define GPIO14_UCLK            MFP_CFG_OUT(GPIO14, AF3, DRIVE_LOW)
+#define GPIO91_UCLK            MFP_CFG_OUT(GPIO91, AF2, DRIVE_LOW)
+#define GPIO19_nURST           MFP_CFG_OUT(GPIO19, AF3, DRIVE_LOW)
+#define GPIO90_nURST           MFP_CFG_OUT(GPIO90, AF2, DRIVE_LOW)
+#define GPIO116_UDET           MFP_CFG_IN(GPIO116, AF3)
+#define GPIO114_UEN            MFP_CFG_OUT(GPIO114, AF1, DRIVE_LOW)
+#define GPIO115_UEN            MFP_CFG_OUT(GPIO115, AF1, DRIVE_LOW)
+
+/* Mobile Scalable Link (MSL) Interface */
+#define GPIO81_BB_OB_DAT_0     MFP_CFG_OUT(GPIO81, AF2, DRIVE_LOW)
+#define GPIO48_BB_OB_DAT_1     MFP_CFG_OUT(GPIO48, AF1, DRIVE_LOW)
+#define GPIO50_BB_OB_DAT_2     MFP_CFG_OUT(GPIO50, AF1, DRIVE_LOW)
+#define GPIO51_BB_OB_DAT_3     MFP_CFG_OUT(GPIO51, AF1, DRIVE_LOW)
+#define GPIO52_BB_OB_CLK       MFP_CFG_OUT(GPIO52, AF1, DRIVE_LOW)
+#define GPIO53_BB_OB_STB       MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
+#define GPIO54_BB_OB_WAIT      MFP_CFG_IN(GPIO54, AF2)
+#define GPIO82_BB_IB_DAT_0     MFP_CFG_IN(GPIO82, AF2)
+#define GPIO55_BB_IB_DAT_1     MFP_CFG_IN(GPIO55, AF2)
+#define GPIO56_BB_IB_DAT_2     MFP_CFG_IN(GPIO56, AF2)
+#define GPIO57_BB_IB_DAT_3     MFP_CFG_IN(GPIO57, AF2)
+#define GPIO83_BB_IB_CLK       MFP_CFG_IN(GPIO83, AF2)
+#define GPIO84_BB_IB_STB       MFP_CFG_IN(GPIO84, AF2)
+#define GPIO85_BB_IB_WAIT      MFP_CFG_OUT(GPIO85, AF2, DRIVE_LOW)
+
+/* Memory Stick Host Controller */
+#define GPIO92_MSBS            MFP_CFG_OUT(GPIO92, AF2, DRIVE_LOW)
+#define GPIO109_MSSDIO         MFP_CFG_IN(GPIO109, AF2)
+#define GPIO112_nMSINS         MFP_CFG_IN(GPIO112, AF2)
+#define GPIO32_MSSCLK          MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
+
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP       \
+       GPIO58_LCD_LDD_0,       \
+       GPIO59_LCD_LDD_1,       \
+       GPIO60_LCD_LDD_2,       \
+       GPIO61_LCD_LDD_3,       \
+       GPIO62_LCD_LDD_4,       \
+       GPIO63_LCD_LDD_5,       \
+       GPIO64_LCD_LDD_6,       \
+       GPIO65_LCD_LDD_7,       \
+       GPIO66_LCD_LDD_8,       \
+       GPIO67_LCD_LDD_9,       \
+       GPIO68_LCD_LDD_10,      \
+       GPIO69_LCD_LDD_11,      \
+       GPIO70_LCD_LDD_12,      \
+       GPIO71_LCD_LDD_13,      \
+       GPIO72_LCD_LDD_14,      \
+       GPIO73_LCD_LDD_15
+
+#define GPIOxx_LCD_TFT_16BPP   \
+       GPIOxx_LCD_16BPP,       \
+       GPIO74_LCD_FCLK,        \
+       GPIO75_LCD_LCLK,        \
+       GPIO76_LCD_PCLK,        \
+       GPIO77_LCD_BIAS
+
+/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */
+#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT)
+#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT)
+
+extern int keypad_set_wake(unsigned int on);
+#endif /* __ASM_ARCH_MFP_PXA27X_H */
index 666b789..3732aec 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/syscore_ops.h>
 
 #include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa2xx.h>
+#include "mfp-pxa2xx.h"
 
 #include "generic.h"
 
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.h b/arch/arm/mach-pxa/mfp-pxa2xx.h
new file mode 100644 (file)
index 0000000..cbf51ae
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef __ASM_ARCH_MFP_PXA2XX_H
+#define __ASM_ARCH_MFP_PXA2XX_H
+
+#include <plat/mfp.h>
+
+/*
+ * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
+ *
+ *  MFP_PIN(x)
+ *  MFP_AFx
+ *  MFP_LPM_DRIVE_{LOW, HIGH}
+ *  MFP_LPM_EDGE_x
+ *
+ * other MFP_x bit definitions will be ignored
+ *
+ * and adds the below two bits specifically for pxa2xx:
+ *
+ * bit     23 - Input/Output (PXA2xx specific)
+ * bit     24 - Wakeup Enable(PXA2xx specific)
+ * bit     25 - Keep Output  (PXA2xx specific)
+ */
+
+#define MFP_DIR_IN             (0x0 << 23)
+#define MFP_DIR_OUT            (0x1 << 23)
+#define MFP_DIR_MASK           (0x1 << 23)
+#define MFP_DIR(x)             (((x) >> 23) & 0x1)
+
+#define MFP_LPM_CAN_WAKEUP     (0x1 << 24)
+
+/*
+ * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to
+ * retain their last output level (low or high).
+ * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input.
+ */
+#define MFP_LPM_KEEP_OUTPUT    (0x1 << 25)
+
+#define WAKEUP_ON_EDGE_RISE    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
+#define WAKEUP_ON_EDGE_FALL    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL)
+#define WAKEUP_ON_EDGE_BOTH    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH)
+
+/* specifically for enabling wakeup on keypad GPIOs */
+#define WAKEUP_ON_LEVEL_HIGH   (MFP_LPM_CAN_WAKEUP)
+
+#define MFP_CFG_IN(pin, af)            \
+       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
+        (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_IN))
+
+/* NOTE:  pins configured as output _must_ provide a low power state,
+ * and this state should help to minimize the power dissipation.
+ */
+#define MFP_CFG_OUT(pin, af, state)    \
+       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
+        (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
+
+/* Common configurations for pxa25x and pxa27x
+ *
+ * Note: pins configured as GPIO are always initialized to input
+ * so not to cause any side effect
+ */
+#define GPIO0_GPIO     MFP_CFG_IN(GPIO0, AF0)
+#define GPIO1_GPIO     MFP_CFG_IN(GPIO1, AF0)
+#define GPIO9_GPIO     MFP_CFG_IN(GPIO9, AF0)
+#define GPIO10_GPIO    MFP_CFG_IN(GPIO10, AF0)
+#define GPIO11_GPIO    MFP_CFG_IN(GPIO11, AF0)
+#define GPIO12_GPIO    MFP_CFG_IN(GPIO12, AF0)
+#define GPIO13_GPIO    MFP_CFG_IN(GPIO13, AF0)
+#define GPIO14_GPIO    MFP_CFG_IN(GPIO14, AF0)
+#define GPIO15_GPIO    MFP_CFG_IN(GPIO15, AF0)
+#define GPIO16_GPIO    MFP_CFG_IN(GPIO16, AF0)
+#define GPIO17_GPIO    MFP_CFG_IN(GPIO17, AF0)
+#define GPIO18_GPIO    MFP_CFG_IN(GPIO18, AF0)
+#define GPIO19_GPIO    MFP_CFG_IN(GPIO19, AF0)
+#define GPIO20_GPIO    MFP_CFG_IN(GPIO20, AF0)
+#define GPIO21_GPIO    MFP_CFG_IN(GPIO21, AF0)
+#define GPIO22_GPIO    MFP_CFG_IN(GPIO22, AF0)
+#define GPIO23_GPIO    MFP_CFG_IN(GPIO23, AF0)
+#define GPIO24_GPIO    MFP_CFG_IN(GPIO24, AF0)
+#define GPIO25_GPIO    MFP_CFG_IN(GPIO25, AF0)
+#define GPIO26_GPIO    MFP_CFG_IN(GPIO26, AF0)
+#define GPIO27_GPIO    MFP_CFG_IN(GPIO27, AF0)
+#define GPIO28_GPIO    MFP_CFG_IN(GPIO28, AF0)
+#define GPIO29_GPIO    MFP_CFG_IN(GPIO29, AF0)
+#define GPIO30_GPIO    MFP_CFG_IN(GPIO30, AF0)
+#define GPIO31_GPIO    MFP_CFG_IN(GPIO31, AF0)
+#define GPIO32_GPIO    MFP_CFG_IN(GPIO32, AF0)
+#define GPIO33_GPIO    MFP_CFG_IN(GPIO33, AF0)
+#define GPIO34_GPIO    MFP_CFG_IN(GPIO34, AF0)
+#define GPIO35_GPIO    MFP_CFG_IN(GPIO35, AF0)
+#define GPIO36_GPIO    MFP_CFG_IN(GPIO36, AF0)
+#define GPIO37_GPIO    MFP_CFG_IN(GPIO37, AF0)
+#define GPIO38_GPIO    MFP_CFG_IN(GPIO38, AF0)
+#define GPIO39_GPIO    MFP_CFG_IN(GPIO39, AF0)
+#define GPIO40_GPIO    MFP_CFG_IN(GPIO40, AF0)
+#define GPIO41_GPIO    MFP_CFG_IN(GPIO41, AF0)
+#define GPIO42_GPIO    MFP_CFG_IN(GPIO42, AF0)
+#define GPIO43_GPIO    MFP_CFG_IN(GPIO43, AF0)
+#define GPIO44_GPIO    MFP_CFG_IN(GPIO44, AF0)
+#define GPIO45_GPIO    MFP_CFG_IN(GPIO45, AF0)
+#define GPIO46_GPIO    MFP_CFG_IN(GPIO46, AF0)
+#define GPIO47_GPIO    MFP_CFG_IN(GPIO47, AF0)
+#define GPIO48_GPIO    MFP_CFG_IN(GPIO48, AF0)
+#define GPIO49_GPIO    MFP_CFG_IN(GPIO49, AF0)
+#define GPIO50_GPIO    MFP_CFG_IN(GPIO50, AF0)
+#define GPIO51_GPIO    MFP_CFG_IN(GPIO51, AF0)
+#define GPIO52_GPIO    MFP_CFG_IN(GPIO52, AF0)
+#define GPIO53_GPIO    MFP_CFG_IN(GPIO53, AF0)
+#define GPIO54_GPIO    MFP_CFG_IN(GPIO54, AF0)
+#define GPIO55_GPIO    MFP_CFG_IN(GPIO55, AF0)
+#define GPIO56_GPIO    MFP_CFG_IN(GPIO56, AF0)
+#define GPIO57_GPIO    MFP_CFG_IN(GPIO57, AF0)
+#define GPIO58_GPIO    MFP_CFG_IN(GPIO58, AF0)
+#define GPIO59_GPIO    MFP_CFG_IN(GPIO59, AF0)
+#define GPIO60_GPIO    MFP_CFG_IN(GPIO60, AF0)
+#define GPIO61_GPIO    MFP_CFG_IN(GPIO61, AF0)
+#define GPIO62_GPIO    MFP_CFG_IN(GPIO62, AF0)
+#define GPIO63_GPIO    MFP_CFG_IN(GPIO63, AF0)
+#define GPIO64_GPIO    MFP_CFG_IN(GPIO64, AF0)
+#define GPIO65_GPIO    MFP_CFG_IN(GPIO65, AF0)
+#define GPIO66_GPIO    MFP_CFG_IN(GPIO66, AF0)
+#define GPIO67_GPIO    MFP_CFG_IN(GPIO67, AF0)
+#define GPIO68_GPIO    MFP_CFG_IN(GPIO68, AF0)
+#define GPIO69_GPIO    MFP_CFG_IN(GPIO69, AF0)
+#define GPIO70_GPIO    MFP_CFG_IN(GPIO70, AF0)
+#define GPIO71_GPIO    MFP_CFG_IN(GPIO71, AF0)
+#define GPIO72_GPIO    MFP_CFG_IN(GPIO72, AF0)
+#define GPIO73_GPIO    MFP_CFG_IN(GPIO73, AF0)
+#define GPIO74_GPIO    MFP_CFG_IN(GPIO74, AF0)
+#define GPIO75_GPIO    MFP_CFG_IN(GPIO75, AF0)
+#define GPIO76_GPIO    MFP_CFG_IN(GPIO76, AF0)
+#define GPIO77_GPIO    MFP_CFG_IN(GPIO77, AF0)
+#define GPIO78_GPIO    MFP_CFG_IN(GPIO78, AF0)
+#define GPIO79_GPIO    MFP_CFG_IN(GPIO79, AF0)
+#define GPIO80_GPIO    MFP_CFG_IN(GPIO80, AF0)
+#define GPIO81_GPIO    MFP_CFG_IN(GPIO81, AF0)
+#define GPIO82_GPIO    MFP_CFG_IN(GPIO82, AF0)
+#define GPIO83_GPIO    MFP_CFG_IN(GPIO83, AF0)
+#define GPIO84_GPIO    MFP_CFG_IN(GPIO84, AF0)
+
+extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num);
+extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm);
+extern int gpio_set_wake(unsigned int gpio, unsigned int on);
+#endif /* __ASM_ARCH_MFP_PXA2XX_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa300.h b/arch/arm/mach-pxa/mfp-pxa300.h
new file mode 100644 (file)
index 0000000..5ee51e2
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp-pxa300.h
+ *
+ * PXA300/PXA310 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ *             initial version
+ *
+ *  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_MFP_PXA300_H
+#define __ASM_ARCH_MFP_PXA300_H
+
+#include "mfp-pxa3xx.h"
+
+/* GPIO */
+#define GPIO46_GPIO            MFP_CFG(GPIO46, AF1)
+#define GPIO49_GPIO            MFP_CFG(GPIO49, AF3)
+#define GPIO50_GPIO            MFP_CFG(GPIO50, AF2)
+#define GPIO51_GPIO            MFP_CFG(GPIO51, AF3)
+#define GPIO52_GPIO            MFP_CFG(GPIO52, AF3)
+#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
+#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
+
+#ifdef CONFIG_CPU_PXA310
+#define GPIO7_2_GPIO           MFP_CFG(GPIO7_2, AF0)
+#define GPIO8_2_GPIO           MFP_CFG(GPIO8_2, AF0)
+#define GPIO9_2_GPIO           MFP_CFG(GPIO9_2, AF0)
+#define GPIO10_2_GPIO          MFP_CFG(GPIO10_2, AF0)
+#define GPIO11_2_GPIO          MFP_CFG(GPIO11_2, AF0)
+#define GPIO12_2_GPIO          MFP_CFG(GPIO12_2, AF0)
+#endif
+
+/* Chip Select */
+#define GPIO1_nCS2             MFP_CFG(GPIO1,  AF1)
+#define GPIO2_nCS3             MFP_CFG(GPIO2,  AF1)
+
+/* AC97 */
+#define GPIO23_AC97_nACRESET   MFP_CFG(GPIO23, AF1)
+#define GPIO24_AC97_SYSCLK     MFP_CFG(GPIO24, AF1)
+#define GPIO29_AC97_BITCLK     MFP_CFG(GPIO29, AF1)
+#define GPIO25_AC97_SDATA_IN_0 MFP_CFG(GPIO25, AF1)
+#define GPIO26_AC97_SDATA_IN_1 MFP_CFG(GPIO26, AF1)
+#define GPIO17_AC97_SDATA_IN_2 MFP_CFG(GPIO17, AF3)
+#define GPIO21_AC97_SDATA_IN_2 MFP_CFG(GPIO21, AF2)
+#define GPIO18_AC97_SDATA_IN_3 MFP_CFG(GPIO18, AF3)
+#define GPIO22_AC97_SDATA_IN_3 MFP_CFG(GPIO22, AF2)
+#define GPIO27_AC97_SDATA_OUT  MFP_CFG(GPIO27, AF1)
+#define GPIO28_AC97_SYNC       MFP_CFG(GPIO28, AF1)
+
+/* I2C */
+#define GPIO21_I2C_SCL         MFP_CFG_LPM(GPIO21, AF1, PULL_HIGH)
+#define GPIO22_I2C_SDA         MFP_CFG_LPM(GPIO22, AF1, PULL_HIGH)
+
+/* QCI */
+#define GPIO39_CI_DD_0         MFP_CFG_DRV(GPIO39, AF1, DS04X)
+#define GPIO40_CI_DD_1         MFP_CFG_DRV(GPIO40, AF1, DS04X)
+#define GPIO41_CI_DD_2         MFP_CFG_DRV(GPIO41, AF1, DS04X)
+#define GPIO42_CI_DD_3         MFP_CFG_DRV(GPIO42, AF1, DS04X)
+#define GPIO43_CI_DD_4         MFP_CFG_DRV(GPIO43, AF1, DS04X)
+#define GPIO44_CI_DD_5         MFP_CFG_DRV(GPIO44, AF1, DS04X)
+#define GPIO45_CI_DD_6         MFP_CFG_DRV(GPIO45, AF1, DS04X)
+#define GPIO46_CI_DD_7         MFP_CFG_DRV(GPIO46, AF0, DS04X)
+#define GPIO47_CI_DD_8         MFP_CFG_DRV(GPIO47, AF1, DS04X)
+#define GPIO48_CI_DD_9         MFP_CFG_DRV(GPIO48, AF1, DS04X)
+#define GPIO49_CI_MCLK         MFP_CFG_DRV(GPIO49, AF0, DS04X)
+#define GPIO50_CI_PCLK         MFP_CFG_DRV(GPIO50, AF0, DS04X)
+#define GPIO51_CI_HSYNC                MFP_CFG_DRV(GPIO51, AF0, DS04X)
+#define GPIO52_CI_VSYNC                MFP_CFG_DRV(GPIO52, AF0, DS04X)
+
+/* KEYPAD */
+#define GPIO3_KP_DKIN_6                MFP_CFG_LPM(GPIO3,   AF2, FLOAT)
+#define GPIO4_KP_DKIN_7                MFP_CFG_LPM(GPIO4,   AF2, FLOAT)
+#define GPIO16_KP_DKIN_6       MFP_CFG_LPM(GPIO16,  AF6, FLOAT)
+#define GPIO83_KP_DKIN_2       MFP_CFG_LPM(GPIO83,  AF5, FLOAT)
+#define GPIO84_KP_DKIN_1       MFP_CFG_LPM(GPIO84,  AF5, FLOAT)
+#define GPIO85_KP_DKIN_0       MFP_CFG_LPM(GPIO85,  AF3, FLOAT)
+#define GPIO86_KP_DKIN_1       MFP_CFG_LPM(GPIO86,  AF3, FLOAT)
+#define GPIO87_KP_DKIN_2       MFP_CFG_LPM(GPIO87,  AF3, FLOAT)
+#define GPIO88_KP_DKIN_3       MFP_CFG_LPM(GPIO88,  AF3, FLOAT)
+#define GPIO89_KP_DKIN_3       MFP_CFG_LPM(GPIO89,  AF3, FLOAT)
+#define GPIO107_KP_DKIN_0      MFP_CFG_LPM(GPIO107, AF2, FLOAT)
+#define GPIO108_KP_DKIN_1      MFP_CFG_LPM(GPIO108, AF2, FLOAT)
+#define GPIO109_KP_DKIN_2      MFP_CFG_LPM(GPIO109, AF2, FLOAT)
+#define GPIO110_KP_DKIN_3      MFP_CFG_LPM(GPIO110, AF2, FLOAT)
+#define GPIO111_KP_DKIN_4      MFP_CFG_LPM(GPIO111, AF2, FLOAT)
+#define GPIO112_KP_DKIN_5      MFP_CFG_LPM(GPIO112, AF2, FLOAT)
+#define GPIO113_KP_DKIN_6      MFP_CFG_LPM(GPIO113, AF2, FLOAT)
+#define GPIO114_KP_DKIN_7      MFP_CFG_LPM(GPIO114, AF2, FLOAT)
+#define GPIO115_KP_DKIN_0      MFP_CFG_LPM(GPIO115, AF2, FLOAT)
+#define GPIO116_KP_DKIN_1      MFP_CFG_LPM(GPIO116, AF2, FLOAT)
+#define GPIO117_KP_DKIN_2      MFP_CFG_LPM(GPIO117, AF2, FLOAT)
+#define GPIO118_KP_DKIN_3      MFP_CFG_LPM(GPIO118, AF2, FLOAT)
+#define GPIO119_KP_DKIN_4      MFP_CFG_LPM(GPIO119, AF2, FLOAT)
+#define GPIO120_KP_DKIN_5      MFP_CFG_LPM(GPIO120, AF2, FLOAT)
+#define GPIO121_KP_DKIN_6      MFP_CFG_LPM(GPIO121, AF2, FLOAT)
+#define GPIO122_KP_DKIN_5      MFP_CFG_LPM(GPIO122, AF2, FLOAT)
+#define GPIO123_KP_DKIN_4      MFP_CFG_LPM(GPIO123, AF2, FLOAT)
+#define GPIO124_KP_DKIN_3      MFP_CFG_LPM(GPIO124, AF2, FLOAT)
+#define GPIO127_KP_DKIN_0      MFP_CFG_LPM(GPIO127, AF5, FLOAT)
+#define GPIO0_2_KP_DKIN_0      MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
+#define GPIO1_2_KP_DKIN_1      MFP_CFG_LPM(GPIO1_2, AF2, FLOAT)
+#define GPIO2_2_KP_DKIN_6      MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
+#define GPIO3_2_KP_DKIN_7      MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
+#define GPIO4_2_KP_DKIN_1      MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
+#define GPIO5_2_KP_DKIN_0      MFP_CFG_LPM(GPIO5_2, AF2, FLOAT)
+
+#define GPIO5_KP_MKIN_0                MFP_CFG_LPM(GPIO5,   AF2, FLOAT)
+#define GPIO6_KP_MKIN_1                MFP_CFG_LPM(GPIO6,   AF2, FLOAT)
+#define GPIO9_KP_MKIN_6                MFP_CFG_LPM(GPIO9,   AF3, FLOAT)
+#define GPIO10_KP_MKIN_7       MFP_CFG_LPM(GPIO10,  AF3, FLOAT)
+#define GPIO70_KP_MKIN_6       MFP_CFG_LPM(GPIO70,  AF3, FLOAT)
+#define GPIO71_KP_MKIN_7       MFP_CFG_LPM(GPIO71,  AF3, FLOAT)
+#define GPIO100_KP_MKIN_6      MFP_CFG_LPM(GPIO100, AF7, FLOAT)
+#define GPIO101_KP_MKIN_7      MFP_CFG_LPM(GPIO101, AF7, FLOAT)
+#define GPIO112_KP_MKIN_6      MFP_CFG_LPM(GPIO112, AF4, FLOAT)
+#define GPIO113_KP_MKIN_7      MFP_CFG_LPM(GPIO113, AF4, FLOAT)
+#define GPIO115_KP_MKIN_0      MFP_CFG_LPM(GPIO115, AF1, FLOAT)
+#define GPIO116_KP_MKIN_1      MFP_CFG_LPM(GPIO116, AF1, FLOAT)
+#define GPIO117_KP_MKIN_2      MFP_CFG_LPM(GPIO117, AF1, FLOAT)
+#define GPIO118_KP_MKIN_3      MFP_CFG_LPM(GPIO118, AF1, FLOAT)
+#define GPIO119_KP_MKIN_4      MFP_CFG_LPM(GPIO119, AF1, FLOAT)
+#define GPIO120_KP_MKIN_5      MFP_CFG_LPM(GPIO120, AF1, FLOAT)
+#define GPIO125_KP_MKIN_2      MFP_CFG_LPM(GPIO125, AF2, FLOAT)
+#define GPIO2_2_KP_MKIN_6      MFP_CFG_LPM(GPIO2_2, AF1, FLOAT)
+#define GPIO3_2_KP_MKIN_7      MFP_CFG_LPM(GPIO3_2, AF1, FLOAT)
+
+#define GPIO7_KP_MKOUT_5       MFP_CFG_LPM(GPIO7,   AF1, DRIVE_HIGH)
+#define GPIO11_KP_MKOUT_5      MFP_CFG_LPM(GPIO11,  AF3, DRIVE_HIGH)
+#define GPIO12_KP_MKOUT_6      MFP_CFG_LPM(GPIO12,  AF3, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_7      MFP_CFG_LPM(GPIO13,  AF3, DRIVE_HIGH)
+#define GPIO19_KP_MKOUT_4      MFP_CFG_LPM(GPIO19,  AF3, DRIVE_HIGH)
+#define GPIO20_KP_MKOUT_5      MFP_CFG_LPM(GPIO20,  AF3, DRIVE_HIGH)
+#define GPIO38_KP_MKOUT_5      MFP_CFG_LPM(GPIO38,  AF5, DRIVE_HIGH)
+#define GPIO53_KP_MKOUT_6      MFP_CFG_LPM(GPIO53,  AF5, DRIVE_HIGH)
+#define GPIO78_KP_MKOUT_7      MFP_CFG_LPM(GPIO78,  AF5, DRIVE_HIGH)
+#define GPIO85_KP_MKOUT_0      MFP_CFG_LPM(GPIO85,  AF2, DRIVE_HIGH)
+#define GPIO86_KP_MKOUT_1      MFP_CFG_LPM(GPIO86,  AF2, DRIVE_HIGH)
+#define GPIO87_KP_MKOUT_2      MFP_CFG_LPM(GPIO87,  AF2, DRIVE_HIGH)
+#define GPIO88_KP_MKOUT_3      MFP_CFG_LPM(GPIO88,  AF2, DRIVE_HIGH)
+#define GPIO104_KP_MKOUT_6     MFP_CFG_LPM(GPIO104, AF5, DRIVE_HIGH)
+#define GPIO105_KP_MKOUT_7     MFP_CFG_LPM(GPIO105, AF5, DRIVE_HIGH)
+#define GPIO121_KP_MKOUT_0     MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
+#define GPIO122_KP_MKOUT_1     MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
+#define GPIO123_KP_MKOUT_2     MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
+#define GPIO124_KP_MKOUT_3     MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
+#define GPIO125_KP_MKOUT_4     MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
+#define GPIO126_KP_MKOUT_7     MFP_CFG_LPM(GPIO126, AF4, DRIVE_HIGH)
+#define GPIO5_2_KP_MKOUT_6     MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
+#define GPIO4_2_KP_MKOUT_5     MFP_CFG_LPM(GPIO4_2, AF1, DRIVE_HIGH)
+#define GPIO6_2_KP_MKOUT_7     MFP_CFG_LPM(GPIO6_2, AF1, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO54_LCD_LDD_0       MFP_CFG_DRV(GPIO54, AF1, DS01X)
+#define GPIO55_LCD_LDD_1       MFP_CFG_DRV(GPIO55, AF1, DS01X)
+#define GPIO56_LCD_LDD_2       MFP_CFG_DRV(GPIO56, AF1, DS01X)
+#define GPIO57_LCD_LDD_3       MFP_CFG_DRV(GPIO57, AF1, DS01X)
+#define GPIO58_LCD_LDD_4       MFP_CFG_DRV(GPIO58, AF1, DS01X)
+#define GPIO59_LCD_LDD_5       MFP_CFG_DRV(GPIO59, AF1, DS01X)
+#define GPIO60_LCD_LDD_6       MFP_CFG_DRV(GPIO60, AF1, DS01X)
+#define GPIO61_LCD_LDD_7       MFP_CFG_DRV(GPIO61, AF1, DS01X)
+#define GPIO62_LCD_LDD_8       MFP_CFG_DRV(GPIO62, AF1, DS01X)
+#define GPIO63_LCD_LDD_9       MFP_CFG_DRV(GPIO63, AF1, DS01X)
+#define GPIO64_LCD_LDD_10      MFP_CFG_DRV(GPIO64, AF1, DS01X)
+#define GPIO65_LCD_LDD_11      MFP_CFG_DRV(GPIO65, AF1, DS01X)
+#define GPIO66_LCD_LDD_12      MFP_CFG_DRV(GPIO66, AF1, DS01X)
+#define GPIO67_LCD_LDD_13      MFP_CFG_DRV(GPIO67, AF1, DS01X)
+#define GPIO68_LCD_LDD_14      MFP_CFG_DRV(GPIO68, AF1, DS01X)
+#define GPIO69_LCD_LDD_15      MFP_CFG_DRV(GPIO69, AF1, DS01X)
+#define GPIO70_LCD_LDD_16      MFP_CFG_DRV(GPIO70, AF1, DS01X)
+#define GPIO71_LCD_LDD_17      MFP_CFG_DRV(GPIO71, AF1, DS01X)
+#define GPIO62_LCD_CS_N                MFP_CFG_DRV(GPIO62, AF2, DS01X)
+#define GPIO72_LCD_FCLK                MFP_CFG_DRV(GPIO72, AF1, DS01X)
+#define GPIO73_LCD_LCLK                MFP_CFG_DRV(GPIO73, AF1, DS01X)
+#define GPIO74_LCD_PCLK                MFP_CFG_DRV(GPIO74, AF1, DS02X)
+#define GPIO75_LCD_BIAS                MFP_CFG_DRV(GPIO75, AF1, DS01X)
+#define GPIO76_LCD_VSYNC       MFP_CFG_DRV(GPIO76, AF2, DS01X)
+
+#define GPIO15_LCD_CS_N                MFP_CFG_DRV(GPIO15,  AF2, DS01X)
+#define GPIO127_LCD_CS_N       MFP_CFG_DRV(GPIO127, AF1, DS01X)
+#define GPIO63_LCD_VSYNC       MFP_CFG_DRV(GPIO63,  AF2, DS01X)
+
+/* Mini-LCD */
+#define GPIO72_MLCD_FCLK       MFP_CFG_DRV(GPIO72, AF7, DS08X)
+#define GPIO73_MLCD_LCLK       MFP_CFG_DRV(GPIO73, AF7, DS08X)
+#define GPIO54_MLCD_LDD_0      MFP_CFG_DRV(GPIO54, AF7, DS08X)
+#define GPIO55_MLCD_LDD_1      MFP_CFG_DRV(GPIO55, AF7, DS08X)
+#define GPIO56_MLCD_LDD_2      MFP_CFG_DRV(GPIO56, AF7, DS08X)
+#define GPIO57_MLCD_LDD_3      MFP_CFG_DRV(GPIO57, AF7, DS08X)
+#define GPIO58_MLCD_LDD_4      MFP_CFG_DRV(GPIO58, AF7, DS08X)
+#define GPIO59_MLCD_LDD_5      MFP_CFG_DRV(GPIO59, AF7, DS08X)
+#define GPIO60_MLCD_LDD_6      MFP_CFG_DRV(GPIO60, AF7, DS08X)
+#define GPIO61_MLCD_LDD_7      MFP_CFG_DRV(GPIO61, AF7, DS08X)
+#define GPIO62_MLCD_LDD_8      MFP_CFG_DRV(GPIO62, AF7, DS08X)
+#define GPIO63_MLCD_LDD_9      MFP_CFG_DRV(GPIO63, AF7, DS08X)
+#define GPIO64_MLCD_LDD_10     MFP_CFG_DRV(GPIO64, AF7, DS08X)
+#define GPIO65_MLCD_LDD_11     MFP_CFG_DRV(GPIO65, AF7, DS08X)
+#define GPIO66_MLCD_LDD_12     MFP_CFG_DRV(GPIO66, AF7, DS08X)
+#define GPIO67_MLCD_LDD_13     MFP_CFG_DRV(GPIO67, AF7, DS08X)
+#define GPIO68_MLCD_LDD_14     MFP_CFG_DRV(GPIO68, AF7, DS08X)
+#define GPIO69_MLCD_LDD_15     MFP_CFG_DRV(GPIO69, AF7, DS08X)
+#define GPIO74_MLCD_PCLK       MFP_CFG_DRV(GPIO74, AF7, DS08X)
+#define GPIO75_MLCD_BIAS       MFP_CFG_DRV(GPIO75, AF2, DS08X)
+
+/* MMC1 */
+#define GPIO7_MMC1_CLK         MFP_CFG_LPM(GPIO7,  AF4, DRIVE_HIGH)
+#define GPIO8_MMC1_CMD         MFP_CFG_LPM(GPIO8,  AF4, DRIVE_HIGH)
+#define GPIO14_MMC1_CMD                MFP_CFG_LPM(GPIO14, AF5, DRIVE_HIGH)
+#define GPIO15_MMC1_CMD                MFP_CFG_LPM(GPIO15, AF5, DRIVE_HIGH)
+#define GPIO3_MMC1_DAT0                MFP_CFG_LPM(GPIO3,  AF4, DRIVE_HIGH)
+#define GPIO4_MMC1_DAT1                MFP_CFG_LPM(GPIO4,  AF4, DRIVE_HIGH)
+#define GPIO5_MMC1_DAT2                MFP_CFG_LPM(GPIO5,  AF4, DRIVE_HIGH)
+#define GPIO6_MMC1_DAT3                MFP_CFG_LPM(GPIO6,  AF4, DRIVE_HIGH)
+
+/* MMC2 */
+#define GPIO9_MMC2_DAT0                MFP_CFG_LPM(GPIO9,  AF4, PULL_HIGH)
+#define GPIO10_MMC2_DAT1       MFP_CFG_LPM(GPIO10, AF4, PULL_HIGH)
+#define GPIO11_MMC2_DAT2       MFP_CFG_LPM(GPIO11, AF4, PULL_HIGH)
+#define GPIO12_MMC2_DAT3       MFP_CFG_LPM(GPIO12, AF4, PULL_HIGH)
+#define GPIO13_MMC2_CLK                MFP_CFG_LPM(GPIO13, AF4, PULL_HIGH)
+#define GPIO14_MMC2_CMD                MFP_CFG_LPM(GPIO14, AF4, PULL_HIGH)
+#define GPIO77_MMC2_DAT0       MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
+#define GPIO78_MMC2_DAT1       MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
+#define GPIO79_MMC2_DAT2       MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
+#define GPIO80_MMC2_DAT3       MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
+#define GPIO81_MMC2_CLK                MFP_CFG_LPM(GPIO81, AF4, PULL_HIGH)
+#define GPIO82_MMC2_CMD                MFP_CFG_LPM(GPIO82, AF4, PULL_HIGH)
+
+/* SSP1 */
+#define GPIO89_SSP1_EXTCLK     MFP_CFG(GPIO89, AF1)
+#define GPIO90_SSP1_SYSCLK     MFP_CFG(GPIO90, AF1)
+#define GPIO15_SSP1_SCLK       MFP_CFG(GPIO15, AF6)
+#define GPIO16_SSP1_FRM                MFP_CFG(GPIO16, AF2)
+#define GPIO33_SSP1_SCLK       MFP_CFG(GPIO33, AF5)
+#define GPIO34_SSP1_FRM                MFP_CFG(GPIO34, AF5)
+#define GPIO85_SSP1_SCLK       MFP_CFG(GPIO85, AF1)
+#define GPIO86_SSP1_FRM                MFP_CFG(GPIO86, AF1)
+#define GPIO18_SSP1_TXD                MFP_CFG(GPIO18, AF7)
+#define GPIO18_SSP1_RXD                MFP_CFG(GPIO18, AF2)
+#define GPIO20_SSP1_TXD                MFP_CFG(GPIO20, AF2)
+#define GPIO20_SSP1_RXD                MFP_CFG(GPIO20, AF7)
+#define GPIO35_SSP1_TXD                MFP_CFG(GPIO35, AF5)
+#define GPIO35_SSP1_RXD                MFP_CFG(GPIO35, AF4)
+#define GPIO36_SSP1_TXD                MFP_CFG(GPIO36, AF5)
+#define GPIO36_SSP1_RXD                MFP_CFG(GPIO36, AF6)
+#define GPIO87_SSP1_TXD                MFP_CFG(GPIO87, AF1)
+#define GPIO87_SSP1_RXD                MFP_CFG(GPIO87, AF6)
+#define GPIO88_SSP1_TXD                MFP_CFG(GPIO88, AF6)
+#define GPIO88_SSP1_RXD                MFP_CFG(GPIO88, AF1)
+
+/* SSP2 */
+#define GPIO29_SSP2_EXTCLK     MFP_CFG(GPIO29, AF2)
+#define GPIO23_SSP2_SCLK       MFP_CFG(GPIO23, AF2)
+#define GPIO17_SSP2_FRM                MFP_CFG(GPIO17, AF2)
+#define GPIO25_SSP2_SCLK       MFP_CFG(GPIO25, AF2)
+#define GPIO26_SSP2_FRM                MFP_CFG(GPIO26, AF2)
+#define GPIO33_SSP2_SCLK       MFP_CFG(GPIO33, AF6)
+#define GPIO34_SSP2_FRM                MFP_CFG(GPIO34, AF6)
+#define GPIO64_SSP2_SCLK       MFP_CFG(GPIO64, AF2)
+#define GPIO65_SSP2_FRM                MFP_CFG(GPIO65, AF2)
+#define GPIO19_SSP2_TXD                MFP_CFG(GPIO19, AF2)
+#define GPIO19_SSP2_RXD                MFP_CFG(GPIO19, AF7)
+#define GPIO24_SSP2_TXD                MFP_CFG(GPIO24, AF5)
+#define GPIO24_SSP2_RXD                MFP_CFG(GPIO24, AF4)
+#define GPIO27_SSP2_TXD                MFP_CFG(GPIO27, AF2)
+#define GPIO27_SSP2_RXD                MFP_CFG(GPIO27, AF5)
+#define GPIO28_SSP2_TXD                MFP_CFG(GPIO28, AF5)
+#define GPIO28_SSP2_RXD                MFP_CFG(GPIO28, AF2)
+#define GPIO35_SSP2_TXD                MFP_CFG(GPIO35, AF7)
+#define GPIO35_SSP2_RXD                MFP_CFG(GPIO35, AF6)
+#define GPIO66_SSP2_TXD                MFP_CFG(GPIO66, AF4)
+#define GPIO66_SSP2_RXD                MFP_CFG(GPIO66, AF2)
+#define GPIO67_SSP2_TXD                MFP_CFG(GPIO67, AF2)
+#define GPIO67_SSP2_RXD                MFP_CFG(GPIO67, AF4)
+#define GPIO36_SSP2_TXD                MFP_CFG(GPIO36, AF7)
+
+/* SSP3 */
+#define GPIO69_SSP3_FRM                MFP_CFG_X(GPIO69, AF2, DS08X, DRIVE_LOW)
+#define GPIO68_SSP3_SCLK       MFP_CFG_X(GPIO68, AF2, DS08X, FLOAT)
+#define GPIO92_SSP3_FRM                MFP_CFG_X(GPIO92, AF1, DS08X, DRIVE_LOW)
+#define GPIO91_SSP3_SCLK       MFP_CFG_X(GPIO91, AF1, DS08X, FLOAT)
+#define GPIO70_SSP3_TXD                MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO70_SSP3_RXD                MFP_CFG_X(GPIO70, AF5, DS08X, FLOAT)
+#define GPIO71_SSP3_TXD                MFP_CFG_X(GPIO71, AF5, DS08X, DRIVE_LOW)
+#define GPIO71_SSP3_RXD                MFP_CFG_X(GPIO71, AF2, DS08X, FLOAT)
+#define GPIO93_SSP3_TXD                MFP_CFG_X(GPIO93, AF1, DS08X, DRIVE_LOW)
+#define GPIO93_SSP3_RXD                MFP_CFG_X(GPIO93, AF5, DS08X, FLOAT)
+#define GPIO94_SSP3_TXD                MFP_CFG_X(GPIO94, AF5, DS08X, DRIVE_LOW)
+#define GPIO94_SSP3_RXD                MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)
+
+/* SSP4 */
+#define GPIO95_SSP4_SCLK       MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_SSP4_FRM                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+#define GPIO97_SSP4_TXD                MFP_CFG_LPM(GPIO97, AF1, PULL_HIGH)
+#define GPIO97_SSP4_RXD                MFP_CFG_LPM(GPIO97, AF5, PULL_HIGH)
+#define GPIO98_SSP4_TXD                MFP_CFG_LPM(GPIO98, AF5, PULL_HIGH)
+#define GPIO98_SSP4_RXD                MFP_CFG_LPM(GPIO98, AF1, PULL_HIGH)
+
+/* UART1 */
+#define GPIO32_UART1_CTS       MFP_CFG_LPM(GPIO32,  AF2, FLOAT)
+#define GPIO37_UART1_CTS       MFP_CFG_LPM(GPIO37,  AF4, FLOAT)
+#define GPIO79_UART1_CTS       MFP_CFG_LPM(GPIO79,  AF1, FLOAT)
+#define GPIO84_UART1_CTS       MFP_CFG_LPM(GPIO84,  AF3, FLOAT)
+#define GPIO101_UART1_CTS      MFP_CFG_LPM(GPIO101, AF1, FLOAT)
+#define GPIO106_UART1_CTS      MFP_CFG_LPM(GPIO106, AF6, FLOAT)
+
+#define GPIO32_UART1_RTS       MFP_CFG_LPM(GPIO32,  AF4, FLOAT)
+#define GPIO37_UART1_RTS       MFP_CFG_LPM(GPIO37,  AF2, FLOAT)
+#define GPIO79_UART1_RTS       MFP_CFG_LPM(GPIO79,  AF3, FLOAT)
+#define GPIO84_UART1_RTS       MFP_CFG_LPM(GPIO84,  AF1, FLOAT)
+#define GPIO101_UART1_RTS      MFP_CFG_LPM(GPIO101, AF6, FLOAT)
+#define GPIO106_UART1_RTS      MFP_CFG_LPM(GPIO106, AF1, FLOAT)
+
+#define GPIO34_UART1_DSR       MFP_CFG_LPM(GPIO34,  AF2, FLOAT)
+#define GPIO36_UART1_DSR       MFP_CFG_LPM(GPIO36,  AF4, FLOAT)
+#define GPIO81_UART1_DSR       MFP_CFG_LPM(GPIO81,  AF1, FLOAT)
+#define GPIO83_UART1_DSR       MFP_CFG_LPM(GPIO83,  AF3, FLOAT)
+#define GPIO103_UART1_DSR      MFP_CFG_LPM(GPIO103, AF1, FLOAT)
+#define GPIO105_UART1_DSR      MFP_CFG_LPM(GPIO105, AF6, FLOAT)
+
+#define GPIO34_UART1_DTR       MFP_CFG_LPM(GPIO34,  AF4, FLOAT)
+#define GPIO36_UART1_DTR       MFP_CFG_LPM(GPIO36,  AF2, FLOAT)
+#define GPIO81_UART1_DTR       MFP_CFG_LPM(GPIO81,  AF3, FLOAT)
+#define GPIO83_UART1_DTR       MFP_CFG_LPM(GPIO83,  AF1, FLOAT)
+#define GPIO103_UART1_DTR      MFP_CFG_LPM(GPIO103, AF6, FLOAT)
+#define GPIO105_UART1_DTR      MFP_CFG_LPM(GPIO105, AF1, FLOAT)
+
+#define GPIO35_UART1_RI                MFP_CFG_LPM(GPIO35,  AF2, FLOAT)
+#define GPIO82_UART1_RI                MFP_CFG_LPM(GPIO82,  AF1, FLOAT)
+#define GPIO104_UART1_RI       MFP_CFG_LPM(GPIO104, AF1, FLOAT)
+
+#define GPIO33_UART1_DCD       MFP_CFG_LPM(GPIO33,  AF2, FLOAT)
+#define GPIO80_UART1_DCD       MFP_CFG_LPM(GPIO80,  AF1, FLOAT)
+#define GPIO102_UART1_DCD      MFP_CFG_LPM(GPIO102, AF1, FLOAT)
+
+#define GPIO30_UART1_RXD       MFP_CFG_LPM(GPIO30,  AF2, FLOAT)
+#define GPIO31_UART1_RXD       MFP_CFG_LPM(GPIO31,  AF4, FLOAT)
+#define GPIO77_UART1_RXD       MFP_CFG_LPM(GPIO77,  AF1, FLOAT)
+#define GPIO78_UART1_RXD       MFP_CFG_LPM(GPIO78,  AF3, FLOAT)
+#define GPIO99_UART1_RXD       MFP_CFG_LPM(GPIO99,  AF1, FLOAT)
+#define GPIO100_UART1_RXD      MFP_CFG_LPM(GPIO100, AF6, FLOAT)
+#define GPIO102_UART1_RXD      MFP_CFG_LPM(GPIO102, AF6, FLOAT)
+#define GPIO104_UART1_RXD      MFP_CFG_LPM(GPIO104, AF4, FLOAT)
+
+#define GPIO30_UART1_TXD       MFP_CFG_LPM(GPIO30,  AF4, FLOAT)
+#define GPIO31_UART1_TXD       MFP_CFG_LPM(GPIO31,  AF2, FLOAT)
+#define GPIO77_UART1_TXD       MFP_CFG_LPM(GPIO77,  AF3, FLOAT)
+#define GPIO78_UART1_TXD       MFP_CFG_LPM(GPIO78,  AF1, FLOAT)
+#define GPIO99_UART1_TXD       MFP_CFG_LPM(GPIO99,  AF6, FLOAT)
+#define GPIO100_UART1_TXD      MFP_CFG_LPM(GPIO100, AF1, FLOAT)
+#define GPIO102_UART1_TXD      MFP_CFG_LPM(GPIO102, AF4, FLOAT)
+
+/* UART2 */
+#define GPIO15_UART2_CTS       MFP_CFG_LPM(GPIO15,  AF3, FLOAT)
+#define GPIO16_UART2_CTS       MFP_CFG_LPM(GPIO16,  AF5, FLOAT)
+#define GPIO111_UART2_CTS      MFP_CFG_LPM(GPIO111, AF3, FLOAT)
+#define GPIO114_UART2_CTS      MFP_CFG_LPM(GPIO114, AF1, FLOAT)
+
+#define GPIO15_UART2_RTS       MFP_CFG_LPM(GPIO15,  AF4, FLOAT)
+#define GPIO16_UART2_RTS       MFP_CFG_LPM(GPIO16,  AF4, FLOAT)
+#define GPIO114_UART2_RTS      MFP_CFG_LPM(GPIO114, AF3, FLOAT)
+#define GPIO111_UART2_RTS      MFP_CFG_LPM(GPIO111, AF1, FLOAT)
+
+#define GPIO18_UART2_RXD       MFP_CFG_LPM(GPIO18,  AF5, FLOAT)
+#define GPIO19_UART2_RXD       MFP_CFG_LPM(GPIO19,  AF4, FLOAT)
+#define GPIO112_UART2_RXD      MFP_CFG_LPM(GPIO112, AF1, FLOAT)
+#define GPIO113_UART2_RXD      MFP_CFG_LPM(GPIO113, AF3, FLOAT)
+
+#define GPIO18_UART2_TXD       MFP_CFG_LPM(GPIO18,  AF4, FLOAT)
+#define GPIO19_UART2_TXD       MFP_CFG_LPM(GPIO19,  AF5, FLOAT)
+#define GPIO112_UART2_TXD      MFP_CFG_LPM(GPIO112, AF3, FLOAT)
+#define GPIO113_UART2_TXD      MFP_CFG_LPM(GPIO113, AF1, FLOAT)
+
+/* UART3 */
+#define GPIO91_UART3_CTS       MFP_CFG_LPM(GPIO91,  AF2, FLOAT)
+#define GPIO92_UART3_CTS       MFP_CFG_LPM(GPIO92,  AF4, FLOAT)
+#define GPIO107_UART3_CTS      MFP_CFG_LPM(GPIO107, AF1, FLOAT)
+#define GPIO108_UART3_CTS      MFP_CFG_LPM(GPIO108, AF3, FLOAT)
+
+#define GPIO91_UART3_RTS       MFP_CFG_LPM(GPIO91,  AF4, FLOAT)
+#define GPIO92_UART3_RTS       MFP_CFG_LPM(GPIO92,  AF2, FLOAT)
+#define GPIO107_UART3_RTS      MFP_CFG_LPM(GPIO107, AF3, FLOAT)
+#define GPIO108_UART3_RTS      MFP_CFG_LPM(GPIO108, AF1, FLOAT)
+
+#define GPIO7_UART3_RXD                MFP_CFG_LPM(GPIO7,   AF2, FLOAT)
+#define GPIO8_UART3_RXD                MFP_CFG_LPM(GPIO8,   AF6, FLOAT)
+#define GPIO93_UART3_RXD       MFP_CFG_LPM(GPIO93,  AF4, FLOAT)
+#define GPIO94_UART3_RXD       MFP_CFG_LPM(GPIO94,  AF2, FLOAT)
+#define GPIO109_UART3_RXD      MFP_CFG_LPM(GPIO109, AF3, FLOAT)
+#define GPIO110_UART3_RXD      MFP_CFG_LPM(GPIO110, AF1, FLOAT)
+
+#define GPIO7_UART3_TXD                MFP_CFG_LPM(GPIO7,   AF6, FLOAT)
+#define GPIO8_UART3_TXD                MFP_CFG_LPM(GPIO8,   AF2, FLOAT)
+#define GPIO93_UART3_TXD       MFP_CFG_LPM(GPIO93,  AF2, FLOAT)
+#define GPIO94_UART3_TXD       MFP_CFG_LPM(GPIO94,  AF4, FLOAT)
+#define GPIO109_UART3_TXD      MFP_CFG_LPM(GPIO109, AF1, FLOAT)
+#define GPIO110_UART3_TXD      MFP_CFG_LPM(GPIO110, AF3, FLOAT)
+
+/* USB Host */
+#define GPIO0_2_USBH_PEN       MFP_CFG(GPIO0_2, AF1)
+#define GPIO1_2_USBH_PWR       MFP_CFG(GPIO1_2, AF1)
+
+/* USB P3 */
+#define GPIO77_USB_P3_1                MFP_CFG(GPIO77,  AF2)
+#define GPIO78_USB_P3_2                MFP_CFG(GPIO78,  AF2)
+#define GPIO79_USB_P3_3                MFP_CFG(GPIO79,  AF2)
+#define GPIO80_USB_P3_4                MFP_CFG(GPIO80,  AF2)
+#define GPIO81_USB_P3_5                MFP_CFG(GPIO81,  AF2)
+#define GPIO82_USB_P3_6                MFP_CFG(GPIO82,  AF2)
+
+/* PWM */
+#define GPIO17_PWM0_OUT                MFP_CFG(GPIO17, AF1)
+#define GPIO18_PWM1_OUT                MFP_CFG(GPIO18, AF1)
+#define GPIO19_PWM2_OUT                MFP_CFG(GPIO19, AF1)
+#define GPIO20_PWM3_OUT                MFP_CFG(GPIO20, AF1)
+
+/* CIR */
+#define GPIO8_CIR_OUT          MFP_CFG(GPIO8, AF5)
+#define GPIO16_CIR_OUT         MFP_CFG(GPIO16, AF3)
+
+#define GPIO20_OW_DQ_IN                MFP_CFG(GPIO20, AF5)
+#define GPIO126_OW_DQ          MFP_CFG(GPIO126, AF2)
+
+#define GPIO0_DF_RDY           MFP_CFG(GPIO0, AF1)
+#define GPIO7_CLK_BYPASS_XSC   MFP_CFG(GPIO7, AF7)
+#define GPIO17_EXT_SYNC_MVT_0  MFP_CFG(GPIO17, AF6)
+#define GPIO18_EXT_SYNC_MVT_1  MFP_CFG(GPIO18, AF6)
+#define GPIO19_OST_CHOUT_MVT_0 MFP_CFG(GPIO19, AF6)
+#define GPIO20_OST_CHOUT_MVT_1 MFP_CFG(GPIO20, AF6)
+#define GPIO49_48M_CLK         MFP_CFG(GPIO49, AF2)
+#define GPIO126_EXT_CLK                MFP_CFG(GPIO126, AF3)
+#define GPIO127_CLK_BYPASS_GB  MFP_CFG(GPIO127, AF7)
+#define GPIO71_EXT_MATCH_MVT   MFP_CFG(GPIO71, AF6)
+
+#define GPIO3_uIO_IN           MFP_CFG(GPIO3, AF1)
+
+#define GPIO4_uSIM_CARD_STATE  MFP_CFG(GPIO4, AF1)
+#define GPIO5_uSIM_uCLK                MFP_CFG(GPIO5, AF1)
+#define GPIO6_uSIM_uRST                MFP_CFG(GPIO6, AF1)
+#define GPIO16_uSIM_UVS_0      MFP_CFG(GPIO16, AF1)
+
+#define GPIO9_SCIO             MFP_CFG(GPIO9, AF1)
+#define GPIO20_RTC_MVT         MFP_CFG(GPIO20, AF4)
+#define GPIO126_RTC_MVT                MFP_CFG(GPIO126, AF1)
+
+/*
+ * PXA300 specific MFP configurations
+ */
+#ifdef CONFIG_CPU_PXA300
+#define GPIO99_USB_P2_2                MFP_CFG(GPIO99, AF2)
+#define GPIO99_USB_P2_5                MFP_CFG(GPIO99, AF3)
+#define GPIO99_USB_P2_6                MFP_CFG(GPIO99, AF4)
+#define GPIO100_USB_P2_2       MFP_CFG(GPIO100, AF4)
+#define GPIO100_USB_P2_5       MFP_CFG(GPIO100, AF5)
+#define GPIO101_USB_P2_1       MFP_CFG(GPIO101, AF2)
+#define GPIO102_USB_P2_4       MFP_CFG(GPIO102, AF2)
+#define GPIO104_USB_P2_3       MFP_CFG(GPIO104, AF2)
+#define GPIO105_USB_P2_5       MFP_CFG(GPIO105, AF2)
+#define GPIO100_USB_P2_6       MFP_CFG(GPIO100, AF2)
+#define GPIO106_USB_P2_7       MFP_CFG(GPIO106, AF2)
+#define GPIO103_USB_P2_8       MFP_CFG(GPIO103, AF2)
+
+/* U2D UTMI */
+#define GPIO38_UTM_CLK         MFP_CFG(GPIO38,  AF1)
+#define GPIO26_U2D_RXERROR     MFP_CFG(GPIO26,  AF3)
+#define GPIO50_U2D_RXERROR     MFP_CFG(GPIO50,  AF1)
+#define GPIO89_U2D_RXERROR     MFP_CFG(GPIO89,  AF5)
+#define GPIO24_UTM_RXVALID     MFP_CFG(GPIO24,  AF3)
+#define GPIO48_UTM_RXVALID     MFP_CFG(GPIO48,  AF2)
+#define GPIO87_UTM_RXVALID     MFP_CFG(GPIO87,  AF5)
+#define GPIO25_UTM_RXACTIVE    MFP_CFG(GPIO25,  AF3)
+#define GPIO47_UTM_RXACTIVE    MFP_CFG(GPIO47,  AF2)
+#define GPIO49_UTM_RXACTIVE    MFP_CFG(GPIO49,  AF1)
+#define GPIO88_UTM_RXACTIVE    MFP_CFG(GPIO88,  AF5)
+#define GPIO53_UTM_TXREADY     MFP_CFG(GPIO53,  AF1)
+#define GPIO67_UTM_LINESTATE_0 MFP_CFG(GPIO67,  AF3)
+#define GPIO92_UTM_LINESTATE_0 MFP_CFG(GPIO92,  AF3)
+#define GPIO104_UTM_LINESTATE_0        MFP_CFG(GPIO104, AF3)
+#define GPIO109_UTM_LINESTATE_0        MFP_CFG(GPIO109, AF4)
+#define GPIO68_UTM_LINESTATE_1 MFP_CFG(GPIO68,  AF3)
+#define GPIO93_UTM_LINESTATE_1 MFP_CFG(GPIO93,  AF3)
+#define GPIO105_UTM_LINESTATE_1        MFP_CFG(GPIO105, AF3)
+#define GPIO27_U2D_OPMODE_0    MFP_CFG(GPIO27,  AF4)
+#define GPIO51_U2D_OPMODE_0    MFP_CFG(GPIO51,  AF2)
+#define GPIO90_U2D_OPMODE_0    MFP_CFG(GPIO90,  AF7)
+#define GPIO28_U2D_OPMODE_1    MFP_CFG(GPIO28,  AF4)
+#define GPIO52_U2D_OPMODE_1    MFP_CFG(GPIO52,  AF2)
+#define GPIO106_U2D_OPMODE_1   MFP_CFG(GPIO106, AF3)
+#define GPIO110_U2D_OPMODE_1   MFP_CFG(GPIO110, AF5)
+#define GPIO76_U2D_RESET       MFP_CFG(GPIO76,  AF1)
+#define GPIO95_U2D_RESET       MFP_CFG(GPIO95,  AF2)
+#define GPIO100_U2D_RESET      MFP_CFG(GPIO100, AF3)
+#define GPIO66_U2D_SUSPEND     MFP_CFG(GPIO66,  AF3)
+#define GPIO98_U2D_SUSPEND     MFP_CFG(GPIO98,  AF2)
+#define GPIO103_U2D_SUSPEND    MFP_CFG(GPIO103, AF3)
+#define GPIO65_U2D_TERM_SEL    MFP_CFG(GPIO65,  AF5)
+#define GPIO97_U2D_TERM_SEL    MFP_CFG(GPIO97,  AF3)
+#define GPIO102_U2D_TERM_SEL   MFP_CFG(GPIO102, AF5)
+#define GPIO29_U2D_TXVALID     MFP_CFG(GPIO29,  AF3)
+#define GPIO52_U2D_TXVALID     MFP_CFG(GPIO52,  AF4)
+#define GPIO69_U2D_TXVALID     MFP_CFG(GPIO69,  AF3)
+#define GPIO85_U2D_TXVALID     MFP_CFG(GPIO85,  AF7)
+#define GPIO64_U2D_XCVR_SEL    MFP_CFG(GPIO64,  AF5)
+#define GPIO96_U2D_XCVR_SEL    MFP_CFG(GPIO96,  AF3)
+#define GPIO101_U2D_XCVR_SEL   MFP_CFG(GPIO101, AF5)
+#define GPIO30_UTM_PHYDATA_0   MFP_CFG(GPIO30,  AF3)
+#define GPIO31_UTM_PHYDATA_1   MFP_CFG(GPIO31,  AF3)
+#define GPIO32_UTM_PHYDATA_2   MFP_CFG(GPIO32,  AF3)
+#define GPIO33_UTM_PHYDATA_3   MFP_CFG(GPIO33,  AF3)
+#define GPIO34_UTM_PHYDATA_4   MFP_CFG(GPIO34,  AF3)
+#define GPIO35_UTM_PHYDATA_5   MFP_CFG(GPIO35,  AF3)
+#define GPIO36_UTM_PHYDATA_6   MFP_CFG(GPIO36,  AF3)
+#define GPIO37_UTM_PHYDATA_7   MFP_CFG(GPIO37,  AF3)
+#define GPIO39_UTM_PHYDATA_0   MFP_CFG(GPIO39,  AF3)
+#define GPIO40_UTM_PHYDATA_1   MFP_CFG(GPIO40,  AF3)
+#define GPIO41_UTM_PHYDATA_2   MFP_CFG(GPIO41,  AF3)
+#define GPIO42_UTM_PHYDATA_3   MFP_CFG(GPIO42,  AF3)
+#define GPIO43_UTM_PHYDATA_4   MFP_CFG(GPIO43,  AF3)
+#define GPIO44_UTM_PHYDATA_5   MFP_CFG(GPIO44,  AF3)
+#define GPIO45_UTM_PHYDATA_6   MFP_CFG(GPIO45,  AF3)
+#define GPIO46_UTM_PHYDATA_7   MFP_CFG(GPIO46,  AF3)
+#endif /* CONFIG_CPU_PXA300 */
+
+/*
+ * PXA310 specific MFP configurations
+ */
+#ifdef CONFIG_CPU_PXA310
+/* USB P2 */
+#define GPIO36_USB_P2_1                MFP_CFG(GPIO36, AF1)
+#define GPIO30_USB_P2_2                MFP_CFG(GPIO30, AF1)
+#define GPIO35_USB_P2_3                MFP_CFG(GPIO35, AF1)
+#define GPIO32_USB_P2_4                MFP_CFG(GPIO32, AF1)
+#define GPIO34_USB_P2_5                MFP_CFG(GPIO34, AF1)
+#define GPIO31_USB_P2_6                MFP_CFG(GPIO31, AF1)
+
+/* MMC1 */
+#define GPIO24_MMC1_CMD                MFP_CFG(GPIO24, AF3)
+#define GPIO29_MMC1_DAT0       MFP_CFG(GPIO29, AF3)
+
+/* MMC3 */
+#define GPIO103_MMC3_CLK       MFP_CFG(GPIO103, AF2)
+#define GPIO105_MMC3_CMD       MFP_CFG(GPIO105, AF2)
+#define GPIO11_2_MMC3_CLK      MFP_CFG(GPIO11_2, AF1)
+#define GPIO12_2_MMC3_CMD      MFP_CFG(GPIO12_2, AF1)
+#define GPIO7_2_MMC3_DAT0      MFP_CFG(GPIO7_2, AF1)
+#define GPIO8_2_MMC3_DAT1      MFP_CFG(GPIO8_2, AF1)
+#define GPIO9_2_MMC3_DAT2      MFP_CFG(GPIO9_2, AF1)
+#define GPIO10_2_MMC3_DAT3     MFP_CFG(GPIO10_2, AF1)
+
+/* ULPI */
+#define GPIO38_ULPI_CLK                MFP_CFG(GPIO38, AF1)
+#define GPIO30_ULPI_DATA_OUT_0 MFP_CFG(GPIO30, AF3)
+#define GPIO31_ULPI_DATA_OUT_1 MFP_CFG(GPIO31, AF3)
+#define GPIO32_ULPI_DATA_OUT_2 MFP_CFG(GPIO32, AF3)
+#define GPIO33_ULPI_DATA_OUT_3 MFP_CFG(GPIO33, AF3)
+#define GPIO34_ULPI_DATA_OUT_4 MFP_CFG(GPIO34, AF3)
+#define GPIO35_ULPI_DATA_OUT_5 MFP_CFG(GPIO35, AF3)
+#define GPIO36_ULPI_DATA_OUT_6 MFP_CFG(GPIO36, AF3)
+#define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3)
+#define GPIO33_ULPI_OTG_INTR   MFP_CFG(GPIO33, AF1)
+
+#define ULPI_DIR       MFP_CFG_DRV(ULPI_DIR, AF0, DS01X)
+#define ULPI_NXT       MFP_CFG_DRV(ULPI_NXT, AF0, DS01X)
+#define ULPI_STP       MFP_CFG_DRV(ULPI_STP, AF0, DS01X)
+#endif /* CONFIG_CPU_PXA310 */
+
+#endif /* __ASM_ARCH_MFP_PXA300_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa320.h b/arch/arm/mach-pxa/mfp-pxa320.h
new file mode 100644 (file)
index 0000000..e8797cf
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp-pxa320.h
+ *
+ * PXA320 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ *             initial version
+ *
+ *  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_MFP_PXA320_H
+#define __ASM_ARCH_MFP_PXA320_H
+
+#include "mfp-pxa3xx.h"
+
+/* GPIO */
+#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
+#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
+
+#define GPIO7_2_GPIO           MFP_CFG(GPIO7_2, AF0)
+#define GPIO8_2_GPIO           MFP_CFG(GPIO8_2, AF0)
+#define GPIO9_2_GPIO           MFP_CFG(GPIO9_2, AF0)
+#define GPIO10_2_GPIO          MFP_CFG(GPIO10_2, AF0)
+#define GPIO11_2_GPIO          MFP_CFG(GPIO11_2, AF0)
+#define GPIO12_2_GPIO          MFP_CFG(GPIO12_2, AF0)
+#define GPIO13_2_GPIO          MFP_CFG(GPIO13_2, AF0)
+#define GPIO14_2_GPIO          MFP_CFG(GPIO14_2, AF0)
+#define GPIO15_2_GPIO          MFP_CFG(GPIO15_2, AF0)
+#define GPIO16_2_GPIO          MFP_CFG(GPIO16_2, AF0)
+#define GPIO17_2_GPIO          MFP_CFG(GPIO17_2, AF0)
+
+/* Chip Select */
+#define GPIO3_nCS2             MFP_CFG(GPIO3, AF1)
+#define GPIO4_nCS3             MFP_CFG(GPIO4, AF1)
+
+/* AC97 */
+#define GPIO34_AC97_SYSCLK     MFP_CFG(GPIO34, AF1)
+#define GPIO39_AC97_BITCLK     MFP_CFG(GPIO39, AF1)
+#define GPIO40_AC97_nACRESET   MFP_CFG(GPIO40, AF1)
+#define GPIO35_AC97_SDATA_IN_0 MFP_CFG(GPIO35, AF1)
+#define GPIO36_AC97_SDATA_IN_1 MFP_CFG(GPIO36, AF1)
+#define GPIO32_AC97_SDATA_IN_2 MFP_CFG(GPIO32, AF2)
+#define GPIO33_AC97_SDATA_IN_3 MFP_CFG(GPIO33, AF2)
+#define GPIO11_AC97_SDATA_IN_2 MFP_CFG(GPIO11, AF3)
+#define GPIO12_AC97_SDATA_IN_3 MFP_CFG(GPIO12, AF3)
+#define GPIO37_AC97_SDATA_OUT  MFP_CFG(GPIO37, AF1)
+#define GPIO38_AC97_SYNC       MFP_CFG(GPIO38, AF1)
+
+/* I2C */
+#define GPIO32_I2C_SCL         MFP_CFG_LPM(GPIO32, AF1, PULL_HIGH)
+#define GPIO33_I2C_SDA         MFP_CFG_LPM(GPIO33, AF1, PULL_HIGH)
+
+/* QCI */
+#define GPIO49_CI_DD_0         MFP_CFG_DRV(GPIO49, AF1, DS04X)
+#define GPIO50_CI_DD_1         MFP_CFG_DRV(GPIO50, AF1, DS04X)
+#define GPIO51_CI_DD_2         MFP_CFG_DRV(GPIO51, AF1, DS04X)
+#define GPIO52_CI_DD_3         MFP_CFG_DRV(GPIO52, AF1, DS04X)
+#define GPIO53_CI_DD_4         MFP_CFG_DRV(GPIO53, AF1, DS04X)
+#define GPIO54_CI_DD_5         MFP_CFG_DRV(GPIO54, AF1, DS04X)
+#define GPIO55_CI_DD_6         MFP_CFG_DRV(GPIO55, AF1, DS04X)
+#define GPIO56_CI_DD_7         MFP_CFG_DRV(GPIO56, AF0, DS04X)
+#define GPIO57_CI_DD_8         MFP_CFG_DRV(GPIO57, AF1, DS04X)
+#define GPIO58_CI_DD_9         MFP_CFG_DRV(GPIO58, AF1, DS04X)
+#define GPIO59_CI_MCLK         MFP_CFG_DRV(GPIO59, AF0, DS04X)
+#define GPIO60_CI_PCLK         MFP_CFG_DRV(GPIO60, AF0, DS04X)
+#define GPIO61_CI_HSYNC                MFP_CFG_DRV(GPIO61, AF0, DS04X)
+#define GPIO62_CI_VSYNC                MFP_CFG_DRV(GPIO62, AF0, DS04X)
+
+#define GPIO31_CIR_OUT         MFP_CFG(GPIO31, AF5)
+
+#define GPIO0_2_CLK_EXT                MFP_CFG(GPIO0_2, AF3)
+#define GPIO0_DRQ              MFP_CFG(GPIO0, AF2)
+#define GPIO11_EXT_SYNC0       MFP_CFG(GPIO11, AF5)
+#define GPIO12_EXT_SYNC1       MFP_CFG(GPIO12, AF6)
+#define GPIO0_2_HZ_CLK         MFP_CFG(GPIO0_2, AF1)
+#define GPIO14_HZ_CLK          MFP_CFG(GPIO14, AF4)
+#define GPIO30_ICP_RXD         MFP_CFG(GPIO30, AF1)
+#define GPIO31_ICP_TXD         MFP_CFG(GPIO31, AF1)
+
+#define GPIO83_KP_DKIN_0       MFP_CFG_LPM(GPIO83, AF3, FLOAT)
+#define GPIO84_KP_DKIN_1       MFP_CFG_LPM(GPIO84, AF3, FLOAT)
+#define GPIO85_KP_DKIN_2       MFP_CFG_LPM(GPIO85, AF3, FLOAT)
+#define GPIO86_KP_DKIN_3       MFP_CFG_LPM(GPIO86, AF3, FLOAT)
+
+#define GPIO105_KP_DKIN_0      MFP_CFG_LPM(GPIO105, AF2, FLOAT)
+#define GPIO106_KP_DKIN_1      MFP_CFG_LPM(GPIO106, AF2, FLOAT)
+#define GPIO107_KP_DKIN_2      MFP_CFG_LPM(GPIO107, AF2, FLOAT)
+#define GPIO108_KP_DKIN_3      MFP_CFG_LPM(GPIO108, AF2, FLOAT)
+#define GPIO109_KP_DKIN_4      MFP_CFG_LPM(GPIO109, AF2, FLOAT)
+#define GPIO110_KP_DKIN_5      MFP_CFG_LPM(GPIO110, AF2, FLOAT)
+#define GPIO111_KP_DKIN_6      MFP_CFG_LPM(GPIO111, AF2, FLOAT)
+#define GPIO112_KP_DKIN_7      MFP_CFG_LPM(GPIO112, AF2, FLOAT)
+
+#define GPIO113_KP_DKIN_0      MFP_CFG_LPM(GPIO113, AF2, FLOAT)
+#define GPIO114_KP_DKIN_1      MFP_CFG_LPM(GPIO114, AF2, FLOAT)
+#define GPIO115_KP_DKIN_2      MFP_CFG_LPM(GPIO115, AF2, FLOAT)
+#define GPIO116_KP_DKIN_3      MFP_CFG_LPM(GPIO116, AF2, FLOAT)
+#define GPIO117_KP_DKIN_4      MFP_CFG_LPM(GPIO117, AF2, FLOAT)
+#define GPIO118_KP_DKIN_5      MFP_CFG_LPM(GPIO118, AF2, FLOAT)
+#define GPIO119_KP_DKIN_6      MFP_CFG_LPM(GPIO119, AF2, FLOAT)
+#define GPIO120_KP_DKIN_7      MFP_CFG_LPM(GPIO120, AF2, FLOAT)
+
+#define GPIO127_KP_DKIN_0      MFP_CFG_LPM(GPIO127, AF2, FLOAT)
+#define GPIO126_KP_DKIN_1      MFP_CFG_LPM(GPIO126, AF2, FLOAT)
+
+#define GPIO2_2_KP_DKIN_0      MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
+#define GPIO3_2_KP_DKIN_1      MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
+#define GPIO125_KP_DKIN_2      MFP_CFG_LPM(GPIO125, AF2, FLOAT)
+#define GPIO124_KP_DKIN_3      MFP_CFG_LPM(GPIO124, AF2, FLOAT)
+#define GPIO123_KP_DKIN_4      MFP_CFG_LPM(GPIO123, AF2, FLOAT)
+#define GPIO122_KP_DKIN_5      MFP_CFG_LPM(GPIO122, AF2, FLOAT)
+#define GPIO121_KP_DKIN_6      MFP_CFG_LPM(GPIO121, AF2, FLOAT)
+#define GPIO4_2_KP_DKIN_7      MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
+
+#define GPIO113_KP_MKIN_0      MFP_CFG_LPM(GPIO113, AF1, FLOAT)
+#define GPIO114_KP_MKIN_1      MFP_CFG_LPM(GPIO114, AF1, FLOAT)
+#define GPIO115_KP_MKIN_2      MFP_CFG_LPM(GPIO115, AF1, FLOAT)
+#define GPIO116_KP_MKIN_3      MFP_CFG_LPM(GPIO116, AF1, FLOAT)
+#define GPIO117_KP_MKIN_4      MFP_CFG_LPM(GPIO117, AF1, FLOAT)
+#define GPIO118_KP_MKIN_5      MFP_CFG_LPM(GPIO118, AF1, FLOAT)
+#define GPIO119_KP_MKIN_6      MFP_CFG_LPM(GPIO119, AF1, FLOAT)
+#define GPIO120_KP_MKIN_7      MFP_CFG_LPM(GPIO120, AF1, FLOAT)
+
+#define GPIO83_KP_MKOUT_0      MFP_CFG_LPM(GPIO83, AF2, DRIVE_HIGH)
+#define GPIO84_KP_MKOUT_1      MFP_CFG_LPM(GPIO84, AF2, DRIVE_HIGH)
+#define GPIO85_KP_MKOUT_2      MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
+#define GPIO86_KP_MKOUT_3      MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_4      MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
+#define GPIO14_KP_MKOUT_5      MFP_CFG_LPM(GPIO14, AF3, DRIVE_HIGH)
+
+#define GPIO121_KP_MKOUT_0     MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
+#define GPIO122_KP_MKOUT_1     MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
+#define GPIO123_KP_MKOUT_2     MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
+#define GPIO124_KP_MKOUT_3     MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
+#define GPIO125_KP_MKOUT_4     MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
+#define GPIO126_KP_MKOUT_5     MFP_CFG_LPM(GPIO126, AF1, DRIVE_HIGH)
+#define GPIO127_KP_MKOUT_6     MFP_CFG_LPM(GPIO127, AF1, DRIVE_HIGH)
+#define GPIO5_2_KP_MKOUT_7     MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO6_2_LCD_LDD_0      MFP_CFG_DRV(GPIO6_2, AF1, DS01X)
+#define GPIO7_2_LCD_LDD_1      MFP_CFG_DRV(GPIO7_2, AF1, DS01X)
+#define GPIO8_2_LCD_LDD_2      MFP_CFG_DRV(GPIO8_2, AF1, DS01X)
+#define GPIO9_2_LCD_LDD_3      MFP_CFG_DRV(GPIO9_2, AF1, DS01X)
+#define GPIO10_2_LCD_LDD_4     MFP_CFG_DRV(GPIO10_2, AF1, DS01X)
+#define GPIO11_2_LCD_LDD_5     MFP_CFG_DRV(GPIO11_2, AF1, DS01X)
+#define GPIO12_2_LCD_LDD_6     MFP_CFG_DRV(GPIO12_2, AF1, DS01X)
+#define GPIO13_2_LCD_LDD_7     MFP_CFG_DRV(GPIO13_2, AF1, DS01X)
+#define GPIO63_LCD_LDD_8       MFP_CFG_DRV(GPIO63, AF1, DS01X)
+#define GPIO64_LCD_LDD_9       MFP_CFG_DRV(GPIO64, AF1, DS01X)
+#define GPIO65_LCD_LDD_10      MFP_CFG_DRV(GPIO65, AF1, DS01X)
+#define GPIO66_LCD_LDD_11      MFP_CFG_DRV(GPIO66, AF1, DS01X)
+#define GPIO67_LCD_LDD_12      MFP_CFG_DRV(GPIO67, AF1, DS01X)
+#define GPIO68_LCD_LDD_13      MFP_CFG_DRV(GPIO68, AF1, DS01X)
+#define GPIO69_LCD_LDD_14      MFP_CFG_DRV(GPIO69, AF1, DS01X)
+#define GPIO70_LCD_LDD_15      MFP_CFG_DRV(GPIO70, AF1, DS01X)
+#define GPIO71_LCD_LDD_16      MFP_CFG_DRV(GPIO71, AF1, DS01X)
+#define GPIO72_LCD_LDD_17      MFP_CFG_DRV(GPIO72, AF1, DS01X)
+#define GPIO73_LCD_CS_N                MFP_CFG_DRV(GPIO73, AF2, DS01X)
+#define GPIO74_LCD_VSYNC       MFP_CFG_DRV(GPIO74, AF2, DS01X)
+#define GPIO14_2_LCD_FCLK      MFP_CFG_DRV(GPIO14_2, AF1, DS01X)
+#define GPIO15_2_LCD_LCLK      MFP_CFG_DRV(GPIO15_2, AF1, DS01X)
+#define GPIO16_2_LCD_PCLK      MFP_CFG_DRV(GPIO16_2, AF1, DS01X)
+#define GPIO17_2_LCD_BIAS      MFP_CFG_DRV(GPIO17_2, AF1, DS01X)
+#define GPIO64_LCD_VSYNC       MFP_CFG_DRV(GPIO64, AF2, DS01X)
+#define GPIO63_LCD_CS_N                MFP_CFG_DRV(GPIO63, AF2, DS01X)
+
+#define GPIO6_2_MLCD_DD_0      MFP_CFG_DRV(GPIO6_2, AF7, DS08X)
+#define GPIO7_2_MLCD_DD_1      MFP_CFG_DRV(GPIO7_2, AF7, DS08X)
+#define GPIO8_2_MLCD_DD_2      MFP_CFG_DRV(GPIO8_2, AF7, DS08X)
+#define GPIO9_2_MLCD_DD_3      MFP_CFG_DRV(GPIO9_2, AF7, DS08X)
+#define GPIO10_2_MLCD_DD_4     MFP_CFG_DRV(GPIO10_2, AF7, DS08X)
+#define GPIO11_2_MLCD_DD_5     MFP_CFG_DRV(GPIO11_2, AF7, DS08X)
+#define GPIO12_2_MLCD_DD_6     MFP_CFG_DRV(GPIO12_2, AF7, DS08X)
+#define GPIO13_2_MLCD_DD_7     MFP_CFG_DRV(GPIO13_2, AF7, DS08X)
+#define GPIO63_MLCD_DD_8       MFP_CFG_DRV(GPIO63, AF7, DS08X)
+#define GPIO64_MLCD_DD_9       MFP_CFG_DRV(GPIO64, AF7, DS08X)
+#define GPIO65_MLCD_DD_10      MFP_CFG_DRV(GPIO65, AF7, DS08X)
+#define GPIO66_MLCD_DD_11      MFP_CFG_DRV(GPIO66, AF7, DS08X)
+#define GPIO67_MLCD_DD_12      MFP_CFG_DRV(GPIO67, AF7, DS08X)
+#define GPIO68_MLCD_DD_13      MFP_CFG_DRV(GPIO68, AF7, DS08X)
+#define GPIO69_MLCD_DD_14      MFP_CFG_DRV(GPIO69, AF7, DS08X)
+#define GPIO70_MLCD_DD_15      MFP_CFG_DRV(GPIO70, AF7, DS08X)
+#define GPIO71_MLCD_DD_16      MFP_CFG_DRV(GPIO71, AF7, DS08X)
+#define GPIO72_MLCD_DD_17      MFP_CFG_DRV(GPIO72, AF7, DS08X)
+#define GPIO73_MLCD_CS         MFP_CFG_DRV(GPIO73, AF7, DS08X)
+#define GPIO74_MLCD_VSYNC      MFP_CFG_DRV(GPIO74, AF7, DS08X)
+#define GPIO14_2_MLCD_FCLK     MFP_CFG_DRV(GPIO14_2, AF7, DS08X)
+#define GPIO15_2_MLCD_LCLK     MFP_CFG_DRV(GPIO15_2, AF7, DS08X)
+#define GPIO16_2_MLCD_PCLK     MFP_CFG_DRV(GPIO16_2, AF7, DS08X)
+#define GPIO17_2_MLCD_BIAS     MFP_CFG_DRV(GPIO17_2, AF7, DS08X)
+
+/* MMC1 */
+#define GPIO9_MMC1_CMD         MFP_CFG_LPM(GPIO9,  AF4, DRIVE_HIGH)
+#define GPIO22_MMC1_CLK                MFP_CFG_LPM(GPIO22, AF4, DRIVE_HIGH)
+#define GPIO23_MMC1_CMD                MFP_CFG_LPM(GPIO23, AF4, DRIVE_HIGH)
+#define GPIO30_MMC1_CLK                MFP_CFG_LPM(GPIO30, AF4, DRIVE_HIGH)
+#define GPIO31_MMC1_CMD                MFP_CFG_LPM(GPIO31, AF4, DRIVE_HIGH)
+#define GPIO5_MMC1_DAT0                MFP_CFG_LPM(GPIO5,  AF4, DRIVE_HIGH)
+#define GPIO6_MMC1_DAT1                MFP_CFG_LPM(GPIO6,  AF4, DRIVE_HIGH)
+#define GPIO7_MMC1_DAT2                MFP_CFG_LPM(GPIO7,  AF4, DRIVE_HIGH)
+#define GPIO8_MMC1_DAT3                MFP_CFG_LPM(GPIO8,  AF4, DRIVE_HIGH)
+#define GPIO18_MMC1_DAT0       MFP_CFG_LPM(GPIO18, AF4, DRIVE_HIGH)
+#define GPIO19_MMC1_DAT1       MFP_CFG_LPM(GPIO19, AF4, DRIVE_HIGH)
+#define GPIO20_MMC1_DAT2       MFP_CFG_LPM(GPIO20, AF4, DRIVE_HIGH)
+#define GPIO21_MMC1_DAT3       MFP_CFG_LPM(GPIO21, AF4, DRIVE_HIGH)
+
+#define GPIO28_MMC2_CLK                MFP_CFG_LPM(GPIO28, AF4, PULL_HIGH)
+#define GPIO29_MMC2_CMD                MFP_CFG_LPM(GPIO29, AF4, PULL_HIGH)
+#define GPIO30_MMC2_CLK                MFP_CFG_LPM(GPIO30, AF3, PULL_HIGH)
+#define GPIO31_MMC2_CMD                MFP_CFG_LPM(GPIO31, AF3, PULL_HIGH)
+#define GPIO79_MMC2_CLK                MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
+#define GPIO80_MMC2_CMD                MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
+
+#define GPIO5_MMC2_DAT0                MFP_CFG_LPM(GPIO5, AF2, PULL_HIGH)
+#define GPIO6_MMC2_DAT1                MFP_CFG_LPM(GPIO6, AF2, PULL_HIGH)
+#define GPIO7_MMC2_DAT2                MFP_CFG_LPM(GPIO7, AF2, PULL_HIGH)
+#define GPIO8_MMC2_DAT3                MFP_CFG_LPM(GPIO8, AF2, PULL_HIGH)
+#define GPIO24_MMC2_DAT0       MFP_CFG_LPM(GPIO24, AF4, PULL_HIGH)
+#define GPIO75_MMC2_DAT0       MFP_CFG_LPM(GPIO75, AF4, PULL_HIGH)
+#define GPIO25_MMC2_DAT1       MFP_CFG_LPM(GPIO25, AF4, PULL_HIGH)
+#define GPIO76_MMC2_DAT1       MFP_CFG_LPM(GPIO76, AF4, PULL_HIGH)
+#define GPIO26_MMC2_DAT2       MFP_CFG_LPM(GPIO26, AF4, PULL_HIGH)
+#define GPIO77_MMC2_DAT2       MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
+#define GPIO27_MMC2_DAT3       MFP_CFG_LPM(GPIO27, AF4, PULL_HIGH)
+#define GPIO78_MMC2_DAT3       MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
+
+/* 1-Wire */
+#define GPIO14_ONE_WIRE                MFP_CFG_LPM(GPIO14,  AF5, FLOAT)
+#define GPIO0_2_ONE_WIRE       MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
+
+/* SSP1 */
+#define GPIO87_SSP1_EXTCLK     MFP_CFG(GPIO87, AF1)
+#define GPIO88_SSP1_SYSCLK     MFP_CFG(GPIO88, AF1)
+#define GPIO83_SSP1_SCLK       MFP_CFG(GPIO83, AF1)
+#define GPIO84_SSP1_SFRM       MFP_CFG(GPIO84, AF1)
+#define GPIO85_SSP1_RXD                MFP_CFG(GPIO85, AF6)
+#define GPIO85_SSP1_TXD                MFP_CFG(GPIO85, AF1)
+#define GPIO86_SSP1_RXD                MFP_CFG(GPIO86, AF1)
+#define GPIO86_SSP1_TXD                MFP_CFG(GPIO86, AF6)
+
+/* SSP2 */
+#define GPIO39_SSP2_EXTCLK     MFP_CFG(GPIO39, AF2)
+#define GPIO40_SSP2_SYSCLK     MFP_CFG(GPIO40, AF2)
+#define GPIO12_SSP2_SCLK       MFP_CFG(GPIO12, AF2)
+#define GPIO35_SSP2_SCLK       MFP_CFG(GPIO35, AF2)
+#define GPIO36_SSP2_SFRM       MFP_CFG(GPIO36, AF2)
+#define GPIO37_SSP2_RXD                MFP_CFG(GPIO37, AF5)
+#define GPIO37_SSP2_TXD                MFP_CFG(GPIO37, AF2)
+#define GPIO38_SSP2_RXD                MFP_CFG(GPIO38, AF2)
+#define GPIO38_SSP2_TXD                MFP_CFG(GPIO38, AF5)
+
+#define GPIO69_SSP3_SCLK       MFP_CFG_X(GPIO69, AF2, DS08X, FLOAT)
+#define GPIO70_SSP3_FRM                MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO89_SSP3_SCLK       MFP_CFG_X(GPIO89, AF1, DS08X, FLOAT)
+#define GPIO90_SSP3_FRM                MFP_CFG_X(GPIO90, AF1, DS08X, DRIVE_LOW)
+#define GPIO71_SSP3_RXD                MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT)
+#define GPIO71_SSP3_TXD                MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW)
+#define GPIO72_SSP3_RXD                MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT)
+#define GPIO72_SSP3_TXD                MFP_CFG_X(GPIO72, AF5, DS08X, DRIVE_LOW)
+#define GPIO91_SSP3_RXD                MFP_CFG_X(GPIO91, AF5, DS08X, FLOAT)
+#define GPIO91_SSP3_TXD                MFP_CFG_X(GPIO91, AF1, DS08X, DRIVE_LOW)
+#define GPIO92_SSP3_RXD                MFP_CFG_X(GPIO92, AF1, DS08X, FLOAT)
+#define GPIO92_SSP3_TXD                MFP_CFG_X(GPIO92, AF5, DS08X, DRIVE_LOW)
+
+#define GPIO93_SSP4_SCLK       MFP_CFG_LPM(GPIO93, AF1, PULL_HIGH)
+#define GPIO94_SSP4_FRM                MFP_CFG_LPM(GPIO94, AF1, PULL_HIGH)
+#define GPIO94_SSP4_RXD                MFP_CFG_LPM(GPIO94, AF5, PULL_HIGH)
+#define GPIO95_SSP4_RXD                MFP_CFG_LPM(GPIO95, AF5, PULL_HIGH)
+#define GPIO95_SSP4_TXD                MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_SSP4_RXD                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+#define GPIO96_SSP4_TXD                MFP_CFG_LPM(GPIO96, AF5, PULL_HIGH)
+
+/* UART1 */
+#define GPIO41_UART1_RXD       MFP_CFG_LPM(GPIO41, AF2, FLOAT)
+#define GPIO41_UART1_TXD       MFP_CFG_LPM(GPIO41, AF4, FLOAT)
+#define GPIO42_UART1_RXD       MFP_CFG_LPM(GPIO42, AF4, FLOAT)
+#define GPIO42_UART1_TXD       MFP_CFG_LPM(GPIO42, AF2, FLOAT)
+#define GPIO75_UART1_RXD       MFP_CFG_LPM(GPIO75, AF1, FLOAT)
+#define GPIO76_UART1_RXD       MFP_CFG_LPM(GPIO76, AF3, FLOAT)
+#define GPIO76_UART1_TXD       MFP_CFG_LPM(GPIO76, AF1, FLOAT)
+#define GPIO97_UART1_RXD       MFP_CFG_LPM(GPIO97, AF1, FLOAT)
+#define GPIO97_UART1_TXD       MFP_CFG_LPM(GPIO97, AF6, FLOAT)
+#define GPIO98_UART1_RXD       MFP_CFG_LPM(GPIO98, AF6, FLOAT)
+#define GPIO98_UART1_TXD       MFP_CFG_LPM(GPIO98, AF1, FLOAT)
+#define GPIO43_UART1_CTS       MFP_CFG_LPM(GPIO43, AF2, FLOAT)
+#define GPIO43_UART1_RTS       MFP_CFG_LPM(GPIO43, AF4, FLOAT)
+#define GPIO48_UART1_CTS       MFP_CFG_LPM(GPIO48, AF4, FLOAT)
+#define GPIO48_UART1_RTS       MFP_CFG_LPM(GPIO48, AF2, FLOAT)
+#define GPIO77_UART1_CTS       MFP_CFG_LPM(GPIO77, AF1, FLOAT)
+#define GPIO82_UART1_RTS       MFP_CFG_LPM(GPIO82, AF1, FLOAT)
+#define GPIO82_UART1_CTS       MFP_CFG_LPM(GPIO82, AF3, FLOAT)
+#define GPIO99_UART1_CTS       MFP_CFG_LPM(GPIO99, AF1, FLOAT)
+#define GPIO99_UART1_RTS       MFP_CFG_LPM(GPIO99, AF6, FLOAT)
+#define GPIO104_UART1_CTS      MFP_CFG_LPM(GPIO104, AF6, FLOAT)
+#define GPIO104_UART1_RTS      MFP_CFG_LPM(GPIO104, AF1, FLOAT)
+#define GPIO45_UART1_DTR       MFP_CFG_LPM(GPIO45, AF4, FLOAT)
+#define GPIO45_UART1_DSR       MFP_CFG_LPM(GPIO45, AF2, FLOAT)
+#define GPIO47_UART1_DTR       MFP_CFG_LPM(GPIO47, AF2, FLOAT)
+#define GPIO47_UART1_DSR       MFP_CFG_LPM(GPIO47, AF4, FLOAT)
+#define GPIO79_UART1_DSR       MFP_CFG_LPM(GPIO79, AF1, FLOAT)
+#define GPIO81_UART1_DTR       MFP_CFG_LPM(GPIO81, AF1, FLOAT)
+#define GPIO81_UART1_DSR       MFP_CFG_LPM(GPIO81, AF3, FLOAT)
+#define GPIO101_UART1_DTR      MFP_CFG_LPM(GPIO101, AF6, FLOAT)
+#define GPIO101_UART1_DSR      MFP_CFG_LPM(GPIO101, AF1, FLOAT)
+#define GPIO103_UART1_DTR      MFP_CFG_LPM(GPIO103, AF1, FLOAT)
+#define GPIO103_UART1_DSR      MFP_CFG_LPM(GPIO103, AF6, FLOAT)
+#define GPIO44_UART1_DCD       MFP_CFG_LPM(GPIO44, AF2, FLOAT)
+#define GPIO78_UART1_DCD       MFP_CFG_LPM(GPIO78, AF1, FLOAT)
+#define GPIO100_UART1_DCD      MFP_CFG_LPM(GPIO100, AF1, FLOAT)
+#define GPIO46_UART1_RI                MFP_CFG_LPM(GPIO46, AF2, FLOAT)
+#define GPIO80_UART1_RI                MFP_CFG_LPM(GPIO80, AF1, FLOAT)
+#define GPIO102_UART1_RI       MFP_CFG_LPM(GPIO102, AF1, FLOAT)
+
+/* UART2 */
+#define GPIO109_UART2_CTS      MFP_CFG_LPM(GPIO109, AF3, FLOAT)
+#define GPIO109_UART2_RTS      MFP_CFG_LPM(GPIO109, AF1, FLOAT)
+#define GPIO112_UART2_CTS      MFP_CFG_LPM(GPIO112, AF1, FLOAT)
+#define GPIO112_UART2_RTS      MFP_CFG_LPM(GPIO112, AF3, FLOAT)
+#define GPIO110_UART2_RXD      MFP_CFG_LPM(GPIO110, AF1, FLOAT)
+#define GPIO110_UART2_TXD      MFP_CFG_LPM(GPIO110, AF3, FLOAT)
+#define GPIO111_UART2_RXD      MFP_CFG_LPM(GPIO111, AF3, FLOAT)
+#define GPIO111_UART2_TXD      MFP_CFG_LPM(GPIO111, AF1, FLOAT)
+
+/* UART3 */
+#define GPIO89_UART3_CTS       MFP_CFG_LPM(GPIO89, AF2, FLOAT)
+#define GPIO89_UART3_RTS       MFP_CFG_LPM(GPIO89, AF4, FLOAT)
+#define GPIO90_UART3_CTS       MFP_CFG_LPM(GPIO90, AF4, FLOAT)
+#define GPIO90_UART3_RTS       MFP_CFG_LPM(GPIO90, AF2, FLOAT)
+#define GPIO105_UART3_CTS      MFP_CFG_LPM(GPIO105, AF1, FLOAT)
+#define GPIO105_UART3_RTS      MFP_CFG_LPM(GPIO105, AF3, FLOAT)
+#define GPIO106_UART3_CTS      MFP_CFG_LPM(GPIO106, AF3, FLOAT)
+#define GPIO106_UART3_RTS      MFP_CFG_LPM(GPIO106, AF1, FLOAT)
+#define GPIO30_UART3_RXD       MFP_CFG_LPM(GPIO30, AF2, FLOAT)
+#define GPIO30_UART3_TXD       MFP_CFG_LPM(GPIO30, AF6, FLOAT)
+#define GPIO31_UART3_RXD       MFP_CFG_LPM(GPIO31, AF6, FLOAT)
+#define GPIO31_UART3_TXD       MFP_CFG_LPM(GPIO31, AF2, FLOAT)
+#define GPIO91_UART3_RXD       MFP_CFG_LPM(GPIO91, AF4, FLOAT)
+#define GPIO91_UART3_TXD       MFP_CFG_LPM(GPIO91, AF2, FLOAT)
+#define GPIO92_UART3_RXD       MFP_CFG_LPM(GPIO92, AF2, FLOAT)
+#define GPIO92_UART3_TXD       MFP_CFG_LPM(GPIO92, AF4, FLOAT)
+#define GPIO107_UART3_RXD      MFP_CFG_LPM(GPIO107, AF3, FLOAT)
+#define GPIO107_UART3_TXD      MFP_CFG_LPM(GPIO107, AF1, FLOAT)
+#define GPIO108_UART3_RXD      MFP_CFG_LPM(GPIO108, AF1, FLOAT)
+#define GPIO108_UART3_TXD      MFP_CFG_LPM(GPIO108, AF3, FLOAT)
+
+
+/* USB 2.0 UTMI */
+#define GPIO10_UTM_CLK         MFP_CFG(GPIO10, AF1)
+#define GPIO36_U2D_RXERROR     MFP_CFG(GPIO36, AF3)
+#define GPIO60_U2D_RXERROR     MFP_CFG(GPIO60, AF1)
+#define GPIO87_U2D_RXERROR     MFP_CFG(GPIO87, AF5)
+#define GPIO34_UTM_RXVALID     MFP_CFG(GPIO34, AF3)
+#define GPIO58_UTM_RXVALID     MFP_CFG(GPIO58, AF2)
+#define GPIO85_UTM_RXVALID     MFP_CFG(GPIO85, AF5)
+#define GPIO35_UTM_RXACTIVE    MFP_CFG(GPIO35, AF3)
+#define GPIO59_UTM_RXACTIVE    MFP_CFG(GPIO59, AF1)
+#define GPIO86_UTM_RXACTIVE    MFP_CFG(GPIO86, AF5)
+#define GPIO73_UTM_TXREADY     MFP_CFG(GPIO73, AF1)
+#define GPIO68_UTM_LINESTATE_0 MFP_CFG(GPIO68, AF3)
+#define GPIO90_UTM_LINESTATE_0 MFP_CFG(GPIO90, AF3)
+#define GPIO102_UTM_LINESTATE_0        MFP_CFG(GPIO102, AF3)
+#define GPIO107_UTM_LINESTATE_0        MFP_CFG(GPIO107, AF4)
+#define GPIO69_UTM_LINESTATE_1 MFP_CFG(GPIO69, AF3)
+#define GPIO91_UTM_LINESTATE_1 MFP_CFG(GPIO91, AF3)
+#define GPIO103_UTM_LINESTATE_1        MFP_CFG(GPIO103, AF3)
+
+#define GPIO41_U2D_PHYDATA_0   MFP_CFG(GPIO41, AF3)
+#define GPIO42_U2D_PHYDATA_1   MFP_CFG(GPIO42, AF3)
+#define GPIO43_U2D_PHYDATA_2   MFP_CFG(GPIO43, AF3)
+#define GPIO44_U2D_PHYDATA_3   MFP_CFG(GPIO44, AF3)
+#define GPIO45_U2D_PHYDATA_4   MFP_CFG(GPIO45, AF3)
+#define GPIO46_U2D_PHYDATA_5   MFP_CFG(GPIO46, AF3)
+#define GPIO47_U2D_PHYDATA_6   MFP_CFG(GPIO47, AF3)
+#define GPIO48_U2D_PHYDATA_7   MFP_CFG(GPIO48, AF3)
+
+#define GPIO49_U2D_PHYDATA_0   MFP_CFG(GPIO49, AF3)
+#define GPIO50_U2D_PHYDATA_1   MFP_CFG(GPIO50, AF3)
+#define GPIO51_U2D_PHYDATA_2   MFP_CFG(GPIO51, AF3)
+#define GPIO52_U2D_PHYDATA_3   MFP_CFG(GPIO52, AF3)
+#define GPIO53_U2D_PHYDATA_4   MFP_CFG(GPIO53, AF3)
+#define GPIO54_U2D_PHYDATA_5   MFP_CFG(GPIO54, AF3)
+#define GPIO55_U2D_PHYDATA_6   MFP_CFG(GPIO55, AF3)
+#define GPIO56_U2D_PHYDATA_7   MFP_CFG(GPIO56, AF3)
+
+#define GPIO37_U2D_OPMODE0     MFP_CFG(GPIO37, AF4)
+#define GPIO61_U2D_OPMODE0     MFP_CFG(GPIO61, AF2)
+#define GPIO88_U2D_OPMODE0     MFP_CFG(GPIO88, AF7)
+
+#define GPIO38_U2D_OPMODE1     MFP_CFG(GPIO38, AF4)
+#define GPIO62_U2D_OPMODE1     MFP_CFG(GPIO62, AF2)
+#define GPIO104_U2D_OPMODE1    MFP_CFG(GPIO104, AF4)
+#define GPIO108_U2D_OPMODE1    MFP_CFG(GPIO108, AF5)
+
+#define GPIO74_U2D_RESET       MFP_CFG(GPIO74, AF1)
+#define GPIO93_U2D_RESET       MFP_CFG(GPIO93, AF2)
+#define GPIO98_U2D_RESET       MFP_CFG(GPIO98, AF3)
+
+#define GPIO67_U2D_SUSPEND     MFP_CFG(GPIO67, AF3)
+#define GPIO96_U2D_SUSPEND     MFP_CFG(GPIO96, AF2)
+#define GPIO101_U2D_SUSPEND    MFP_CFG(GPIO101, AF3)
+
+#define GPIO66_U2D_TERM_SEL    MFP_CFG(GPIO66, AF5)
+#define GPIO95_U2D_TERM_SEL    MFP_CFG(GPIO95, AF3)
+#define GPIO97_U2D_TERM_SEL    MFP_CFG(GPIO97, AF7)
+#define GPIO100_U2D_TERM_SEL   MFP_CFG(GPIO100, AF5)
+
+#define GPIO39_U2D_TXVALID     MFP_CFG(GPIO39, AF4)
+#define GPIO70_U2D_TXVALID     MFP_CFG(GPIO70, AF5)
+#define GPIO83_U2D_TXVALID     MFP_CFG(GPIO83, AF7)
+
+#define GPIO65_U2D_XCVR_SEL    MFP_CFG(GPIO65, AF5)
+#define GPIO94_U2D_XCVR_SEL    MFP_CFG(GPIO94, AF3)
+#define GPIO99_U2D_XCVR_SEL    MFP_CFG(GPIO99, AF5)
+
+/* USB Host 1.1 */
+#define GPIO2_2_USBH_PEN       MFP_CFG(GPIO2_2, AF1)
+#define GPIO3_2_USBH_PWR       MFP_CFG(GPIO3_2, AF1)
+
+/* USB P2 */
+#define GPIO97_USB_P2_2                MFP_CFG(GPIO97, AF2)
+#define GPIO97_USB_P2_6                MFP_CFG(GPIO97, AF4)
+#define GPIO98_USB_P2_2                MFP_CFG(GPIO98, AF4)
+#define GPIO98_USB_P2_6                MFP_CFG(GPIO98, AF2)
+#define GPIO99_USB_P2_1                MFP_CFG(GPIO99, AF2)
+#define GPIO100_USB_P2_4       MFP_CFG(GPIO100, AF2)
+#define GPIO101_USB_P2_8       MFP_CFG(GPIO101, AF2)
+#define GPIO102_USB_P2_3       MFP_CFG(GPIO102, AF2)
+#define GPIO103_USB_P2_5       MFP_CFG(GPIO103, AF2)
+#define GPIO104_USB_P2_7       MFP_CFG(GPIO104, AF2)
+
+/* USB P3 */
+#define GPIO75_USB_P3_1                MFP_CFG(GPIO75, AF2)
+#define GPIO76_USB_P3_2                MFP_CFG(GPIO76, AF2)
+#define GPIO77_USB_P3_3                MFP_CFG(GPIO77, AF2)
+#define GPIO78_USB_P3_4                MFP_CFG(GPIO78, AF2)
+#define GPIO79_USB_P3_5                MFP_CFG(GPIO79, AF2)
+#define GPIO80_USB_P3_6                MFP_CFG(GPIO80, AF2)
+
+#define GPIO13_CHOUT0          MFP_CFG(GPIO13, AF6)
+#define GPIO14_CHOUT1          MFP_CFG(GPIO14, AF6)
+
+#define GPIO2_RDY              MFP_CFG(GPIO2, AF1)
+#define GPIO5_NPIOR            MFP_CFG(GPIO5, AF3)
+#define GPIO6_NPIOW            MFP_CFG(GPIO6, AF3)
+#define GPIO7_NPIOS16          MFP_CFG(GPIO7, AF3)
+#define GPIO8_NPWAIT           MFP_CFG(GPIO8, AF3)
+
+#define GPIO11_PWM0_OUT                MFP_CFG(GPIO11, AF1)
+#define GPIO12_PWM1_OUT                MFP_CFG(GPIO12, AF1)
+#define GPIO13_PWM2_OUT                MFP_CFG(GPIO13, AF1)
+#define GPIO14_PWM3_OUT                MFP_CFG(GPIO14, AF1)
+
+#endif /* __ASM_ARCH_MFP_PXA320_H */
index 89863a0..994edc0 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
-#include <mach/mfp-pxa3xx.h>
+#include "mfp-pxa3xx.h"
 #include <mach/pxa3xx-regs.h>
 
 #ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.h b/arch/arm/mach-pxa/mfp-pxa3xx.h
new file mode 100644 (file)
index 0000000..d375195
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef __ASM_ARCH_MFP_PXA3XX_H
+#define __ASM_ARCH_MFP_PXA3XX_H
+
+#include <plat/mfp.h>
+
+#define MFPR_BASE      (0x40e10000)
+
+/* PXA3xx common MFP configurations - processor specific ones defined
+ * in mfp-pxa300.h and mfp-pxa320.h
+ */
+#define GPIO0_GPIO             MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO             MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO             MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO             MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO             MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO             MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO             MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO             MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO             MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO             MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO            MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO            MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO            MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO            MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO            MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO            MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO            MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO            MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO            MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO            MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO            MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO            MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO            MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO            MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO            MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO            MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO            MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO            MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO            MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO            MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO            MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO            MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO            MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO            MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO            MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO            MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO            MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO            MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO            MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO            MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO            MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO            MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO            MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO            MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO            MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO            MFP_CFG(GPIO45, AF0)
+
+#define GPIO47_GPIO            MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO            MFP_CFG(GPIO48, AF0)
+
+#define GPIO53_GPIO            MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO            MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO            MFP_CFG(GPIO55, AF0)
+
+#define GPIO57_GPIO            MFP_CFG(GPIO57, AF0)
+
+#define GPIO63_GPIO            MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO            MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO            MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO            MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO            MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO            MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO            MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO            MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO            MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO            MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO            MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO            MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO            MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO            MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO            MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO            MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO            MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO            MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO            MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO            MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO            MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO            MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO            MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO            MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO            MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO            MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO            MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO            MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO            MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO            MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO            MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO            MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO            MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO            MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO            MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO            MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO            MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO           MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO           MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO           MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO           MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO           MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO           MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO           MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO           MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO           MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO           MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO           MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO           MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO           MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO           MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO           MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO           MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO           MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO           MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO           MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO           MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO           MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO           MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO           MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO           MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO           MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO           MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO           MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO           MFP_CFG(GPIO127, AF0)
+
+#define GPIO0_2_GPIO           MFP_CFG(GPIO0_2, AF0)
+#define GPIO1_2_GPIO           MFP_CFG(GPIO1_2, AF0)
+#define GPIO2_2_GPIO           MFP_CFG(GPIO2_2, AF0)
+#define GPIO3_2_GPIO           MFP_CFG(GPIO3_2, AF0)
+#define GPIO4_2_GPIO           MFP_CFG(GPIO4_2, AF0)
+#define GPIO5_2_GPIO           MFP_CFG(GPIO5_2, AF0)
+#define GPIO6_2_GPIO           MFP_CFG(GPIO6_2, AF0)
+
+/* NOTE: usage of these two functions is not recommended,
+ * use pxa3xx_mfp_config() instead.
+ */
+static inline unsigned long pxa3xx_mfp_read(int mfp)
+{
+       return mfp_read(mfp);
+}
+
+static inline void pxa3xx_mfp_write(int mfp, unsigned long val)
+{
+       mfp_write(mfp, val);
+}
+
+static inline void pxa3xx_mfp_config(unsigned long *mfp_cfg, int num)
+{
+       mfp_config(mfp_cfg, num);
+}
+#endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa930.h b/arch/arm/mach-pxa/mfp-pxa930.h
new file mode 100644 (file)
index 0000000..113967b
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp-pxa930.h
+ *
+ * PXA930 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007-2008 Marvell International 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.
+ */
+
+#ifndef __ASM_ARCH_MFP_PXA9xx_H
+#define __ASM_ARCH_MFP_PXA9xx_H
+
+#include "mfp-pxa3xx.h"
+
+/* GPIO */
+#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
+#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
+#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
+#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
+
+#define GSIM_UCLK_GPIO_79      MFP_CFG(GSIM_UCLK, AF0)
+#define GSIM_UIO_GPIO_80       MFP_CFG(GSIM_UIO, AF0)
+#define GSIM_nURST_GPIO_81     MFP_CFG(GSIM_nURST, AF0)
+#define GSIM_UDET_GPIO_82      MFP_CFG(GSIM_UDET, AF0)
+
+#define DF_IO15_GPIO_28                MFP_CFG(DF_IO15, AF0)
+#define DF_IO14_GPIO_29                MFP_CFG(DF_IO14, AF0)
+#define DF_IO13_GPIO_30                MFP_CFG(DF_IO13, AF0)
+#define DF_IO12_GPIO_31                MFP_CFG(DF_IO12, AF0)
+#define DF_IO11_GPIO_32                MFP_CFG(DF_IO11, AF0)
+#define DF_IO10_GPIO_33                MFP_CFG(DF_IO10, AF0)
+#define DF_IO9_GPIO_34         MFP_CFG(DF_IO9, AF0)
+#define DF_IO8_GPIO_35         MFP_CFG(DF_IO8, AF0)
+#define DF_IO7_GPIO_36         MFP_CFG(DF_IO7, AF0)
+#define DF_IO6_GPIO_37         MFP_CFG(DF_IO6, AF0)
+#define DF_IO5_GPIO_38         MFP_CFG(DF_IO5, AF0)
+#define DF_IO4_GPIO_39         MFP_CFG(DF_IO4, AF0)
+#define DF_IO3_GPIO_40         MFP_CFG(DF_IO3, AF0)
+#define DF_IO2_GPIO_41         MFP_CFG(DF_IO2, AF0)
+#define DF_IO1_GPIO_42         MFP_CFG(DF_IO1, AF0)
+#define DF_IO0_GPIO_43         MFP_CFG(DF_IO0, AF0)
+#define DF_nCS0_GPIO_44                MFP_CFG(DF_nCS0, AF0)
+#define DF_nCS1_GPIO_45                MFP_CFG(DF_nCS1, AF0)
+#define DF_nWE_GPIO_46         MFP_CFG(DF_nWE, AF0)
+#define DF_nRE_nOE_GPIO_47     MFP_CFG(DF_nRE_nOE, AF0)
+#define DF_CLE_nOE_GPIO_48     MFP_CFG(DF_CLE_nOE, AF0)
+#define DF_nADV1_ALE_GPIO_49   MFP_CFG(DF_nADV1_ALE, AF0)
+#define DF_nADV2_ALE_GPIO_50   MFP_CFG(DF_nADV2_ALE, AF0)
+#define DF_INT_RnB_GPIO_51     MFP_CFG(DF_INT_RnB, AF0)
+#define DF_SCLK_E_GPIO_52      MFP_CFG(DF_SCLK_E, AF0)
+
+#define DF_ADDR0_GPIO_53       MFP_CFG(DF_ADDR0, AF0)
+#define DF_ADDR1_GPIO_54       MFP_CFG(DF_ADDR1, AF0)
+#define DF_ADDR2_GPIO_55       MFP_CFG(DF_ADDR2, AF0)
+#define DF_ADDR3_GPIO_56       MFP_CFG(DF_ADDR3, AF0)
+#define nXCVREN_GPIO_57                MFP_CFG(nXCVREN, AF0)
+#define nLUA_GPIO_58           MFP_CFG(nLUA, AF0)
+#define nLLA_GPIO_59           MFP_CFG(nLLA, AF0)
+#define nBE0_GPIO_60           MFP_CFG(nBE0, AF0)
+#define nBE1_GPIO_61           MFP_CFG(nBE1, AF0)
+#define RDY_GPIO_62            MFP_CFG(RDY, AF0)
+#define PMIC_INT_GPIO83                MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH)
+
+/* Chip Select */
+#define DF_nCS0_nCS2           MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
+#define DF_nCS1_nCS3           MFP_CFG_LPM(DF_nCS1, AF3, PULL_HIGH)
+
+/* AC97 */
+#define GPIO83_BAC97_SYSCLK    MFP_CFG(GPIO83, AF3)
+#define GPIO84_BAC97_SDATA_IN0 MFP_CFG(GPIO84, AF3)
+#define GPIO85_BAC97_BITCLK    MFP_CFG(GPIO85, AF3)
+#define GPIO86_BAC97_nRESET    MFP_CFG(GPIO86, AF3)
+#define GPIO87_BAC97_SYNC      MFP_CFG(GPIO87, AF3)
+#define GPIO88_BAC97_SDATA_OUT MFP_CFG(GPIO88, AF3)
+
+/* I2C */
+#define GPIO39_CI2C_SCL                MFP_CFG_LPM(GPIO39, AF3, PULL_HIGH)
+#define GPIO40_CI2C_SDA                MFP_CFG_LPM(GPIO40, AF3, PULL_HIGH)
+
+#define GPIO51_CI2C_SCL                MFP_CFG_LPM(GPIO51, AF3, PULL_HIGH)
+#define GPIO52_CI2C_SDA                MFP_CFG_LPM(GPIO52, AF3, PULL_HIGH)
+
+#define GPIO63_CI2C_SCL                MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
+#define GPIO64_CI2C_SDA                MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
+
+#define GPIO73_CI2C_SCL                MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH)
+#define GPIO74_CI2C_SDA                MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH)
+
+#define GPIO77_CI2C_SCL                MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
+#define GPIO78_CI2C_SDA                MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
+
+#define GPIO89_CI2C_SCL                MFP_CFG_LPM(GPIO89, AF1, PULL_HIGH)
+#define GPIO90_CI2C_SDA                MFP_CFG_LPM(GPIO90, AF1, PULL_HIGH)
+
+#define GPIO95_CI2C_SCL                MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_CI2C_SDA                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+
+#define GPIO97_CI2C_SCL                MFP_CFG_LPM(GPIO97, AF3, PULL_HIGH)
+#define GPIO98_CI2C_SDA                MFP_CFG_LPM(GPIO98, AF3, PULL_HIGH)
+
+/* QCI */
+#define GPIO63_CI_DD_9         MFP_CFG_LPM(GPIO63, AF1, PULL_LOW)
+#define GPIO64_CI_DD_8         MFP_CFG_LPM(GPIO64, AF1, PULL_LOW)
+#define GPIO65_CI_DD_7         MFP_CFG_LPM(GPIO65, AF1, PULL_LOW)
+#define GPIO66_CI_DD_6         MFP_CFG_LPM(GPIO66, AF1, PULL_LOW)
+#define GPIO67_CI_DD_5         MFP_CFG_LPM(GPIO67, AF1, PULL_LOW)
+#define GPIO68_CI_DD_4         MFP_CFG_LPM(GPIO68, AF1, PULL_LOW)
+#define GPIO69_CI_DD_3         MFP_CFG_LPM(GPIO69, AF1, PULL_LOW)
+#define GPIO70_CI_DD_2         MFP_CFG_LPM(GPIO70, AF1, PULL_LOW)
+#define GPIO71_CI_DD_1         MFP_CFG_LPM(GPIO71, AF1, PULL_LOW)
+#define GPIO72_CI_DD_0         MFP_CFG_LPM(GPIO72, AF1, PULL_LOW)
+#define GPIO73_CI_HSYNC                MFP_CFG_LPM(GPIO73, AF1, PULL_LOW)
+#define GPIO74_CI_VSYNC                MFP_CFG_LPM(GPIO74, AF1, PULL_LOW)
+#define GPIO75_CI_MCLK         MFP_CFG_LPM(GPIO75, AF1, PULL_LOW)
+#define GPIO76_CI_PCLK         MFP_CFG_LPM(GPIO76, AF1, PULL_LOW)
+
+/* KEYPAD */
+#define GPIO4_KP_DKIN_4                MFP_CFG_LPM(GPIO4, AF3, FLOAT)
+#define GPIO5_KP_DKIN_5                MFP_CFG_LPM(GPIO5, AF3, FLOAT)
+#define GPIO6_KP_DKIN_6                MFP_CFG_LPM(GPIO6, AF3, FLOAT)
+#define GPIO7_KP_DKIN_7                MFP_CFG_LPM(GPIO7, AF3, FLOAT)
+#define GPIO8_KP_DKIN_4                MFP_CFG_LPM(GPIO8, AF3, FLOAT)
+#define GPIO9_KP_DKIN_5                MFP_CFG_LPM(GPIO9, AF3, FLOAT)
+#define GPIO10_KP_DKIN_6       MFP_CFG_LPM(GPIO10, AF3, FLOAT)
+#define GPIO11_KP_DKIN_7       MFP_CFG_LPM(GPIO11, AF3, FLOAT)
+
+#define GPIO12_KP_DKIN_0       MFP_CFG_LPM(GPIO12, AF2, FLOAT)
+#define GPIO13_KP_DKIN_1       MFP_CFG_LPM(GPIO13, AF2, FLOAT)
+#define GPIO14_KP_DKIN_2       MFP_CFG_LPM(GPIO14, AF2, FLOAT)
+#define GPIO15_KP_DKIN_3       MFP_CFG_LPM(GPIO15, AF2, FLOAT)
+
+#define GPIO41_KP_DKIN_0       MFP_CFG_LPM(GPIO41, AF2, FLOAT)
+#define GPIO42_KP_DKIN_1       MFP_CFG_LPM(GPIO42, AF2, FLOAT)
+#define GPIO43_KP_DKIN_2       MFP_CFG_LPM(GPIO43, AF2, FLOAT)
+#define GPIO44_KP_DKIN_3       MFP_CFG_LPM(GPIO44, AF2, FLOAT)
+#define GPIO41_KP_DKIN_4       MFP_CFG_LPM(GPIO41, AF4, FLOAT)
+#define GPIO42_KP_DKIN_5       MFP_CFG_LPM(GPIO42, AF4, FLOAT)
+
+#define GPIO0_KP_MKIN_0                MFP_CFG_LPM(GPIO0, AF1, FLOAT)
+#define GPIO2_KP_MKIN_1                MFP_CFG_LPM(GPIO2, AF1, FLOAT)
+#define GPIO4_KP_MKIN_2                MFP_CFG_LPM(GPIO4, AF1, FLOAT)
+#define GPIO6_KP_MKIN_3                MFP_CFG_LPM(GPIO6, AF1, FLOAT)
+#define GPIO8_KP_MKIN_4                MFP_CFG_LPM(GPIO8, AF1, FLOAT)
+#define GPIO10_KP_MKIN_5       MFP_CFG_LPM(GPIO10, AF1, FLOAT)
+#define GPIO12_KP_MKIN_6       MFP_CFG_LPM(GPIO12, AF1, FLOAT)
+#define GPIO14_KP_MKIN_7       MFP_CFG(GPIO14, AF1)
+#define GPIO35_KP_MKIN_5       MFP_CFG(GPIO35, AF4)
+
+#define GPIO1_KP_MKOUT_0       MFP_CFG_LPM(GPIO1, AF1, DRIVE_HIGH)
+#define GPIO3_KP_MKOUT_1       MFP_CFG_LPM(GPIO3, AF1, DRIVE_HIGH)
+#define GPIO5_KP_MKOUT_2       MFP_CFG_LPM(GPIO5, AF1, DRIVE_HIGH)
+#define GPIO7_KP_MKOUT_3       MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
+#define GPIO9_KP_MKOUT_4       MFP_CFG_LPM(GPIO9, AF1, DRIVE_HIGH)
+#define GPIO11_KP_MKOUT_5      MFP_CFG_LPM(GPIO11, AF1, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_6      MFP_CFG_LPM(GPIO13, AF1, DRIVE_HIGH)
+#define GPIO15_KP_MKOUT_7      MFP_CFG_LPM(GPIO15, AF1, DRIVE_HIGH)
+#define GPIO36_KP_MKOUT_5      MFP_CFG_LPM(GPIO36, AF4, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO17_LCD_FCLK_RD     MFP_CFG(GPIO17, AF1)
+#define GPIO18_LCD_LCLK_A0     MFP_CFG(GPIO18, AF1)
+#define GPIO19_LCD_PCLK_WR     MFP_CFG(GPIO19, AF1)
+#define GPIO20_LCD_BIAS                MFP_CFG(GPIO20, AF1)
+#define GPIO21_LCD_CS          MFP_CFG(GPIO21, AF1)
+#define GPIO22_LCD_CS2         MFP_CFG(GPIO22, AF2)
+#define GPIO22_LCD_VSYNC       MFP_CFG(GPIO22, AF1)
+#define GPIO23_LCD_DD0         MFP_CFG(GPIO23, AF1)
+#define GPIO24_LCD_DD1         MFP_CFG(GPIO24, AF1)
+#define GPIO25_LCD_DD2         MFP_CFG(GPIO25, AF1)
+#define GPIO26_LCD_DD3         MFP_CFG(GPIO26, AF1)
+#define GPIO27_LCD_DD4         MFP_CFG(GPIO27, AF1)
+#define GPIO28_LCD_DD5         MFP_CFG(GPIO28, AF1)
+#define GPIO29_LCD_DD6         MFP_CFG(GPIO29, AF1)
+#define GPIO30_LCD_DD7         MFP_CFG(GPIO30, AF1)
+#define GPIO31_LCD_DD8         MFP_CFG(GPIO31, AF1)
+#define GPIO32_LCD_DD9         MFP_CFG(GPIO32, AF1)
+#define GPIO33_LCD_DD10                MFP_CFG(GPIO33, AF1)
+#define GPIO34_LCD_DD11                MFP_CFG(GPIO34, AF1)
+#define GPIO35_LCD_DD12                MFP_CFG(GPIO35, AF1)
+#define GPIO36_LCD_DD13                MFP_CFG(GPIO36, AF1)
+#define GPIO37_LCD_DD14                MFP_CFG(GPIO37, AF1)
+#define GPIO38_LCD_DD15                MFP_CFG(GPIO38, AF1)
+#define GPIO39_LCD_DD16                MFP_CFG(GPIO39, AF1)
+#define GPIO40_LCD_DD17                MFP_CFG(GPIO40, AF1)
+#define GPIO41_LCD_CS2         MFP_CFG(GPIO41, AF3)
+#define GPIO42_LCD_VSYNC2      MFP_CFG(GPIO42, AF3)
+#define GPIO44_LCD_DD7         MFP_CFG(GPIO44, AF1)
+
+/* Mini-LCD */
+#define GPIO17_MLCD_FCLK       MFP_CFG(GPIO17, AF3)
+#define GPIO18_MLCD_LCLK       MFP_CFG(GPIO18, AF3)
+#define GPIO19_MLCD_PCLK       MFP_CFG(GPIO19, AF3)
+#define GPIO20_MLCD_BIAS       MFP_CFG(GPIO20, AF3)
+#define GPIO23_MLCD_DD0                MFP_CFG(GPIO23, AF3)
+#define GPIO24_MLCD_DD1                MFP_CFG(GPIO24, AF3)
+#define GPIO25_MLCD_DD2                MFP_CFG(GPIO25, AF3)
+#define GPIO26_MLCD_DD3                MFP_CFG(GPIO26, AF3)
+#define GPIO27_MLCD_DD4                MFP_CFG(GPIO27, AF3)
+#define GPIO28_MLCD_DD5                MFP_CFG(GPIO28, AF3)
+#define GPIO29_MLCD_DD6                MFP_CFG(GPIO29, AF3)
+#define GPIO30_MLCD_DD7                MFP_CFG(GPIO30, AF3)
+#define GPIO31_MLCD_DD8                MFP_CFG(GPIO31, AF3)
+#define GPIO32_MLCD_DD9                MFP_CFG(GPIO32, AF3)
+#define GPIO33_MLCD_DD10       MFP_CFG(GPIO33, AF3)
+#define GPIO34_MLCD_DD11       MFP_CFG(GPIO34, AF3)
+#define GPIO35_MLCD_DD12       MFP_CFG(GPIO35, AF3)
+#define GPIO36_MLCD_DD13       MFP_CFG(GPIO36, AF3)
+#define GPIO37_MLCD_DD14       MFP_CFG(GPIO37, AF3)
+#define GPIO38_MLCD_DD15       MFP_CFG(GPIO38, AF3)
+#define GPIO44_MLCD_DD7                MFP_CFG(GPIO44, AF5)
+
+/* MMC1 */
+#define GPIO10_MMC1_DAT3       MFP_CFG(GPIO10, AF4)
+#define GPIO11_MMC1_DAT2       MFP_CFG(GPIO11, AF4)
+#define GPIO12_MMC1_DAT1       MFP_CFG(GPIO12, AF4)
+#define GPIO13_MMC1_DAT0       MFP_CFG(GPIO13, AF4)
+#define GPIO14_MMC1_CMD                MFP_CFG(GPIO14, AF4)
+#define GPIO15_MMC1_CLK                MFP_CFG(GPIO15, AF4)
+#define GPIO55_MMC1_CMD                MFP_CFG(GPIO55, AF3)
+#define GPIO56_MMC1_CLK                MFP_CFG(GPIO56, AF3)
+#define GPIO57_MMC1_DAT0       MFP_CFG(GPIO57, AF3)
+#define GPIO58_MMC1_DAT1       MFP_CFG(GPIO58, AF3)
+#define GPIO59_MMC1_DAT2       MFP_CFG(GPIO59, AF3)
+#define GPIO60_MMC1_DAT3       MFP_CFG(GPIO60, AF3)
+
+#define DF_ADDR0_MMC1_CLK      MFP_CFG(DF_ADDR0, AF2)
+#define DF_ADDR1_MMC1_CMD      MFP_CFG(DF_ADDR1, AF2)
+#define DF_ADDR2_MMC1_DAT0     MFP_CFG(DF_ADDR2, AF2)
+#define DF_ADDR3_MMC1_DAT1     MFP_CFG(DF_ADDR3, AF3)
+#define nXCVREN_MMC1_DAT2      MFP_CFG(nXCVREN, AF2)
+
+/* MMC2 */
+#define GPIO31_MMC2_CMD                MFP_CFG(GPIO31, AF7)
+#define GPIO32_MMC2_CLK                MFP_CFG(GPIO32, AF7)
+#define GPIO33_MMC2_DAT0       MFP_CFG(GPIO33, AF7)
+#define GPIO34_MMC2_DAT1       MFP_CFG(GPIO34, AF7)
+#define GPIO35_MMC2_DAT2       MFP_CFG(GPIO35, AF7)
+#define GPIO36_MMC2_DAT3       MFP_CFG(GPIO36, AF7)
+
+#define GPIO101_MMC2_DAT3      MFP_CFG(GPIO101, AF1)
+#define GPIO102_MMC2_DAT2      MFP_CFG(GPIO102, AF1)
+#define GPIO103_MMC2_DAT1      MFP_CFG(GPIO103, AF1)
+#define GPIO104_MMC2_DAT0      MFP_CFG(GPIO104, AF1)
+#define GPIO105_MMC2_CMD       MFP_CFG(GPIO105, AF1)
+#define GPIO106_MMC2_CLK       MFP_CFG(GPIO106, AF1)
+
+#define DF_IO10_MMC2_DAT3      MFP_CFG(DF_IO10, AF3)
+#define DF_IO11_MMC2_DAT2      MFP_CFG(DF_IO11, AF3)
+#define DF_IO12_MMC2_DAT1      MFP_CFG(DF_IO12, AF3)
+#define DF_IO13_MMC2_DAT0      MFP_CFG(DF_IO13, AF3)
+#define DF_IO14_MMC2_CLK       MFP_CFG(DF_IO14, AF3)
+#define DF_IO15_MMC2_CMD       MFP_CFG(DF_IO15, AF3)
+
+/* BSSP1 */
+#define GPIO12_BSSP1_CLK       MFP_CFG(GPIO12, AF3)
+#define GPIO13_BSSP1_FRM       MFP_CFG(GPIO13, AF3)
+#define GPIO14_BSSP1_RXD       MFP_CFG(GPIO14, AF3)
+#define GPIO15_BSSP1_TXD       MFP_CFG(GPIO15, AF3)
+#define GPIO97_BSSP1_CLK       MFP_CFG(GPIO97, AF5)
+#define GPIO98_BSSP1_FRM       MFP_CFG(GPIO98, AF5)
+
+/* BSSP2 */
+#define GPIO84_BSSP2_SDATA_IN  MFP_CFG(GPIO84, AF1)
+#define GPIO85_BSSP2_BITCLK    MFP_CFG(GPIO85, AF1)
+#define GPIO86_BSSP2_SYSCLK    MFP_CFG(GPIO86, AF1)
+#define GPIO87_BSSP2_SYNC      MFP_CFG(GPIO87, AF1)
+#define GPIO88_BSSP2_DATA_OUT  MFP_CFG(GPIO88, AF1)
+#define GPIO86_BSSP2_SDATA_IN  MFP_CFG(GPIO86, AF4)
+
+/* BSSP3 */
+#define GPIO79_BSSP3_CLK       MFP_CFG(GPIO79, AF1)
+#define GPIO80_BSSP3_FRM       MFP_CFG(GPIO80, AF1)
+#define GPIO81_BSSP3_TXD       MFP_CFG(GPIO81, AF1)
+#define GPIO82_BSSP3_RXD       MFP_CFG(GPIO82, AF1)
+#define GPIO83_BSSP3_SYSCLK    MFP_CFG(GPIO83, AF1)
+
+/* BSSP4 */
+#define GPIO43_BSSP4_CLK       MFP_CFG(GPIO43, AF4)
+#define GPIO44_BSSP4_FRM       MFP_CFG(GPIO44, AF4)
+#define GPIO45_BSSP4_TXD       MFP_CFG(GPIO45, AF4)
+#define GPIO46_BSSP4_RXD       MFP_CFG(GPIO46, AF4)
+
+#define GPIO51_BSSP4_CLK       MFP_CFG(GPIO51, AF4)
+#define GPIO52_BSSP4_FRM       MFP_CFG(GPIO52, AF4)
+#define GPIO53_BSSP4_TXD       MFP_CFG(GPIO53, AF4)
+#define GPIO54_BSSP4_RXD       MFP_CFG(GPIO54, AF4)
+
+/* GSSP1 */
+#define GPIO79_GSSP1_CLK       MFP_CFG(GPIO79, AF2)
+#define GPIO80_GSSP1_FRM       MFP_CFG(GPIO80, AF2)
+#define GPIO81_GSSP1_TXD       MFP_CFG(GPIO81, AF2)
+#define GPIO82_GSSP1_RXD       MFP_CFG(GPIO82, AF2)
+#define GPIO83_GSSP1_SYSCLK    MFP_CFG(GPIO83, AF2)
+
+#define GPIO93_GSSP1_CLK       MFP_CFG(GPIO93, AF4)
+#define GPIO94_GSSP1_FRM       MFP_CFG(GPIO94, AF4)
+#define GPIO95_GSSP1_TXD       MFP_CFG(GPIO95, AF4)
+#define GPIO96_GSSP1_RXD       MFP_CFG(GPIO96, AF4)
+
+/* GSSP2 */
+#define GPIO47_GSSP2_CLK       MFP_CFG(GPIO47, AF4)
+#define GPIO48_GSSP2_FRM       MFP_CFG(GPIO48, AF4)
+#define GPIO49_GSSP2_RXD       MFP_CFG(GPIO49, AF4)
+#define GPIO50_GSSP2_TXD       MFP_CFG(GPIO50, AF4)
+
+#define GPIO69_GSSP2_CLK       MFP_CFG(GPIO69, AF4)
+#define GPIO70_GSSP2_FRM       MFP_CFG(GPIO70, AF4)
+#define GPIO71_GSSP2_RXD       MFP_CFG(GPIO71, AF4)
+#define GPIO72_GSSP2_TXD       MFP_CFG(GPIO72, AF4)
+
+#define GPIO84_GSSP2_RXD       MFP_CFG(GPIO84, AF2)
+#define GPIO85_GSSP2_CLK       MFP_CFG(GPIO85, AF2)
+#define GPIO86_GSSP2_SYSCLK    MFP_CFG(GPIO86, AF2)
+#define GPIO87_GSSP2_FRM       MFP_CFG(GPIO87, AF2)
+#define GPIO88_GSSP2_TXD       MFP_CFG(GPIO88, AF2)
+#define GPIO86_GSSP2_RXD       MFP_CFG(GPIO86, AF5)
+
+#define GPIO103_GSSP2_CLK      MFP_CFG(GPIO103, AF2)
+#define GPIO104_GSSP2_FRM      MFP_CFG(GPIO104, AF2)
+#define GPIO105_GSSP2_RXD      MFP_CFG(GPIO105, AF2)
+#define GPIO106_GSSP2_TXD      MFP_CFG(GPIO106, AF2)
+
+/* UART1 - FFUART */
+#define GPIO47_UART1_DSR_N     MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART1_DTR_N     MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART1_RI                MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART1_DCD       MFP_CFG(GPIO50, AF1)
+#define GPIO51_UART1_CTS       MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART1_RTS       MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART1_RXD       MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART1_TXD       MFP_CFG(GPIO54, AF1)
+
+#define GPIO63_UART1_TXD       MFP_CFG(GPIO63, AF2)
+#define GPIO64_UART1_RXD       MFP_CFG(GPIO64, AF2)
+#define GPIO65_UART1_DSR       MFP_CFG(GPIO65, AF2)
+#define GPIO66_UART1_DTR       MFP_CFG(GPIO66, AF2)
+#define GPIO67_UART1_RI                MFP_CFG(GPIO67, AF2)
+#define GPIO68_UART1_DCD       MFP_CFG(GPIO68, AF2)
+#define GPIO69_UART1_CTS       MFP_CFG(GPIO69, AF2)
+#define GPIO70_UART1_RTS       MFP_CFG(GPIO70, AF2)
+
+#define GPIO53_UART1_TXD       MFP_CFG(GPIO53, AF2)
+#define GPIO54_UART1_RXD       MFP_CFG(GPIO54, AF2)
+
+/* UART2 - BTUART */
+#define GPIO91_UART2_RXD       MFP_CFG(GPIO91, AF1)
+#define GPIO92_UART2_TXD       MFP_CFG(GPIO92, AF1)
+#define GPIO93_UART2_CTS       MFP_CFG(GPIO93, AF1)
+#define GPIO94_UART2_RTS       MFP_CFG(GPIO94, AF1)
+
+/* UART3 - STUART */
+#define GPIO43_UART3_RTS       MFP_CFG(GPIO43, AF3)
+#define GPIO44_UART3_CTS       MFP_CFG(GPIO44, AF3)
+#define GPIO45_UART3_RXD       MFP_CFG(GPIO45, AF3)
+#define GPIO46_UART3_TXD       MFP_CFG(GPIO46, AF3)
+
+#define GPIO75_UART3_RTS       MFP_CFG(GPIO75, AF5)
+#define GPIO76_UART3_CTS       MFP_CFG(GPIO76, AF5)
+#define GPIO77_UART3_TXD       MFP_CFG(GPIO77, AF5)
+#define GPIO78_UART3_RXD       MFP_CFG(GPIO78, AF5)
+
+/* DFI */
+#define DF_IO0_DF_IO0          MFP_CFG(DF_IO0, AF2)
+#define DF_IO1_DF_IO1          MFP_CFG(DF_IO1, AF2)
+#define DF_IO2_DF_IO2          MFP_CFG(DF_IO2, AF2)
+#define DF_IO3_DF_IO3          MFP_CFG(DF_IO3, AF2)
+#define DF_IO4_DF_IO4          MFP_CFG(DF_IO4, AF2)
+#define DF_IO5_DF_IO5          MFP_CFG(DF_IO5, AF2)
+#define DF_IO6_DF_IO6          MFP_CFG(DF_IO6, AF2)
+#define DF_IO7_DF_IO7          MFP_CFG(DF_IO7, AF2)
+#define DF_IO8_DF_IO8          MFP_CFG(DF_IO8, AF2)
+#define DF_IO9_DF_IO9          MFP_CFG(DF_IO9, AF2)
+#define DF_IO10_DF_IO10                MFP_CFG(DF_IO10, AF2)
+#define DF_IO11_DF_IO11                MFP_CFG(DF_IO11, AF2)
+#define DF_IO12_DF_IO12                MFP_CFG(DF_IO12, AF2)
+#define DF_IO13_DF_IO13                MFP_CFG(DF_IO13, AF2)
+#define DF_IO14_DF_IO14                MFP_CFG(DF_IO14, AF2)
+#define DF_IO15_DF_IO15                MFP_CFG(DF_IO15, AF2)
+#define DF_nADV1_ALE_DF_nADV1  MFP_CFG(DF_nADV1_ALE, AF2)
+#define DF_nADV2_ALE_DF_nADV2  MFP_CFG(DF_nADV2_ALE, AF2)
+#define DF_nCS0_DF_nCS0                MFP_CFG(DF_nCS0, AF2)
+#define DF_nCS1_DF_nCS1                MFP_CFG(DF_nCS1, AF2)
+#define DF_nRE_nOE_DF_nOE      MFP_CFG(DF_nRE_nOE, AF2)
+#define DF_nWE_DF_nWE          MFP_CFG(DF_nWE, AF2)
+
+/* DFI - NAND */
+#define DF_CLE_nOE_ND_CLE      MFP_CFG_LPM(DF_CLE_nOE, AF1, PULL_HIGH)
+#define DF_INT_RnB_ND_INT_RnB  MFP_CFG_LPM(DF_INT_RnB, AF1, PULL_LOW)
+#define DF_IO0_ND_IO0          MFP_CFG_LPM(DF_IO0, AF1, PULL_LOW)
+#define DF_IO1_ND_IO1          MFP_CFG_LPM(DF_IO1, AF1, PULL_LOW)
+#define DF_IO2_ND_IO2          MFP_CFG_LPM(DF_IO2, AF1, PULL_LOW)
+#define DF_IO3_ND_IO3          MFP_CFG_LPM(DF_IO3, AF1, PULL_LOW)
+#define DF_IO4_ND_IO4          MFP_CFG_LPM(DF_IO4, AF1, PULL_LOW)
+#define DF_IO5_ND_IO5          MFP_CFG_LPM(DF_IO5, AF1, PULL_LOW)
+#define DF_IO6_ND_IO6          MFP_CFG_LPM(DF_IO6, AF1, PULL_LOW)
+#define DF_IO7_ND_IO7          MFP_CFG_LPM(DF_IO7, AF1, PULL_LOW)
+#define DF_IO8_ND_IO8          MFP_CFG_LPM(DF_IO8, AF1, PULL_LOW)
+#define DF_IO9_ND_IO9          MFP_CFG_LPM(DF_IO9, AF1, PULL_LOW)
+#define DF_IO10_ND_IO10                MFP_CFG_LPM(DF_IO10, AF1, PULL_LOW)
+#define DF_IO11_ND_IO11                MFP_CFG_LPM(DF_IO11, AF1, PULL_LOW)
+#define DF_IO12_ND_IO12                MFP_CFG_LPM(DF_IO12, AF1, PULL_LOW)
+#define DF_IO13_ND_IO13                MFP_CFG_LPM(DF_IO13, AF1, PULL_LOW)
+#define DF_IO14_ND_IO14                MFP_CFG_LPM(DF_IO14, AF1, PULL_LOW)
+#define DF_IO15_ND_IO15                MFP_CFG_LPM(DF_IO15, AF1, PULL_LOW)
+#define DF_nADV1_ALE_ND_ALE    MFP_CFG_LPM(DF_nADV1_ALE, AF1, PULL_HIGH)
+#define DF_nADV2_ALE_ND_ALE    MFP_CFG_LPM(DF_nADV2_ALE, AF1, PULL_HIGH)
+#define        DF_nADV2_ALE_nCS3       MFP_CFG_LPM(DF_nADV2_ALE, AF3, PULL_HIGH)
+#define DF_nCS0_ND_nCS0                MFP_CFG_LPM(DF_nCS0, AF1, PULL_HIGH)
+#define DF_nCS1_ND_nCS1                MFP_CFG_LPM(DF_nCS1, AF1, PULL_HIGH)
+#define DF_nRE_nOE_ND_nRE      MFP_CFG_LPM(DF_nRE_nOE, AF1, PULL_HIGH)
+#define DF_nWE_ND_nWE          MFP_CFG_LPM(DF_nWE, AF1, PULL_HIGH)
+
+/* PWM */
+#define GPIO41_PWM0            MFP_CFG_LPM(GPIO41, AF1, PULL_LOW)
+#define GPIO42_PWM1            MFP_CFG_LPM(GPIO42, AF1, PULL_LOW)
+#define GPIO43_PWM3            MFP_CFG_LPM(GPIO43, AF1, PULL_LOW)
+#define GPIO20_PWM0            MFP_CFG_LPM(GPIO20, AF2, PULL_LOW)
+#define GPIO21_PWM2            MFP_CFG_LPM(GPIO21, AF3, PULL_LOW)
+#define GPIO22_PWM3            MFP_CFG_LPM(GPIO22, AF3, PULL_LOW)
+#define GPIO32_PWM0            MFP_CFG_LPM(GPIO32, AF4, PULL_LOW)
+
+/* CIR */
+#define GPIO46_CIR_OUT         MFP_CFG(GPIO46, AF1)
+#define GPIO77_CIR_OUT         MFP_CFG(GPIO77, AF3)
+
+/* USB P2 */
+#define GPIO0_USB_P2_7         MFP_CFG(GPIO0, AF3)
+#define GPIO15_USB_P2_7                MFP_CFG(GPIO15, AF5)
+#define GPIO16_USB_P2_7                MFP_CFG(GPIO16, AF2)
+#define GPIO48_USB_P2_7                MFP_CFG(GPIO48, AF7)
+#define GPIO49_USB_P2_7                MFP_CFG(GPIO49, AF6)
+#define DF_IO9_USB_P2_7                MFP_CFG(DF_IO9, AF3)
+
+#define GPIO48_USB_P2_8                MFP_CFG(GPIO48, AF2)
+#define GPIO50_USB_P2_7                MFP_CFG_X(GPIO50, AF2, DS02X, FLOAT)
+#define GPIO51_USB_P2_5                MFP_CFG(GPIO51, AF2)
+#define GPIO47_USB_P2_4                MFP_CFG(GPIO47, AF2)
+#define GPIO53_USB_P2_3                MFP_CFG(GPIO53, AF2)
+#define GPIO54_USB_P2_6                MFP_CFG(GPIO54, AF2)
+#define GPIO49_USB_P2_2                MFP_CFG(GPIO49, AF2)
+#define GPIO52_USB_P2_1                MFP_CFG(GPIO52, AF2)
+
+#define GPIO63_USB_P2_8                MFP_CFG(GPIO63, AF3)
+#define GPIO64_USB_P2_7                MFP_CFG(GPIO64, AF3)
+#define GPIO65_USB_P2_6                MFP_CFG(GPIO65, AF3)
+#define GPIO66_USG_P2_5                MFP_CFG(GPIO66, AF3)
+#define GPIO67_USB_P2_4                MFP_CFG(GPIO67, AF3)
+#define GPIO68_USB_P2_3                MFP_CFG(GPIO68, AF3)
+#define GPIO69_USB_P2_2                MFP_CFG(GPIO69, AF3)
+#define GPIO70_USB_P2_1                MFP_CFG(GPIO70, AF3)
+
+/* ULPI */
+#define GPIO31_USB_ULPI_D0     MFP_CFG(GPIO31, AF4)
+#define GPIO30_USB_ULPI_D1     MFP_CFG(GPIO30, AF7)
+#define GPIO33_USB_ULPI_D2     MFP_CFG(GPIO33, AF5)
+#define GPIO34_USB_ULPI_D3     MFP_CFG(GPIO34, AF5)
+#define GPIO35_USB_ULPI_D4     MFP_CFG(GPIO35, AF5)
+#define GPIO36_USB_ULPI_D5     MFP_CFG(GPIO36, AF5)
+#define GPIO41_USB_ULPI_D6     MFP_CFG(GPIO41, AF5)
+#define GPIO42_USB_ULPI_D7     MFP_CFG(GPIO42, AF5)
+#define GPIO37_USB_ULPI_DIR    MFP_CFG(GPIO37, AF4)
+#define GPIO38_USB_ULPI_CLK    MFP_CFG(GPIO38, AF4)
+#define GPIO39_USB_ULPI_STP    MFP_CFG(GPIO39, AF4)
+#define GPIO40_USB_ULPI_NXT    MFP_CFG(GPIO40, AF4)
+
+#define GPIO3_CLK26MOUTDMD     MFP_CFG(GPIO3, AF3)
+#define GPIO40_CLK26MOUTDMD    MFP_CFG(GPIO40, AF7)
+#define GPIO94_CLK26MOUTDMD    MFP_CFG(GPIO94, AF5)
+#define GPIO104_CLK26MOUTDMD   MFP_CFG(GPIO104, AF4)
+#define DF_ADDR1_CLK26MOUTDMD  MFP_CFG(DF_ADDR2, AF3)
+#define DF_ADDR3_CLK26MOUTDMD  MFP_CFG(DF_ADDR3, AF3)
+
+#define GPIO14_CLK26MOUT       MFP_CFG(GPIO14, AF5)
+#define GPIO38_CLK26MOUT       MFP_CFG(GPIO38, AF7)
+#define GPIO92_CLK26MOUT       MFP_CFG(GPIO92, AF5)
+#define GPIO105_CLK26MOUT      MFP_CFG(GPIO105, AF4)
+
+#define GPIO2_CLK13MOUTDMD     MFP_CFG(GPIO2, AF3)
+#define GPIO39_CLK13MOUTDMD    MFP_CFG(GPIO39, AF7)
+#define GPIO50_CLK13MOUTDMD    MFP_CFG(GPIO50, AF3)
+#define GPIO93_CLK13MOUTDMD    MFP_CFG(GPIO93, AF5)
+#define GPIO103_CLK13MOUTDMD   MFP_CFG(GPIO103, AF4)
+#define DF_ADDR2_CLK13MOUTDMD  MFP_CFG(DF_ADDR2, AF3)
+
+/* 1 wire */
+#define GPIO95_OW_DQ_IN                MFP_CFG(GPIO95, AF5)
+
+#endif /* __ASM_ARCH_MFP_PXA9xx_H */
index ccfd2b6..38a96a1 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa27x.h>
-#include <mach/regs-rtc.h>
+#include "pxa27x.h"
+#include "regs-rtc.h"
 #include <linux/platform_data/keypad-pxa27x.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/pxa27x-udc.h>
+#include "udc.h"
+#include "pxa27x-udc.h"
 #include <linux/platform_data/media/camera-pxa.h>
 #include <mach/audio.h>
 #include <mach/smemc.h>
 #include <media/soc_camera.h>
 
-#include <mach/mioa701.h>
+#include "mioa701.h"
 
 #include "generic.h"
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/mioa701.h b/arch/arm/mach-pxa/mioa701.h
new file mode 100644 (file)
index 0000000..e57f5c7
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef _MIOA701_H_
+#define _MIOA701_H_
+
+#define MIO_CFG_IN(pin, af)            \
+       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
+        (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN))
+
+#define MIO_CFG_OUT(pin, af, state)    \
+       ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
+        (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
+
+/* Global GPIOs */
+#define GPIO9_CHARGE_EN                                9
+#define GPIO18_POWEROFF                                18
+#define GPIO87_LCD_POWER                       87
+#define GPIO96_AC_DETECT                       96
+#define GPIO80_MAYBE_CHARGE_VDROP              80      /* Drop of 88mV */
+
+/* USB */
+#define GPIO13_nUSB_DETECT                     13
+#define GPIO22_USB_ENABLE                      22
+
+/* SDIO bits */
+#define GPIO78_SDIO_RO                         78
+#define GPIO15_SDIO_INSERT                     15
+#define GPIO91_SDIO_EN                         91
+
+/* Bluetooth */
+#define GPIO14_BT_nACTIVITY                    14
+#define GPIO83_BT_ON                           83
+#define GPIO77_BT_UNKNOWN1                     77
+#define GPIO86_BT_MAYBE_nRESET                 86
+
+/* GPS */
+#define GPIO23_GPS_UNKNOWN1                    23
+#define GPIO26_GPS_ON                          26
+#define GPIO27_GPS_RESET                       27
+#define GPIO106_GPS_UNKNOWN2                   106
+#define GPIO107_GPS_UNKNOWN3                   107
+
+/* GSM */
+#define GPIO24_GSM_MOD_RESET_CMD               24
+#define GPIO88_GSM_nMOD_ON_CMD                 88
+#define GPIO90_GSM_nMOD_OFF_CMD                        90
+#define GPIO114_GSM_nMOD_DTE_UART_STATE        114
+#define GPIO25_GSM_MOD_ON_STATE                        25
+#define GPIO113_GSM_EVENT                      113
+
+/* SOUND */
+#define GPIO12_HPJACK_INSERT                   12
+
+/* LEDS */
+#define GPIO10_LED_nCharging                   10
+#define GPIO97_LED_nBlue                       97
+#define GPIO98_LED_nOrange                     98
+#define GPIO82_LED_nVibra                      82
+#define GPIO115_LED_nKeyboard                  115
+
+/* Keyboard */
+#define GPIO0_KEY_POWER                                0
+#define GPIO93_KEY_VOLUME_UP                   93
+#define GPIO94_KEY_VOLUME_DOWN                 94
+
+/* Camera */
+#define GPIO56_MT9M111_nOE                     56
+
+extern struct input_dev *mioa701_evdev;
+extern void mioa701_gpio_lpm_set(unsigned long mfp_pin);
+
+/* Assembler externals mioa701_bootresume.S */
+extern u32 mioa701_bootstrap;
+extern u32 mioa701_jumpaddr;
+extern u32 mioa701_bootstrap_lg;
+
+#endif /* _MIOA701_H */
index 14f6aaf..4d89029 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include "generic.h"
 
 static void isp116x_pfm_delay(struct device *dev, int delay)
index d04ed49..9a22ae0 100644 (file)
@@ -29,9 +29,9 @@
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pxa320.h>
+#include "pxa320.h"
 
-#include <mach/mxm8x10.h>
+#include "mxm8x10.h"
 
 #include "devices.h"
 #include "generic.h"
diff --git a/arch/arm/mach-pxa/mxm8x10.h b/arch/arm/mach-pxa/mxm8x10.h
new file mode 100644 (file)
index 0000000..ffa1566
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __MACH_MXM_8X10_H
+#define __MACH_MXM_8X10_H
+
+#define MXM_8X10_ETH_PHYS      0x13000000
+
+#if defined(CONFIG_MMC)
+
+#define MXM_8X10_SD_nCD (72)
+#define MXM_8X10_SD_WP (84)
+
+extern void mxm_8x10_mmc_init(void);
+#else
+static inline void mxm_8x10_mmc_init(void) {}
+#endif
+
+extern void mxm_8x10_usb_host_init(void);
+extern void mxm_8x10_ac97_init(void);
+
+extern void mxm_8x10_barebones_init(void);
+
+#endif /* __MACH_MXM_8X10_H */
index 8fbfb10..e5ae99d 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
 
 #include "generic.h"
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/palm27x.h b/arch/arm/mach-pxa/palm27x.h
new file mode 100644 (file)
index 0000000..d4eac3d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Common functions for Palm LD, T5, TX, Z72
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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        __INCLUDE_MACH_PALM27X__
+#define        __INCLUDE_MACH_PALM27X__
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+extern void __init palm27x_mmc_init(int detect, int ro, int power,
+                                       int power_inverted);
+#else
+static inline void palm27x_mmc_init(int detect, int ro, int power,
+                                       int power_inverted)
+{}
+#endif
+
+#if defined(CONFIG_SUSPEND)
+extern void __init palm27x_pm_init(unsigned long str_base);
+#else
+static inline void palm27x_pm_init(unsigned long str_base) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+extern struct pxafb_mode_info palm_320x480_lcd_mode;
+extern struct pxafb_mode_info palm_320x320_lcd_mode;
+extern struct pxafb_mode_info palm_320x320_new_lcd_mode;
+extern void __init palm27x_lcd_init(int power,
+                                       struct pxafb_mode_info *mode);
+#else
+#define palm27x_lcd_init(power, mode)  do {} while (0)
+#endif
+
+#if    defined(CONFIG_USB_PXA27X) || \
+       defined(CONFIG_USB_PXA27X_MODULE)
+extern void __init palm27x_udc_init(int vbus, int pullup,
+                                       int vbus_inverted);
+#else
+static inline void palm27x_udc_init(int vbus, int pullup, int vbus_inverted) {}
+#endif
+
+#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
+extern void __init palm27x_irda_init(int pwdn);
+#else
+static inline void palm27x_irda_init(int pwdn) {}
+#endif
+
+#if    defined(CONFIG_TOUCHSCREEN_WM97XX) || \
+       defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE)
+extern void __init palm27x_ac97_init(int minv, int maxv, int jack,
+                                       int reset);
+#else
+static inline void palm27x_ac97_init(int minv, int maxv, int jack, int reset) {}
+#endif
+
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+extern void __init palm27x_pwm_init(int bl, int lcd);
+#else
+static inline void palm27x_pwm_init(int bl, int lcd) {}
+#endif
+
+#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE)
+extern void __init palm27x_power_init(int ac, int usb);
+#else
+static inline void palm27x_power_init(int ac, int usb) {}
+#endif
+
+#if defined(CONFIG_REGULATOR_MAX1586) || \
+    defined(CONFIG_REGULATOR_MAX1586_MODULE)
+extern void __init palm27x_pmic_init(void);
+#else
+static inline void palm27x_pmic_init(void) {}
+#endif
+
+#endif /* __INCLUDE_MACH_PALM27X__ */
index cf210b1..980f284 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
 #include <mach/palmld.h>
 #include <linux/platform_data/mmc-pxamci.h>
@@ -40,7 +40,7 @@
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/keypad-pxa27x.h>
 #include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
 
 #include "generic.h"
 #include "devices.h"
index 3ed9b02..876144a 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
-#include <mach/palmt5.h>
+#include "palmt5.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
 
 #include "generic.h"
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/palmt5.h b/arch/arm/mach-pxa/palmt5.h
new file mode 100644 (file)
index 0000000..f850cc9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer
+ *
+ * Authors:    Ales Snuparek <snuparek@atlas.cz>
+ *             Marek Vasut <marek.vasut@gmail.com>
+ *             Justin Kendrick <twilightsentry@gmail.com>
+ *             RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_PALMT5_H_
+#define _INCLUDE_PALMT5_H_
+
+#include <mach/irqs.h> /* PXA_GPIO_TO_IRQ */
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMT5_GPIO_RESET              1
+
+#define GPIO_NR_PALMT5_POWER_DETECT            90
+#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N                10
+#define GPIO_NR_PALMT5_EARPHONE_DETECT         107
+
+/* SD/MMC */
+#define GPIO_NR_PALMT5_SD_DETECT_N             14
+#define GPIO_NR_PALMT5_SD_POWER                        114
+#define GPIO_NR_PALMT5_SD_READONLY             115
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMT5_WM9712_IRQ              27
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMT5_IR_DISABLE              40
+
+/* USB */
+#define GPIO_NR_PALMT5_USB_DETECT_N            15
+#define GPIO_NR_PALMT5_USB_PULLUP              93
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMT5_BL_POWER                        84
+#define GPIO_NR_PALMT5_LCD_POWER               96
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMT5_BT_POWER                        17
+#define GPIO_NR_PALMT5_BT_RESET                        83
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMT5_SD_DETECT_N    PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N)
+#define IRQ_GPIO_PALMT5_WM9712_IRQ     PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ)
+#define IRQ_GPIO_PALMT5_USB_DETECT     PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT)
+#define IRQ_GPIO_PALMT5_GPIO_RESET     PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses  */
+#define PALMT5_PHYS_RAM_START  0xa0000000
+#define PALMT5_PHYS_IO_START   0x40000000
+#define PALMT5_STR_BASE                0xa0200000
+
+/* TOUCHSCREEN */
+#define AC97_LINK_FRAME                21
+
+/* BATTERY */
+#define PALMT5_BAT_MAX_VOLTAGE         4000    /* 4.00v current voltage */
+#define PALMT5_BAT_MIN_VOLTAGE         3550    /* 3.55v critical voltage */
+#define PALMT5_BAT_MAX_CURRENT         0       /* unknown */
+#define PALMT5_BAT_MIN_CURRENT         0       /* unknown */
+#define PALMT5_BAT_MAX_CHARGE          1       /* unknown */
+#define PALMT5_BAT_MIN_CHARGE          1       /* unknown */
+#define PALMT5_MAX_LIFE_MINS           360    /* on-life in minutes */
+
+#define PALMT5_BAT_MEASURE_DELAY       (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMT5_MAX_INTENSITY           0xFE
+#define PALMT5_DEFAULT_INTENSITY       0x7E
+#define PALMT5_LIMIT_MASK              0x7F
+#define PALMT5_PRESCALER               0x3F
+#define PALMT5_PERIOD_NS               3500
+
+#endif
index 0b5c387..1894659 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/audio.h>
 #include <mach/palmtc.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
-#include <mach/udc.h>
+#include "udc.h"
 
 #include "generic.h"
 #include "devices.h"
index e64bb43..36b4614 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/audio.h>
-#include <mach/palmte2.h>
+#include "palmte2.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/asoc-palm27x.h>
 
 #include "generic.h"
diff --git a/arch/arm/mach-pxa/palmte2.h b/arch/arm/mach-pxa/palmte2.h
new file mode 100644 (file)
index 0000000..f89e989
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer
+ *
+ * Author:
+ *             Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.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 _INCLUDE_PALMTE2_H_
+#define _INCLUDE_PALMTE2_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTE2_POWER_DETECT           9
+#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N       4
+#define GPIO_NR_PALMTE2_EARPHONE_DETECT                15
+
+/* SD/MMC */
+#define GPIO_NR_PALMTE2_SD_DETECT_N            10
+#define GPIO_NR_PALMTE2_SD_POWER               55
+#define GPIO_NR_PALMTE2_SD_READONLY            51
+
+/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMTE2_IR_DISABLE             48
+
+/* USB */
+#define GPIO_NR_PALMTE2_USB_DETECT_N           35
+#define GPIO_NR_PALMTE2_USB_PULLUP             53
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTE2_BL_POWER               56
+#define GPIO_NR_PALMTE2_LCD_POWER              37
+
+/* KEYS */
+#define GPIO_NR_PALMTE2_KEY_NOTES      5
+#define GPIO_NR_PALMTE2_KEY_TASKS      7
+#define GPIO_NR_PALMTE2_KEY_CALENDAR   11
+#define GPIO_NR_PALMTE2_KEY_CONTACTS   13
+#define GPIO_NR_PALMTE2_KEY_CENTER     14
+#define GPIO_NR_PALMTE2_KEY_LEFT       19
+#define GPIO_NR_PALMTE2_KEY_RIGHT      20
+#define GPIO_NR_PALMTE2_KEY_DOWN       21
+#define GPIO_NR_PALMTE2_KEY_UP         22
+
+/** HERE ARE INIT VALUES **/
+
+/* BACKLIGHT */
+#define PALMTE2_MAX_INTENSITY          0xFE
+#define PALMTE2_DEFAULT_INTENSITY      0x7E
+#define PALMTE2_LIMIT_MASK             0x7F
+#define PALMTE2_PRESCALER              0x3F
+#define PALMTE2_PERIOD_NS              3500
+
+/* BATTERY */
+#define PALMTE2_BAT_MAX_VOLTAGE                4000    /* 4.00v current voltage */
+#define PALMTE2_BAT_MIN_VOLTAGE                3550    /* 3.55v critical voltage */
+#define PALMTE2_BAT_MAX_CURRENT                0       /* unknown */
+#define PALMTE2_BAT_MIN_CURRENT                0       /* unknown */
+#define PALMTE2_BAT_MAX_CHARGE         1       /* unknown */
+#define PALMTE2_BAT_MIN_CHARGE         1       /* unknown */
+#define PALMTE2_MAX_LIFE_MINS          360     /* on-life in minutes */
+
+#endif
index 2dc5606..4cc05ec 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "pxa27x-udc.h"
 #include <mach/audio.h>
-#include <mach/palmtreo.h>
+#include "palmtreo.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <mach/pxa2xx-regs.h>
 #include <linux/platform_data/asoc-palm27x.h>
 #include <linux/platform_data/media/camera-pxa.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
 
 #include <sound/pxa2xx-lib.h>
 
diff --git a/arch/arm/mach-pxa/palmtreo.h b/arch/arm/mach-pxa/palmtreo.h
new file mode 100644 (file)
index 0000000..714b657
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * GPIOs and interrupts for Palm Treo smartphones
+ *
+ * currently supported:
+ *     Palm Treo 680 (GSM)
+ *     Palm Centro 685 (GSM)
+ *
+ * Author:     Tomas Cech <sleep_walker@suse.cz>
+ *
+ * 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.
+ *
+ * find more info at www.hackndev.com
+ *
+ */
+
+#ifndef _INCLUDE_TREO_H_
+#define _INCLUDE_TREO_H_
+
+/* GPIOs */
+#define GPIO_NR_TREO_POWER_DETECT      0
+#define GPIO_NR_TREO_AMP_EN            27
+#define GPIO_NR_TREO_GREEN_LED 20
+#define GPIO_NR_TREO_RED_LED           79
+#define GPIO_NR_TREO_SD_DETECT_N       113
+#define GPIO_NR_TREO_EP_DETECT_N       116
+#define GPIO_NR_TREO_USB_DETECT        1
+#define GPIO_NR_TREO_USB_PULLUP        114
+#define GPIO_NR_TREO_GSM_POWER 40
+#define GPIO_NR_TREO_GSM_RESET 87
+#define GPIO_NR_TREO_GSM_WAKE  57
+#define GPIO_NR_TREO_GSM_HOST_WAKE     14
+#define GPIO_NR_TREO_GSM_TRIGGER       10
+#define GPIO_NR_TREO_IR_EN             115
+#define GPIO_NR_TREO_IR_TXD            47
+#define GPIO_NR_TREO_BL_POWER  38
+#define GPIO_NR_TREO_LCD_POWER 25
+
+/* Treo680 specific GPIOs */
+#define GPIO_NR_TREO680_SD_READONLY    33
+#define GPIO_NR_TREO680_SD_POWER       42
+#define GPIO_NR_TREO680_VIBRATE_EN     44
+#define GPIO_NR_TREO680_KEYB_BL                24
+#define GPIO_NR_TREO680_BT_EN          43
+#define GPIO_NR_TREO680_LCD_POWER      77
+#define GPIO_NR_TREO680_LCD_EN         86
+#define GPIO_NR_TREO680_LCD_EN_N       25
+
+/* Centro685 specific GPIOs */
+#define GPIO_NR_CENTRO_SD_POWER                21
+#define GPIO_NR_CENTRO_VIBRATE_EN      22
+#define GPIO_NR_CENTRO_KEYB_BL         33
+#define GPIO_NR_CENTRO_BT_EN           80
+
+/* Various addresses  */
+#define TREO_PHYS_RAM_START    0xa0000000
+#define TREO_PHYS_IO_START     0x40000000
+#define TREO_STR_BASE  0xa2000000
+
+/* BACKLIGHT */
+#define TREO_MAX_INTENSITY             254
+#define TREO_DEFAULT_INTENSITY 160
+#define TREO_LIMIT_MASK                0x7F
+#define TREO_PRESCALER         63
+#define TREO_PERIOD_NS         3500
+
+#endif
index d787dd1..3664697 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
 #include <mach/palmtx.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
 
 #include "generic.h"
 #include "devices.h"
index e3df17a..9c308de 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
-#include <mach/palmz72.h>
+#include "palmz72.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
 
-#include <mach/pm.h>
+#include "pm.h"
 #include <linux/platform_data/media/camera-pxa.h>
 
 #include <media/soc_camera.h>
diff --git a/arch/arm/mach-pxa/palmz72.h b/arch/arm/mach-pxa/palmz72.h
new file mode 100644 (file)
index 0000000..0d4700a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * GPIOs and interrupts for Palm Zire72 Handheld Computer
+ *
+ * Authors:    Alex Osborne <bobofdoom@gmail.com>
+ *             Jan Herman <2hp@seznam.cz>
+ *             Sergey Lapin <slapin@ossfans.org>
+ *
+ * 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 _INCLUDE_PALMZ72_H_
+#define _INCLUDE_PALMZ72_H_
+
+/* Power and control */
+#define GPIO_NR_PALMZ72_GPIO_RESET             1
+#define GPIO_NR_PALMZ72_POWER_DETECT           0
+
+/* SD/MMC */
+#define GPIO_NR_PALMZ72_SD_DETECT_N            14
+#define GPIO_NR_PALMZ72_SD_POWER_N             98
+#define GPIO_NR_PALMZ72_SD_RO                  115
+
+/* Touchscreen */
+#define GPIO_NR_PALMZ72_WM9712_IRQ             27
+
+/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMZ72_IR_DISABLE             49
+
+/* USB */
+#define GPIO_NR_PALMZ72_USB_DETECT_N           15
+#define GPIO_NR_PALMZ72_USB_PULLUP             95
+
+/* LCD/Backlight */
+#define GPIO_NR_PALMZ72_BL_POWER               20
+#define GPIO_NR_PALMZ72_LCD_POWER              96
+
+/* LED */
+#define GPIO_NR_PALMZ72_LED_GREEN              88
+
+/* Bluetooth */
+#define GPIO_NR_PALMZ72_BT_POWER               17
+#define GPIO_NR_PALMZ72_BT_RESET               83
+
+/* Camera */
+#define GPIO_NR_PALMZ72_CAM_PWDN               56
+#define GPIO_NR_PALMZ72_CAM_RESET              57
+#define GPIO_NR_PALMZ72_CAM_POWER              91
+
+/** Initial values **/
+
+/* Battery */
+#define PALMZ72_BAT_MAX_VOLTAGE                4000    /* 4.00v current voltage */
+#define PALMZ72_BAT_MIN_VOLTAGE                3550    /* 3.55v critical voltage */
+#define PALMZ72_BAT_MAX_CURRENT                0       /* unknown */
+#define PALMZ72_BAT_MIN_CURRENT                0       /* unknown */
+#define PALMZ72_BAT_MAX_CHARGE         1       /* unknown */
+#define PALMZ72_BAT_MIN_CHARGE         1       /* unknown */
+#define PALMZ72_MAX_LIFE_MINS          360     /* on-life in minutes */
+
+/* Backlight */
+#define PALMZ72_MAX_INTENSITY          0xFE
+#define PALMZ72_DEFAULT_INTENSITY      0x7E
+#define PALMZ72_LIMIT_MASK             0x7F
+#define PALMZ72_PRESCALER              0x3F
+#define PALMZ72_PERIOD_NS              3500
+
+#ifdef CONFIG_PM
+struct palmz72_resume_info {
+       u32 magic0;             /* 0x0 */
+       u32 magic1;             /* 0x4 */
+       u32 resume_addr;        /* 0x8 */
+       u32 pad[11];            /* 0xc..0x37 */
+       u32 arm_control;        /* 0x38 */
+       u32 aux_control;        /* 0x3c */
+       u32 ttb;                /* 0x40 */
+       u32 domain_access;      /* 0x44 */
+       u32 process_id;         /* 0x48 */
+};
+#endif
+#endif
+
index 69918c7..ccca9f7 100644 (file)
@@ -30,8 +30,8 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
-#include <mach/pcm027.h>
+#include "pxa27x.h"
+#include "pcm027.h"
 #include "generic.h"
 
 /*
diff --git a/arch/arm/mach-pxa/pcm027.h b/arch/arm/mach-pxa/pcm027.h
new file mode 100644 (file)
index 0000000..047cdf2
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pcm027.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; 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
+ */
+
+/*
+ * Definitions of CPU card resources only
+ */
+
+#include <mach/irqs.h> /* PXA_GPIO_TO_IRQ */
+
+/* phyCORE-PXA270 (PCM027) Interrupts */
+#define PCM027_IRQ(x)          (IRQ_BOARD_START + (x))
+#define PCM027_BTDET_IRQ       PCM027_IRQ(0)
+#define PCM027_FF_RI_IRQ       PCM027_IRQ(1)
+#define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
+#define PCM027_PM_5V_IRQ       PCM027_IRQ(3)
+
+#define PCM027_NR_IRQS         (IRQ_BOARD_START + 32)
+
+/* I2C RTC */
+#define PCM027_RTC_IRQ_GPIO    0
+#define PCM027_RTC_IRQ         PXA_GPIO_TO_IRQ(PCM027_RTC_IRQ_GPIO)
+#define PCM027_RTC_IRQ_EDGE    IRQ_TYPE_EDGE_FALLING
+#define ADR_PCM027_RTC         0x51    /* I2C address */
+
+/* I2C EEPROM */
+#define ADR_PCM027_EEPROM      0x54    /* I2C address */
+
+/* Ethernet chip (SMSC91C111) */
+#define PCM027_ETH_IRQ_GPIO    52
+#define PCM027_ETH_IRQ         PXA_GPIO_TO_IRQ(PCM027_ETH_IRQ_GPIO)
+#define PCM027_ETH_IRQ_EDGE    IRQ_TYPE_EDGE_RISING
+#define PCM027_ETH_PHYS                PXA_CS5_PHYS
+#define PCM027_ETH_SIZE                (1*1024*1024)
+
+/* CAN controller SJA1000 (unsupported yet) */
+#define PCM027_CAN_IRQ_GPIO    114
+#define PCM027_CAN_IRQ         PXA_GPIO_TO_IRQ(PCM027_CAN_IRQ_GPIO)
+#define PCM027_CAN_IRQ_EDGE    IRQ_TYPE_EDGE_FALLING
+#define PCM027_CAN_PHYS                0x22000000
+#define PCM027_CAN_SIZE                0x100
+
+/* SPI GPIO expander (unsupported yet) */
+#define PCM027_EGPIO_IRQ_GPIO  27
+#define PCM027_EGPIO_IRQ       PXA_GPIO_TO_IRQ(PCM027_EGPIO_IRQ_GPIO)
+#define PCM027_EGPIO_IRQ_EDGE  IRQ_TYPE_EDGE_FALLING
+#define PCM027_EGPIO_CS                24
+/*
+ * TODO: Switch this pin from dedicated usage to GPIO if
+ * more than the MAX7301 device is connected to this SPI bus
+ */
+#define PCM027_EGPIO_CS_MODE   GPIO24_SFRM_MD
+
+/* Flash memory */
+#define PCM027_FLASH_PHYS      0x00000000
+#define PCM027_FLASH_SIZE      0x02000000
+
+/* onboard LEDs connected to GPIO */
+#define PCM027_LED_CPU         90
+#define PCM027_LED_HEARD_BEAT  91
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own basebaord init function and call it from
+ * inside pcm027_init(). This example here is for the developmen board.
+ * Refer pcm990-baseboard.c
+ */
+extern void pcm990_baseboard_init(void);
index 8459239..0bd5959 100644 (file)
 
 #include <linux/platform_data/media/camera-pxa.h>
 #include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pcm990_baseboard.h>
+#include "pcm990_baseboard.h"
 #include <linux/platform_data/video-pxafb.h>
 
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/pcm990_baseboard.h b/arch/arm/mach-pxa/pcm990_baseboard.h
new file mode 100644 (file)
index 0000000..79d35ad
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "pcm027.h"
+#include <mach/irqs.h> /* PXA_GPIO_TO_IRQ */
+
+/*
+ * definitions relevant only when the PCM-990
+ * development base board is in use
+ */
+
+/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
+#define PCM990_CTRL_INT_IRQ_GPIO       9
+#define PCM990_CTRL_INT_IRQ            PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO)
+#define PCM990_CTRL_INT_IRQ_EDGE       IRQ_TYPE_EDGE_RISING
+#define PCM990_CTRL_PHYS               PXA_CS1_PHYS    /* 16-Bit */
+#define PCM990_CTRL_SIZE               (1*1024*1024)
+
+#define PCM990_CTRL_PWR_IRQ_GPIO       14
+#define PCM990_CTRL_PWR_IRQ            PXA_GPIO_TO_IRQ(PCM990_CTRL_PWR_IRQ_GPIO)
+#define PCM990_CTRL_PWR_IRQ_EDGE       IRQ_TYPE_EDGE_RISING
+
+/* visible CPLD (U7) registers */
+#define PCM990_CTRL_REG0       0x0000  /* RESET REGISTER */
+#define PCM990_CTRL_SYSRES     0x0001  /* System RESET REGISTER */
+#define PCM990_CTRL_RESOUT     0x0002  /* RESETOUT Enable REGISTER */
+#define PCM990_CTRL_RESGPIO    0x0004  /* RESETGPIO Enable REGISTER */
+
+#define PCM990_CTRL_REG1       0x0002  /* Power REGISTER */
+#define PCM990_CTRL_5VOFF      0x0001  /* Disable  5V Regulators */
+#define PCM990_CTRL_CANPWR     0x0004  /* Enable CANPWR ADUM */
+#define PCM990_CTRL_PM_5V      0x0008  /* Read 5V OK */
+
+#define PCM990_CTRL_REG2       0x0004  /* LED REGISTER */
+#define PCM990_CTRL_LEDPWR     0x0001  /* POWER LED enable */
+#define PCM990_CTRL_LEDBAS     0x0002  /* BASIS LED enable */
+#define PCM990_CTRL_LEDUSR     0x0004  /* USER LED enable */
+
+#define PCM990_CTRL_REG3       0x0006  /* LCD CTRL REGISTER 3 */
+#define PCM990_CTRL_LCDPWR     0x0001  /* RW LCD Power on */
+#define PCM990_CTRL_LCDON      0x0002  /* RW LCD Latch on */
+#define PCM990_CTRL_LCDPOS1    0x0004  /* RW POS 1 */
+#define PCM990_CTRL_LCDPOS2    0x0008  /* RW POS 2 */
+
+#define PCM990_CTRL_REG4       0x0008  /* MMC1 CTRL REGISTER 4 */
+#define PCM990_CTRL_MMC1PWR    0x0001 /* RW MMC1 Power on */
+
+#define PCM990_CTRL_REG5       0x000A  /* MMC2 CTRL REGISTER 5 */
+#define PCM990_CTRL_MMC2PWR    0x0001  /* RW MMC2 Power on */
+#define PCM990_CTRL_MMC2LED    0x0002  /* RW MMC2 LED */
+#define PCM990_CTRL_MMC2DE     0x0004  /* R MMC2 Card detect */
+#define PCM990_CTRL_MMC2WP     0x0008  /* R MMC2 Card write protect */
+
+#define PCM990_CTRL_INTSETCLR  0x000C  /* Interrupt Clear REGISTER */
+#define PCM990_CTRL_INTC0      0x0001  /* Clear Reg BT Detect */
+#define PCM990_CTRL_INTC1      0x0002  /* Clear Reg FR RI */
+#define PCM990_CTRL_INTC2      0x0004  /* Clear Reg MMC1 Detect */
+#define PCM990_CTRL_INTC3      0x0008  /* Clear Reg PM_5V off */
+
+#define PCM990_CTRL_INTMSKENA  0x000E  /* Interrupt Enable REGISTER */
+#define PCM990_CTRL_ENAINT0    0x0001  /* Enable Int BT Detect */
+#define PCM990_CTRL_ENAINT1    0x0002  /* Enable Int FR RI */
+#define PCM990_CTRL_ENAINT2    0x0004  /* Enable Int MMC1 Detect */
+#define PCM990_CTRL_ENAINT3    0x0008  /* Enable Int PM_5V off */
+
+#define PCM990_CTRL_REG8       0x0014  /* Uart REGISTER */
+#define PCM990_CTRL_FFSD       0x0001  /* BT Uart Enable */
+#define PCM990_CTRL_BTSD       0x0002  /* FF Uart Enable */
+#define PCM990_CTRL_FFRI       0x0004  /* FF Uart RI detect */
+#define PCM990_CTRL_BTRX       0x0008  /* BT Uart Rx detect */
+
+#define PCM990_CTRL_REG9       0x0010  /* AC97 Flash REGISTER */
+#define PCM990_CTRL_FLWP       0x0001  /* pC Flash Write Protect */
+#define PCM990_CTRL_FLDIS      0x0002  /* pC Flash Disable */
+#define PCM990_CTRL_AC97ENA    0x0004  /* Enable AC97 Expansion */
+
+#define PCM990_CTRL_REG10      0x0012  /* GPS-REGISTER */
+#define PCM990_CTRL_GPSPWR     0x0004  /* GPS-Modul Power on */
+#define PCM990_CTRL_GPSENA     0x0008  /* GPS-Modul Enable */
+
+#define PCM990_CTRL_REG11      0x0014  /* Accu REGISTER */
+#define PCM990_CTRL_ACENA      0x0001  /* Charge Enable */
+#define PCM990_CTRL_ACSEL      0x0002  /* Charge Akku -> DC Enable */
+#define PCM990_CTRL_ACPRES     0x0004  /* DC Present */
+#define PCM990_CTRL_ACALARM    0x0008  /* Error Akku */
+
+/*
+ * IDE
+ */
+#define PCM990_IDE_IRQ_GPIO    13
+#define PCM990_IDE_IRQ         PXA_GPIO_TO_IRQ(PCM990_IDE_IRQ_GPIO)
+#define PCM990_IDE_IRQ_EDGE    IRQ_TYPE_EDGE_RISING
+#define PCM990_IDE_PLD_PHYS    0x20000000      /* 16 bit wide */
+#define PCM990_IDE_PLD_BASE    0xee000000
+#define PCM990_IDE_PLD_SIZE    (1*1024*1024)
+
+/* visible CPLD (U6) registers */
+#define PCM990_IDE_PLD_REG0    0x1000  /* OFFSET IDE REGISTER 0 */
+#define PCM990_IDE_PM5V                0x0004  /* R System VCC_5V */
+#define PCM990_IDE_STBY                0x0008  /* R System StandBy */
+
+#define PCM990_IDE_PLD_REG1    0x1002  /* OFFSET IDE REGISTER 1 */
+#define PCM990_IDE_IDEMODE     0x0001  /* R TrueIDE Mode */
+#define PCM990_IDE_DMAENA      0x0004  /* RW DMA Enable */
+#define PCM990_IDE_DMA1_0      0x0008  /* RW 1=DREQ1 0=DREQ0 */
+
+#define PCM990_IDE_PLD_REG2    0x1004  /* OFFSET IDE REGISTER 2 */
+#define PCM990_IDE_RESENA      0x0001  /* RW IDE Reset Bit enable */
+#define PCM990_IDE_RES         0x0002  /* RW IDE Reset Bit */
+#define PCM990_IDE_RDY         0x0008  /* RDY */
+
+#define PCM990_IDE_PLD_REG3    0x1006  /* OFFSET IDE REGISTER 3 */
+#define PCM990_IDE_IDEOE       0x0001  /* RW Latch on Databus */
+#define PCM990_IDE_IDEON       0x0002  /* RW Latch on Control Address */
+#define PCM990_IDE_IDEIN       0x0004  /* RW Latch on Interrupt usw. */
+
+#define PCM990_IDE_PLD_REG4    0x1008  /* OFFSET IDE REGISTER 4 */
+#define PCM990_IDE_PWRENA      0x0001  /* RW IDE Power enable */
+#define PCM990_IDE_5V          0x0002  /* R IDE Power 5V */
+#define PCM990_IDE_PWG         0x0008  /* R IDE Power is on */
+
+#define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
+#define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)
+
+/*
+ * Compact Flash
+ */
+#define PCM990_CF_IRQ_GPIO     11
+#define PCM990_CF_IRQ          PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO)
+#define PCM990_CF_IRQ_EDGE     IRQ_TYPE_EDGE_RISING
+
+#define PCM990_CF_CD_GPIO      12
+#define PCM990_CF_CD           PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO)
+#define PCM990_CF_CD_EDGE      IRQ_TYPE_EDGE_RISING
+
+#define PCM990_CF_PLD_PHYS     0x30000000      /* 16 bit wide */
+
+/* visible CPLD (U6) registers */
+#define PCM990_CF_PLD_REG0     0x1000  /* OFFSET CF REGISTER 0 */
+#define PCM990_CF_REG0_LED     0x0001  /* RW LED on */
+#define PCM990_CF_REG0_BLK     0x0002  /* RW LED flash when access */
+#define PCM990_CF_REG0_PM5V    0x0004  /* R System VCC_5V enable */
+#define PCM990_CF_REG0_STBY    0x0008  /* R System StandBy */
+
+#define PCM990_CF_PLD_REG1     0x1002  /* OFFSET CF REGISTER 1 */
+#define PCM990_CF_REG1_IDEMODE 0x0001  /* RW CF card run as TrueIDE */
+#define PCM990_CF_REG1_CF0     0x0002  /* RW CF card at ADDR 0x28000000 */
+
+#define PCM990_CF_PLD_REG2     0x1004  /* OFFSET CF REGISTER 2 */
+#define PCM990_CF_REG2_RES     0x0002  /* RW CF RESET BIT */
+#define PCM990_CF_REG2_RDYENA  0x0004  /* RW Enable CF_RDY */
+#define PCM990_CF_REG2_RDY     0x0008  /* R CF_RDY auf PWAIT */
+
+#define PCM990_CF_PLD_REG3     0x1006  /* OFFSET CF REGISTER 3 */
+#define PCM990_CF_REG3_CFOE    0x0001  /* RW Latch on Databus */
+#define PCM990_CF_REG3_CFON    0x0002  /* RW Latch on Control Address */
+#define PCM990_CF_REG3_CFIN    0x0004  /* RW Latch on Interrupt usw. */
+#define PCM990_CF_REG3_CFCD    0x0008  /* RW Latch on CD1/2 VS1/2 usw */
+
+#define PCM990_CF_PLD_REG4     0x1008  /* OFFSET CF REGISTER 4 */
+#define PCM990_CF_REG4_PWRENA  0x0001  /* RW CF Power on (CD1/2 = "00") */
+#define PCM990_CF_REG4_5_3V    0x0002  /* RW 1 = 5V CF_VCC 0 = 3 V CF_VCC */
+#define PCM990_CF_REG4_3B      0x0004  /* RW 3.0V Backup from VCC (5_3V=0) */
+#define PCM990_CF_REG4_PWG     0x0008  /* R CF-Power is on */
+
+#define PCM990_CF_PLD_REG5     0x100A  /* OFFSET CF REGISTER 5 */
+#define PCM990_CF_REG5_BVD1    0x0001  /* R CF /BVD1 */
+#define PCM990_CF_REG5_BVD2    0x0002  /* R CF /BVD2 */
+#define PCM990_CF_REG5_VS1     0x0004  /* R CF /VS1 */
+#define PCM990_CF_REG5_VS2     0x0008  /* R CF /VS2 */
+
+#define PCM990_CF_PLD_REG6     0x100C  /* OFFSET CF REGISTER 6 */
+#define PCM990_CF_REG6_CD1     0x0001  /* R CF Card_Detect1 */
+#define PCM990_CF_REG6_CD2     0x0002  /* R CF Card_Detect2 */
+
+/*
+ * Wolfson AC97 Touch
+ */
+#define PCM990_AC97_IRQ_GPIO   10
+#define PCM990_AC97_IRQ                PXA_GPIO_TO_IRQ(PCM990_AC97_IRQ_GPIO)
+#define PCM990_AC97_IRQ_EDGE   IRQ_TYPE_EDGE_RISING
+
+/*
+ * MMC phyCORE
+ */
+#define PCM990_MMC0_IRQ_GPIO   9
+#define PCM990_MMC0_IRQ                PXA_GPIO_TO_IRQ(PCM990_MMC0_IRQ_GPIO)
+#define PCM990_MMC0_IRQ_EDGE   IRQ_TYPE_EDGE_FALLING
+
+/*
+ * USB phyCore
+ */
+#define PCM990_USB_OVERCURRENT (88 | GPIO_ALT_FN_1_IN)
+#define PCM990_USB_PWR_EN (89 | GPIO_ALT_FN_2_OUT)
index 37178a8..388463b 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
-#include <mach/pm.h>
+#include "pm.h"
 
 struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
 static unsigned long *sleep_save;
diff --git a/arch/arm/mach-pxa/pm.h b/arch/arm/mach-pxa/pm.h
new file mode 100644 (file)
index 0000000..51558bc
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * 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/suspend.h>
+
+struct pxa_cpu_pm_fns {
+       int     save_count;
+       void    (*save)(unsigned long *);
+       void    (*restore)(unsigned long *);
+       int     (*valid)(suspend_state_t state);
+       void    (*enter)(suspend_state_t state);
+       int     (*prepare)(void);
+       void    (*finish)(void);
+};
+
+extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
+
+/* sleep.S */
+extern int pxa25x_finish_suspend(unsigned long);
+extern int pxa27x_finish_suspend(unsigned long);
+
+extern int pxa_pm_enter(suspend_state_t state);
+extern int pxa_pm_prepare(void);
+extern void pxa_pm_finish(void);
+
+/* NOTE: this is for PM debugging on Lubbock,  it's really a big
+ * ugly, but let's keep the crap minimum here, instead of direct
+ * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c
+ */
+#ifdef CONFIG_ARCH_LUBBOCK
+extern void lubbock_set_hexled(uint32_t value);
+#else
+#define lubbock_set_hexled(x)
+#endif
index 195b112..62a1191 100644 (file)
@@ -41,9 +41,9 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
+#include "udc.h"
 #include <linux/platform_data/irda-pxaficp.h>
 #include <mach/poodle.h>
 #include <linux/platform_data/video-pxafb.h>
index 1dc85ff..a177bf4 100644 (file)
@@ -30,9 +30,9 @@
 #include <asm/suspend.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/reset.h>
-#include <mach/pm.h>
+#include "pm.h"
 #include <mach/dma.h>
 #include <mach/smemc.h>
 
diff --git a/arch/arm/mach-pxa/pxa25x.h b/arch/arm/mach-pxa/pxa25x.h
new file mode 100644 (file)
index 0000000..2011e8d
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __MACH_PXA25x_H
+#define __MACH_PXA25x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include "mfp-pxa25x.h"
+#include <mach/irqs.h>
+
+#endif /* __MACH_PXA25x_H */
diff --git a/arch/arm/mach-pxa/pxa27x-udc.h b/arch/arm/mach-pxa/pxa27x-udc.h
new file mode 100644 (file)
index 0000000..4cf28f6
--- /dev/null
@@ -0,0 +1,257 @@
+#ifndef _ASM_ARCH_PXA27X_UDC_H
+#define _ASM_ARCH_PXA27X_UDC_H
+
+#ifdef _ASM_ARCH_PXA25X_UDC_H
+#error You cannot include both PXA25x and PXA27x UDC support
+#endif
+
+#define UDCCR           __REG(0x40600000) /* UDC Control Register */
+#define UDCCR_OEN      (1 << 31)       /* On-the-Go Enable */
+#define UDCCR_AALTHNP  (1 << 30)       /* A-device Alternate Host Negotiation
+                                          Protocol Port Support */
+#define UDCCR_AHNP     (1 << 29)       /* A-device Host Negotiation Protocol
+                                          Support */
+#define UDCCR_BHNP     (1 << 28)       /* B-device Host Negotiation Protocol
+                                          Enable */
+#define UDCCR_DWRE     (1 << 16)       /* Device Remote Wake-up Enable */
+#define UDCCR_ACN      (0x03 << 11)    /* Active UDC configuration Number */
+#define UDCCR_ACN_S    11
+#define UDCCR_AIN      (0x07 << 8)     /* Active UDC interface Number */
+#define UDCCR_AIN_S    8
+#define UDCCR_AAISN    (0x07 << 5)     /* Active UDC Alternate Interface
+                                          Setting Number */
+#define UDCCR_AAISN_S  5
+#define UDCCR_SMAC     (1 << 4)        /* Switch Endpoint Memory to Active
+                                          Configuration */
+#define UDCCR_EMCE     (1 << 3)        /* Endpoint Memory Configuration
+                                          Error */
+#define UDCCR_UDR      (1 << 2)        /* UDC Resume */
+#define UDCCR_UDA      (1 << 1)        /* UDC Active */
+#define UDCCR_UDE      (1 << 0)        /* UDC Enable */
+
+#define UDCICR0         __REG(0x40600004) /* UDC Interrupt Control Register0 */
+#define UDCICR1         __REG(0x40600008) /* UDC Interrupt Control Register1 */
+#define UDCICR_FIFOERR (1 << 1)        /* FIFO Error interrupt for EP */
+#define UDCICR_PKTCOMPL (1 << 0)       /* Packet Complete interrupt for EP */
+
+#define UDC_INT_FIFOERROR  (0x2)
+#define UDC_INT_PACKETCMP  (0x1)
+
+#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCICR1_IECC   (1 << 31)       /* IntEn - Configuration Change */
+#define UDCICR1_IESOF  (1 << 30)       /* IntEn - Start of Frame */
+#define UDCICR1_IERU   (1 << 29)       /* IntEn - Resume */
+#define UDCICR1_IESU   (1 << 28)       /* IntEn - Suspend */
+#define UDCICR1_IERS   (1 << 27)       /* IntEn - Reset */
+
+#define UDCISR0         __REG(0x4060000C) /* UDC Interrupt Status Register 0 */
+#define UDCISR1         __REG(0x40600010) /* UDC Interrupt Status Register 1 */
+#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCISR1_IRCC   (1 << 31)       /* IntReq - Configuration Change */
+#define UDCISR1_IRSOF  (1 << 30)       /* IntReq - Start of Frame */
+#define UDCISR1_IRRU   (1 << 29)       /* IntReq - Resume */
+#define UDCISR1_IRSU   (1 << 28)       /* IntReq - Suspend */
+#define UDCISR1_IRRS   (1 << 27)       /* IntReq - Reset */
+
+#define UDCFNR          __REG(0x40600014) /* UDC Frame Number Register */
+#define UDCOTGICR      __REG(0x40600018) /* UDC On-The-Go interrupt control */
+#define UDCOTGICR_IESF (1 << 24)       /* OTG SET_FEATURE command recvd */
+#define UDCOTGICR_IEXR (1 << 17)       /* Extra Transceiver Interrupt
+                                          Rising Edge Interrupt Enable */
+#define UDCOTGICR_IEXF (1 << 16)       /* Extra Transceiver Interrupt
+                                          Falling Edge Interrupt Enable */
+#define UDCOTGICR_IEVV40R (1 << 9)     /* OTG Vbus Valid 4.0V Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEVV40F (1 << 8)     /* OTG Vbus Valid 4.0V Falling Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEVV44R (1 << 7)     /* OTG Vbus Valid 4.4V Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEVV44F (1 << 6)     /* OTG Vbus Valid 4.4V Falling Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IESVR        (1 << 5)        /* OTG Session Valid Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IESVF        (1 << 4)        /* OTG Session Valid Falling Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IESDR        (1 << 3)        /* OTG A-Device SRP Detect Rising
+                                          Edge Interrupt Enable */
+#define UDCOTGICR_IESDF        (1 << 2)        /* OTG A-Device SRP Detect Falling
+                                          Edge Interrupt Enable */
+#define UDCOTGICR_IEIDR        (1 << 1)        /* OTG ID Change Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEIDF        (1 << 0)        /* OTG ID Change Falling Edge
+                                          Interrupt Enable */
+
+#define UP2OCR           __REG(0x40600020)  /* USB Port 2 Output Control register */
+#define UP3OCR           __REG(0x40600024)  /* USB Port 2 Output Control register */
+
+#define UP2OCR_CPVEN   (1 << 0)        /* Charge Pump Vbus Enable */
+#define UP2OCR_CPVPE   (1 << 1)        /* Charge Pump Vbus Pulse Enable */
+#define UP2OCR_DPPDE   (1 << 2)        /* Host Port 2 Transceiver D+ Pull Down Enable */
+#define UP2OCR_DMPDE   (1 << 3)        /* Host Port 2 Transceiver D- Pull Down Enable */
+#define UP2OCR_DPPUE   (1 << 4)        /* Host Port 2 Transceiver D+ Pull Up Enable */
+#define UP2OCR_DMPUE   (1 << 5)        /* Host Port 2 Transceiver D- Pull Up Enable */
+#define UP2OCR_DPPUBE  (1 << 6)        /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */
+#define UP2OCR_DMPUBE  (1 << 7)        /* Host Port 2 Transceiver D- Pull Up Bypass Enable */
+#define UP2OCR_EXSP            (1 << 8)        /* External Transceiver Speed Control */
+#define UP2OCR_EXSUS   (1 << 9)        /* External Transceiver Speed Enable */
+#define UP2OCR_IDON            (1 << 10)       /* OTG ID Read Enable */
+#define UP2OCR_HXS             (1 << 16)       /* Host Port 2 Transceiver Output Select */
+#define UP2OCR_HXOE            (1 << 17)       /* Host Port 2 Transceiver Output Enable */
+#define UP2OCR_SEOS(x)         ((x & 7) << 24) /* Single-Ended Output Select */
+
+#define UDCCSN(x)      __REG2(0x40600100, (x) << 2)
+#define UDCCSR0         __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */
+#define UDCCSR0_SA     (1 << 7)        /* Setup Active */
+#define UDCCSR0_RNE    (1 << 6)        /* Receive FIFO Not Empty */
+#define UDCCSR0_FST    (1 << 5)        /* Force Stall */
+#define UDCCSR0_SST    (1 << 4)        /* Sent Stall */
+#define UDCCSR0_DME    (1 << 3)        /* DMA Enable */
+#define UDCCSR0_FTF    (1 << 2)        /* Flush Transmit FIFO */
+#define UDCCSR0_IPR    (1 << 1)        /* IN Packet Ready */
+#define UDCCSR0_OPC    (1 << 0)        /* OUT Packet Complete */
+
+#define UDCCSRA         __REG(0x40600104) /* UDC Control/Status register - Endpoint A */
+#define UDCCSRB         __REG(0x40600108) /* UDC Control/Status register - Endpoint B */
+#define UDCCSRC         __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */
+#define UDCCSRD         __REG(0x40600110) /* UDC Control/Status register - Endpoint D */
+#define UDCCSRE         __REG(0x40600114) /* UDC Control/Status register - Endpoint E */
+#define UDCCSRF         __REG(0x40600118) /* UDC Control/Status register - Endpoint F */
+#define UDCCSRG         __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */
+#define UDCCSRH         __REG(0x40600120) /* UDC Control/Status register - Endpoint H */
+#define UDCCSRI         __REG(0x40600124) /* UDC Control/Status register - Endpoint I */
+#define UDCCSRJ         __REG(0x40600128) /* UDC Control/Status register - Endpoint J */
+#define UDCCSRK         __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */
+#define UDCCSRL         __REG(0x40600130) /* UDC Control/Status register - Endpoint L */
+#define UDCCSRM         __REG(0x40600134) /* UDC Control/Status register - Endpoint M */
+#define UDCCSRN         __REG(0x40600138) /* UDC Control/Status register - Endpoint N */
+#define UDCCSRP         __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */
+#define UDCCSRQ         __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */
+#define UDCCSRR         __REG(0x40600144) /* UDC Control/Status register - Endpoint R */
+#define UDCCSRS         __REG(0x40600148) /* UDC Control/Status register - Endpoint S */
+#define UDCCSRT         __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */
+#define UDCCSRU         __REG(0x40600150) /* UDC Control/Status register - Endpoint U */
+#define UDCCSRV         __REG(0x40600154) /* UDC Control/Status register - Endpoint V */
+#define UDCCSRW         __REG(0x40600158) /* UDC Control/Status register - Endpoint W */
+#define UDCCSRX         __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */
+
+#define UDCCSR_DPE     (1 << 9)        /* Data Packet Error */
+#define UDCCSR_FEF     (1 << 8)        /* Flush Endpoint FIFO */
+#define UDCCSR_SP      (1 << 7)        /* Short Packet Control/Status */
+#define UDCCSR_BNE     (1 << 6)        /* Buffer Not Empty (IN endpoints) */
+#define UDCCSR_BNF     (1 << 6)        /* Buffer Not Full (OUT endpoints) */
+#define UDCCSR_FST     (1 << 5)        /* Force STALL */
+#define UDCCSR_SST     (1 << 4)        /* Sent STALL */
+#define UDCCSR_DME     (1 << 3)        /* DMA Enable */
+#define UDCCSR_TRN     (1 << 2)        /* Tx/Rx NAK */
+#define UDCCSR_PC      (1 << 1)        /* Packet Complete */
+#define UDCCSR_FS      (1 << 0)        /* FIFO needs service */
+
+#define UDCBCN(x)      __REG2(0x40600200, (x)<<2)
+#define UDCBCR0         __REG(0x40600200) /* Byte Count Register - EP0 */
+#define UDCBCRA         __REG(0x40600204) /* Byte Count Register - EPA */
+#define UDCBCRB         __REG(0x40600208) /* Byte Count Register - EPB */
+#define UDCBCRC         __REG(0x4060020C) /* Byte Count Register - EPC */
+#define UDCBCRD         __REG(0x40600210) /* Byte Count Register - EPD */
+#define UDCBCRE         __REG(0x40600214) /* Byte Count Register - EPE */
+#define UDCBCRF         __REG(0x40600218) /* Byte Count Register - EPF */
+#define UDCBCRG         __REG(0x4060021C) /* Byte Count Register - EPG */
+#define UDCBCRH         __REG(0x40600220) /* Byte Count Register - EPH */
+#define UDCBCRI         __REG(0x40600224) /* Byte Count Register - EPI */
+#define UDCBCRJ         __REG(0x40600228) /* Byte Count Register - EPJ */
+#define UDCBCRK         __REG(0x4060022C) /* Byte Count Register - EPK */
+#define UDCBCRL         __REG(0x40600230) /* Byte Count Register - EPL */
+#define UDCBCRM         __REG(0x40600234) /* Byte Count Register - EPM */
+#define UDCBCRN         __REG(0x40600238) /* Byte Count Register - EPN */
+#define UDCBCRP         __REG(0x4060023C) /* Byte Count Register - EPP */
+#define UDCBCRQ         __REG(0x40600240) /* Byte Count Register - EPQ */
+#define UDCBCRR         __REG(0x40600244) /* Byte Count Register - EPR */
+#define UDCBCRS         __REG(0x40600248) /* Byte Count Register - EPS */
+#define UDCBCRT         __REG(0x4060024C) /* Byte Count Register - EPT */
+#define UDCBCRU         __REG(0x40600250) /* Byte Count Register - EPU */
+#define UDCBCRV         __REG(0x40600254) /* Byte Count Register - EPV */
+#define UDCBCRW         __REG(0x40600258) /* Byte Count Register - EPW */
+#define UDCBCRX         __REG(0x4060025C) /* Byte Count Register - EPX */
+
+#define UDCDN(x)       __REG2(0x40600300, (x)<<2)
+#define PHYS_UDCDN(x)  (0x40600300 + ((x)<<2))
+#define PUDCDN(x)      (volatile u32 *)(io_p2v(PHYS_UDCDN((x))))
+#define UDCDR0          __REG(0x40600300) /* Data Register - EP0 */
+#define UDCDRA          __REG(0x40600304) /* Data Register - EPA */
+#define UDCDRB          __REG(0x40600308) /* Data Register - EPB */
+#define UDCDRC          __REG(0x4060030C) /* Data Register - EPC */
+#define UDCDRD          __REG(0x40600310) /* Data Register - EPD */
+#define UDCDRE          __REG(0x40600314) /* Data Register - EPE */
+#define UDCDRF          __REG(0x40600318) /* Data Register - EPF */
+#define UDCDRG          __REG(0x4060031C) /* Data Register - EPG */
+#define UDCDRH          __REG(0x40600320) /* Data Register - EPH */
+#define UDCDRI          __REG(0x40600324) /* Data Register - EPI */
+#define UDCDRJ          __REG(0x40600328) /* Data Register - EPJ */
+#define UDCDRK          __REG(0x4060032C) /* Data Register - EPK */
+#define UDCDRL          __REG(0x40600330) /* Data Register - EPL */
+#define UDCDRM          __REG(0x40600334) /* Data Register - EPM */
+#define UDCDRN          __REG(0x40600338) /* Data Register - EPN */
+#define UDCDRP          __REG(0x4060033C) /* Data Register - EPP */
+#define UDCDRQ          __REG(0x40600340) /* Data Register - EPQ */
+#define UDCDRR          __REG(0x40600344) /* Data Register - EPR */
+#define UDCDRS          __REG(0x40600348) /* Data Register - EPS */
+#define UDCDRT          __REG(0x4060034C) /* Data Register - EPT */
+#define UDCDRU          __REG(0x40600350) /* Data Register - EPU */
+#define UDCDRV          __REG(0x40600354) /* Data Register - EPV */
+#define UDCDRW          __REG(0x40600358) /* Data Register - EPW */
+#define UDCDRX          __REG(0x4060035C) /* Data Register - EPX */
+
+#define UDCCN(x)       __REG2(0x40600400, (x)<<2)
+#define UDCCRA          __REG(0x40600404) /* Configuration register EPA */
+#define UDCCRB          __REG(0x40600408) /* Configuration register EPB */
+#define UDCCRC          __REG(0x4060040C) /* Configuration register EPC */
+#define UDCCRD          __REG(0x40600410) /* Configuration register EPD */
+#define UDCCRE          __REG(0x40600414) /* Configuration register EPE */
+#define UDCCRF          __REG(0x40600418) /* Configuration register EPF */
+#define UDCCRG          __REG(0x4060041C) /* Configuration register EPG */
+#define UDCCRH          __REG(0x40600420) /* Configuration register EPH */
+#define UDCCRI          __REG(0x40600424) /* Configuration register EPI */
+#define UDCCRJ          __REG(0x40600428) /* Configuration register EPJ */
+#define UDCCRK          __REG(0x4060042C) /* Configuration register EPK */
+#define UDCCRL          __REG(0x40600430) /* Configuration register EPL */
+#define UDCCRM          __REG(0x40600434) /* Configuration register EPM */
+#define UDCCRN          __REG(0x40600438) /* Configuration register EPN */
+#define UDCCRP          __REG(0x4060043C) /* Configuration register EPP */
+#define UDCCRQ          __REG(0x40600440) /* Configuration register EPQ */
+#define UDCCRR          __REG(0x40600444) /* Configuration register EPR */
+#define UDCCRS          __REG(0x40600448) /* Configuration register EPS */
+#define UDCCRT          __REG(0x4060044C) /* Configuration register EPT */
+#define UDCCRU          __REG(0x40600450) /* Configuration register EPU */
+#define UDCCRV          __REG(0x40600454) /* Configuration register EPV */
+#define UDCCRW          __REG(0x40600458) /* Configuration register EPW */
+#define UDCCRX          __REG(0x4060045C) /* Configuration register EPX */
+
+#define UDCCONR_CN     (0x03 << 25)    /* Configuration Number */
+#define UDCCONR_CN_S   (25)
+#define UDCCONR_IN     (0x07 << 22)    /* Interface Number */
+#define UDCCONR_IN_S   (22)
+#define UDCCONR_AISN   (0x07 << 19)    /* Alternate Interface Number */
+#define UDCCONR_AISN_S (19)
+#define UDCCONR_EN     (0x0f << 15)    /* Endpoint Number */
+#define UDCCONR_EN_S   (15)
+#define UDCCONR_ET     (0x03 << 13)    /* Endpoint Type: */
+#define UDCCONR_ET_S   (13)
+#define UDCCONR_ET_INT (0x03 << 13)    /*   Interrupt */
+#define UDCCONR_ET_BULK        (0x02 << 13)    /*   Bulk */
+#define UDCCONR_ET_ISO (0x01 << 13)    /*   Isochronous */
+#define UDCCONR_ET_NU  (0x00 << 13)    /*   Not used */
+#define UDCCONR_ED     (1 << 12)       /* Endpoint Direction */
+#define UDCCONR_MPS    (0x3ff << 2)    /* Maximum Packet Size */
+#define UDCCONR_MPS_S  (2)
+#define UDCCONR_DE     (1 << 1)        /* Double Buffering Enable */
+#define UDCCONR_EE     (1 << 0)        /* Endpoint Enable */
+
+
+#define UDC_INT_FIFOERROR  (0x2)
+#define UDC_INT_PACKETCMP  (0x1)
+
+#define UDC_FNR_MASK     (0x7ff)
+
+#define UDCCSR_WR_MASK   (UDCCSR_DME|UDCCSR_FST)
+#define UDC_BCR_MASK    (0x3ff)
+
+#endif
index ffc4240..8dfd175 100644 (file)
 #include <asm/irq.h>
 #include <asm/suspend.h>
 #include <mach/irqs.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/reset.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pm.h>
+#include "pm.h"
 #include <mach/dma.h>
 #include <mach/smemc.h>
 
diff --git a/arch/arm/mach-pxa/pxa27x.h b/arch/arm/mach-pxa/pxa27x.h
new file mode 100644 (file)
index 0000000..075131d
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __MACH_PXA27x_H
+#define __MACH_PXA27x_H
+
+#include <linux/suspend.h>
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include "mfp-pxa27x.h"
+#include <mach/irqs.h>
+
+#define ARB_CNTRL      __REG(0x48000048)  /* Arbiter Control Register */
+
+#define ARB_DMA_SLV_PARK       (1<<31)    /* Be parked with DMA slave when idle */
+#define ARB_CI_PARK            (1<<30)    /* Be parked with Camera Interface when idle */
+#define ARB_EX_MEM_PARK        (1<<29)    /* Be parked with external MEMC when idle */
+#define ARB_INT_MEM_PARK       (1<<28)    /* Be parked with internal MEMC when idle */
+#define ARB_USB_PARK           (1<<27)    /* Be parked with USB when idle */
+#define ARB_LCD_PARK           (1<<26)    /* Be parked with LCD when idle */
+#define ARB_DMA_PARK           (1<<25)    /* Be parked with DMA when idle */
+#define ARB_CORE_PARK          (1<<24)    /* Be parked with core when idle */
+#define ARB_LOCK_FLAG          (1<<23)    /* Only Locking masters gain access to the bus */
+
+extern int pxa27x_set_pwrmode(unsigned int mode);
+extern void pxa27x_cpu_pm_enter(suspend_state_t state);
+
+#endif /* __MACH_PXA27x_H */
index 447dcbb..6b5e566 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <mach/hardware.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include "mfp-pxa25x.h"
 #include <mach/reset.h>
 #include <linux/platform_data/irda-pxaficp.h>
 
index 28c5b56..df83b1b 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <mach/pxa300.h>
+#include "pxa300.h"
 
 #include "generic.h"
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/pxa300.h b/arch/arm/mach-pxa/pxa300.h
new file mode 100644 (file)
index 0000000..59fa410
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MACH_PXA300_H
+#define __MACH_PXA300_H
+
+#include "pxa3xx.h"
+#include "mfp-pxa300.h"
+
+#endif /* __MACH_PXA300_H */
index 2f55bb4..a26eec5 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <mach/pxa320.h>
+#include "pxa320.h"
 
 #include "generic.h"
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/pxa320.h b/arch/arm/mach-pxa/pxa320.h
new file mode 100644 (file)
index 0000000..b9e5115
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA320_H
+#define __MACH_PXA320_H
+
+#include "pxa3xx.h"
+#include "mfp-pxa320.h"
+
+#endif /* __MACH_PXA320_H */
+
index 1c85275..eba595f 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/usb/otg.h>
 
 #include <mach/hardware.h>
-#include <mach/regs-u2d.h>
+#include "regs-u2d.h"
 #include <linux/platform_data/usb-pxa3xx-ulpi.h>
 
 struct pxa3xx_u2d_ulpi {
index 20ce2d3..a1c4c88 100644 (file)
@@ -30,7 +30,7 @@
 #include <mach/pxa3xx-regs.h>
 #include <mach/reset.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pm.h>
+#include "pm.h"
 #include <mach/dma.h>
 #include <mach/smemc.h>
 #include <mach/irqs.h>
diff --git a/arch/arm/mach-pxa/pxa3xx.h b/arch/arm/mach-pxa/pxa3xx.h
new file mode 100644 (file)
index 0000000..b4143fb
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA3XX_H        
+#define __MACH_PXA3XX_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/irqs.h>
+
+#endif /* __MACH_PXA3XX_H */
index ab62448..da912be 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/gpio-pxa.h>
 #include <linux/platform_device.h>
 
-#include <mach/pxa930.h>
+#include "pxa930.h"
 
 #include "devices.h"
 
diff --git a/arch/arm/mach-pxa/pxa930.h b/arch/arm/mach-pxa/pxa930.h
new file mode 100644 (file)
index 0000000..4eceb02
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MACH_PXA930_H
+#define __MACH_PXA930_H
+
+#include "pxa3xx.h"
+#include "mfp-pxa930.h"
+
+#endif /* __MACH_PXA930_H */
index 36571a9..8347d87 100644 (file)
@@ -49,7 +49,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa300.h>
+#include "pxa300.h"
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
@@ -1046,7 +1046,7 @@ static void __init raumfeld_common_init(void)
        i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
 }
 
-static void __init raumfeld_controller_init(void)
+static void __init __maybe_unused raumfeld_controller_init(void)
 {
        int ret;
 
@@ -1067,7 +1067,7 @@ static void __init raumfeld_controller_init(void)
        raumfeld_w1_init();
 }
 
-static void __init raumfeld_connector_init(void)
+static void __init __maybe_unused raumfeld_connector_init(void)
 {
        pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config));
        spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
@@ -1079,7 +1079,7 @@ static void __init raumfeld_connector_init(void)
        raumfeld_common_init();
 }
 
-static void __init raumfeld_speaker_init(void)
+static void __init __maybe_unused raumfeld_speaker_init(void)
 {
        pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_speaker_pin_config));
        spi_register_board_info(ARRAY_AND_SIZE(speaker_spi_devices));
diff --git a/arch/arm/mach-pxa/regs-rtc.h b/arch/arm/mach-pxa/regs-rtc.h
new file mode 100644 (file)
index 0000000..f0e4a58
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR           __REG(0x40900000)  /* RTC Count Register */
+#define RTAR           __REG(0x40900004)  /* RTC Alarm Register */
+#define RTSR           __REG(0x40900008)  /* RTC Status Register */
+#define RTTR           __REG(0x4090000C)  /* RTC Timer Trim Register */
+#define PIAR           __REG(0x40900038)  /* Periodic Interrupt Alarm Register */
+
+#define RTSR_PICE      (1 << 15)       /* Periodic interrupt count enable */
+#define RTSR_PIALE     (1 << 14)       /* Periodic interrupt Alarm enable */
+#define RTSR_HZE       (1 << 3)        /* HZ interrupt enable */
+#define RTSR_ALE       (1 << 2)        /* RTC alarm interrupt enable */
+#define RTSR_HZ                (1 << 1)        /* HZ rising-edge detected */
+#define RTSR_AL                (1 << 0)        /* RTC alarm detected */
+
+#endif /* __ASM_MACH_REGS_RTC_H */
diff --git a/arch/arm/mach-pxa/regs-u2d.h b/arch/arm/mach-pxa/regs-u2d.h
new file mode 100644 (file)
index 0000000..c15c0c5
--- /dev/null
@@ -0,0 +1,200 @@
+#ifndef __ASM_ARCH_PXA3xx_U2D_H
+#define __ASM_ARCH_PXA3xx_U2D_H
+
+#include <mach/bitfield.h>
+
+/*
+ * USB2 device controller registers and bits definitions
+ */
+#define U2DCR          (0x0000)        /* U2D Control Register */
+#define U2DCR_NDC      (1   << 31)     /* NAK During Config */
+#define U2DCR_HSTC     (0x7 << 28)     /* High Speed Timeout Calibration */
+#define U2DCR_SPEOREN  (1   << 27)     /* Short Packet EOR INTR generation Enable */
+#define U2DCR_FSTC     (0x7 << 24)     /* Full Speed Timeout Calibration */
+#define U2DCR_UCLKOVR  (1   << 22)     /* UTM Clock Override */
+#define U2DCR_ABP      (1   << 21)     /* Application Bus Power */
+#define U2DCR_ADD      (1   << 20)     /* Application Device Disconnect */
+#define U2DCR_CC       (1   << 19)     /* Configuration Change */
+#define U2DCR_HS       (1   << 18)     /* High Speed USB Detection */
+#define U2DCR_SMAC     (1   << 17)     /* Switch Endpoint Memory to Active Configuration */
+#define U2DCR_DWRE     (1   << 16)     /* Device Remote Wake-up Feature */
+#define U2DCR_ACN      (0xf << 12)     /* Active U2D Configuration Number */
+#define U2DCR_AIN      (0xf << 8)      /* Active U2D Interface Number */
+#define U2DCR_AAISN    (0xf << 4)      /* Active U2D Alternate Interface Setting Number */
+#define U2DCR_EMCE     (1   << 3)      /* Endpoint Memory Configuration Error */
+#define U2DCR_UDR      (1   << 2)      /* U2D Resume */
+#define U2DCR_UDA      (1   << 1)      /* U2D Active */
+#define U2DCR_UDE      (1   << 0)      /* U2D Enable */
+
+#define U2DICR                 (0x0004)        /* U2D Interrupt Control Register */
+#define U2DISR                 (0x000C)        /* U2D Interrupt Status Register */
+#define U2DINT_CC              (1 << 31)       /* Interrupt - Configuration Change */
+#define U2DINT_SOF             (1 << 30)       /* Interrupt - SOF */
+#define U2DINT_USOF            (1 << 29)       /* Interrupt - micro SOF */
+#define U2DINT_RU              (1 << 28)       /* Interrupt - Resume */
+#define U2DINT_SU              (1 << 27)       /* Interrupt - Suspend */
+#define U2DINT_RS              (1 << 26)       /* Interrupt - Reset */
+#define U2DINT_DPE             (1 << 25)       /* Interrupt - Data Packet Error */
+#define U2DINT_FIFOERR         (0x4)           /* Interrupt - endpoint FIFO error */
+#define U2DINT_PACKETCMP       (0x2)           /* Interrupt - endpoint packet complete */
+#define U2DINT_SPACKETCMP      (0x1)           /* Interrupt - endpoint short packet complete */
+
+#define U2DFNR                 (0x0014)        /* U2D Frame Number Register */
+
+#define U2DINT(n, intr)                (((intr) & 0x07) << (((n) & 0x07) * 3))
+#define U2DICR2                        (0x0008)        /* U2D Interrupt Control Register 2 */
+#define U2DISR2                        (0x0010)        /* U2D Interrupt Status Register 2 */
+
+#define U2DOTGCR               (0x0020)        /* U2D OTG Control Register */
+#define U2DOTGCR_OTGEN         (1 << 31)       /* On-The-Go Enable */
+#define U2DOTGCR_AALTHNP       (1 << 30)       /* A-device Alternate Host Negotiation Protocal Port Support */
+#define U2DOTGCR_AHNP          (1 << 29)       /* A-device Host Negotiation Protocal Support */
+#define U2DOTGCR_BHNP          (1 << 28)       /* B-device Host Negotiation Protocal Enable */
+
+#ifdef CONFIG_CPU_PXA930
+#define U2DOTGCR_LPA           (1 << 15)       /* ULPI low power mode active */
+#define U2DOTGCR_IESI          (1 << 13)       /* OTG interrupt Enable */
+#define U2DOTGCR_ISSI          (1 << 12)       /* OTG interrupt status */
+#endif
+
+#define U2DOTGCR_CKAF  (1 << 5)        /* Carkit Mode Alternate Function Select */
+#define U2DOTGCR_UTMID (1 << 4)        /* UTMI Interface Disable */
+#define U2DOTGCR_ULAF  (1 << 3)        /* ULPI Mode Alternate Function Select */
+#define U2DOTGCR_SMAF  (1 << 2)        /* Serial Mode Alternate Function Select */
+#define U2DOTGCR_RTSM  (1 << 1)        /* Return to Synchronous Mode (ULPI Mode) */
+#define U2DOTGCR_ULE   (1 << 0)        /* ULPI Wrapper Enable */
+
+#define U2DOTGICR      (0x0024)        /* U2D OTG Interrupt Control Register */
+#define U2DOTGISR      (0x0028)        /* U2D OTG Interrupt Status Register */
+
+#define U2DOTGINT_SF   (1 << 17)       /* OTG Set Feature Command Received */
+#define U2DOTGINT_SI   (1 << 16)       /* OTG Interrupt */
+#define U2DOTGINT_RLS1 (1 << 14)       /* RXCMD Linestate[1] Change Interrupt Rise */
+#define U2DOTGINT_RLS0 (1 << 13)       /* RXCMD Linestate[0] Change Interrupt Rise */
+#define U2DOTGINT_RID  (1 << 12)       /* RXCMD OTG ID Change Interrupt Rise */
+#define U2DOTGINT_RSE  (1 << 11)       /* RXCMD OTG Session End Interrupt Rise */
+#define U2DOTGINT_RSV  (1 << 10)       /* RXCMD OTG Session Valid Interrupt Rise */
+#define U2DOTGINT_RVV  (1 << 9)        /* RXCMD OTG Vbus Valid Interrupt Rise */
+#define U2DOTGINT_RCK  (1 << 8)        /* RXCMD Carkit Interrupt Rise */
+#define U2DOTGINT_FLS1 (1 << 6)        /* RXCMD Linestate[1] Change Interrupt Fall */
+#define U2DOTGINT_FLS0 (1 << 5)        /* RXCMD Linestate[0] Change Interrupt Fall */
+#define U2DOTGINT_FID  (1 << 4)        /* RXCMD OTG ID Change Interrupt Fall */
+#define U2DOTGINT_FSE  (1 << 3)        /* RXCMD OTG Session End Interrupt Fall */
+#define U2DOTGINT_FSV  (1 << 2)        /* RXCMD OTG Session Valid Interrupt Fall */
+#define U2DOTGINT_FVV  (1 << 1)        /* RXCMD OTG Vbus Valid Interrupt Fall */
+#define U2DOTGINT_FCK  (1 << 0)        /* RXCMD Carkit Interrupt Fall */
+
+#define U2DOTGUSR      (0x002C)        /* U2D OTG ULPI Status Register */
+#define U2DOTGUSR_LPA  (1 << 31)       /* ULPI Low Power Mode Active */
+#define U2DOTGUSR_S6A  (1 << 30)       /* ULPI Serial Mode (6-pin) Active */
+#define U2DOTGUSR_S3A  (1 << 29)       /* ULPI Serial Mode (3-pin) Active */
+#define U2DOTGUSR_CKA  (1 << 28)       /* ULPI Car Kit Mode Active */
+#define U2DOTGUSR_LS1  (1 << 6)        /* RXCMD Linestate 1 Status */
+#define U2DOTGUSR_LS0  (1 << 5)        /* RXCMD Linestate 0 Status */
+#define U2DOTGUSR_ID   (1 << 4)        /* OTG IDGnd Status */
+#define U2DOTGUSR_SE   (1 << 3)        /* OTG Session End Status */
+#define U2DOTGUSR_SV   (1 << 2)        /* OTG Session Valid Status */
+#define U2DOTGUSR_VV   (1 << 1)        /* OTG Vbus Valid Status */
+#define U2DOTGUSR_CK   (1 << 0)        /* Carkit Interrupt Status */
+
+#define U2DOTGUCR      (0x0030)        /* U2D OTG ULPI Control Register */
+#define U2DOTGUCR_RUN  (1    << 25)    /* RUN */
+#define U2DOTGUCR_RNW  (1    << 24)    /* Read or Write operation */
+#define U2DOTGUCR_ADDR (0x3f << 16)    /* Address of the ULPI PHY register */
+#define U2DOTGUCR_WDATA        (0xff << 8)     /* The data for a WRITE command */
+#define U2DOTGUCR_RDATA        (0xff << 0)     /* The data for a READ command */
+
+#define U2DP3CR                (0x0034)        /* U2D Port 3 Control Register */
+#define U2DP3CR_P2SS   (0x3 << 8)      /* Host Port 2 Serial Mode Select */
+#define U2DP3CR_P3SS   (0x7 << 4)      /* Host Port 3 Serial Mode Select */
+#define U2DP3CR_VPVMBEN        (0x1 << 2)      /* Host Port 3 Vp/Vm Block Enable */
+#define U2DP3CR_CFG    (0x3 << 0)      /* Host Port 3 Configuration */
+
+#define U2DCSR0                (0x0100)        /* U2D Control/Status Register - Endpoint 0 */
+#define U2DCSR0_IPA    (1 << 8)        /* IN Packet Adjusted */
+#define U2DCSR0_SA     (1 << 7)        /* SETUP Active */
+#define U2DCSR0_RNE    (1 << 6)        /* Receive FIFO Not Empty */
+#define U2DCSR0_FST    (1 << 5)        /* Force Stall */
+#define U2DCSR0_SST    (1 << 4)        /* Send Stall */
+#define U2DCSR0_DME    (1 << 3)        /* DMA Enable */
+#define U2DCSR0_FTF    (1 << 2)        /* Flush Transmit FIFO */
+#define U2DCSR0_IPR    (1 << 1)        /* IN Packet Ready */
+#define U2DCSR0_OPC    (1 << 0)        /* OUT Packet Complete */
+
+#define U2DCSR(x)      (0x0100 + ((x) << 2))   /* U2D Control/Status Register - Endpoint x */
+#define U2DCSR_BF      (1 << 10)       /* Buffer Full, for OUT eps */
+#define U2DCSR_BE      (1 << 10)       /* Buffer Empty, for IN eps */
+#define U2DCSR_DPE     (1 << 9)        /* Data Packet Error, for ISO eps only */
+#define U2DCSR_FEF     (1 << 8)        /* Flush Endpoint FIFO */
+#define U2DCSR_SP      (1 << 7)        /* Short Packet Control/Status, for OUT eps only, readonly */
+#define U2DCSR_BNE     (1 << 6)        /* Buffer Not Empty, for OUT eps */
+#define U2DCSR_BNF     (1 << 6)        /* Buffer Not Full, for IN eps */
+#define U2DCSR_FST     (1 << 5)        /* Force STALL, write 1 set */
+#define U2DCSR_SST     (1 << 4)        /* Sent STALL, write 1 clear */
+#define U2DCSR_DME     (1 << 3)        /* DMA Enable */
+#define U2DCSR_TRN     (1 << 2)        /* Tx/Rx NAK, write 1 clear */
+#define U2DCSR_PC      (1 << 1)        /* Packet Complete, write 1 clear */
+#define U2DCSR_FS      (1 << 0)        /* FIFO needs Service */
+
+#define U2DBCR0                (0x0200)                /* U2D Byte Count Register - Endpoint 0 */
+#define U2DBCR(x)      (0x0200 + ((x) << 2))   /* U2D Byte Count Register - Endpoint x */
+
+#define U2DDR0         (0x0300)                /* U2D Data Register - Endpoint 0 */
+
+#define U2DEPCR(x)     (0x0400 + ((x) << 2))   /* U2D Configuration Register - Endpoint x */
+#define U2DEPCR_EE     (1 << 0)                /* Endpoint Enable */
+#define U2DEPCR_BS_MASK        (0x3FE)                 /* Buffer Size, BS*8=FIFO size, max 8184B = 8KB */
+
+#define U2DSCA         (0x0500)                /* U2D Setup Command Address */
+#define U2DSCA_VALUE   (0x0120)
+
+#define U2DEN0         (0x0504)                /* U2D Endpoint Information Register - Endpoint 0 */
+#define U2DEN(x)       (0x0504 + ((x) << 2))   /* U2D Endpoint Information Register - Endpoint x */
+
+/* U2DMA registers */
+#define U2DMACSR0              (0x1000)        /* U2DMA Control/Status Register - Channel 0 */
+#define U2DMACSR(x)            (0x1000 + ((x) << 2))   /* U2DMA Control/Status Register - Channel x */
+#define U2DMACSR_RUN           (1 << 31)       /* Run Bit (read / write) */
+#define U2DMACSR_STOPIRQEN     (1 << 29)       /* Stop Interrupt Enable (read / write) */
+#define U2DMACSR_EORIRQEN      (1 << 28)       /* End of Receive Interrupt Enable (R/W) */
+#define U2DMACSR_EORJMPEN      (1 << 27)       /* Jump to next descriptor on EOR */
+#define U2DMACSR_EORSTOPEN     (1 << 26)       /* STOP on an EOR */
+#define U2DMACSR_RASIRQEN      (1 << 23)       /* Request After Cnannel Stopped Interrupt Enable */
+#define U2DMACSR_MASKRUN       (1 << 22)       /* Mask Run */
+#define U2DMACSR_SCEMC         (3 << 18)       /* System Bus Split Completion Error Message Class */
+#define U2DMACSR_SCEMI         (0x1f << 13)    /* System Bus Split Completion Error Message Index */
+#define U2DMACSR_BUSERRTYPE    (7 << 10)       /* PX Bus Error Type */
+#define U2DMACSR_EORINTR       (1 << 9)        /* End Of Receive */
+#define U2DMACSR_REQPEND       (1 << 8)        /* Request Pending */
+#define U2DMACSR_RASINTR       (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */
+#define U2DMACSR_STOPINTR      (1 << 3)        /* Stop Interrupt (read only) */
+#define U2DMACSR_ENDINTR       (1 << 2)        /* End Interrupt (read / write 1 clear) */
+#define U2DMACSR_STARTINTR     (1 << 1)        /* Start Interrupt (read / write 1 clear) */
+#define U2DMACSR_BUSERRINTR    (1 << 0)        /* Bus Error Interrupt (read / write 1 clear) */
+
+#define U2DMACR                (0x1080)                /* U2DMA Control Register */
+#define U2DMAINT       (0x10F0)                /* U2DMA Interrupt Register */
+
+#define U2DMABR0       (0x1100)                /* U2DMA Branch Register - Channel 0 */
+#define U2DMABR(x)      (0x1100 + (x) << 2)    /* U2DMA Branch Register - Channel x */
+
+#define U2DMADADR0      (0x1200)               /* U2DMA Descriptor Address Register - Channel 0 */
+#define U2DMADADR(x)    (0x1200 + (x) * 0x10)  /* U2DMA Descriptor Address Register - Channel x */
+
+#define U2DMADADR_STOP (1U << 0)
+
+#define U2DMASADR0     (0x1204)                /* U2DMA Source Address Register - Channel 0 */
+#define U2DMASADR(x)   (0x1204 + (x) * 0x10)   /* U2DMA Source Address Register - Channel x */
+#define U2DMATADR0     (0x1208)                /* U2DMA Target Address Register - Channel 0 */
+#define U2DMATADR(x)   (0x1208 + (x) * 0x10)   /* U2DMA Target Address Register - Channel x */
+
+#define U2DMACMDR0     (0x120C)                /* U2DMA Command Address Register - Channel 0 */
+#define U2DMACMDR(x)   (0x120C + (x) * 0x10)   /* U2DMA Command Address Register - Channel x */
+
+#define U2DMACMDR_XFRDIS       (1 << 31)       /* Transfer Direction */
+#define U2DMACMDR_STARTIRQEN   (1 << 22)       /* Start Interrupt Enable */
+#define U2DMACMDR_ENDIRQEN     (1 << 21)       /* End Interrupt Enable */
+#define U2DMACMDR_PACKCOMP     (1 << 13)       /* Packet Complete */
+#define U2DMACMDR_LEN          (0x07ff)        /* length mask (max = 2K - 1) */
+
+#endif /* __ASM_ARCH_PXA3xx_U2D_H */
index 710c493..1414b5f 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa930.h>
+#include "pxa930.h"
 #include <linux/platform_data/video-pxafb.h>
 
 #include "devices.h"
index bdc0c41..b80eab9 100644 (file)
 #include <linux/io.h>
 
 #include <asm/mach-types.h>
-#include <mach/pm.h>
+#include "pm.h"
 #include <mach/pxa2xx-regs.h>
-#include <mach/regs-rtc.h>
-#include <mach/sharpsl_pm.h>
+#include "regs-rtc.h"
+#include "sharpsl_pm.h"
 
 /*
  * Constants
diff --git a/arch/arm/mach-pxa/sharpsl_pm.h b/arch/arm/mach-pxa/sharpsl_pm.h
new file mode 100644 (file)
index 0000000..905be67
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * SharpSL Battery/PM Driver
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * 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 _MACH_SHARPSL_PM
+#define _MACH_SHARPSL_PM
+
+struct sharpsl_charger_machinfo {
+       void (*init)(void);
+       void (*exit)(void);
+       int gpio_acin;
+       int gpio_batfull;
+       int batfull_irq;
+       int gpio_batlock;
+       int gpio_fatal;
+       void (*discharge)(int);
+       void (*discharge1)(int);
+       void (*charge)(int);
+       void (*measure_temp)(int);
+       void (*presuspend)(void);
+       void (*postsuspend)(void);
+       void (*earlyresume)(void);
+       unsigned long (*read_devdata)(int);
+#define SHARPSL_BATT_VOLT       1
+#define SHARPSL_BATT_TEMP       2
+#define SHARPSL_ACIN_VOLT       3
+#define SHARPSL_STATUS_ACIN     4
+#define SHARPSL_STATUS_LOCK     5
+#define SHARPSL_STATUS_CHRGFULL 6
+#define SHARPSL_STATUS_FATAL    7
+       unsigned long (*charger_wakeup)(void);
+       int (*should_wakeup)(unsigned int resume_on_alarm);
+       void (*backlight_limit)(int);
+       int (*backlight_get_status) (void);
+       int charge_on_volt;
+       int charge_on_temp;
+       int charge_acin_high;
+       int charge_acin_low;
+       int fatal_acin_volt;
+       int fatal_noacin_volt;
+       int bat_levels;
+       struct battery_thresh *bat_levels_noac;
+       struct battery_thresh *bat_levels_acin;
+       struct battery_thresh *bat_levels_noac_bl;
+       struct battery_thresh *bat_levels_acin_bl;
+       int status_high_acin;
+       int status_low_acin;
+       int status_high_noac;
+       int status_low_noac;
+};
+
+struct battery_thresh {
+       int voltage;
+       int percentage;
+};
+
+struct battery_stat {
+       int ac_status;         /* APM AC Present/Not Present */
+       int mainbat_status;    /* APM Main Battery Status */
+       int mainbat_percent;   /* Main Battery Percentage Charge */
+       int mainbat_voltage;   /* Main Battery Voltage */
+};
+
+struct sharpsl_pm_status {
+       struct device *dev;
+       struct timer_list ac_timer;
+       struct timer_list chrg_full_timer;
+
+       int charge_mode;
+#define CHRG_ERROR    (-1)
+#define CHRG_OFF      (0)
+#define CHRG_ON       (1)
+#define CHRG_DONE     (2)
+
+       unsigned int flags;
+#define SHARPSL_SUSPENDED       (1 << 0)  /* Device is Suspended */
+#define SHARPSL_ALARM_ACTIVE    (1 << 1)  /* Alarm is for charging event (not user) */
+#define SHARPSL_BL_LIMIT        (1 << 2)  /* Backlight Intensity Limited */
+#define SHARPSL_APM_QUEUED      (1 << 3)  /* APM Event Queued */
+#define SHARPSL_DO_OFFLINE_CHRG (1 << 4)  /* Trigger the offline charger */
+
+       int full_count;
+       unsigned long charge_start_time;
+       struct sharpsl_charger_machinfo *machinfo;
+       struct battery_stat battstat;
+};
+
+extern struct sharpsl_pm_status sharpsl_pm;
+
+extern struct battery_thresh sharpsl_battery_levels_acin[];
+extern struct battery_thresh sharpsl_battery_levels_noac[];
+
+#define SHARPSL_LED_ERROR  2
+#define SHARPSL_LED_ON     1
+#define SHARPSL_LED_OFF    0
+
+void sharpsl_battery_kick(void);
+void sharpsl_pm_led(int val);
+
+/* MAX1111 Channel Definitions */
+#define MAX1111_BATT_VOLT   4u
+#define MAX1111_BATT_TEMP   2u
+#define MAX1111_ACIN_VOLT   6u
+int sharpsl_pm_pxa_read_max1111(int channel);
+
+void corgi_lcd_limit_intensity(int limit);
+#endif
index f4e2e27..825f903 100644 (file)
 #include <asm/mach/sharpsl_param.h>
 #include <asm/hardware/scoop.h>
 
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "pxa27x-udc.h"
 #include <mach/reset.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <mach/spitz.h>
-#include <mach/sharpsl_pm.h>
+#include "sharpsl_pm.h"
 #include <mach/smemc.h>
 
 #include "generic.h"
index e191f99..ea9f903 100644 (file)
@@ -25,8 +25,8 @@
 #include <mach/hardware.h>
 
 #include <mach/spitz.h>
-#include <mach/pxa27x.h>
-#include <mach/sharpsl_pm.h>
+#include "pxa27x.h"
+#include "sharpsl_pm.h"
 
 #include "generic.h"
 
index 01de542..702f4f1 100644 (file)
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/pxa27x-udc.h>
+#include "udc.h"
+#include "pxa27x-udc.h"
 #include <mach/smemc.h>
 
 #include <linux/spi/spi.h>
index 349a13a..4b38e82 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa930.h>
+#include "pxa930.h"
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/keypad-pxa27x.h>
 
index e0a5320..107f372 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/delay.h>
 #include <linux/rfkill.h>
 
-#include <mach/tosa_bt.h>
+#include "tosa_bt.h"
 
 static void tosa_bt_on(struct tosa_bt_data *data)
 {
index e6e27c0..13de660 100644 (file)
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/reset.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/tosa_bt.h>
+#include "udc.h"
+#include "tosa_bt.h"
 #include <mach/audio.h>
 #include <mach/smemc.h>
 
diff --git a/arch/arm/mach-pxa/tosa_bt.h b/arch/arm/mach-pxa/tosa_bt.h
new file mode 100644 (file)
index 0000000..efc3c3d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Tosa bluetooth built-in chip control.
+ *
+ * Later it may be shared with some other platforms.
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * 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 TOSA_BT_H
+#define TOSA_BT_H
+
+struct tosa_bt_data {
+       int gpio_pwr;
+       int gpio_reset;
+};
+
+#endif
+
index 066e3a2..ea78bc5 100644 (file)
@@ -41,7 +41,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/trizeps4.h>
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
diff --git a/arch/arm/mach-pxa/udc.h b/arch/arm/mach-pxa/udc.h
new file mode 100644 (file)
index 0000000..9a827e3
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * arch/arm/mach-pxa/include/mach/udc.h
+ *
+ */
+#include <linux/platform_data/pxa2xx_udc.h>
+
+extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
+
index 7ecc61a..8e89d91 100644 (file)
 #include <linux/mtd/physmap.h>
 #include <linux/syscore_ops.h>
 
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <mach/regs-uart.h>
 #include <linux/platform_data/pcmcia-pxa2xx_viper.h>
-#include <mach/viper.h>
+#include "viper.h"
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-pxa/viper.h b/arch/arm/mach-pxa/viper.h
new file mode 100644 (file)
index 0000000..5f5fbf1
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-pxa/include/mach/viper.h
+ *
+ * Author:     Ian Campbell
+ * Created:    Feb 03, 2003
+ * Copyright:  Arcom Control Systems.
+ *
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ *                           <marc.zyngier@altran.com>
+ *
+ * Created based on lubbock.h:
+ *  Author:    Nicolas Pitre
+ *  Created:   Jun 15, 2001
+ *  Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_VIPER_H
+#define ARCH_VIPER_H
+
+#define VIPER_BOOT_PHYS                PXA_CS0_PHYS
+#define VIPER_FLASH_PHYS       PXA_CS1_PHYS
+#define VIPER_ETH_PHYS         PXA_CS2_PHYS
+#define VIPER_USB_PHYS         PXA_CS3_PHYS
+#define VIPER_ETH_DATA_PHYS    PXA_CS4_PHYS
+#define VIPER_CPLD_PHYS                PXA_CS5_PHYS
+
+#define VIPER_CPLD_BASE                (0xf0000000)
+#define VIPER_PC104IO_BASE     (0xf1000000)
+#define VIPER_USB_BASE         (0xf1800000)
+
+#define VIPER_ETH_GPIO         (0)
+#define VIPER_CPLD_GPIO                (1)
+#define VIPER_USB_GPIO         (2)
+#define VIPER_UARTA_GPIO       (4)
+#define VIPER_UARTB_GPIO       (3)
+#define VIPER_CF_CD_GPIO       (32)
+#define VIPER_CF_RDY_GPIO      (8)
+#define VIPER_BCKLIGHT_EN_GPIO (9)
+#define VIPER_LCD_EN_GPIO      (10)
+#define VIPER_PSU_DATA_GPIO    (6)
+#define VIPER_PSU_CLK_GPIO     (11)
+#define VIPER_UART_SHDN_GPIO   (12)
+#define VIPER_BRIGHTNESS_GPIO  (16)
+#define VIPER_PSU_nCS_LD_GPIO  (19)
+#define VIPER_UPS_GPIO         (20)
+#define VIPER_CF_POWER_GPIO    (82)
+#define VIPER_TPM_I2C_SDA_GPIO (26)
+#define VIPER_TPM_I2C_SCL_GPIO (27)
+#define VIPER_RTC_I2C_SDA_GPIO (83)
+#define VIPER_RTC_I2C_SCL_GPIO (84)
+
+#define VIPER_CPLD_P2V(x)      ((x) - VIPER_CPLD_PHYS + VIPER_CPLD_BASE)
+#define VIPER_CPLD_V2P(x)      ((x) - VIPER_CPLD_BASE + VIPER_CPLD_PHYS)
+
+#ifndef __ASSEMBLY__
+#  define __VIPER_CPLD_REG(x)  (*((volatile u16 *)VIPER_CPLD_P2V(x)))
+#endif
+
+/* board level registers in the CPLD: (offsets from CPLD_BASE) ... */
+
+/* ... Physical addresses */
+#define _VIPER_LO_IRQ_STATUS   (VIPER_CPLD_PHYS + 0x100000)
+#define _VIPER_ICR_PHYS                (VIPER_CPLD_PHYS + 0x100002)
+#define _VIPER_HI_IRQ_STATUS   (VIPER_CPLD_PHYS + 0x100004)
+#define _VIPER_VERSION_PHYS    (VIPER_CPLD_PHYS + 0x100006)
+#define VIPER_UARTA_PHYS       (VIPER_CPLD_PHYS + 0x300010)
+#define VIPER_UARTB_PHYS       (VIPER_CPLD_PHYS + 0x300000)
+#define _VIPER_SRAM_BASE       (VIPER_CPLD_PHYS + 0x800000)
+
+/* ... Virtual addresses */
+#define VIPER_LO_IRQ_STATUS    __VIPER_CPLD_REG(_VIPER_LO_IRQ_STATUS)
+#define VIPER_HI_IRQ_STATUS    __VIPER_CPLD_REG(_VIPER_HI_IRQ_STATUS)
+#define VIPER_VERSION          __VIPER_CPLD_REG(_VIPER_VERSION_PHYS)
+#define VIPER_ICR              __VIPER_CPLD_REG(_VIPER_ICR_PHYS)
+
+/* Decode VIPER_VERSION register */
+#define VIPER_CPLD_REVISION(x) (((x) >> 5) & 0x7)
+#define VIPER_BOARD_VERSION(x) (((x) >> 3) & 0x3)
+#define VIPER_BOARD_ISSUE(x)   (((x) >> 0) & 0x7)
+
+/* Interrupt and Configuration Register (VIPER_ICR) */
+/* This is a write only register. Only CF_RST is used under Linux */
+
+#define VIPER_ICR_RETRIG       (1 << 0)
+#define VIPER_ICR_AUTO_CLR     (1 << 1)
+#define VIPER_ICR_R_DIS                (1 << 2)
+#define VIPER_ICR_CF_RST       (1 << 3)
+
+#endif
+
index 54122a9..c006ee9 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/audio.h>
 #include <mach/vpac270.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pxa27x-udc.h>
-#include <mach/udc.h>
+#include "pxa27x-udc.h"
+#include "udc.h"
 #include <linux/platform_data/ata-pxa.h>
 
 #include "generic.h"
index 13b1d45..3f06cd9 100644 (file)
@@ -28,7 +28,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
 #include <mach/smemc.h>
 
 #include "generic.h"
index d9899d7..510e533 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/pxa27x.h>
-#include <mach/mfp-pxa27x.h>
+#include "pxa27x.h"
+#include "mfp-pxa27x.h"
 #include <mach/z2.h>
 #include <linux/platform_data/video-pxafb.h>
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/keypad-pxa27x.h>
-#include <mach/pm.h>
+#include "pm.h"
 
 #include "generic.h"
 #include "devices.h"
index 30e62a3..515b7dd 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
 #include <mach/regs-uart.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/mmc-pxamci.h>
-#include <mach/pxa27x-udc.h>
-#include <mach/udc.h>
+#include "pxa27x-udc.h"
+#include "udc.h"
 #include <linux/platform_data/video-pxafb.h>
-#include <mach/pm.h>
+#include "pm.h"
 #include <mach/audio.h>
 #include <linux/platform_data/pcmcia-pxa2xx_viper.h>
-#include <mach/zeus.h>
+#include "zeus.h"
 #include <mach/smemc.h>
 
 #include "generic.h"
diff --git a/arch/arm/mach-pxa/zeus.h b/arch/arm/mach-pxa/zeus.h
new file mode 100644 (file)
index 0000000..56024f8
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  arch/arm/mach-pxa/include/mach/zeus.h
+ *
+ *  Author:    David Vrabel
+ *  Created:   Sept 28, 2005
+ *  Copyright: Arcom Control Systems Ltd.
+ *
+ *  Maintained by: Marc Zyngier <maz@misterjones.org>
+ *
+ * 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 _MACH_ZEUS_H
+#define _MACH_ZEUS_H
+
+#define ZEUS_NR_IRQS           (IRQ_BOARD_START + 48)
+
+/* Physical addresses */
+#define ZEUS_FLASH_PHYS                PXA_CS0_PHYS
+#define ZEUS_ETH0_PHYS         PXA_CS1_PHYS
+#define ZEUS_ETH1_PHYS         PXA_CS2_PHYS
+#define ZEUS_CPLD_PHYS         (PXA_CS4_PHYS+0x2000000)
+#define ZEUS_SRAM_PHYS         PXA_CS5_PHYS
+#define ZEUS_PC104IO_PHYS      (0x30000000)
+
+#define ZEUS_CPLD_VERSION_PHYS (ZEUS_CPLD_PHYS + 0x00000000)
+#define ZEUS_CPLD_ISA_IRQ_PHYS (ZEUS_CPLD_PHYS + 0x00800000)
+#define ZEUS_CPLD_CONTROL_PHYS (ZEUS_CPLD_PHYS + 0x01000000)
+#define ZEUS_CPLD_EXTWDOG_PHYS (ZEUS_CPLD_PHYS + 0x01800000)
+
+/* GPIOs */
+#define ZEUS_AC97_GPIO         0
+#define ZEUS_WAKEUP_GPIO       1
+#define ZEUS_UARTA_GPIO                9
+#define ZEUS_UARTB_GPIO                10
+#define ZEUS_UARTC_GPIO                12
+#define ZEUS_UARTD_GPIO                11
+#define ZEUS_ETH0_GPIO         14
+#define ZEUS_ISA_GPIO          17
+#define ZEUS_BKLEN_GPIO                19
+#define ZEUS_USB2_PWREN_GPIO   22
+#define ZEUS_PTT_GPIO          27
+#define ZEUS_CF_CD_GPIO         35
+#define ZEUS_MMC_WP_GPIO        52
+#define ZEUS_MMC_CD_GPIO        53
+#define ZEUS_EXTGPIO_GPIO      91
+#define ZEUS_CF_PWEN_GPIO       97
+#define ZEUS_CF_RDY_GPIO        99
+#define ZEUS_LCD_EN_GPIO       101
+#define ZEUS_ETH1_GPIO         113
+#define ZEUS_CAN_GPIO          116
+
+#define ZEUS_EXT0_GPIO_BASE    128
+#define ZEUS_EXT1_GPIO_BASE    160
+#define ZEUS_USER_GPIO_BASE    192
+
+#define ZEUS_EXT0_GPIO(x)      (ZEUS_EXT0_GPIO_BASE + (x))
+#define ZEUS_EXT1_GPIO(x)      (ZEUS_EXT1_GPIO_BASE + (x))
+#define ZEUS_USER_GPIO(x)      (ZEUS_USER_GPIO_BASE + (x))
+
+#define        ZEUS_CAN_SHDN_GPIO      ZEUS_EXT1_GPIO(2)
+
+/*
+ * CPLD registers:
+ * Only 4 registers, but spread over a 32MB address space.
+ * Be gentle, and remap that over 32kB...
+ */
+
+#define ZEUS_CPLD              IOMEM(0xf0000000)
+#define ZEUS_CPLD_VERSION      (ZEUS_CPLD + 0x0000)
+#define ZEUS_CPLD_ISA_IRQ      (ZEUS_CPLD + 0x1000)
+#define ZEUS_CPLD_CONTROL      (ZEUS_CPLD + 0x2000)
+
+/* CPLD register bits */
+#define ZEUS_CPLD_CONTROL_CF_RST        0x01
+
+#define ZEUS_PC104IO           IOMEM(0xf1000000)
+
+#define ZEUS_SRAM_SIZE         (256 * 1024)
+
+#endif
+
+
index e20359a..3642389 100644 (file)
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/pxa3xx.h>
+#include "pxa3xx.h"
 #include <mach/audio.h>
 #include <linux/platform_data/video-pxafb.h>
-#include <mach/zylonite.h>
+#include "zylonite.h"
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/keypad-pxa27x.h>
diff --git a/arch/arm/mach-pxa/zylonite.h b/arch/arm/mach-pxa/zylonite.h
new file mode 100644 (file)
index 0000000..ecca976
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __ASM_ARCH_ZYLONITE_H
+#define __ASM_ARCH_ZYLONITE_H
+
+#define ZYLONITE_ETH_PHYS      0x14000000
+
+#define EXT_GPIO(x)            (128 + (x))
+
+#define ZYLONITE_NR_IRQS       (IRQ_BOARD_START + 32)
+
+/* the following variables are processor specific and initialized
+ * by the corresponding zylonite_pxa3xx_init()
+ */
+extern int gpio_eth_irq;
+extern int gpio_debug_led1;
+extern int gpio_debug_led2;
+
+extern int wm9713_irq;
+
+extern int lcd_id;
+extern int lcd_orientation;
+
+#ifdef CONFIG_MACH_ZYLONITE300
+extern void zylonite_pxa300_init(void);
+#else
+static inline void zylonite_pxa300_init(void)
+{
+       if (cpu_is_pxa300() || cpu_is_pxa310())
+               panic("%s: PXA300/PXA310 not supported\n", __func__);
+}
+#endif
+
+#ifdef CONFIG_MACH_ZYLONITE320
+extern void zylonite_pxa320_init(void);
+#else
+static inline void zylonite_pxa320_init(void)
+{
+       if (cpu_is_pxa320())
+               panic("%s: PXA320 not supported\n", __func__);
+}
+#endif
+
+#endif /* __ASM_ARCH_ZYLONITE_H */
index 869bce7..e247acf 100644 (file)
@@ -21,8 +21,8 @@
 #include <linux/platform_data/pca953x.h>
 #include <linux/gpio.h>
 
-#include <mach/pxa300.h>
-#include <mach/zylonite.h>
+#include "pxa300.h"
+#include "zylonite.h"
 
 #include "generic.h"
 
index 9942bac..47961ae 100644 (file)
@@ -18,8 +18,8 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 
-#include <mach/pxa320.h>
-#include <mach/zylonite.h>
+#include "pxa320.h"
+#include "zylonite.h"
 
 #include "generic.h"
 
index 2256cd1..7349450 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_QCOM
-       bool "Qualcomm Support" if ARCH_MULTI_V7
+       bool "Qualcomm Support"
+       depends on ARCH_MULTI_V7
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_GIC
        select ARM_AMBA
index 9b00123..5494c9e 100644 (file)
@@ -332,7 +332,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
        }
 }
 
-static struct smp_operations smp_msm8660_ops __initdata = {
+static const struct smp_operations smp_msm8660_ops __initconst = {
        .smp_prepare_cpus       = qcom_smp_prepare_cpus,
        .smp_secondary_init     = qcom_secondary_init,
        .smp_boot_secondary     = msm8660_boot_secondary,
@@ -342,7 +342,7 @@ static struct smp_operations smp_msm8660_ops __initdata = {
 };
 CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
 
-static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
+static const struct smp_operations qcom_smp_kpssv1_ops __initconst = {
        .smp_prepare_cpus       = qcom_smp_prepare_cpus,
        .smp_secondary_init     = qcom_secondary_init,
        .smp_boot_secondary     = kpssv1_boot_secondary,
@@ -352,7 +352,7 @@ static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
 };
 CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
 
-static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
+static const struct smp_operations qcom_smp_kpssv2_ops __initconst = {
        .smp_prepare_cpus       = qcom_smp_prepare_cpus,
        .smp_secondary_init     = qcom_secondary_init,
        .smp_boot_secondary     = kpssv2_boot_secondary,
index 565925f..def40a0 100644 (file)
@@ -1,13 +1,29 @@
-menu "RealView platform type"
-       depends on ARCH_REALVIEW
+menuconfig ARCH_REALVIEW
+       bool "ARM Ltd. RealView family" if ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
+       select ARM_AMBA
+       select ARM_TIMER_SP804
+       select COMMON_CLK_VERSATILE
+       select GPIO_PL061 if GPIOLIB
+       select ICST
+       select PLAT_VERSATILE
+       select PLAT_VERSATILE_SCHED_CLOCK
+       help
+         This enables support for ARM Ltd RealView boards.
+
+if ARCH_REALVIEW
 
 config REALVIEW_DT
        bool "Support RealView(R) Device Tree based boot"
        select ARM_GIC
+       select CLK_SP810
+       select HAVE_SMP
+       select ICST
+       select MACH_REALVIEW_EB if ARCH_MULTI_V5
        select MFD_SYSCON
        select POWER_RESET
        select POWER_RESET_VERSATILE
        select POWER_SUPPLY
+       select SMP_ON_UP if SMP
        select SOC_REALVIEW
        select USE_OF
        help
@@ -17,14 +33,32 @@ config REALVIEW_DT
 config MACH_REALVIEW_EB
        bool "Support RealView(R) Emulation Baseboard"
        select ARM_GIC
+       select CPU_ARM926T if ARCH_MULTI_V5
        help
          Include support for the ARM(R) RealView(R) Emulation Baseboard
-         platform.
+         platform. On an ARMv5 kernel, this will include support for
+         the ARM926EJ-S core tile, while on an ARMv6/v7 kernel, at least
+         one of the ARM1136, ARM1176, ARM11MPCore or Cortex-A9MPCore
+         core tile options should be enabled.
+
+config REALVIEW_EB_ARM1136
+       bool "Support ARM1136J(F)-S Tile"
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+       select CPU_V6
+       help
+         Enable support for the ARM1136 tile fitted to the
+         Realview(R) Emulation Baseboard platform.
+
+config REALVIEW_EB_ARM1176
+       bool "Support ARM1176JZ(F)-S Tile"
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+       help
+         Enable support for the ARM1176 tile fitted to the
+         Realview(R) Emulation Baseboard platform.
 
 config REALVIEW_EB_A9MP
        bool "Support Multicore Cortex-A9 Tile"
-       depends on MACH_REALVIEW_EB
-       select CPU_V7
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V7
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_SMP
@@ -35,9 +69,7 @@ config REALVIEW_EB_A9MP
 
 config REALVIEW_EB_ARM11MP
        bool "Support ARM11MPCore Tile"
-       depends on MACH_REALVIEW_EB
-       select ARCH_HAS_BARRIERS if SMP
-       select CPU_V6K
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_SMP
@@ -48,7 +80,7 @@ config REALVIEW_EB_ARM11MP
 
 config REALVIEW_EB_ARM11MP_REVB
        bool "Support ARM11MPCore RevB Tile"
-       depends on REALVIEW_EB_ARM11MP
+       depends on REALVIEW_EB_ARM11MP && ARCH_MULTI_V6
        help
          Enable support for the ARM11MPCore Revision B tile on the
          Realview(R) Emulation Baseboard platform. Since there are device
@@ -57,9 +89,8 @@ config REALVIEW_EB_ARM11MP_REVB
 
 config MACH_REALVIEW_PB11MP
        bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
-       select ARCH_HAS_BARRIERS if SMP
+       depends on ARCH_MULTI_V6
        select ARM_GIC
-       select CPU_V6K
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_PATA_PLATFORM
@@ -73,6 +104,7 @@ config MACH_REALVIEW_PB11MP
 # ARMv6 CPU without K extensions, but does have the new exclusive ops
 config MACH_REALVIEW_PB1176
        bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
+       depends on ARCH_MULTI_V6
        select ARM_GIC
        select CPU_V6
        select HAVE_TCM
@@ -92,8 +124,8 @@ config REALVIEW_PB1176_SECURE_FLASH
 
 config MACH_REALVIEW_PBA8
        bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
+       depends on ARCH_MULTI_V7
        select ARM_GIC
-       select CPU_V7
        select HAVE_PATA_PLATFORM
        help
          Include support for the ARM(R) RealView Platform Baseboard for
@@ -101,15 +133,15 @@ config MACH_REALVIEW_PBA8
          support for PCI-E and Compact Flash.
 
 config MACH_REALVIEW_PBX
-       bool "Support RealView(R) Platform Baseboard Explore"
-       select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
+       bool "Support RealView(R) Platform Baseboard Explore for Cortex-A9"
+       depends on ARCH_MULTI_V7
        select ARM_GIC
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_PATA_PLATFORM
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
-       select ZONE_DMA if SPARSEMEM
+       select ZONE_DMA
        help
          Include support for the ARM(R) RealView(R) Platform Baseboard
          Explore.
@@ -124,6 +156,6 @@ config REALVIEW_HIGH_PHYS_OFFSET
          the board supports 512MB of RAM, this option allows the
          memory to be accessed contiguously at the high physical
          offset. On the PBX board, disabling this option allows 1GB of
-         RAM to be used with SPARSEMEM.
+         RAM to be used with HIGHMEM.
 
-endmenu
+endif
index e07fdf7..dae8d86 100644 (file)
@@ -1,13 +1,19 @@
 #
 # Makefile for the linux kernel.
 #
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
+       -I$(srctree)/arch/arm/plat-versatile/include
 
 obj-y                                  := core.o
 obj-$(CONFIG_REALVIEW_DT)              += realview-dt.o
+obj-$(CONFIG_SMP)                      += platsmp-dt.o
+
+ifdef CONFIG_ATAGS
 obj-$(CONFIG_MACH_REALVIEW_EB)         += realview_eb.o
 obj-$(CONFIG_MACH_REALVIEW_PB11MP)     += realview_pb11mp.o
 obj-$(CONFIG_MACH_REALVIEW_PB1176)     += realview_pb1176.o
 obj-$(CONFIG_MACH_REALVIEW_PBA8)       += realview_pba8.o
 obj-$(CONFIG_MACH_REALVIEW_PBX)                += realview_pbx.o
 obj-$(CONFIG_SMP)                      += platsmp.o
+endif
 obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
diff --git a/arch/arm/mach-realview/board-eb.h b/arch/arm/mach-realview/board-eb.h
new file mode 100644 (file)
index 0000000..a850ae6
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_EB_H
+#define __ASM_ARCH_BOARD_EB_H
+
+#include "platform.h"
+
+/*
+ * RealView EB + ARM11MPCore peripheral addresses
+ */
+#define REALVIEW_EB_UART0_BASE         0x10009000      /* UART 0 */
+#define REALVIEW_EB_UART1_BASE         0x1000A000      /* UART 1 */
+#define REALVIEW_EB_UART2_BASE         0x1000B000      /* UART 2 */
+#define REALVIEW_EB_UART3_BASE         0x1000C000      /* UART 3 */
+#define REALVIEW_EB_SSP_BASE           0x1000D000      /* Synchronous Serial Port */
+#define REALVIEW_EB_WATCHDOG_BASE      0x10010000      /* watchdog interface */
+#define REALVIEW_EB_TIMER0_1_BASE      0x10011000      /* Timer 0 and 1 */
+#define REALVIEW_EB_TIMER2_3_BASE      0x10012000      /* Timer 2 and 3 */
+#define REALVIEW_EB_GPIO0_BASE         0x10013000      /* GPIO port 0 */
+#define REALVIEW_EB_RTC_BASE           0x10017000      /* Real Time Clock */
+#define REALVIEW_EB_CLCD_BASE          0x10020000      /* CLCD */
+#define REALVIEW_EB_GIC_CPU_BASE       0x10040000      /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB_GIC_DIST_BASE      0x10041000      /* Generic interrupt controller distributor */
+#define REALVIEW_EB_SMC_BASE           0x10080000      /* Static memory controller */
+
+#define REALVIEW_EB_FLASH_BASE         0x40000000
+#define REALVIEW_EB_FLASH_SIZE         SZ_64M
+#define REALVIEW_EB_ETH_BASE           0x4E000000      /* Ethernet */
+#define REALVIEW_EB_USB_BASE           0x4F000000      /* USB */
+
+#ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB
+#define REALVIEW_EB11MP_PRIV_MEM_BASE  0x10100000
+#define REALVIEW_EB11MP_L220_BASE      0x10102000      /* L220 registers */
+#define REALVIEW_EB11MP_SYS_PLD_CTRL1  0xD8            /* Register offset for MPCore sysctl */
+#else
+#define REALVIEW_EB11MP_PRIV_MEM_BASE  0x1F000000
+#define REALVIEW_EB11MP_L220_BASE      0x1F002000      /* L220 registers */
+#define REALVIEW_EB11MP_SYS_PLD_CTRL1  0x74            /* Register offset for MPCore sysctl */
+#endif
+
+#define REALVIEW_EB11MP_PRIV_MEM_SIZE  SZ_8K
+#define REALVIEW_EB11MP_PRIV_MEM_OFF(x)        (REALVIEW_EB11MP_PRIV_MEM_BASE + (x))
+
+#define REALVIEW_EB11MP_SCU_BASE       REALVIEW_EB11MP_PRIV_MEM_OFF(0)         /* SCU registers */
+#define REALVIEW_EB11MP_GIC_CPU_BASE   REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100)    /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB11MP_TWD_BASE       REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600)
+#define REALVIEW_EB11MP_GIC_DIST_BASE  REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000)    /* Generic interrupt controller distributor */
+
+/*
+ * Core tile identification (REALVIEW_SYS_PROCID)
+ */
+#define REALVIEW_EB_PROC_MASK          0xFF000000
+#define REALVIEW_EB_PROC_ARM7TDMI      0x00000000
+#define REALVIEW_EB_PROC_ARM9          0x02000000
+#define REALVIEW_EB_PROC_ARM11         0x04000000
+#define REALVIEW_EB_PROC_ARM11MP       0x06000000
+#define REALVIEW_EB_PROC_A9MP          0x0C000000
+
+#define check_eb_proc(proc_type)                                               \
+       ((readl(__io_address(REALVIEW_SYS_PROCID)) & REALVIEW_EB_PROC_MASK)     \
+        == proc_type)
+
+#ifdef CONFIG_REALVIEW_EB_ARM11MP
+#define core_tile_eb11mp()     check_eb_proc(REALVIEW_EB_PROC_ARM11MP)
+#else
+#define core_tile_eb11mp()     0
+#endif
+
+#ifdef CONFIG_REALVIEW_EB_A9MP
+#define core_tile_a9mp()       check_eb_proc(REALVIEW_EB_PROC_A9MP)
+#else
+#define core_tile_a9mp()       0
+#endif
+
+#define machine_is_realview_eb_mp() \
+       (machine_is_realview_eb() && (core_tile_eb11mp() || core_tile_a9mp()))
+
+#endif /* __ASM_ARCH_BOARD_EB_H */
diff --git a/arch/arm/mach-realview/board-pb1176.h b/arch/arm/mach-realview/board-pb1176.h
new file mode 100644 (file)
index 0000000..29c04a9
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_PB1176_H
+#define __ASM_ARCH_BOARD_PB1176_H
+
+#include "platform.h"
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PB1176_UART4_BASE             0x10009000 /* UART 4 */
+#define REALVIEW_PB1176_SCTL_BASE              0x10100000 /* System controller */
+#define REALVIEW_PB1176_SMC_BASE               0x10111000 /* SMC */
+#define REALVIEW_PB1176_DMC_BASE               0x10109000 /* DMC configuration */
+#define REALVIEW_PB1176_SDRAM67_BASE           0x70000000 /* SDRAM banks 6 and 7 */
+#define REALVIEW_PB1176_FLASH_BASE             0x30000000
+#define REALVIEW_PB1176_FLASH_SIZE             SZ_64M
+#define REALVIEW_PB1176_SEC_FLASH_BASE         0x3C000000 /* Secure flash */
+#define REALVIEW_PB1176_SEC_FLASH_SIZE         SZ_64M
+
+#define REALVIEW_PB1176_TIMER0_1_BASE          0x10104000 /* Timer 0 and 1 */
+#define REALVIEW_PB1176_TIMER2_3_BASE          0x10105000 /* Timer 2 and 3 */
+#define REALVIEW_PB1176_TIMER4_5_BASE          0x10106000 /* Timer 4 and 5 */
+#define REALVIEW_PB1176_WATCHDOG_BASE          0x10107000 /* watchdog interface */
+#define REALVIEW_PB1176_RTC_BASE               0x10108000 /* Real Time Clock */
+#define REALVIEW_PB1176_GPIO0_BASE             0x1010A000 /* GPIO port 0 */
+#define REALVIEW_PB1176_SSP_BASE               0x1010B000 /* Synchronous Serial Port */
+#define REALVIEW_PB1176_UART0_BASE             0x1010C000 /* UART 0 */
+#define REALVIEW_PB1176_UART1_BASE             0x1010D000 /* UART 1 */
+#define REALVIEW_PB1176_UART2_BASE             0x1010E000 /* UART 2 */
+#define REALVIEW_PB1176_UART3_BASE             0x1010F000 /* UART 3 */
+#define REALVIEW_PB1176_CLCD_BASE              0x10112000 /* CLCD */
+#define REALVIEW_PB1176_ETH_BASE               0x3A000000 /* Ethernet */
+#define REALVIEW_PB1176_USB_BASE               0x3B000000 /* USB */
+
+/*
+ * PCI regions
+ */
+#define REALVIEW_PB1176_PCI_BASE               0x60000000 /* PCI self config */
+#define REALVIEW_PB1176_PCI_CFG_BASE           0x61000000 /* PCI config */
+#define REALVIEW_PB1176_PCI_IO_BASE0           0x62000000 /* PCI IO region */
+#define REALVIEW_PB1176_PCI_MEM_BASE0          0x63000000 /* Memory region 1 */
+#define REALVIEW_PB1176_PCI_MEM_BASE1          0x64000000 /* Memory region 2 */
+#define REALVIEW_PB1176_PCI_MEM_BASE2          0x68000000 /* Memory region 3 */
+
+#define REALVIEW_PB1176_PCI_BASE_SIZE          0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_CFG_BASE_SIZE      0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_IO_BASE0_SIZE      0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_MEM_BASE0_SIZE     0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_MEM_BASE1_SIZE     0x04000000 /* 64MB */
+#define REALVIEW_PB1176_PCI_MEM_BASE2_SIZE     0x08000000 /* 128MB */
+
+#define REALVIEW_DC1176_GIC_CPU_BASE           0x10120000 /* GIC CPU interface, on devchip */
+#define REALVIEW_DC1176_GIC_DIST_BASE          0x10121000 /* GIC distributor, on devchip */
+#define REALVIEW_DC1176_ROM_BASE               0x10200000 /* 16KiB NRAM preudo-ROM, on devchip */
+#define REALVIEW_PB1176_GIC_CPU_BASE           0x10040000 /* GIC CPU interface, on FPGA */
+#define REALVIEW_PB1176_GIC_DIST_BASE          0x10041000 /* GIC distributor, on FPGA */
+#define REALVIEW_PB1176_L220_BASE              0x10110000 /* L220 registers */
+
+/*
+ * Control register SYS_RESETCTL Bit 8 is set to 1 to force a soft reset
+ */
+#define REALVIEW_PB1176_SYS_SOFT_RESET    0x0100
+
+#endif /* __ASM_ARCH_BOARD_PB1176_H */
diff --git a/arch/arm/mach-realview/board-pb11mp.h b/arch/arm/mach-realview/board-pb11mp.h
new file mode 100644 (file)
index 0000000..b16e6e8
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_PB11MP_H
+#define __ASM_ARCH_BOARD_PB11MP_H
+
+#include "platform.h"
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PB11MP_UART0_BASE             0x10009000      /* UART 0 */
+#define REALVIEW_PB11MP_UART1_BASE             0x1000A000      /* UART 1 */
+#define REALVIEW_PB11MP_UART2_BASE             0x1000B000      /* UART 2 */
+#define REALVIEW_PB11MP_UART3_BASE             0x1000C000      /* UART 3 */
+#define REALVIEW_PB11MP_SSP_BASE               0x1000D000      /* Synchronous Serial Port */
+#define REALVIEW_PB11MP_WATCHDOG0_BASE         0x1000F000      /* Watchdog 0 */
+#define REALVIEW_PB11MP_WATCHDOG_BASE          0x10010000      /* watchdog interface */
+#define REALVIEW_PB11MP_TIMER0_1_BASE          0x10011000      /* Timer 0 and 1 */
+#define REALVIEW_PB11MP_TIMER2_3_BASE          0x10012000      /* Timer 2 and 3 */
+#define REALVIEW_PB11MP_GPIO0_BASE             0x10013000      /* GPIO port 0 */
+#define REALVIEW_PB11MP_RTC_BASE               0x10017000      /* Real Time Clock */
+#define REALVIEW_PB11MP_TIMER4_5_BASE          0x10018000      /* Timer 4/5 */
+#define REALVIEW_PB11MP_TIMER6_7_BASE          0x10019000      /* Timer 6/7 */
+#define REALVIEW_PB11MP_SCTL_BASE              0x1001A000      /* System Controller */
+#define REALVIEW_PB11MP_CLCD_BASE              0x10020000      /* CLCD */
+#define REALVIEW_PB11MP_ONB_SRAM_BASE          0x10060000      /* On-board SRAM */
+#define REALVIEW_PB11MP_DMC_BASE               0x100E0000      /* DMC configuration */
+#define REALVIEW_PB11MP_SMC_BASE               0x100E1000      /* SMC configuration */
+#define REALVIEW_PB11MP_CAN_BASE               0x100E2000      /* CAN bus */
+#define REALVIEW_PB11MP_CF_BASE                        0x18000000      /* Compact flash */
+#define REALVIEW_PB11MP_CF_MEM_BASE            0x18003000      /* SMC for Compact flash */
+#define REALVIEW_PB11MP_GIC_CPU_BASE           0x1E000000      /* Generic interrupt controller CPU interface */
+#define REALVIEW_PB11MP_FLASH0_BASE            0x40000000
+#define REALVIEW_PB11MP_FLASH0_SIZE            SZ_64M
+#define REALVIEW_PB11MP_FLASH1_BASE            0x44000000
+#define REALVIEW_PB11MP_FLASH1_SIZE            SZ_64M
+#define REALVIEW_PB11MP_ETH_BASE               0x4E000000      /* Ethernet */
+#define REALVIEW_PB11MP_USB_BASE               0x4F000000      /* USB */
+#define REALVIEW_PB11MP_GIC_DIST_BASE          0x1E001000      /* Generic interrupt controller distributor */
+#define REALVIEW_PB11MP_LT_BASE                        0xC0000000      /* Logic Tile expansion */
+#define REALVIEW_PB11MP_SDRAM6_BASE            0x70000000      /* SDRAM bank 6 256MB */
+#define REALVIEW_PB11MP_SDRAM7_BASE            0x80000000      /* SDRAM bank 7 256MB */
+
+#define REALVIEW_PB11MP_SYS_PLD_CTRL1          0x74
+
+/*
+ * PB11MPCore PCI regions
+ */
+#define REALVIEW_PB11MP_PCI_BASE               0x90040000      /* PCI-X Unit base */
+#define REALVIEW_PB11MP_PCI_IO_BASE            0x90050000      /* IO Region on AHB */
+#define REALVIEW_PB11MP_PCI_MEM_BASE           0xA0000000      /* MEM Region on AHB */
+
+#define REALVIEW_PB11MP_PCI_BASE_SIZE          0x10000         /* 16 Kb */
+#define REALVIEW_PB11MP_PCI_IO_SIZE            0x1000          /* 4 Kb */
+#define REALVIEW_PB11MP_PCI_MEM_SIZE           0x20000000      /* 512 MB */
+
+/*
+ * Testchip peripheral and fpga gic regions
+ */
+#define REALVIEW_TC11MP_PRIV_MEM_BASE          0x1F000000
+#define REALVIEW_TC11MP_PRIV_MEM_SIZE          SZ_8K
+#define REALVIEW_TC11MP_SCU_BASE               0x1F000000      /* IRQ, Test chip */
+#define REALVIEW_TC11MP_GIC_CPU_BASE           0x1F000100      /* Test chip interrupt controller CPU interface */
+#define REALVIEW_TC11MP_TWD_BASE               0x1F000600
+#define REALVIEW_TC11MP_GIC_DIST_BASE          0x1F001000      /* Test chip interrupt controller distributor */
+#define REALVIEW_TC11MP_L220_BASE              0x1F002000      /* L220 registers */
+
+ /*
+ * Values for REALVIEW_SYS_RESET_CTRL
+ */
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR    0x01
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT   0x02
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET     0x03
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET     0x04
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR          0x05
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC          0x06
+
+#define REALVIEW_PB11MP_SYS_CTRL_LED         (1 << 0)
+
+#endif /* __ASM_ARCH_BOARD_PB11MP_H */
diff --git a/arch/arm/mach-realview/board-pba8.h b/arch/arm/mach-realview/board-pba8.h
new file mode 100644 (file)
index 0000000..6a1391f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_PBA8_H
+#define __ASM_ARCH_BOARD_PBA8_H
+
+#include "platform.h"
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PBA8_UART0_BASE               0x10009000      /* UART 0 */
+#define REALVIEW_PBA8_UART1_BASE               0x1000A000      /* UART 1 */
+#define REALVIEW_PBA8_UART2_BASE               0x1000B000      /* UART 2 */
+#define REALVIEW_PBA8_UART3_BASE               0x1000C000      /* UART 3 */
+#define REALVIEW_PBA8_SSP_BASE                 0x1000D000      /* Synchronous Serial Port */
+#define REALVIEW_PBA8_WATCHDOG0_BASE           0x1000F000      /* Watchdog 0 */
+#define REALVIEW_PBA8_WATCHDOG_BASE            0x10010000      /* watchdog interface */
+#define REALVIEW_PBA8_TIMER0_1_BASE            0x10011000      /* Timer 0 and 1 */
+#define REALVIEW_PBA8_TIMER2_3_BASE            0x10012000      /* Timer 2 and 3 */
+#define REALVIEW_PBA8_GPIO0_BASE               0x10013000      /* GPIO port 0 */
+#define REALVIEW_PBA8_RTC_BASE                 0x10017000      /* Real Time Clock */
+#define REALVIEW_PBA8_TIMER4_5_BASE            0x10018000      /* Timer 4/5 */
+#define REALVIEW_PBA8_TIMER6_7_BASE            0x10019000      /* Timer 6/7 */
+#define REALVIEW_PBA8_SCTL_BASE                        0x1001A000      /* System Controller */
+#define REALVIEW_PBA8_CLCD_BASE                        0x10020000      /* CLCD */
+#define REALVIEW_PBA8_ONB_SRAM_BASE            0x10060000      /* On-board SRAM */
+#define REALVIEW_PBA8_DMC_BASE                 0x100E0000      /* DMC configuration */
+#define REALVIEW_PBA8_SMC_BASE                 0x100E1000      /* SMC configuration */
+#define REALVIEW_PBA8_CAN_BASE                 0x100E2000      /* CAN bus */
+#define REALVIEW_PBA8_GIC_CPU_BASE             0x1E000000      /* Generic interrupt controller CPU interface */
+#define REALVIEW_PBA8_FLASH0_BASE              0x40000000
+#define REALVIEW_PBA8_FLASH0_SIZE              SZ_64M
+#define REALVIEW_PBA8_FLASH1_BASE              0x44000000
+#define REALVIEW_PBA8_FLASH1_SIZE              SZ_64M
+#define REALVIEW_PBA8_ETH_BASE                 0x4E000000      /* Ethernet */
+#define REALVIEW_PBA8_USB_BASE                 0x4F000000      /* USB */
+#define REALVIEW_PBA8_GIC_DIST_BASE            0x1E001000      /* Generic interrupt controller distributor */
+#define REALVIEW_PBA8_LT_BASE                  0xC0000000      /* Logic Tile expansion */
+#define REALVIEW_PBA8_SDRAM6_BASE              0x70000000      /* SDRAM bank 6 256MB */
+#define REALVIEW_PBA8_SDRAM7_BASE              0x80000000      /* SDRAM bank 7 256MB */
+
+#define REALVIEW_PBA8_SYS_PLD_CTRL1            0x74
+
+/*
+ * PBA8 PCI regions
+ */
+#define REALVIEW_PBA8_PCI_BASE                 0x90040000      /* PCI-X Unit base */
+#define REALVIEW_PBA8_PCI_IO_BASE              0x90050000      /* IO Region on AHB */
+#define REALVIEW_PBA8_PCI_MEM_BASE             0xA0000000      /* MEM Region on AHB */
+
+#define REALVIEW_PBA8_PCI_BASE_SIZE            0x10000         /* 16 Kb */
+#define REALVIEW_PBA8_PCI_IO_SIZE              0x1000          /* 4 Kb */
+#define REALVIEW_PBA8_PCI_MEM_SIZE             0x20000000      /* 512 MB */
+
+#endif /* __ASM_ARCH_BOARD_PBA8_H */
diff --git a/arch/arm/mach-realview/board-pbx.h b/arch/arm/mach-realview/board-pbx.h
new file mode 100644 (file)
index 0000000..5cda480
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2009 ARM Limited
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_BOARD_PBX_H
+#define __ASM_ARCH_BOARD_PBX_H
+
+#include "platform.h"
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PBX_UART0_BASE                        0x10009000      /* UART 0 */
+#define REALVIEW_PBX_UART1_BASE                        0x1000A000      /* UART 1 */
+#define REALVIEW_PBX_UART2_BASE                        0x1000B000      /* UART 2 */
+#define REALVIEW_PBX_UART3_BASE                        0x1000C000      /* UART 3 */
+#define REALVIEW_PBX_SSP_BASE                  0x1000D000      /* Synchronous Serial Port */
+#define REALVIEW_PBX_WATCHDOG0_BASE            0x1000F000      /* Watchdog 0 */
+#define REALVIEW_PBX_WATCHDOG_BASE             0x10010000      /* watchdog interface */
+#define REALVIEW_PBX_TIMER0_1_BASE             0x10011000      /* Timer 0 and 1 */
+#define REALVIEW_PBX_TIMER2_3_BASE             0x10012000      /* Timer 2 and 3 */
+#define REALVIEW_PBX_GPIO0_BASE                        0x10013000      /* GPIO port 0 */
+#define REALVIEW_PBX_RTC_BASE                  0x10017000      /* Real Time Clock */
+#define REALVIEW_PBX_TIMER4_5_BASE             0x10018000      /* Timer 4/5 */
+#define REALVIEW_PBX_TIMER6_7_BASE             0x10019000      /* Timer 6/7 */
+#define REALVIEW_PBX_SCTL_BASE                 0x1001A000      /* System Controller */
+#define REALVIEW_PBX_CLCD_BASE                 0x10020000      /* CLCD */
+#define REALVIEW_PBX_ONB_SRAM_BASE             0x10060000      /* On-board SRAM */
+#define REALVIEW_PBX_DMC_BASE                  0x100E0000      /* DMC configuration */
+#define REALVIEW_PBX_SMC_BASE                  0x100E1000      /* SMC configuration */
+#define REALVIEW_PBX_CAN_BASE                  0x100E2000      /* CAN bus */
+#define REALVIEW_PBX_GIC_CPU_BASE              0x1E000000      /* Generic interrupt controller CPU interface */
+#define REALVIEW_PBX_FLASH0_BASE               0x40000000
+#define REALVIEW_PBX_FLASH0_SIZE               SZ_64M
+#define REALVIEW_PBX_FLASH1_BASE               0x44000000
+#define REALVIEW_PBX_FLASH1_SIZE               SZ_64M
+#define REALVIEW_PBX_ETH_BASE                  0x4E000000      /* Ethernet */
+#define REALVIEW_PBX_USB_BASE                  0x4F000000      /* USB */
+#define REALVIEW_PBX_GIC_DIST_BASE             0x1E001000      /* Generic interrupt controller distributor */
+#define REALVIEW_PBX_LT_BASE                   0xC0000000      /* Logic Tile expansion */
+#define REALVIEW_PBX_SDRAM6_BASE               0x70000000      /* SDRAM bank 6 256MB */
+#define REALVIEW_PBX_SDRAM7_BASE               0x80000000      /* SDRAM bank 7 256MB */
+
+/*
+ * Tile-specific addresses
+ */
+#define REALVIEW_PBX_TILE_SCU_BASE             0x1F000000      /* SCU registers */
+#define REALVIEW_PBX_TILE_GIC_CPU_BASE         0x1F000100      /* Private Generic interrupt controller CPU interface */
+#define REALVIEW_PBX_TILE_TWD_BASE             0x1F000600
+#define REALVIEW_PBX_TILE_TWD_PERCPU_BASE      0x1F000700
+#define REALVIEW_PBX_TILE_TWD_SIZE             0x00000100
+#define REALVIEW_PBX_TILE_GIC_DIST_BASE                0x1F001000      /* Private Generic interrupt controller distributor */
+#define REALVIEW_PBX_TILE_L220_BASE            0x1F002000      /* L220 registers */
+
+#define REALVIEW_PBX_SYS_PLD_CTRL1             0x74
+
+/*
+ * PBX PCI regions
+ */
+#define REALVIEW_PBX_PCI_BASE                  0x90040000      /* PCI-X Unit base */
+#define REALVIEW_PBX_PCI_IO_BASE               0x90050000      /* IO Region on AHB */
+#define REALVIEW_PBX_PCI_MEM_BASE              0xA0000000      /* MEM Region on AHB */
+
+#define REALVIEW_PBX_PCI_BASE_SIZE             0x10000         /* 16 Kb */
+#define REALVIEW_PBX_PCI_IO_SIZE               0x1000          /* 4 Kb */
+#define REALVIEW_PBX_PCI_MEM_SIZE              0x20000000      /* 512 MB */
+
+/*
+ * Core tile identification (REALVIEW_SYS_PROCID)
+ */
+#define REALVIEW_PBX_PROC_MASK          0xFF000000
+#define REALVIEW_PBX_PROC_ARM7TDMI      0x00000000
+#define REALVIEW_PBX_PROC_ARM9          0x02000000
+#define REALVIEW_PBX_PROC_ARM11         0x04000000
+#define REALVIEW_PBX_PROC_ARM11MP       0x06000000
+#define REALVIEW_PBX_PROC_A9MP          0x0C000000
+#define REALVIEW_PBX_PROC_A8            0x0E000000
+
+#define check_pbx_proc(proc_type)                                            \
+       ((readl(__io_address(REALVIEW_SYS_PROCID)) & REALVIEW_PBX_PROC_MASK) \
+       == proc_type)
+
+#ifdef CONFIG_MACH_REALVIEW_PBX
+#define core_tile_pbx11mp()     check_pbx_proc(REALVIEW_PBX_PROC_ARM11MP)
+#define core_tile_pbxa9mp()     check_pbx_proc(REALVIEW_PBX_PROC_A9MP)
+#define core_tile_pbxa8()       check_pbx_proc(REALVIEW_PBX_PROC_A8)
+#else
+#define core_tile_pbx11mp()     0
+#define core_tile_pbxa9mp()     0
+#define core_tile_pbxa8()       0
+#endif
+
+#endif /* __ASM_ARCH_BOARD_PBX_H */
index 44575ed..baf1745 100644 (file)
@@ -36,8 +36,7 @@
 #include <linux/memblock.h>
 
 #include <clocksource/timer-sp804.h>
-
-#include <mach/hardware.h>
+#include "hardware.h"
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/icst.h>
@@ -46,8 +45,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 
-#include <mach/platform.h>
-#include <mach/irqs.h>
+#include "platform.h"
 
 #include <plat/sched_clock.h>
 
index 868ece2..05a995e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/arm/mach-realview/core.h
- *
  *  Copyright (C) 2004 ARM Limited
  *  Copyright (C) 2000 Deep Blue Solutions Ltd
  *
@@ -54,7 +52,7 @@ extern int realview_usb_register(struct resource *res);
 extern void realview_init_early(void);
 extern void realview_fixup(struct tag *tags, char **from);
 
-extern struct smp_operations realview_smp_ops;
+extern const struct smp_operations realview_smp_ops;
 extern void realview_cpu_die(unsigned int cpu);
 
 #endif
diff --git a/arch/arm/mach-realview/hardware.h b/arch/arm/mach-realview/hardware.h
new file mode 100644 (file)
index 0000000..957a230
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  This file contains the hardware definitions of the RealView boards.
+ *
+ *  Copyright (C) 2003 ARM Limited.
+ *
+ * This program is free software; 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_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
+/*
+ * Statically mapped addresses:
+ *
+ * 10xx xxxx -> fbxx xxxx
+ * 1exx xxxx -> fdxx xxxx
+ * 1fxx xxxx -> fexx xxxx
+ */
+#define IO_ADDRESS(x)          (((x) & 0x03ffffff) + 0xfb000000)
+#else
+#define IO_ADDRESS(x)          (x)
+#endif
+#define __io_address(n)                IOMEM(IO_ADDRESS(n))
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/barriers.h b/arch/arm/mach-realview/include/mach/barriers.h
deleted file mode 100644 (file)
index 9a73219..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * Barriers redefined for RealView ARM11MPCore platforms with L220 cache
- * controller to work around hardware errata causing the outer_sync()
- * operation to deadlock the system.
- */
-#define mb()           dsb()
-#define rmb()          dsb()
-#define wmb()          mb()
diff --git a/arch/arm/mach-realview/include/mach/board-eb.h b/arch/arm/mach-realview/include/mach/board-eb.h
deleted file mode 100644 (file)
index a301e61..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/board-eb.h
- *
- * Copyright (C) 2007 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __ASM_ARCH_BOARD_EB_H
-#define __ASM_ARCH_BOARD_EB_H
-
-#include <mach/platform.h>
-
-/*
- * RealView EB + ARM11MPCore peripheral addresses
- */
-#define REALVIEW_EB_UART0_BASE         0x10009000      /* UART 0 */
-#define REALVIEW_EB_UART1_BASE         0x1000A000      /* UART 1 */
-#define REALVIEW_EB_UART2_BASE         0x1000B000      /* UART 2 */
-#define REALVIEW_EB_UART3_BASE         0x1000C000      /* UART 3 */
-#define REALVIEW_EB_SSP_BASE           0x1000D000      /* Synchronous Serial Port */
-#define REALVIEW_EB_WATCHDOG_BASE      0x10010000      /* watchdog interface */
-#define REALVIEW_EB_TIMER0_1_BASE      0x10011000      /* Timer 0 and 1 */
-#define REALVIEW_EB_TIMER2_3_BASE      0x10012000      /* Timer 2 and 3 */
-#define REALVIEW_EB_GPIO0_BASE         0x10013000      /* GPIO port 0 */
-#define REALVIEW_EB_RTC_BASE           0x10017000      /* Real Time Clock */
-#define REALVIEW_EB_CLCD_BASE          0x10020000      /* CLCD */
-#define REALVIEW_EB_GIC_CPU_BASE       0x10040000      /* Generic interrupt controller CPU interface */
-#define REALVIEW_EB_GIC_DIST_BASE      0x10041000      /* Generic interrupt controller distributor */
-#define REALVIEW_EB_SMC_BASE           0x10080000      /* Static memory controller */
-
-#define REALVIEW_EB_FLASH_BASE         0x40000000
-#define REALVIEW_EB_FLASH_SIZE         SZ_64M
-#define REALVIEW_EB_ETH_BASE           0x4E000000      /* Ethernet */
-#define REALVIEW_EB_USB_BASE           0x4F000000      /* USB */
-
-#ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB
-#define REALVIEW_EB11MP_PRIV_MEM_BASE  0x10100000
-#define REALVIEW_EB11MP_L220_BASE      0x10102000      /* L220 registers */
-#define REALVIEW_EB11MP_SYS_PLD_CTRL1  0xD8            /* Register offset for MPCore sysctl */
-#else
-#define REALVIEW_EB11MP_PRIV_MEM_BASE  0x1F000000
-#define REALVIEW_EB11MP_L220_BASE      0x1F002000      /* L220 registers */
-#define REALVIEW_EB11MP_SYS_PLD_CTRL1  0x74            /* Register offset for MPCore sysctl */
-#endif
-
-#define REALVIEW_EB11MP_PRIV_MEM_SIZE  SZ_8K
-#define REALVIEW_EB11MP_PRIV_MEM_OFF(x)        (REALVIEW_EB11MP_PRIV_MEM_BASE + (x))
-
-#define REALVIEW_EB11MP_SCU_BASE       REALVIEW_EB11MP_PRIV_MEM_OFF(0)         /* SCU registers */
-#define REALVIEW_EB11MP_GIC_CPU_BASE   REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100)    /* Generic interrupt controller CPU interface */
-#define REALVIEW_EB11MP_TWD_BASE       REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600)
-#define REALVIEW_EB11MP_GIC_DIST_BASE  REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000)    /* Generic interrupt controller distributor */
-
-/*
- * Core tile identification (REALVIEW_SYS_PROCID)
- */
-#define REALVIEW_EB_PROC_MASK          0xFF000000
-#define REALVIEW_EB_PROC_ARM7TDMI      0x00000000
-#define REALVIEW_EB_PROC_ARM9          0x02000000
-#define REALVIEW_EB_PROC_ARM11         0x04000000
-#define REALVIEW_EB_PROC_ARM11MP       0x06000000
-#define REALVIEW_EB_PROC_A9MP          0x0C000000
-
-#define check_eb_proc(proc_type)                                               \
-       ((readl(__io_address(REALVIEW_SYS_PROCID)) & REALVIEW_EB_PROC_MASK)     \
-        == proc_type)
-
-#ifdef CONFIG_REALVIEW_EB_ARM11MP
-#define core_tile_eb11mp()     check_eb_proc(REALVIEW_EB_PROC_ARM11MP)
-#else
-#define core_tile_eb11mp()     0
-#endif
-
-#ifdef CONFIG_REALVIEW_EB_A9MP
-#define core_tile_a9mp()       check_eb_proc(REALVIEW_EB_PROC_A9MP)
-#else
-#define core_tile_a9mp()       0
-#endif
-
-#define machine_is_realview_eb_mp() \
-       (machine_is_realview_eb() && (core_tile_eb11mp() || core_tile_a9mp()))
-
-#endif /* __ASM_ARCH_BOARD_EB_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h
deleted file mode 100644 (file)
index 2a15fef..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/board-pb1176.h
- *
- * Copyright (C) 2008 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __ASM_ARCH_BOARD_PB1176_H
-#define __ASM_ARCH_BOARD_PB1176_H
-
-#include <mach/platform.h>
-
-/*
- * Peripheral addresses
- */
-#define REALVIEW_PB1176_UART4_BASE             0x10009000 /* UART 4 */
-#define REALVIEW_PB1176_SCTL_BASE              0x10100000 /* System controller */
-#define REALVIEW_PB1176_SMC_BASE               0x10111000 /* SMC */
-#define REALVIEW_PB1176_DMC_BASE               0x10109000 /* DMC configuration */
-#define REALVIEW_PB1176_SDRAM67_BASE           0x70000000 /* SDRAM banks 6 and 7 */
-#define REALVIEW_PB1176_FLASH_BASE             0x30000000
-#define REALVIEW_PB1176_FLASH_SIZE             SZ_64M
-#define REALVIEW_PB1176_SEC_FLASH_BASE         0x3C000000 /* Secure flash */
-#define REALVIEW_PB1176_SEC_FLASH_SIZE         SZ_64M
-
-#define REALVIEW_PB1176_TIMER0_1_BASE          0x10104000 /* Timer 0 and 1 */
-#define REALVIEW_PB1176_TIMER2_3_BASE          0x10105000 /* Timer 2 and 3 */
-#define REALVIEW_PB1176_TIMER4_5_BASE          0x10106000 /* Timer 4 and 5 */
-#define REALVIEW_PB1176_WATCHDOG_BASE          0x10107000 /* watchdog interface */
-#define REALVIEW_PB1176_RTC_BASE               0x10108000 /* Real Time Clock */
-#define REALVIEW_PB1176_GPIO0_BASE             0x1010A000 /* GPIO port 0 */
-#define REALVIEW_PB1176_SSP_BASE               0x1010B000 /* Synchronous Serial Port */
-#define REALVIEW_PB1176_UART0_BASE             0x1010C000 /* UART 0 */
-#define REALVIEW_PB1176_UART1_BASE             0x1010D000 /* UART 1 */
-#define REALVIEW_PB1176_UART2_BASE             0x1010E000 /* UART 2 */
-#define REALVIEW_PB1176_UART3_BASE             0x1010F000 /* UART 3 */
-#define REALVIEW_PB1176_CLCD_BASE              0x10112000 /* CLCD */
-#define REALVIEW_PB1176_ETH_BASE               0x3A000000 /* Ethernet */
-#define REALVIEW_PB1176_USB_BASE               0x3B000000 /* USB */
-
-/*
- * PCI regions
- */
-#define REALVIEW_PB1176_PCI_BASE               0x60000000 /* PCI self config */
-#define REALVIEW_PB1176_PCI_CFG_BASE           0x61000000 /* PCI config */
-#define REALVIEW_PB1176_PCI_IO_BASE0           0x62000000 /* PCI IO region */
-#define REALVIEW_PB1176_PCI_MEM_BASE0          0x63000000 /* Memory region 1 */
-#define REALVIEW_PB1176_PCI_MEM_BASE1          0x64000000 /* Memory region 2 */
-#define REALVIEW_PB1176_PCI_MEM_BASE2          0x68000000 /* Memory region 3 */
-
-#define REALVIEW_PB1176_PCI_BASE_SIZE          0x01000000 /* 16MB */
-#define REALVIEW_PB1176_PCI_CFG_BASE_SIZE      0x01000000 /* 16MB */
-#define REALVIEW_PB1176_PCI_IO_BASE0_SIZE      0x01000000 /* 16MB */
-#define REALVIEW_PB1176_PCI_MEM_BASE0_SIZE     0x01000000 /* 16MB */
-#define REALVIEW_PB1176_PCI_MEM_BASE1_SIZE     0x04000000 /* 64MB */
-#define REALVIEW_PB1176_PCI_MEM_BASE2_SIZE     0x08000000 /* 128MB */
-
-#define REALVIEW_DC1176_GIC_CPU_BASE           0x10120000 /* GIC CPU interface, on devchip */
-#define REALVIEW_DC1176_GIC_DIST_BASE          0x10121000 /* GIC distributor, on devchip */
-#define REALVIEW_DC1176_ROM_BASE               0x10200000 /* 16KiB NRAM preudo-ROM, on devchip */
-#define REALVIEW_PB1176_GIC_CPU_BASE           0x10040000 /* GIC CPU interface, on FPGA */
-#define REALVIEW_PB1176_GIC_DIST_BASE          0x10041000 /* GIC distributor, on FPGA */
-#define REALVIEW_PB1176_L220_BASE              0x10110000 /* L220 registers */
-
-/*
- * Control register SYS_RESETCTL Bit 8 is set to 1 to force a soft reset
- */
-#define REALVIEW_PB1176_SYS_SOFT_RESET    0x0100
-
-#endif /* __ASM_ARCH_BOARD_PB1176_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pb11mp.h b/arch/arm/mach-realview/include/mach/board-pb11mp.h
deleted file mode 100644 (file)
index aa2d4e0..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/board-pb11mp.h
- *
- * Copyright (C) 2008 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __ASM_ARCH_BOARD_PB11MP_H
-#define __ASM_ARCH_BOARD_PB11MP_H
-
-#include <mach/platform.h>
-
-/*
- * Peripheral addresses
- */
-#define REALVIEW_PB11MP_UART0_BASE             0x10009000      /* UART 0 */
-#define REALVIEW_PB11MP_UART1_BASE             0x1000A000      /* UART 1 */
-#define REALVIEW_PB11MP_UART2_BASE             0x1000B000      /* UART 2 */
-#define REALVIEW_PB11MP_UART3_BASE             0x1000C000      /* UART 3 */
-#define REALVIEW_PB11MP_SSP_BASE               0x1000D000      /* Synchronous Serial Port */
-#define REALVIEW_PB11MP_WATCHDOG0_BASE         0x1000F000      /* Watchdog 0 */
-#define REALVIEW_PB11MP_WATCHDOG_BASE          0x10010000      /* watchdog interface */
-#define REALVIEW_PB11MP_TIMER0_1_BASE          0x10011000      /* Timer 0 and 1 */
-#define REALVIEW_PB11MP_TIMER2_3_BASE          0x10012000      /* Timer 2 and 3 */
-#define REALVIEW_PB11MP_GPIO0_BASE             0x10013000      /* GPIO port 0 */
-#define REALVIEW_PB11MP_RTC_BASE               0x10017000      /* Real Time Clock */
-#define REALVIEW_PB11MP_TIMER4_5_BASE          0x10018000      /* Timer 4/5 */
-#define REALVIEW_PB11MP_TIMER6_7_BASE          0x10019000      /* Timer 6/7 */
-#define REALVIEW_PB11MP_SCTL_BASE              0x1001A000      /* System Controller */
-#define REALVIEW_PB11MP_CLCD_BASE              0x10020000      /* CLCD */
-#define REALVIEW_PB11MP_ONB_SRAM_BASE          0x10060000      /* On-board SRAM */
-#define REALVIEW_PB11MP_DMC_BASE               0x100E0000      /* DMC configuration */
-#define REALVIEW_PB11MP_SMC_BASE               0x100E1000      /* SMC configuration */
-#define REALVIEW_PB11MP_CAN_BASE               0x100E2000      /* CAN bus */
-#define REALVIEW_PB11MP_CF_BASE                        0x18000000      /* Compact flash */
-#define REALVIEW_PB11MP_CF_MEM_BASE            0x18003000      /* SMC for Compact flash */
-#define REALVIEW_PB11MP_GIC_CPU_BASE           0x1E000000      /* Generic interrupt controller CPU interface */
-#define REALVIEW_PB11MP_FLASH0_BASE            0x40000000
-#define REALVIEW_PB11MP_FLASH0_SIZE            SZ_64M
-#define REALVIEW_PB11MP_FLASH1_BASE            0x44000000
-#define REALVIEW_PB11MP_FLASH1_SIZE            SZ_64M
-#define REALVIEW_PB11MP_ETH_BASE               0x4E000000      /* Ethernet */
-#define REALVIEW_PB11MP_USB_BASE               0x4F000000      /* USB */
-#define REALVIEW_PB11MP_GIC_DIST_BASE          0x1E001000      /* Generic interrupt controller distributor */
-#define REALVIEW_PB11MP_LT_BASE                        0xC0000000      /* Logic Tile expansion */
-#define REALVIEW_PB11MP_SDRAM6_BASE            0x70000000      /* SDRAM bank 6 256MB */
-#define REALVIEW_PB11MP_SDRAM7_BASE            0x80000000      /* SDRAM bank 7 256MB */
-
-#define REALVIEW_PB11MP_SYS_PLD_CTRL1          0x74
-
-/*
- * PB11MPCore PCI regions
- */
-#define REALVIEW_PB11MP_PCI_BASE               0x90040000      /* PCI-X Unit base */
-#define REALVIEW_PB11MP_PCI_IO_BASE            0x90050000      /* IO Region on AHB */
-#define REALVIEW_PB11MP_PCI_MEM_BASE           0xA0000000      /* MEM Region on AHB */
-
-#define REALVIEW_PB11MP_PCI_BASE_SIZE          0x10000         /* 16 Kb */
-#define REALVIEW_PB11MP_PCI_IO_SIZE            0x1000          /* 4 Kb */
-#define REALVIEW_PB11MP_PCI_MEM_SIZE           0x20000000      /* 512 MB */
-
-/*
- * Testchip peripheral and fpga gic regions
- */
-#define REALVIEW_TC11MP_PRIV_MEM_BASE          0x1F000000
-#define REALVIEW_TC11MP_PRIV_MEM_SIZE          SZ_8K
-#define REALVIEW_TC11MP_SCU_BASE               0x1F000000      /* IRQ, Test chip */
-#define REALVIEW_TC11MP_GIC_CPU_BASE           0x1F000100      /* Test chip interrupt controller CPU interface */
-#define REALVIEW_TC11MP_TWD_BASE               0x1F000600
-#define REALVIEW_TC11MP_GIC_DIST_BASE          0x1F001000      /* Test chip interrupt controller distributor */
-#define REALVIEW_TC11MP_L220_BASE              0x1F002000      /* L220 registers */
-
- /*
- * Values for REALVIEW_SYS_RESET_CTRL
- */
-#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR    0x01
-#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT   0x02
-#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET     0x03
-#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET     0x04
-#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR          0x05
-#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC          0x06
-
-#define REALVIEW_PB11MP_SYS_CTRL_LED         (1 << 0)
-
-#endif /* __ASM_ARCH_BOARD_PB11MP_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pba8.h b/arch/arm/mach-realview/include/mach/board-pba8.h
deleted file mode 100644 (file)
index 4dfc67a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * include/asm-arm/arch-realview/board-pba8.h
- *
- * Copyright (C) 2008 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __ASM_ARCH_BOARD_PBA8_H
-#define __ASM_ARCH_BOARD_PBA8_H
-
-#include <mach/platform.h>
-
-/*
- * Peripheral addresses
- */
-#define REALVIEW_PBA8_UART0_BASE               0x10009000      /* UART 0 */
-#define REALVIEW_PBA8_UART1_BASE               0x1000A000      /* UART 1 */
-#define REALVIEW_PBA8_UART2_BASE               0x1000B000      /* UART 2 */
-#define REALVIEW_PBA8_UART3_BASE               0x1000C000      /* UART 3 */
-#define REALVIEW_PBA8_SSP_BASE                 0x1000D000      /* Synchronous Serial Port */
-#define REALVIEW_PBA8_WATCHDOG0_BASE           0x1000F000      /* Watchdog 0 */
-#define REALVIEW_PBA8_WATCHDOG_BASE            0x10010000      /* watchdog interface */
-#define REALVIEW_PBA8_TIMER0_1_BASE            0x10011000      /* Timer 0 and 1 */
-#define REALVIEW_PBA8_TIMER2_3_BASE            0x10012000      /* Timer 2 and 3 */
-#define REALVIEW_PBA8_GPIO0_BASE               0x10013000      /* GPIO port 0 */
-#define REALVIEW_PBA8_RTC_BASE                 0x10017000      /* Real Time Clock */
-#define REALVIEW_PBA8_TIMER4_5_BASE            0x10018000      /* Timer 4/5 */
-#define REALVIEW_PBA8_TIMER6_7_BASE            0x10019000      /* Timer 6/7 */
-#define REALVIEW_PBA8_SCTL_BASE                        0x1001A000      /* System Controller */
-#define REALVIEW_PBA8_CLCD_BASE                        0x10020000      /* CLCD */
-#define REALVIEW_PBA8_ONB_SRAM_BASE            0x10060000      /* On-board SRAM */
-#define REALVIEW_PBA8_DMC_BASE                 0x100E0000      /* DMC configuration */
-#define REALVIEW_PBA8_SMC_BASE                 0x100E1000      /* SMC configuration */
-#define REALVIEW_PBA8_CAN_BASE                 0x100E2000      /* CAN bus */
-#define REALVIEW_PBA8_GIC_CPU_BASE             0x1E000000      /* Generic interrupt controller CPU interface */
-#define REALVIEW_PBA8_FLASH0_BASE              0x40000000
-#define REALVIEW_PBA8_FLASH0_SIZE              SZ_64M
-#define REALVIEW_PBA8_FLASH1_BASE              0x44000000
-#define REALVIEW_PBA8_FLASH1_SIZE              SZ_64M
-#define REALVIEW_PBA8_ETH_BASE                 0x4E000000      /* Ethernet */
-#define REALVIEW_PBA8_USB_BASE                 0x4F000000      /* USB */
-#define REALVIEW_PBA8_GIC_DIST_BASE            0x1E001000      /* Generic interrupt controller distributor */
-#define REALVIEW_PBA8_LT_BASE                  0xC0000000      /* Logic Tile expansion */
-#define REALVIEW_PBA8_SDRAM6_BASE              0x70000000      /* SDRAM bank 6 256MB */
-#define REALVIEW_PBA8_SDRAM7_BASE              0x80000000      /* SDRAM bank 7 256MB */
-
-#define REALVIEW_PBA8_SYS_PLD_CTRL1            0x74
-
-/*
- * PBA8 PCI regions
- */
-#define REALVIEW_PBA8_PCI_BASE                 0x90040000      /* PCI-X Unit base */
-#define REALVIEW_PBA8_PCI_IO_BASE              0x90050000      /* IO Region on AHB */
-#define REALVIEW_PBA8_PCI_MEM_BASE             0xA0000000      /* MEM Region on AHB */
-
-#define REALVIEW_PBA8_PCI_BASE_SIZE            0x10000         /* 16 Kb */
-#define REALVIEW_PBA8_PCI_IO_SIZE              0x1000          /* 4 Kb */
-#define REALVIEW_PBA8_PCI_MEM_SIZE             0x20000000      /* 512 MB */
-
-#endif /* __ASM_ARCH_BOARD_PBA8_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pbx.h b/arch/arm/mach-realview/include/mach/board-pbx.h
deleted file mode 100644 (file)
index 848bfff..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/board-pbx.h
- *
- * Copyright (C) 2009 ARM Limited
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_BOARD_PBX_H
-#define __ASM_ARCH_BOARD_PBX_H
-
-#include <mach/platform.h>
-
-/*
- * Peripheral addresses
- */
-#define REALVIEW_PBX_UART0_BASE                        0x10009000      /* UART 0 */
-#define REALVIEW_PBX_UART1_BASE                        0x1000A000      /* UART 1 */
-#define REALVIEW_PBX_UART2_BASE                        0x1000B000      /* UART 2 */
-#define REALVIEW_PBX_UART3_BASE                        0x1000C000      /* UART 3 */
-#define REALVIEW_PBX_SSP_BASE                  0x1000D000      /* Synchronous Serial Port */
-#define REALVIEW_PBX_WATCHDOG0_BASE            0x1000F000      /* Watchdog 0 */
-#define REALVIEW_PBX_WATCHDOG_BASE             0x10010000      /* watchdog interface */
-#define REALVIEW_PBX_TIMER0_1_BASE             0x10011000      /* Timer 0 and 1 */
-#define REALVIEW_PBX_TIMER2_3_BASE             0x10012000      /* Timer 2 and 3 */
-#define REALVIEW_PBX_GPIO0_BASE                        0x10013000      /* GPIO port 0 */
-#define REALVIEW_PBX_RTC_BASE                  0x10017000      /* Real Time Clock */
-#define REALVIEW_PBX_TIMER4_5_BASE             0x10018000      /* Timer 4/5 */
-#define REALVIEW_PBX_TIMER6_7_BASE             0x10019000      /* Timer 6/7 */
-#define REALVIEW_PBX_SCTL_BASE                 0x1001A000      /* System Controller */
-#define REALVIEW_PBX_CLCD_BASE                 0x10020000      /* CLCD */
-#define REALVIEW_PBX_ONB_SRAM_BASE             0x10060000      /* On-board SRAM */
-#define REALVIEW_PBX_DMC_BASE                  0x100E0000      /* DMC configuration */
-#define REALVIEW_PBX_SMC_BASE                  0x100E1000      /* SMC configuration */
-#define REALVIEW_PBX_CAN_BASE                  0x100E2000      /* CAN bus */
-#define REALVIEW_PBX_GIC_CPU_BASE              0x1E000000      /* Generic interrupt controller CPU interface */
-#define REALVIEW_PBX_FLASH0_BASE               0x40000000
-#define REALVIEW_PBX_FLASH0_SIZE               SZ_64M
-#define REALVIEW_PBX_FLASH1_BASE               0x44000000
-#define REALVIEW_PBX_FLASH1_SIZE               SZ_64M
-#define REALVIEW_PBX_ETH_BASE                  0x4E000000      /* Ethernet */
-#define REALVIEW_PBX_USB_BASE                  0x4F000000      /* USB */
-#define REALVIEW_PBX_GIC_DIST_BASE             0x1E001000      /* Generic interrupt controller distributor */
-#define REALVIEW_PBX_LT_BASE                   0xC0000000      /* Logic Tile expansion */
-#define REALVIEW_PBX_SDRAM6_BASE               0x70000000      /* SDRAM bank 6 256MB */
-#define REALVIEW_PBX_SDRAM7_BASE               0x80000000      /* SDRAM bank 7 256MB */
-
-/*
- * Tile-specific addresses
- */
-#define REALVIEW_PBX_TILE_SCU_BASE             0x1F000000      /* SCU registers */
-#define REALVIEW_PBX_TILE_GIC_CPU_BASE         0x1F000100      /* Private Generic interrupt controller CPU interface */
-#define REALVIEW_PBX_TILE_TWD_BASE             0x1F000600
-#define REALVIEW_PBX_TILE_TWD_PERCPU_BASE      0x1F000700
-#define REALVIEW_PBX_TILE_TWD_SIZE             0x00000100
-#define REALVIEW_PBX_TILE_GIC_DIST_BASE                0x1F001000      /* Private Generic interrupt controller distributor */
-#define REALVIEW_PBX_TILE_L220_BASE            0x1F002000      /* L220 registers */
-
-#define REALVIEW_PBX_SYS_PLD_CTRL1             0x74
-
-/*
- * PBX PCI regions
- */
-#define REALVIEW_PBX_PCI_BASE                  0x90040000      /* PCI-X Unit base */
-#define REALVIEW_PBX_PCI_IO_BASE               0x90050000      /* IO Region on AHB */
-#define REALVIEW_PBX_PCI_MEM_BASE              0xA0000000      /* MEM Region on AHB */
-
-#define REALVIEW_PBX_PCI_BASE_SIZE             0x10000         /* 16 Kb */
-#define REALVIEW_PBX_PCI_IO_SIZE               0x1000          /* 4 Kb */
-#define REALVIEW_PBX_PCI_MEM_SIZE              0x20000000      /* 512 MB */
-
-/*
- * Core tile identification (REALVIEW_SYS_PROCID)
- */
-#define REALVIEW_PBX_PROC_MASK          0xFF000000
-#define REALVIEW_PBX_PROC_ARM7TDMI      0x00000000
-#define REALVIEW_PBX_PROC_ARM9          0x02000000
-#define REALVIEW_PBX_PROC_ARM11         0x04000000
-#define REALVIEW_PBX_PROC_ARM11MP       0x06000000
-#define REALVIEW_PBX_PROC_A9MP          0x0C000000
-#define REALVIEW_PBX_PROC_A8            0x0E000000
-
-#define check_pbx_proc(proc_type)                                            \
-       ((readl(__io_address(REALVIEW_SYS_PROCID)) & REALVIEW_PBX_PROC_MASK) \
-       == proc_type)
-
-#ifdef CONFIG_MACH_REALVIEW_PBX
-#define core_tile_pbx11mp()     check_pbx_proc(REALVIEW_PBX_PROC_ARM11MP)
-#define core_tile_pbxa9mp()     check_pbx_proc(REALVIEW_PBX_PROC_A9MP)
-#define core_tile_pbxa8()       check_pbx_proc(REALVIEW_PBX_PROC_A8)
-#else
-#define core_tile_pbx11mp()     0
-#define core_tile_pbxa9mp()     0
-#define core_tile_pbxa8()       0
-#endif
-
-#endif /* __ASM_ARCH_BOARD_PBX_H */
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
deleted file mode 100644 (file)
index 281e71c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  arch/arm/mach-realview/include/mach/hardware.h
- *
- *  This file contains the hardware definitions of the RealView boards.
- *
- *  Copyright (C) 2003 ARM Limited.
- *
- * This program is free software; 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_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/sizes.h>
-
-/* macro to get at IO space when running virtually */
-#ifdef CONFIG_MMU
-/*
- * Statically mapped addresses:
- *
- * 10xx xxxx -> fbxx xxxx
- * 1exx xxxx -> fdxx xxxx
- * 1fxx xxxx -> fexx xxxx
- */
-#define IO_ADDRESS(x)          (((x) & 0x03ffffff) + 0xfb000000)
-#else
-#define IO_ADDRESS(x)          (x)
-#endif
-#define __io_address(n)                IOMEM(IO_ADDRESS(n))
-
-#endif
diff --git a/arch/arm/mach-realview/include/mach/irqs-eb.h b/arch/arm/mach-realview/include/mach/irqs-eb.h
deleted file mode 100644 (file)
index 4475423..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/irqs-eb.h
- *
- * Copyright (C) 2007 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __MACH_IRQS_EB_H
-#define __MACH_IRQS_EB_H
-
-#define IRQ_EB_GIC_START       32
-
-/*
- * RealView EB interrupt sources
- */
-#define IRQ_EB_WDOG            (IRQ_EB_GIC_START + 0)          /* Watchdog timer */
-#define IRQ_EB_SOFT            (IRQ_EB_GIC_START + 1)          /* Software interrupt */
-#define IRQ_EB_COMMRx          (IRQ_EB_GIC_START + 2)          /* Debug Comm Rx interrupt */
-#define IRQ_EB_COMMTx          (IRQ_EB_GIC_START + 3)          /* Debug Comm Tx interrupt */
-#define IRQ_EB_TIMER0_1                (IRQ_EB_GIC_START + 4)          /* Timer 0 and 1 */
-#define IRQ_EB_TIMER2_3                (IRQ_EB_GIC_START + 5)          /* Timer 2 and 3 */
-#define IRQ_EB_GPIO0           (IRQ_EB_GIC_START + 6)          /* GPIO 0 */
-#define IRQ_EB_GPIO1           (IRQ_EB_GIC_START + 7)          /* GPIO 1 */
-#define IRQ_EB_GPIO2           (IRQ_EB_GIC_START + 8)          /* GPIO 2 */
-                                                               /* 9 reserved */
-#define IRQ_EB_RTC             (IRQ_EB_GIC_START + 10)         /* Real Time Clock */
-#define IRQ_EB_SSP             (IRQ_EB_GIC_START + 11)         /* Synchronous Serial Port */
-#define IRQ_EB_UART0           (IRQ_EB_GIC_START + 12)         /* UART 0 on development chip */
-#define IRQ_EB_UART1           (IRQ_EB_GIC_START + 13)         /* UART 1 on development chip */
-#define IRQ_EB_UART2           (IRQ_EB_GIC_START + 14)         /* UART 2 on development chip */
-#define IRQ_EB_UART3           (IRQ_EB_GIC_START + 15)         /* UART 3 on development chip */
-#define IRQ_EB_SCI             (IRQ_EB_GIC_START + 16)         /* Smart Card Interface */
-#define IRQ_EB_MMCI0A          (IRQ_EB_GIC_START + 17)         /* Multimedia Card 0A */
-#define IRQ_EB_MMCI0B          (IRQ_EB_GIC_START + 18)         /* Multimedia Card 0B */
-#define IRQ_EB_AACI            (IRQ_EB_GIC_START + 19)         /* Audio Codec */
-#define IRQ_EB_KMI0            (IRQ_EB_GIC_START + 20)         /* Keyboard/Mouse port 0 */
-#define IRQ_EB_KMI1            (IRQ_EB_GIC_START + 21)         /* Keyboard/Mouse port 1 */
-#define IRQ_EB_CHARLCD         (IRQ_EB_GIC_START + 22)         /* Character LCD */
-#define IRQ_EB_CLCD            (IRQ_EB_GIC_START + 23)         /* CLCD controller */
-#define IRQ_EB_DMA             (IRQ_EB_GIC_START + 24)         /* DMA controller */
-#define IRQ_EB_PWRFAIL         (IRQ_EB_GIC_START + 25)         /* Power failure */
-#define IRQ_EB_PISMO           (IRQ_EB_GIC_START + 26)         /* PISMO interface */
-#define IRQ_EB_DoC             (IRQ_EB_GIC_START + 27)         /* Disk on Chip memory controller */
-#define IRQ_EB_ETH             (IRQ_EB_GIC_START + 28)         /* Ethernet controller */
-#define IRQ_EB_USB             (IRQ_EB_GIC_START + 29)         /* USB controller */
-#define IRQ_EB_TSPEN           (IRQ_EB_GIC_START + 30)         /* Touchscreen pen */
-#define IRQ_EB_TSKPAD          (IRQ_EB_GIC_START + 31)         /* Touchscreen keypad */
-
-/*
- * RealView EB + ARM11MPCore interrupt sources (primary GIC on the core tile)
- */
-#define IRQ_EB11MP_AACI                (IRQ_EB_GIC_START + 0)
-#define IRQ_EB11MP_TIMER0_1    (IRQ_EB_GIC_START + 1)
-#define IRQ_EB11MP_TIMER2_3    (IRQ_EB_GIC_START + 2)
-#define IRQ_EB11MP_USB         (IRQ_EB_GIC_START + 3)
-#define IRQ_EB11MP_UART0       (IRQ_EB_GIC_START + 4)
-#define IRQ_EB11MP_UART1       (IRQ_EB_GIC_START + 5)
-#define IRQ_EB11MP_RTC         (IRQ_EB_GIC_START + 6)
-#define IRQ_EB11MP_KMI0                (IRQ_EB_GIC_START + 7)
-#define IRQ_EB11MP_KMI1                (IRQ_EB_GIC_START + 8)
-#define IRQ_EB11MP_ETH         (IRQ_EB_GIC_START + 9)
-#define IRQ_EB11MP_EB_IRQ1     (IRQ_EB_GIC_START + 10)         /* main GIC */
-#define IRQ_EB11MP_EB_IRQ2     (IRQ_EB_GIC_START + 11)         /* tile GIC */
-#define IRQ_EB11MP_EB_FIQ1     (IRQ_EB_GIC_START + 12)         /* main GIC */
-#define IRQ_EB11MP_EB_FIQ2     (IRQ_EB_GIC_START + 13)         /* tile GIC */
-#define IRQ_EB11MP_MMCI0A      (IRQ_EB_GIC_START + 14)
-#define IRQ_EB11MP_MMCI0B      (IRQ_EB_GIC_START + 15)
-
-#define IRQ_EB11MP_PMU_CPU0    (IRQ_EB_GIC_START + 17)
-#define IRQ_EB11MP_PMU_CPU1    (IRQ_EB_GIC_START + 18)
-#define IRQ_EB11MP_PMU_CPU2    (IRQ_EB_GIC_START + 19)
-#define IRQ_EB11MP_PMU_CPU3    (IRQ_EB_GIC_START + 20)
-#define IRQ_EB11MP_PMU_SCU0    (IRQ_EB_GIC_START + 21)
-#define IRQ_EB11MP_PMU_SCU1    (IRQ_EB_GIC_START + 22)
-#define IRQ_EB11MP_PMU_SCU2    (IRQ_EB_GIC_START + 23)
-#define IRQ_EB11MP_PMU_SCU3    (IRQ_EB_GIC_START + 24)
-#define IRQ_EB11MP_PMU_SCU4    (IRQ_EB_GIC_START + 25)
-#define IRQ_EB11MP_PMU_SCU5    (IRQ_EB_GIC_START + 26)
-#define IRQ_EB11MP_PMU_SCU6    (IRQ_EB_GIC_START + 27)
-#define IRQ_EB11MP_PMU_SCU7    (IRQ_EB_GIC_START + 28)
-
-#define IRQ_EB11MP_L220_EVENT  (IRQ_EB_GIC_START + 29)
-#define IRQ_EB11MP_L220_SLAVE  (IRQ_EB_GIC_START + 30)
-#define IRQ_EB11MP_L220_DECODE (IRQ_EB_GIC_START + 31)
-
-/*
- * The 11MPcore tile leaves the following unconnected.
- */
-#define IRQ_EB11MP_UART2       0
-#define IRQ_EB11MP_UART3       0
-#define IRQ_EB11MP_CLCD                0
-#define IRQ_EB11MP_DMA         0
-#define IRQ_EB11MP_WDOG                0
-#define IRQ_EB11MP_GPIO0       0
-#define IRQ_EB11MP_GPIO1       0
-#define IRQ_EB11MP_GPIO2       0
-#define IRQ_EB11MP_SCI         0
-#define IRQ_EB11MP_SSP         0
-
-#define NR_GIC_EB11MP          2
-
-/*
- * Only define NR_IRQS if less than NR_IRQS_EB
- */
-#define NR_IRQS_EB             (IRQ_EB_GIC_START + 128)
-
-#if defined(CONFIG_MACH_REALVIEW_EB) \
-       && (!defined(NR_IRQS) || (NR_IRQS < NR_IRQS_EB))
-#undef NR_IRQS
-#define NR_IRQS                        NR_IRQS_EB
-#endif
-
-#if defined(CONFIG_REALVIEW_EB_ARM11MP) || defined(CONFIG_REALVIEW_EB_A9MP) \
-       && (!defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_EB11MP))
-#undef MAX_GIC_NR
-#define MAX_GIC_NR             NR_GIC_EB11MP
-#endif
-
-#endif /* __MACH_IRQS_EB_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
deleted file mode 100644 (file)
index 708f841..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/irqs-pb1176.h
- *
- * Copyright (C) 2008 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __MACH_IRQS_PB1176_H
-#define __MACH_IRQS_PB1176_H
-
-#define IRQ_DC1176_GIC_START                   32
-#define IRQ_PB1176_GIC_START                   64
-
-/*
- * ARM1176 DevChip interrupt sources (primary GIC)
- */
-#define IRQ_DC1176_WATCHDOG    (IRQ_DC1176_GIC_START + 0)      /* Watchdog timer */
-#define IRQ_DC1176_SOFTINT     (IRQ_DC1176_GIC_START + 1)      /* Software interrupt */
-#define IRQ_DC1176_COMMRx      (IRQ_DC1176_GIC_START + 2)      /* Debug Comm Rx interrupt */
-#define IRQ_DC1176_COMMTx      (IRQ_DC1176_GIC_START + 3)      /* Debug Comm Tx interrupt */
-#define IRQ_DC1176_CORE_PMU    (IRQ_DC1176_GIC_START + 7)      /* Core PMU interrupt */
-#define IRQ_DC1176_TIMER0      (IRQ_DC1176_GIC_START + 8)      /* Timer 0 */
-#define IRQ_DC1176_TIMER1      (IRQ_DC1176_GIC_START + 9)      /* Timer 1 */
-#define IRQ_DC1176_TIMER2      (IRQ_DC1176_GIC_START + 10)     /* Timer 2 */
-#define IRQ_DC1176_APC         (IRQ_DC1176_GIC_START + 11)
-#define IRQ_DC1176_IEC         (IRQ_DC1176_GIC_START + 12)
-#define IRQ_DC1176_L2CC                (IRQ_DC1176_GIC_START + 13)
-#define IRQ_DC1176_RTC         (IRQ_DC1176_GIC_START + 14)
-#define IRQ_DC1176_CLCD                (IRQ_DC1176_GIC_START + 15)     /* CLCD controller */
-#define IRQ_DC1176_GPIO0       (IRQ_DC1176_GIC_START + 16)
-#define IRQ_DC1176_SSP         (IRQ_DC1176_GIC_START + 17)     /* SSP port */
-#define IRQ_DC1176_UART0       (IRQ_DC1176_GIC_START + 18)     /* UART 0 on development chip */
-#define IRQ_DC1176_UART1       (IRQ_DC1176_GIC_START + 19)     /* UART 1 on development chip */
-#define IRQ_DC1176_UART2       (IRQ_DC1176_GIC_START + 20)     /* UART 2 on development chip */
-#define IRQ_DC1176_UART3       (IRQ_DC1176_GIC_START + 21)     /* UART 3 on development chip */
-
-#define IRQ_DC1176_PB_IRQ2     (IRQ_DC1176_GIC_START + 30)     /* tile GIC */
-#define IRQ_DC1176_PB_IRQ1     (IRQ_DC1176_GIC_START + 31)     /* main GIC */
-
-/*
- * RealView PB1176 interrupt sources (secondary GIC)
- */
-#define IRQ_PB1176_MMCI0A      (IRQ_PB1176_GIC_START + 1)      /* Multimedia Card 0A */
-#define IRQ_PB1176_MMCI0B      (IRQ_PB1176_GIC_START + 2)      /* Multimedia Card 0A */
-#define IRQ_PB1176_KMI0                (IRQ_PB1176_GIC_START + 3)      /* Keyboard/Mouse port 0 */
-#define IRQ_PB1176_KMI1                (IRQ_PB1176_GIC_START + 4)      /* Keyboard/Mouse port 1 */
-#define IRQ_PB1176_SCI         (IRQ_PB1176_GIC_START + 5)
-#define IRQ_PB1176_UART4       (IRQ_PB1176_GIC_START + 6)      /* UART 4 on baseboard */
-#define IRQ_PB1176_CHARLCD     (IRQ_PB1176_GIC_START + 7)      /* Character LCD */
-#define IRQ_PB1176_GPIO1       (IRQ_PB1176_GIC_START + 8)
-#define IRQ_PB1176_GPIO2       (IRQ_PB1176_GIC_START + 9)
-#define IRQ_PB1176_ETH         (IRQ_PB1176_GIC_START + 10)     /* Ethernet controller */
-#define IRQ_PB1176_USB         (IRQ_PB1176_GIC_START + 11)     /* USB controller */
-
-#define IRQ_PB1176_PISMO       (IRQ_PB1176_GIC_START + 16)
-
-#define IRQ_PB1176_AACI                (IRQ_PB1176_GIC_START + 19)     /* Audio Codec */
-
-#define IRQ_PB1176_TIMER0_1    (IRQ_PB1176_GIC_START + 22)
-#define IRQ_PB1176_TIMER2_3    (IRQ_PB1176_GIC_START + 23)
-#define IRQ_PB1176_DMAC                (IRQ_PB1176_GIC_START + 24)     /* DMA controller */
-#define IRQ_PB1176_RTC         (IRQ_PB1176_GIC_START + 25)     /* Real Time Clock */
-
-#define IRQ_PB1176_SCTL                -1
-
-#define NR_GIC_PB1176          2
-
-/*
- * Only define NR_IRQS if less than NR_IRQS_PB1176
- */
-#define NR_IRQS_PB1176         (IRQ_DC1176_GIC_START + 96)
-
-#if defined(CONFIG_MACH_REALVIEW_PB1176)
-
-#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PB1176)
-#undef NR_IRQS
-#define NR_IRQS                        NR_IRQS_PB1176
-#endif
-
-#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PB1176)
-#undef MAX_GIC_NR
-#define MAX_GIC_NR             NR_GIC_PB1176
-#endif
-
-#endif /* CONFIG_MACH_REALVIEW_PB1176 */
-
-#endif /* __MACH_IRQS_PB1176_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb11mp.h b/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
deleted file mode 100644 (file)
index 34e255a..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/irqs-pb11mp.h
- *
- * Copyright (C) 2008 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __MACH_IRQS_PB11MP_H
-#define __MACH_IRQS_PB11MP_H
-
-#define IRQ_TC11MP_GIC_START                   32
-#define IRQ_PB11MP_GIC_START                   64
-
-/*
- * ARM11MPCore test chip interrupt sources (primary GIC on the test chip)
- */
-#define IRQ_TC11MP_AACI                (IRQ_TC11MP_GIC_START + 0)
-#define IRQ_TC11MP_TIMER0_1    (IRQ_TC11MP_GIC_START + 1)
-#define IRQ_TC11MP_TIMER2_3    (IRQ_TC11MP_GIC_START + 2)
-#define IRQ_TC11MP_USB         (IRQ_TC11MP_GIC_START + 3)
-#define IRQ_TC11MP_UART0       (IRQ_TC11MP_GIC_START + 4)
-#define IRQ_TC11MP_UART1       (IRQ_TC11MP_GIC_START + 5)
-#define IRQ_TC11MP_RTC         (IRQ_TC11MP_GIC_START + 6)
-#define IRQ_TC11MP_KMI0                (IRQ_TC11MP_GIC_START + 7)
-#define IRQ_TC11MP_KMI1                (IRQ_TC11MP_GIC_START + 8)
-#define IRQ_TC11MP_ETH         (IRQ_TC11MP_GIC_START + 9)
-#define IRQ_TC11MP_PB_IRQ1     (IRQ_TC11MP_GIC_START + 10)             /* main GIC */
-#define IRQ_TC11MP_PB_IRQ2     (IRQ_TC11MP_GIC_START + 11)             /* tile GIC */
-#define IRQ_TC11MP_PB_FIQ1     (IRQ_TC11MP_GIC_START + 12)             /* main GIC */
-#define IRQ_TC11MP_PB_FIQ2     (IRQ_TC11MP_GIC_START + 13)             /* tile GIC */
-#define IRQ_TC11MP_MMCI0A      (IRQ_TC11MP_GIC_START + 14)
-#define IRQ_TC11MP_MMCI0B      (IRQ_TC11MP_GIC_START + 15)
-
-#define IRQ_TC11MP_PMU_CPU0    (IRQ_TC11MP_GIC_START + 17)
-#define IRQ_TC11MP_PMU_CPU1    (IRQ_TC11MP_GIC_START + 18)
-#define IRQ_TC11MP_PMU_CPU2    (IRQ_TC11MP_GIC_START + 19)
-#define IRQ_TC11MP_PMU_CPU3    (IRQ_TC11MP_GIC_START + 20)
-#define IRQ_TC11MP_PMU_SCU0    (IRQ_TC11MP_GIC_START + 21)
-#define IRQ_TC11MP_PMU_SCU1    (IRQ_TC11MP_GIC_START + 22)
-#define IRQ_TC11MP_PMU_SCU2    (IRQ_TC11MP_GIC_START + 23)
-#define IRQ_TC11MP_PMU_SCU3    (IRQ_TC11MP_GIC_START + 24)
-#define IRQ_TC11MP_PMU_SCU4    (IRQ_TC11MP_GIC_START + 25)
-#define IRQ_TC11MP_PMU_SCU5    (IRQ_TC11MP_GIC_START + 26)
-#define IRQ_TC11MP_PMU_SCU6    (IRQ_TC11MP_GIC_START + 27)
-#define IRQ_TC11MP_PMU_SCU7    (IRQ_TC11MP_GIC_START + 28)
-
-#define IRQ_TC11MP_L220_EVENT  (IRQ_TC11MP_GIC_START + 29)
-#define IRQ_TC11MP_L220_SLAVE  (IRQ_TC11MP_GIC_START + 30)
-#define IRQ_TC11MP_L220_DECODE (IRQ_TC11MP_GIC_START + 31)
-
-/*
- * RealView PB11MPCore GIC interrupt sources (secondary GIC on the board)
- */
-#define IRQ_PB11MP_WATCHDOG    (IRQ_PB11MP_GIC_START + 0)      /* Watchdog timer */
-#define IRQ_PB11MP_SOFT                (IRQ_PB11MP_GIC_START + 1)      /* Software interrupt */
-#define IRQ_PB11MP_COMMRx      (IRQ_PB11MP_GIC_START + 2)      /* Debug Comm Rx interrupt */
-#define IRQ_PB11MP_COMMTx      (IRQ_PB11MP_GIC_START + 3)      /* Debug Comm Tx interrupt */
-#define IRQ_PB11MP_GPIO0       (IRQ_PB11MP_GIC_START + 6)      /* GPIO 0 */
-#define IRQ_PB11MP_GPIO1       (IRQ_PB11MP_GIC_START + 7)      /* GPIO 1 */
-#define IRQ_PB11MP_GPIO2       (IRQ_PB11MP_GIC_START + 8)      /* GPIO 2 */
-                                                               /* 9 reserved */
-#define IRQ_PB11MP_RTC_GIC1    (IRQ_PB11MP_GIC_START + 10)     /* Real Time Clock */
-#define IRQ_PB11MP_SSP         (IRQ_PB11MP_GIC_START + 11)     /* Synchronous Serial Port */
-#define IRQ_PB11MP_UART0_GIC1  (IRQ_PB11MP_GIC_START + 12)     /* UART 0 on development chip */
-#define IRQ_PB11MP_UART1_GIC1  (IRQ_PB11MP_GIC_START + 13)     /* UART 1 on development chip */
-#define IRQ_PB11MP_UART2       (IRQ_PB11MP_GIC_START + 14)     /* UART 2 on development chip */
-#define IRQ_PB11MP_UART3       (IRQ_PB11MP_GIC_START + 15)     /* UART 3 on development chip */
-#define IRQ_PB11MP_SCI         (IRQ_PB11MP_GIC_START + 16)     /* Smart Card Interface */
-#define IRQ_PB11MP_MMCI0A_GIC1 (IRQ_PB11MP_GIC_START + 17)     /* Multimedia Card 0A */
-#define IRQ_PB11MP_MMCI0B_GIC1 (IRQ_PB11MP_GIC_START + 18)     /* Multimedia Card 0B */
-#define IRQ_PB11MP_AACI_GIC1   (IRQ_PB11MP_GIC_START + 19)     /* Audio Codec */
-#define IRQ_PB11MP_KMI0_GIC1   (IRQ_PB11MP_GIC_START + 20)     /* Keyboard/Mouse port 0 */
-#define IRQ_PB11MP_KMI1_GIC1   (IRQ_PB11MP_GIC_START + 21)     /* Keyboard/Mouse port 1 */
-#define IRQ_PB11MP_CHARLCD     (IRQ_PB11MP_GIC_START + 22)     /* Character LCD */
-#define IRQ_PB11MP_CLCD                (IRQ_PB11MP_GIC_START + 23)     /* CLCD controller */
-#define IRQ_PB11MP_DMAC                (IRQ_PB11MP_GIC_START + 24)     /* DMA controller */
-#define IRQ_PB11MP_PWRFAIL     (IRQ_PB11MP_GIC_START + 25)     /* Power failure */
-#define IRQ_PB11MP_PISMO       (IRQ_PB11MP_GIC_START + 26)     /* PISMO interface */
-#define IRQ_PB11MP_DoC         (IRQ_PB11MP_GIC_START + 27)     /* Disk on Chip memory controller */
-#define IRQ_PB11MP_ETH_GIC1    (IRQ_PB11MP_GIC_START + 28)     /* Ethernet controller */
-#define IRQ_PB11MP_USB_GIC1    (IRQ_PB11MP_GIC_START + 29)     /* USB controller */
-#define IRQ_PB11MP_TSPEN       (IRQ_PB11MP_GIC_START + 30)     /* Touchscreen pen */
-#define IRQ_PB11MP_TSKPAD      (IRQ_PB11MP_GIC_START + 31)     /* Touchscreen keypad */
-
-#define IRQ_PB11MP_SMC         -1
-#define IRQ_PB11MP_SCTL                -1
-
-#define NR_GIC_PB11MP          2
-
-/*
- * Only define NR_IRQS if less than NR_IRQS_PB11MP
- */
-#define NR_IRQS_PB11MP         (IRQ_TC11MP_GIC_START + 96)
-
-#if defined(CONFIG_MACH_REALVIEW_PB11MP)
-
-#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PB11MP)
-#undef NR_IRQS
-#define NR_IRQS                        NR_IRQS_PB11MP
-#endif
-
-#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PB11MP)
-#undef MAX_GIC_NR
-#define MAX_GIC_NR             NR_GIC_PB11MP
-#endif
-
-#endif /* CONFIG_MACH_REALVIEW_PB11MP */
-
-#endif /* __MACH_IRQS_PB11MP_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pba8.h b/arch/arm/mach-realview/include/mach/irqs-pba8.h
deleted file mode 100644 (file)
index 4a88a4e..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/irqs-pba8.h
- *
- * Copyright (C) 2008 ARM Limited
- *
- * 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 Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __MACH_IRQS_PBA8_H
-#define __MACH_IRQS_PBA8_H
-
-#define IRQ_PBA8_GIC_START                     32
-
-/*
- * PB-A8 on-board gic irq sources
- */
-#define IRQ_PBA8_WATCHDOG      (IRQ_PBA8_GIC_START + 0)        /* Watchdog timer */
-#define IRQ_PBA8_SOFT          (IRQ_PBA8_GIC_START + 1)        /* Software interrupt */
-#define IRQ_PBA8_COMMRx                (IRQ_PBA8_GIC_START + 2)        /* Debug Comm Rx interrupt */
-#define IRQ_PBA8_COMMTx                (IRQ_PBA8_GIC_START + 3)        /* Debug Comm Tx interrupt */
-#define IRQ_PBA8_TIMER0_1      (IRQ_PBA8_GIC_START + 4)        /* Timer 0/1 (default timer) */
-#define IRQ_PBA8_TIMER2_3      (IRQ_PBA8_GIC_START + 5)        /* Timer 2/3 */
-#define IRQ_PBA8_GPIO0         (IRQ_PBA8_GIC_START + 6)        /* GPIO 0 */
-#define IRQ_PBA8_GPIO1         (IRQ_PBA8_GIC_START + 7)        /* GPIO 1 */
-#define IRQ_PBA8_GPIO2         (IRQ_PBA8_GIC_START + 8)        /* GPIO 2 */
-                                                               /* 9 reserved */
-#define IRQ_PBA8_RTC           (IRQ_PBA8_GIC_START + 10)       /* Real Time Clock */
-#define IRQ_PBA8_SSP           (IRQ_PBA8_GIC_START + 11)       /* Synchronous Serial Port */
-#define IRQ_PBA8_UART0         (IRQ_PBA8_GIC_START + 12)       /* UART 0 on development chip */
-#define IRQ_PBA8_UART1         (IRQ_PBA8_GIC_START + 13)       /* UART 1 on development chip */
-#define IRQ_PBA8_UART2         (IRQ_PBA8_GIC_START + 14)       /* UART 2 on development chip */
-#define IRQ_PBA8_UART3         (IRQ_PBA8_GIC_START + 15)       /* UART 3 on development chip */
-#define IRQ_PBA8_SCI           (IRQ_PBA8_GIC_START + 16)       /* Smart Card Interface */
-#define IRQ_PBA8_MMCI0A                (IRQ_PBA8_GIC_START + 17)       /* Multimedia Card 0A */
-#define IRQ_PBA8_MMCI0B                (IRQ_PBA8_GIC_START + 18)       /* Multimedia Card 0B */
-#define IRQ_PBA8_AACI          (IRQ_PBA8_GIC_START + 19)       /* Audio Codec */
-#define IRQ_PBA8_KMI0          (IRQ_PBA8_GIC_START + 20)       /* Keyboard/Mouse port 0 */
-#define IRQ_PBA8_KMI1          (IRQ_PBA8_GIC_START + 21)       /* Keyboard/Mouse port 1 */
-#define IRQ_PBA8_CHARLCD       (IRQ_PBA8_GIC_START + 22)       /* Character LCD */
-#define IRQ_PBA8_CLCD          (IRQ_PBA8_GIC_START + 23)       /* CLCD controller */
-#define IRQ_PBA8_DMAC          (IRQ_PBA8_GIC_START + 24)       /* DMA controller */
-#define IRQ_PBA8_PWRFAIL       (IRQ_PBA8_GIC_START + 25)       /* Power failure */
-#define IRQ_PBA8_PISMO         (IRQ_PBA8_GIC_START + 26)       /* PISMO interface */
-#define IRQ_PBA8_DoC           (IRQ_PBA8_GIC_START + 27)       /* Disk on Chip memory controller */
-#define IRQ_PBA8_ETH           (IRQ_PBA8_GIC_START + 28)       /* Ethernet controller */
-#define IRQ_PBA8_USB           (IRQ_PBA8_GIC_START + 29)       /* USB controller */
-#define IRQ_PBA8_TSPEN         (IRQ_PBA8_GIC_START + 30)       /* Touchscreen pen */
-#define IRQ_PBA8_TSKPAD                (IRQ_PBA8_GIC_START + 31)       /* Touchscreen keypad */
-
-#define IRQ_PBA8_PMU           (IRQ_PBA8_GIC_START + 47)       /* Cortex-A8 PMU */
-
-/* ... */
-#define IRQ_PBA8_PCI0          (IRQ_PBA8_GIC_START + 50)
-#define IRQ_PBA8_PCI1          (IRQ_PBA8_GIC_START + 51)
-#define IRQ_PBA8_PCI2          (IRQ_PBA8_GIC_START + 52)
-#define IRQ_PBA8_PCI3          (IRQ_PBA8_GIC_START + 53)
-
-#define IRQ_PBA8_SMC           -1
-#define IRQ_PBA8_SCTL          -1
-
-#define NR_GIC_PBA8            1
-
-/*
- * Only define NR_IRQS if less than NR_IRQS_PBA8
- */
-#define NR_IRQS_PBA8           (IRQ_PBA8_GIC_START + 64)
-
-#if defined(CONFIG_MACH_REALVIEW_PBA8)
-
-#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PBA8)
-#undef NR_IRQS
-#define NR_IRQS                        NR_IRQS_PBA8
-#endif
-
-#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PBA8)
-#undef MAX_GIC_NR
-#define MAX_GIC_NR             NR_GIC_PBA8
-#endif
-
-#endif /* CONFIG_MACH_REALVIEW_PBA8 */
-
-#endif /* __MACH_IRQS_PBA8_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pbx.h b/arch/arm/mach-realview/include/mach/irqs-pbx.h
deleted file mode 100644 (file)
index 206a300..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/irqs-pbx.h
- *
- * Copyright (C) 2009 ARM Limited
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __MACH_IRQS_PBX_H
-#define __MACH_IRQS_PBX_H
-
-#define IRQ_PBX_GIC_START                      32
-
-/*
- * PBX on-board gic irq sources
- */
-#define IRQ_PBX_WATCHDOG       (IRQ_PBX_GIC_START + 0) /* Watchdog timer */
-#define IRQ_PBX_SOFT           (IRQ_PBX_GIC_START + 1) /* Software interrupt */
-#define IRQ_PBX_COMMRx         (IRQ_PBX_GIC_START + 2) /* Debug Comm Rx interrupt */
-#define IRQ_PBX_COMMTx         (IRQ_PBX_GIC_START + 3) /* Debug Comm Tx interrupt */
-#define IRQ_PBX_TIMER0_1       (IRQ_PBX_GIC_START + 4) /* Timer 0/1 (default timer) */
-#define IRQ_PBX_TIMER2_3       (IRQ_PBX_GIC_START + 5) /* Timer 2/3 */
-#define IRQ_PBX_GPIO0          (IRQ_PBX_GIC_START + 6) /* GPIO 0 */
-#define IRQ_PBX_GPIO1          (IRQ_PBX_GIC_START + 7) /* GPIO 1 */
-#define IRQ_PBX_GPIO2          (IRQ_PBX_GIC_START + 8) /* GPIO 2 */
-                                                               /* 9 reserved */
-#define IRQ_PBX_RTC            (IRQ_PBX_GIC_START + 10)        /* Real Time Clock */
-#define IRQ_PBX_SSP            (IRQ_PBX_GIC_START + 11)        /* Synchronous Serial Port */
-#define IRQ_PBX_UART0          (IRQ_PBX_GIC_START + 12)        /* UART 0 on development chip */
-#define IRQ_PBX_UART1          (IRQ_PBX_GIC_START + 13)        /* UART 1 on development chip */
-#define IRQ_PBX_UART2          (IRQ_PBX_GIC_START + 14)        /* UART 2 on development chip */
-#define IRQ_PBX_UART3          (IRQ_PBX_GIC_START + 15)        /* UART 3 on development chip */
-#define IRQ_PBX_SCI            (IRQ_PBX_GIC_START + 16)        /* Smart Card Interface */
-#define IRQ_PBX_MMCI0A         (IRQ_PBX_GIC_START + 17)        /* Multimedia Card 0A */
-#define IRQ_PBX_MMCI0B         (IRQ_PBX_GIC_START + 18)        /* Multimedia Card 0B */
-#define IRQ_PBX_AACI           (IRQ_PBX_GIC_START + 19)        /* Audio Codec */
-#define IRQ_PBX_KMI0           (IRQ_PBX_GIC_START + 20)        /* Keyboard/Mouse port 0 */
-#define IRQ_PBX_KMI1           (IRQ_PBX_GIC_START + 21)        /* Keyboard/Mouse port 1 */
-#define IRQ_PBX_CHARLCD                (IRQ_PBX_GIC_START + 22)        /* Character LCD */
-#define IRQ_PBX_CLCD           (IRQ_PBX_GIC_START + 23)        /* CLCD controller */
-#define IRQ_PBX_DMAC           (IRQ_PBX_GIC_START + 24)        /* DMA controller */
-#define IRQ_PBX_PWRFAIL                (IRQ_PBX_GIC_START + 25)        /* Power failure */
-#define IRQ_PBX_PISMO          (IRQ_PBX_GIC_START + 26)        /* PISMO interface */
-#define IRQ_PBX_DoC            (IRQ_PBX_GIC_START + 27)        /* Disk on Chip memory controller */
-#define IRQ_PBX_ETH            (IRQ_PBX_GIC_START + 28)        /* Ethernet controller */
-#define IRQ_PBX_USB            (IRQ_PBX_GIC_START + 29)        /* USB controller */
-#define IRQ_PBX_TSPEN          (IRQ_PBX_GIC_START + 30)        /* Touchscreen pen */
-#define IRQ_PBX_TSKPAD         (IRQ_PBX_GIC_START + 31)        /* Touchscreen keypad */
-
-#define IRQ_PBX_PMU_SCU0        (IRQ_PBX_GIC_START + 32)        /* SCU PMU Interrupts (11mp) */
-#define IRQ_PBX_PMU_SCU1        (IRQ_PBX_GIC_START + 33)
-#define IRQ_PBX_PMU_SCU2        (IRQ_PBX_GIC_START + 34)
-#define IRQ_PBX_PMU_SCU3        (IRQ_PBX_GIC_START + 35)
-#define IRQ_PBX_PMU_SCU4        (IRQ_PBX_GIC_START + 36)
-#define IRQ_PBX_PMU_SCU5        (IRQ_PBX_GIC_START + 37)
-#define IRQ_PBX_PMU_SCU6        (IRQ_PBX_GIC_START + 38)
-#define IRQ_PBX_PMU_SCU7        (IRQ_PBX_GIC_START + 39)
-
-#define IRQ_PBX_WATCHDOG1       (IRQ_PBX_GIC_START + 40)        /* Watchdog1 timer */
-#define IRQ_PBX_TIMER4_5        (IRQ_PBX_GIC_START + 41)        /* Timer 0/1 (default timer) */
-#define IRQ_PBX_TIMER6_7        (IRQ_PBX_GIC_START + 42)        /* Timer 2/3 */
-/* ... */
-#define IRQ_PBX_PMU_CPU0        (IRQ_PBX_GIC_START + 44)        /* CPU PMU Interrupts */
-#define IRQ_PBX_PMU_CPU1        (IRQ_PBX_GIC_START + 45)
-#define IRQ_PBX_PMU_CPU2        (IRQ_PBX_GIC_START + 46)
-#define IRQ_PBX_PMU_CPU3        (IRQ_PBX_GIC_START + 47)
-
-/* ... */
-#define IRQ_PBX_PCI0           (IRQ_PBX_GIC_START + 50)
-#define IRQ_PBX_PCI1           (IRQ_PBX_GIC_START + 51)
-#define IRQ_PBX_PCI2           (IRQ_PBX_GIC_START + 52)
-#define IRQ_PBX_PCI3           (IRQ_PBX_GIC_START + 53)
-
-#define IRQ_PBX_SMC            -1
-#define IRQ_PBX_SCTL           -1
-
-#define NR_GIC_PBX             1
-
-/*
- * Only define NR_IRQS if less than NR_IRQS_PBX
- */
-#define NR_IRQS_PBX            (IRQ_PBX_GIC_START + 96)
-
-#if defined(CONFIG_MACH_REALVIEW_PBX)
-
-#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PBX)
-#undef NR_IRQS
-#define NR_IRQS                        NR_IRQS_PBX
-#endif
-
-#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PBX)
-#undef MAX_GIC_NR
-#define MAX_GIC_NR             NR_GIC_PBX
-#endif
-
-#endif /* CONFIG_MACH_REALVIEW_PBX */
-
-#endif /* __MACH_IRQS_PBX_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs.h b/arch/arm/mach-realview/include/mach/irqs.h
deleted file mode 100644 (file)
index 78854f2..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  arch/arm/mach-realview/include/mach/irqs.h
- *
- *  Copyright (C) 2003 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; 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_IRQS_H
-#define __ASM_ARCH_IRQS_H
-
-#include <mach/irqs-eb.h>
-#include <mach/irqs-pb11mp.h>
-#include <mach/irqs-pb1176.h>
-#include <mach/irqs-pba8.h>
-#include <mach/irqs-pbx.h>
-
-#define IRQ_LOCALTIMER         29
-#define IRQ_LOCALWDOG          30
-
-#define IRQ_GIC_START          32
-
-#ifndef NR_IRQS
-#error "NR_IRQS not defined by the board-specific files"
-#endif
-
-#endif
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
deleted file mode 100644 (file)
index 23e7a31..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  arch/arm/mach-realview/include/mach/memory.h
- *
- *  Copyright (C) 2003 ARM Limited
- *
- * This program is free software; 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
-
-#ifdef CONFIG_SPARSEMEM
-
-/*
- * Sparsemem definitions for RealView PBX.
- *
- * The RealView PBX board has another block of 512MB of RAM at 0x20000000,
- * however only the block at 0x70000000 (or the 256MB mirror at 0x00000000)
- * may be used for DMA.
- *
- * The macros below define a section size of 256MB and a non-linear virtual to
- * physical mapping:
- *
- * 256MB @ 0x00000000 -> PAGE_OFFSET
- * 512MB @ 0x20000000 -> PAGE_OFFSET + 0x10000000
- * 256MB @ 0x80000000 -> PAGE_OFFSET + 0x30000000
- */
-#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
-#error "SPARSEMEM not available with REALVIEW_HIGH_PHYS_OFFSET"
-#endif
-
-#define MAX_PHYSMEM_BITS       32
-#define SECTION_SIZE_BITS      28
-
-/* bank page offsets */
-#define PAGE_OFFSET1   (PAGE_OFFSET + 0x10000000)
-#define PAGE_OFFSET2   (PAGE_OFFSET + 0x30000000)
-
-#define PHYS_OFFSET PLAT_PHYS_OFFSET
-
-#define __phys_to_virt(phys)                                           \
-       ((phys) >= 0x80000000 ? (phys) - 0x80000000 + PAGE_OFFSET2 :    \
-        (phys) >= 0x20000000 ? (phys) - 0x20000000 + PAGE_OFFSET1 :    \
-        (phys) + PAGE_OFFSET)
-
-#define __virt_to_phys(virt)                                           \
-        ((virt) >= PAGE_OFFSET2 ? (virt) - PAGE_OFFSET2 + 0x80000000 : \
-         (virt) >= PAGE_OFFSET1 ? (virt) - PAGE_OFFSET1 + 0x20000000 : \
-         (virt) - PAGE_OFFSET)
-
-#endif /* CONFIG_SPARSEMEM */
-
-#endif
diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h
deleted file mode 100644 (file)
index 1b77a27..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/platform.h
- *
- * Copyright (c) ARM Limited 2003.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __ASM_ARCH_PLATFORM_H
-#define __ASM_ARCH_PLATFORM_H
-
-/*
- * Memory definitions
- */
-#define REALVIEW_BOOT_ROM_LO          0x30000000               /* DoC Base (64Mb)...*/
-#define REALVIEW_BOOT_ROM_HI          0x30000000
-#define REALVIEW_BOOT_ROM_BASE        REALVIEW_BOOT_ROM_HI      /*  Normal position */
-#define REALVIEW_BOOT_ROM_SIZE        SZ_64M
-
-#define REALVIEW_SSRAM_BASE           /* REALVIEW_SSMC_BASE ? */
-#define REALVIEW_SSRAM_SIZE           SZ_2M
-
-/* 
- *  SDRAM
- */
-#define REALVIEW_SDRAM_BASE           0x00000000
-
-/* 
- *  Logic expansion modules
- * 
- */
-
-
-/* ------------------------------------------------------------------------
- *  RealView Registers
- * ------------------------------------------------------------------------
- * 
- */
-#define REALVIEW_SYS_ID_OFFSET               0x00
-#define REALVIEW_SYS_SW_OFFSET               0x04
-#define REALVIEW_SYS_LED_OFFSET              0x08
-#define REALVIEW_SYS_OSC0_OFFSET             0x0C
-
-#define REALVIEW_SYS_OSC1_OFFSET             0x10
-#define REALVIEW_SYS_OSC2_OFFSET             0x14
-#define REALVIEW_SYS_OSC3_OFFSET             0x18
-#define REALVIEW_SYS_OSC4_OFFSET             0x1C      /* OSC1 for RealView/AB */
-
-#define REALVIEW_SYS_LOCK_OFFSET             0x20
-#define REALVIEW_SYS_100HZ_OFFSET            0x24
-#define REALVIEW_SYS_CFGDATA1_OFFSET         0x28
-#define REALVIEW_SYS_CFGDATA2_OFFSET         0x2C
-#define REALVIEW_SYS_FLAGS_OFFSET            0x30
-#define REALVIEW_SYS_FLAGSSET_OFFSET         0x30
-#define REALVIEW_SYS_FLAGSCLR_OFFSET         0x34
-#define REALVIEW_SYS_NVFLAGS_OFFSET          0x38
-#define REALVIEW_SYS_NVFLAGSSET_OFFSET       0x38
-#define REALVIEW_SYS_NVFLAGSCLR_OFFSET       0x3C
-#define REALVIEW_SYS_RESETCTL_OFFSET         0x40
-#define REALVIEW_SYS_PCICTL_OFFSET           0x44
-#define REALVIEW_SYS_MCI_OFFSET              0x48
-#define REALVIEW_SYS_FLASH_OFFSET            0x4C
-#define REALVIEW_SYS_CLCD_OFFSET             0x50
-#define REALVIEW_SYS_CLCDSER_OFFSET          0x54
-#define REALVIEW_SYS_BOOTCS_OFFSET           0x58
-#define REALVIEW_SYS_24MHz_OFFSET            0x5C
-#define REALVIEW_SYS_MISC_OFFSET             0x60
-#define REALVIEW_SYS_IOSEL_OFFSET            0x70
-#define REALVIEW_SYS_PROCID_OFFSET           0x84
-#define REALVIEW_SYS_TEST_OSC0_OFFSET        0xC0
-#define REALVIEW_SYS_TEST_OSC1_OFFSET        0xC4
-#define REALVIEW_SYS_TEST_OSC2_OFFSET        0xC8
-#define REALVIEW_SYS_TEST_OSC3_OFFSET        0xCC
-#define REALVIEW_SYS_TEST_OSC4_OFFSET        0xD0
-
-#define REALVIEW_SYS_BASE                    0x10000000
-#define REALVIEW_SYS_ID                      (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
-#define REALVIEW_SYS_SW                      (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
-#define REALVIEW_SYS_LED                     (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
-#define REALVIEW_SYS_OSC0                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
-#define REALVIEW_SYS_OSC1                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
-
-#define REALVIEW_SYS_LOCK                    (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
-#define REALVIEW_SYS_100HZ                   (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
-#define REALVIEW_SYS_CFGDATA1                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
-#define REALVIEW_SYS_CFGDATA2                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
-#define REALVIEW_SYS_FLAGS                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
-#define REALVIEW_SYS_FLAGSSET                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
-#define REALVIEW_SYS_FLAGSCLR                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
-#define REALVIEW_SYS_NVFLAGS                 (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
-#define REALVIEW_SYS_NVFLAGSSET              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
-#define REALVIEW_SYS_NVFLAGSCLR              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
-#define REALVIEW_SYS_RESETCTL                (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
-#define REALVIEW_SYS_PCICTL                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
-#define REALVIEW_SYS_MCI                     (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
-#define REALVIEW_SYS_FLASH                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
-#define REALVIEW_SYS_CLCD                    (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
-#define REALVIEW_SYS_CLCDSER                 (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
-#define REALVIEW_SYS_BOOTCS                  (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
-#define REALVIEW_SYS_24MHz                   (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
-#define REALVIEW_SYS_MISC                    (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
-#define REALVIEW_SYS_IOSEL                   (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
-#define REALVIEW_SYS_PROCID                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET)
-#define REALVIEW_SYS_TEST_OSC0               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
-#define REALVIEW_SYS_TEST_OSC1               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
-#define REALVIEW_SYS_TEST_OSC2               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
-#define REALVIEW_SYS_TEST_OSC3               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
-#define REALVIEW_SYS_TEST_OSC4               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
-
-/* ------------------------------------------------------------------------
- *  RealView control registers
- * ------------------------------------------------------------------------
- */
-
-/* 
- * REALVIEW_IDFIELD
- *
- * 31:24 = manufacturer (0x41 = ARM)
- * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
- * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
- * 11:4  = build value
- * 3:0   = revision number (0x1 = rev B (AHB))
- */
-
-/*
- * REALVIEW_SYS_LOCK
- *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
- *     SYS_CLD, SYS_BOOTCS
- */
-#define REALVIEW_SYS_LOCK_LOCKED    (1 << 16)
-#define REALVIEW_SYS_LOCK_VAL  0xA05F         /* Enable write access */
-
-/*
- * REALVIEW_SYS_FLASH
- */
-#define REALVIEW_FLASHPROG_FLVPPEN     (1 << 0)        /* Enable writing to flash */
-
-/*
- * REALVIEW_INTREG
- *     - used to acknowledge and control MMCI and UART interrupts 
- */
-#define REALVIEW_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
-#define REALVIEW_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
-#define REALVIEW_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
-                                                /* write 1 to acknowledge and clear               */
-#define REALVIEW_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
-#define REALVIEW_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
-
-/*
- * RealView common peripheral addresses
- */
-#define REALVIEW_SCTL_BASE            0x10001000       /* System controller */
-#define REALVIEW_I2C_BASE             0x10002000       /* I2C control */
-#define REALVIEW_AACI_BASE            0x10004000       /* Audio */
-#define REALVIEW_MMCI0_BASE           0x10005000       /* MMC interface */
-#define REALVIEW_KMI0_BASE            0x10006000       /* KMI interface */
-#define REALVIEW_KMI1_BASE            0x10007000       /* KMI 2nd interface */
-#define REALVIEW_CHAR_LCD_BASE        0x10008000       /* Character LCD */
-#define REALVIEW_SCI_BASE             0x1000E000       /* Smart card controller */
-#define REALVIEW_GPIO1_BASE           0x10014000       /* GPIO port 1 */
-#define REALVIEW_GPIO2_BASE           0x10015000       /* GPIO port 2 */
-#define REALVIEW_DMC_BASE             0x10018000       /* DMC configuration */
-#define REALVIEW_DMAC_BASE            0x10030000       /* DMA controller */
-
-/* PCI space */
-#define REALVIEW_PCI_BASE             0x41000000       /* PCI Interface */
-#define REALVIEW_PCI_CFG_BASE        0x42000000
-#define REALVIEW_PCI_MEM_BASE0        0x44000000
-#define REALVIEW_PCI_MEM_BASE1        0x50000000
-#define REALVIEW_PCI_MEM_BASE2        0x60000000
-/* Sizes of above maps */
-#define REALVIEW_PCI_BASE_SIZE        0x01000000
-#define REALVIEW_PCI_CFG_BASE_SIZE    0x02000000
-#define REALVIEW_PCI_MEM_BASE0_SIZE   0x0c000000       /* 32Mb */
-#define REALVIEW_PCI_MEM_BASE1_SIZE   0x10000000       /* 256Mb */
-#define REALVIEW_PCI_MEM_BASE2_SIZE   0x10000000       /* 256Mb */
-
-#define REALVIEW_SDRAM67_BASE         0x70000000       /* SDRAM banks 6 and 7 */
-#define REALVIEW_LT_BASE              0x80000000       /* Logic Tile expansion */
-
-/*
- * CompactFlash
- */
-#define REALVIEW_CF_BASE               0x18000000      /* CompactFlash */
-#define REALVIEW_CF_MEM_BASE           0x18003000      /* SMC for CompactFlash */
-
-/*
- * Disk on Chip
- */
-#define REALVIEW_DOC_BASE             0x2C000000
-#define REALVIEW_DOC_SIZE             (16 << 20)
-#define REALVIEW_DOC_PAGE_SIZE        512
-#define REALVIEW_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
-
-#define ERASE_UNIT_PAGES    32
-#define START_PAGE          0x80
-
-/* 
- *  LED settings, bits [7:0]
- */
-#define REALVIEW_SYS_LED0             (1 << 0)
-#define REALVIEW_SYS_LED1             (1 << 1)
-#define REALVIEW_SYS_LED2             (1 << 2)
-#define REALVIEW_SYS_LED3             (1 << 3)
-#define REALVIEW_SYS_LED4             (1 << 4)
-#define REALVIEW_SYS_LED5             (1 << 5)
-#define REALVIEW_SYS_LED6             (1 << 6)
-#define REALVIEW_SYS_LED7             (1 << 7)
-
-#define ALL_LEDS                  0xFF
-
-#define LED_BANK                  REALVIEW_SYS_LED
-
-/* 
- * Control registers
- */
-#define REALVIEW_IDFIELD_OFFSET        0x0     /* RealView build information */
-#define REALVIEW_FLASHPROG_OFFSET      0x4     /* Flash devices */
-#define REALVIEW_INTREG_OFFSET         0x8     /* Interrupt control */
-#define REALVIEW_DECODE_OFFSET         0xC     /* Fitted logic modules */
-
-/*
- * System controller bit assignment
- */
-#define REALVIEW_REFCLK        0
-#define REALVIEW_TIMCLK        1
-
-#define REALVIEW_TIMER1_EnSel  15
-#define REALVIEW_TIMER2_EnSel  17
-#define REALVIEW_TIMER3_EnSel  19
-#define REALVIEW_TIMER4_EnSel  21
-
-
-#define REALVIEW_CSR_BASE             0x10000000
-#define REALVIEW_CSR_SIZE             0x10000000
-
-#endif /* __ASM_ARCH_PLATFORM_H */
diff --git a/arch/arm/mach-realview/include/mach/uncompress.h b/arch/arm/mach-realview/include/mach/uncompress.h
deleted file mode 100644 (file)
index cfa30d2..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  arch/arm/mach-realview/include/mach/uncompress.h
- *
- *  Copyright (C) 2003 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#include <mach/board-eb.h>
-#include <mach/board-pb11mp.h>
-#include <mach/board-pb1176.h>
-#include <mach/board-pba8.h>
-#include <mach/board-pbx.h>
-
-#define AMBA_UART_DR(base)     (*(volatile unsigned char *)((base) + 0x00))
-#define AMBA_UART_LCRH(base)   (*(volatile unsigned char *)((base) + 0x2c))
-#define AMBA_UART_CR(base)     (*(volatile unsigned char *)((base) + 0x30))
-#define AMBA_UART_FR(base)     (*(volatile unsigned char *)((base) + 0x18))
-
-/*
- * Return the UART base address
- */
-static inline unsigned long get_uart_base(void)
-{
-       if (machine_is_realview_eb())
-               return REALVIEW_EB_UART0_BASE;
-       else if (machine_is_realview_pb11mp())
-               return REALVIEW_PB11MP_UART0_BASE;
-       else if (machine_is_realview_pb1176())
-               return REALVIEW_PB1176_UART0_BASE;
-       else if (machine_is_realview_pba8())
-               return REALVIEW_PBA8_UART0_BASE;
-       else if (machine_is_realview_pbx())
-               return REALVIEW_PBX_UART0_BASE;
-       else
-               return 0;
-}
-
-/*
- * This does not append a newline
- */
-static inline void putc(int c)
-{
-       unsigned long base = get_uart_base();
-
-       while (AMBA_UART_FR(base) & (1 << 5))
-               barrier();
-
-       AMBA_UART_DR(base) = c;
-}
-
-static inline void flush(void)
-{
-       unsigned long base = get_uart_base();
-
-       while (AMBA_UART_FR(base) & (1 << 3))
-               barrier();
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
diff --git a/arch/arm/mach-realview/irqs-eb.h b/arch/arm/mach-realview/irqs-eb.h
new file mode 100644 (file)
index 0000000..61e3168
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2007 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_EB_H
+#define __MACH_IRQS_EB_H
+
+#define IRQ_LOCALTIMER         29
+#define IRQ_EB_GIC_START       32
+
+/*
+ * RealView EB interrupt sources
+ */
+#define IRQ_EB_WDOG            (IRQ_EB_GIC_START + 0)          /* Watchdog timer */
+#define IRQ_EB_SOFT            (IRQ_EB_GIC_START + 1)          /* Software interrupt */
+#define IRQ_EB_COMMRx          (IRQ_EB_GIC_START + 2)          /* Debug Comm Rx interrupt */
+#define IRQ_EB_COMMTx          (IRQ_EB_GIC_START + 3)          /* Debug Comm Tx interrupt */
+#define IRQ_EB_TIMER0_1                (IRQ_EB_GIC_START + 4)          /* Timer 0 and 1 */
+#define IRQ_EB_TIMER2_3                (IRQ_EB_GIC_START + 5)          /* Timer 2 and 3 */
+#define IRQ_EB_GPIO0           (IRQ_EB_GIC_START + 6)          /* GPIO 0 */
+#define IRQ_EB_GPIO1           (IRQ_EB_GIC_START + 7)          /* GPIO 1 */
+#define IRQ_EB_GPIO2           (IRQ_EB_GIC_START + 8)          /* GPIO 2 */
+                                                               /* 9 reserved */
+#define IRQ_EB_RTC             (IRQ_EB_GIC_START + 10)         /* Real Time Clock */
+#define IRQ_EB_SSP             (IRQ_EB_GIC_START + 11)         /* Synchronous Serial Port */
+#define IRQ_EB_UART0           (IRQ_EB_GIC_START + 12)         /* UART 0 on development chip */
+#define IRQ_EB_UART1           (IRQ_EB_GIC_START + 13)         /* UART 1 on development chip */
+#define IRQ_EB_UART2           (IRQ_EB_GIC_START + 14)         /* UART 2 on development chip */
+#define IRQ_EB_UART3           (IRQ_EB_GIC_START + 15)         /* UART 3 on development chip */
+#define IRQ_EB_SCI             (IRQ_EB_GIC_START + 16)         /* Smart Card Interface */
+#define IRQ_EB_MMCI0A          (IRQ_EB_GIC_START + 17)         /* Multimedia Card 0A */
+#define IRQ_EB_MMCI0B          (IRQ_EB_GIC_START + 18)         /* Multimedia Card 0B */
+#define IRQ_EB_AACI            (IRQ_EB_GIC_START + 19)         /* Audio Codec */
+#define IRQ_EB_KMI0            (IRQ_EB_GIC_START + 20)         /* Keyboard/Mouse port 0 */
+#define IRQ_EB_KMI1            (IRQ_EB_GIC_START + 21)         /* Keyboard/Mouse port 1 */
+#define IRQ_EB_CHARLCD         (IRQ_EB_GIC_START + 22)         /* Character LCD */
+#define IRQ_EB_CLCD            (IRQ_EB_GIC_START + 23)         /* CLCD controller */
+#define IRQ_EB_DMA             (IRQ_EB_GIC_START + 24)         /* DMA controller */
+#define IRQ_EB_PWRFAIL         (IRQ_EB_GIC_START + 25)         /* Power failure */
+#define IRQ_EB_PISMO           (IRQ_EB_GIC_START + 26)         /* PISMO interface */
+#define IRQ_EB_DoC             (IRQ_EB_GIC_START + 27)         /* Disk on Chip memory controller */
+#define IRQ_EB_ETH             (IRQ_EB_GIC_START + 28)         /* Ethernet controller */
+#define IRQ_EB_USB             (IRQ_EB_GIC_START + 29)         /* USB controller */
+#define IRQ_EB_TSPEN           (IRQ_EB_GIC_START + 30)         /* Touchscreen pen */
+#define IRQ_EB_TSKPAD          (IRQ_EB_GIC_START + 31)         /* Touchscreen keypad */
+
+/*
+ * RealView EB + ARM11MPCore interrupt sources (primary GIC on the core tile)
+ */
+#define IRQ_EB11MP_AACI                (IRQ_EB_GIC_START + 0)
+#define IRQ_EB11MP_TIMER0_1    (IRQ_EB_GIC_START + 1)
+#define IRQ_EB11MP_TIMER2_3    (IRQ_EB_GIC_START + 2)
+#define IRQ_EB11MP_USB         (IRQ_EB_GIC_START + 3)
+#define IRQ_EB11MP_UART0       (IRQ_EB_GIC_START + 4)
+#define IRQ_EB11MP_UART1       (IRQ_EB_GIC_START + 5)
+#define IRQ_EB11MP_RTC         (IRQ_EB_GIC_START + 6)
+#define IRQ_EB11MP_KMI0                (IRQ_EB_GIC_START + 7)
+#define IRQ_EB11MP_KMI1                (IRQ_EB_GIC_START + 8)
+#define IRQ_EB11MP_ETH         (IRQ_EB_GIC_START + 9)
+#define IRQ_EB11MP_EB_IRQ1     (IRQ_EB_GIC_START + 10)         /* main GIC */
+#define IRQ_EB11MP_EB_IRQ2     (IRQ_EB_GIC_START + 11)         /* tile GIC */
+#define IRQ_EB11MP_EB_FIQ1     (IRQ_EB_GIC_START + 12)         /* main GIC */
+#define IRQ_EB11MP_EB_FIQ2     (IRQ_EB_GIC_START + 13)         /* tile GIC */
+#define IRQ_EB11MP_MMCI0A      (IRQ_EB_GIC_START + 14)
+#define IRQ_EB11MP_MMCI0B      (IRQ_EB_GIC_START + 15)
+
+#define IRQ_EB11MP_PMU_CPU0    (IRQ_EB_GIC_START + 17)
+#define IRQ_EB11MP_PMU_CPU1    (IRQ_EB_GIC_START + 18)
+#define IRQ_EB11MP_PMU_CPU2    (IRQ_EB_GIC_START + 19)
+#define IRQ_EB11MP_PMU_CPU3    (IRQ_EB_GIC_START + 20)
+#define IRQ_EB11MP_PMU_SCU0    (IRQ_EB_GIC_START + 21)
+#define IRQ_EB11MP_PMU_SCU1    (IRQ_EB_GIC_START + 22)
+#define IRQ_EB11MP_PMU_SCU2    (IRQ_EB_GIC_START + 23)
+#define IRQ_EB11MP_PMU_SCU3    (IRQ_EB_GIC_START + 24)
+#define IRQ_EB11MP_PMU_SCU4    (IRQ_EB_GIC_START + 25)
+#define IRQ_EB11MP_PMU_SCU5    (IRQ_EB_GIC_START + 26)
+#define IRQ_EB11MP_PMU_SCU6    (IRQ_EB_GIC_START + 27)
+#define IRQ_EB11MP_PMU_SCU7    (IRQ_EB_GIC_START + 28)
+
+#define IRQ_EB11MP_L220_EVENT  (IRQ_EB_GIC_START + 29)
+#define IRQ_EB11MP_L220_SLAVE  (IRQ_EB_GIC_START + 30)
+#define IRQ_EB11MP_L220_DECODE (IRQ_EB_GIC_START + 31)
+
+/*
+ * The 11MPcore tile leaves the following unconnected.
+ */
+#define IRQ_EB11MP_UART2       0
+#define IRQ_EB11MP_UART3       0
+#define IRQ_EB11MP_CLCD                0
+#define IRQ_EB11MP_DMA         0
+#define IRQ_EB11MP_WDOG                0
+#define IRQ_EB11MP_GPIO0       0
+#define IRQ_EB11MP_GPIO1       0
+#define IRQ_EB11MP_GPIO2       0
+#define IRQ_EB11MP_SCI         0
+#define IRQ_EB11MP_SSP         0
+
+#define NR_GIC_EB11MP          2
+
+#endif /* __MACH_IRQS_EB_H */
diff --git a/arch/arm/mach-realview/irqs-pb1176.h b/arch/arm/mach-realview/irqs-pb1176.h
new file mode 100644 (file)
index 0000000..778edfd
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_PB1176_H
+#define __MACH_IRQS_PB1176_H
+
+#define IRQ_DC1176_GIC_START                   32
+#define IRQ_PB1176_GIC_START                   64
+
+/*
+ * ARM1176 DevChip interrupt sources (primary GIC)
+ */
+#define IRQ_DC1176_WATCHDOG    (IRQ_DC1176_GIC_START + 0)      /* Watchdog timer */
+#define IRQ_DC1176_SOFTINT     (IRQ_DC1176_GIC_START + 1)      /* Software interrupt */
+#define IRQ_DC1176_COMMRx      (IRQ_DC1176_GIC_START + 2)      /* Debug Comm Rx interrupt */
+#define IRQ_DC1176_COMMTx      (IRQ_DC1176_GIC_START + 3)      /* Debug Comm Tx interrupt */
+#define IRQ_DC1176_CORE_PMU    (IRQ_DC1176_GIC_START + 7)      /* Core PMU interrupt */
+#define IRQ_DC1176_TIMER0      (IRQ_DC1176_GIC_START + 8)      /* Timer 0 */
+#define IRQ_DC1176_TIMER1      (IRQ_DC1176_GIC_START + 9)      /* Timer 1 */
+#define IRQ_DC1176_TIMER2      (IRQ_DC1176_GIC_START + 10)     /* Timer 2 */
+#define IRQ_DC1176_APC         (IRQ_DC1176_GIC_START + 11)
+#define IRQ_DC1176_IEC         (IRQ_DC1176_GIC_START + 12)
+#define IRQ_DC1176_L2CC                (IRQ_DC1176_GIC_START + 13)
+#define IRQ_DC1176_RTC         (IRQ_DC1176_GIC_START + 14)
+#define IRQ_DC1176_CLCD                (IRQ_DC1176_GIC_START + 15)     /* CLCD controller */
+#define IRQ_DC1176_GPIO0       (IRQ_DC1176_GIC_START + 16)
+#define IRQ_DC1176_SSP         (IRQ_DC1176_GIC_START + 17)     /* SSP port */
+#define IRQ_DC1176_UART0       (IRQ_DC1176_GIC_START + 18)     /* UART 0 on development chip */
+#define IRQ_DC1176_UART1       (IRQ_DC1176_GIC_START + 19)     /* UART 1 on development chip */
+#define IRQ_DC1176_UART2       (IRQ_DC1176_GIC_START + 20)     /* UART 2 on development chip */
+#define IRQ_DC1176_UART3       (IRQ_DC1176_GIC_START + 21)     /* UART 3 on development chip */
+
+#define IRQ_DC1176_PB_IRQ2     (IRQ_DC1176_GIC_START + 30)     /* tile GIC */
+#define IRQ_DC1176_PB_IRQ1     (IRQ_DC1176_GIC_START + 31)     /* main GIC */
+
+/*
+ * RealView PB1176 interrupt sources (secondary GIC)
+ */
+#define IRQ_PB1176_MMCI0A      (IRQ_PB1176_GIC_START + 1)      /* Multimedia Card 0A */
+#define IRQ_PB1176_MMCI0B      (IRQ_PB1176_GIC_START + 2)      /* Multimedia Card 0A */
+#define IRQ_PB1176_KMI0                (IRQ_PB1176_GIC_START + 3)      /* Keyboard/Mouse port 0 */
+#define IRQ_PB1176_KMI1                (IRQ_PB1176_GIC_START + 4)      /* Keyboard/Mouse port 1 */
+#define IRQ_PB1176_SCI         (IRQ_PB1176_GIC_START + 5)
+#define IRQ_PB1176_UART4       (IRQ_PB1176_GIC_START + 6)      /* UART 4 on baseboard */
+#define IRQ_PB1176_CHARLCD     (IRQ_PB1176_GIC_START + 7)      /* Character LCD */
+#define IRQ_PB1176_GPIO1       (IRQ_PB1176_GIC_START + 8)
+#define IRQ_PB1176_GPIO2       (IRQ_PB1176_GIC_START + 9)
+#define IRQ_PB1176_ETH         (IRQ_PB1176_GIC_START + 10)     /* Ethernet controller */
+#define IRQ_PB1176_USB         (IRQ_PB1176_GIC_START + 11)     /* USB controller */
+
+#define IRQ_PB1176_PISMO       (IRQ_PB1176_GIC_START + 16)
+
+#define IRQ_PB1176_AACI                (IRQ_PB1176_GIC_START + 19)     /* Audio Codec */
+
+#define IRQ_PB1176_TIMER0_1    (IRQ_PB1176_GIC_START + 22)
+#define IRQ_PB1176_TIMER2_3    (IRQ_PB1176_GIC_START + 23)
+#define IRQ_PB1176_DMAC                (IRQ_PB1176_GIC_START + 24)     /* DMA controller */
+#define IRQ_PB1176_RTC         (IRQ_PB1176_GIC_START + 25)     /* Real Time Clock */
+
+#define IRQ_PB1176_SCTL                -1
+
+#endif /* __MACH_IRQS_PB1176_H */
diff --git a/arch/arm/mach-realview/irqs-pb11mp.h b/arch/arm/mach-realview/irqs-pb11mp.h
new file mode 100644 (file)
index 0000000..938898a
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_PB11MP_H
+#define __MACH_IRQS_PB11MP_H
+
+#define IRQ_LOCALTIMER                         29
+#define IRQ_TC11MP_GIC_START                   32
+#define IRQ_PB11MP_GIC_START                   64
+
+/*
+ * ARM11MPCore test chip interrupt sources (primary GIC on the test chip)
+ */
+#define IRQ_TC11MP_AACI                (IRQ_TC11MP_GIC_START + 0)
+#define IRQ_TC11MP_TIMER0_1    (IRQ_TC11MP_GIC_START + 1)
+#define IRQ_TC11MP_TIMER2_3    (IRQ_TC11MP_GIC_START + 2)
+#define IRQ_TC11MP_USB         (IRQ_TC11MP_GIC_START + 3)
+#define IRQ_TC11MP_UART0       (IRQ_TC11MP_GIC_START + 4)
+#define IRQ_TC11MP_UART1       (IRQ_TC11MP_GIC_START + 5)
+#define IRQ_TC11MP_RTC         (IRQ_TC11MP_GIC_START + 6)
+#define IRQ_TC11MP_KMI0                (IRQ_TC11MP_GIC_START + 7)
+#define IRQ_TC11MP_KMI1                (IRQ_TC11MP_GIC_START + 8)
+#define IRQ_TC11MP_ETH         (IRQ_TC11MP_GIC_START + 9)
+#define IRQ_TC11MP_PB_IRQ1     (IRQ_TC11MP_GIC_START + 10)             /* main GIC */
+#define IRQ_TC11MP_PB_IRQ2     (IRQ_TC11MP_GIC_START + 11)             /* tile GIC */
+#define IRQ_TC11MP_PB_FIQ1     (IRQ_TC11MP_GIC_START + 12)             /* main GIC */
+#define IRQ_TC11MP_PB_FIQ2     (IRQ_TC11MP_GIC_START + 13)             /* tile GIC */
+#define IRQ_TC11MP_MMCI0A      (IRQ_TC11MP_GIC_START + 14)
+#define IRQ_TC11MP_MMCI0B      (IRQ_TC11MP_GIC_START + 15)
+
+#define IRQ_TC11MP_PMU_CPU0    (IRQ_TC11MP_GIC_START + 17)
+#define IRQ_TC11MP_PMU_CPU1    (IRQ_TC11MP_GIC_START + 18)
+#define IRQ_TC11MP_PMU_CPU2    (IRQ_TC11MP_GIC_START + 19)
+#define IRQ_TC11MP_PMU_CPU3    (IRQ_TC11MP_GIC_START + 20)
+#define IRQ_TC11MP_PMU_SCU0    (IRQ_TC11MP_GIC_START + 21)
+#define IRQ_TC11MP_PMU_SCU1    (IRQ_TC11MP_GIC_START + 22)
+#define IRQ_TC11MP_PMU_SCU2    (IRQ_TC11MP_GIC_START + 23)
+#define IRQ_TC11MP_PMU_SCU3    (IRQ_TC11MP_GIC_START + 24)
+#define IRQ_TC11MP_PMU_SCU4    (IRQ_TC11MP_GIC_START + 25)
+#define IRQ_TC11MP_PMU_SCU5    (IRQ_TC11MP_GIC_START + 26)
+#define IRQ_TC11MP_PMU_SCU6    (IRQ_TC11MP_GIC_START + 27)
+#define IRQ_TC11MP_PMU_SCU7    (IRQ_TC11MP_GIC_START + 28)
+
+#define IRQ_TC11MP_L220_EVENT  (IRQ_TC11MP_GIC_START + 29)
+#define IRQ_TC11MP_L220_SLAVE  (IRQ_TC11MP_GIC_START + 30)
+#define IRQ_TC11MP_L220_DECODE (IRQ_TC11MP_GIC_START + 31)
+
+/*
+ * RealView PB11MPCore GIC interrupt sources (secondary GIC on the board)
+ */
+#define IRQ_PB11MP_WATCHDOG    (IRQ_PB11MP_GIC_START + 0)      /* Watchdog timer */
+#define IRQ_PB11MP_SOFT                (IRQ_PB11MP_GIC_START + 1)      /* Software interrupt */
+#define IRQ_PB11MP_COMMRx      (IRQ_PB11MP_GIC_START + 2)      /* Debug Comm Rx interrupt */
+#define IRQ_PB11MP_COMMTx      (IRQ_PB11MP_GIC_START + 3)      /* Debug Comm Tx interrupt */
+#define IRQ_PB11MP_GPIO0       (IRQ_PB11MP_GIC_START + 6)      /* GPIO 0 */
+#define IRQ_PB11MP_GPIO1       (IRQ_PB11MP_GIC_START + 7)      /* GPIO 1 */
+#define IRQ_PB11MP_GPIO2       (IRQ_PB11MP_GIC_START + 8)      /* GPIO 2 */
+                                                               /* 9 reserved */
+#define IRQ_PB11MP_RTC_GIC1    (IRQ_PB11MP_GIC_START + 10)     /* Real Time Clock */
+#define IRQ_PB11MP_SSP         (IRQ_PB11MP_GIC_START + 11)     /* Synchronous Serial Port */
+#define IRQ_PB11MP_UART0_GIC1  (IRQ_PB11MP_GIC_START + 12)     /* UART 0 on development chip */
+#define IRQ_PB11MP_UART1_GIC1  (IRQ_PB11MP_GIC_START + 13)     /* UART 1 on development chip */
+#define IRQ_PB11MP_UART2       (IRQ_PB11MP_GIC_START + 14)     /* UART 2 on development chip */
+#define IRQ_PB11MP_UART3       (IRQ_PB11MP_GIC_START + 15)     /* UART 3 on development chip */
+#define IRQ_PB11MP_SCI         (IRQ_PB11MP_GIC_START + 16)     /* Smart Card Interface */
+#define IRQ_PB11MP_MMCI0A_GIC1 (IRQ_PB11MP_GIC_START + 17)     /* Multimedia Card 0A */
+#define IRQ_PB11MP_MMCI0B_GIC1 (IRQ_PB11MP_GIC_START + 18)     /* Multimedia Card 0B */
+#define IRQ_PB11MP_AACI_GIC1   (IRQ_PB11MP_GIC_START + 19)     /* Audio Codec */
+#define IRQ_PB11MP_KMI0_GIC1   (IRQ_PB11MP_GIC_START + 20)     /* Keyboard/Mouse port 0 */
+#define IRQ_PB11MP_KMI1_GIC1   (IRQ_PB11MP_GIC_START + 21)     /* Keyboard/Mouse port 1 */
+#define IRQ_PB11MP_CHARLCD     (IRQ_PB11MP_GIC_START + 22)     /* Character LCD */
+#define IRQ_PB11MP_CLCD                (IRQ_PB11MP_GIC_START + 23)     /* CLCD controller */
+#define IRQ_PB11MP_DMAC                (IRQ_PB11MP_GIC_START + 24)     /* DMA controller */
+#define IRQ_PB11MP_PWRFAIL     (IRQ_PB11MP_GIC_START + 25)     /* Power failure */
+#define IRQ_PB11MP_PISMO       (IRQ_PB11MP_GIC_START + 26)     /* PISMO interface */
+#define IRQ_PB11MP_DoC         (IRQ_PB11MP_GIC_START + 27)     /* Disk on Chip memory controller */
+#define IRQ_PB11MP_ETH_GIC1    (IRQ_PB11MP_GIC_START + 28)     /* Ethernet controller */
+#define IRQ_PB11MP_USB_GIC1    (IRQ_PB11MP_GIC_START + 29)     /* USB controller */
+#define IRQ_PB11MP_TSPEN       (IRQ_PB11MP_GIC_START + 30)     /* Touchscreen pen */
+#define IRQ_PB11MP_TSKPAD      (IRQ_PB11MP_GIC_START + 31)     /* Touchscreen keypad */
+
+#endif /* __MACH_IRQS_PB11MP_H */
diff --git a/arch/arm/mach-realview/irqs-pba8.h b/arch/arm/mach-realview/irqs-pba8.h
new file mode 100644 (file)
index 0000000..262e321
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_PBA8_H
+#define __MACH_IRQS_PBA8_H
+
+#define IRQ_PBA8_GIC_START                     32
+
+/*
+ * PB-A8 on-board gic irq sources
+ */
+#define IRQ_PBA8_WATCHDOG      (IRQ_PBA8_GIC_START + 0)        /* Watchdog timer */
+#define IRQ_PBA8_SOFT          (IRQ_PBA8_GIC_START + 1)        /* Software interrupt */
+#define IRQ_PBA8_COMMRx                (IRQ_PBA8_GIC_START + 2)        /* Debug Comm Rx interrupt */
+#define IRQ_PBA8_COMMTx                (IRQ_PBA8_GIC_START + 3)        /* Debug Comm Tx interrupt */
+#define IRQ_PBA8_TIMER0_1      (IRQ_PBA8_GIC_START + 4)        /* Timer 0/1 (default timer) */
+#define IRQ_PBA8_TIMER2_3      (IRQ_PBA8_GIC_START + 5)        /* Timer 2/3 */
+#define IRQ_PBA8_GPIO0         (IRQ_PBA8_GIC_START + 6)        /* GPIO 0 */
+#define IRQ_PBA8_GPIO1         (IRQ_PBA8_GIC_START + 7)        /* GPIO 1 */
+#define IRQ_PBA8_GPIO2         (IRQ_PBA8_GIC_START + 8)        /* GPIO 2 */
+                                                               /* 9 reserved */
+#define IRQ_PBA8_RTC           (IRQ_PBA8_GIC_START + 10)       /* Real Time Clock */
+#define IRQ_PBA8_SSP           (IRQ_PBA8_GIC_START + 11)       /* Synchronous Serial Port */
+#define IRQ_PBA8_UART0         (IRQ_PBA8_GIC_START + 12)       /* UART 0 on development chip */
+#define IRQ_PBA8_UART1         (IRQ_PBA8_GIC_START + 13)       /* UART 1 on development chip */
+#define IRQ_PBA8_UART2         (IRQ_PBA8_GIC_START + 14)       /* UART 2 on development chip */
+#define IRQ_PBA8_UART3         (IRQ_PBA8_GIC_START + 15)       /* UART 3 on development chip */
+#define IRQ_PBA8_SCI           (IRQ_PBA8_GIC_START + 16)       /* Smart Card Interface */
+#define IRQ_PBA8_MMCI0A                (IRQ_PBA8_GIC_START + 17)       /* Multimedia Card 0A */
+#define IRQ_PBA8_MMCI0B                (IRQ_PBA8_GIC_START + 18)       /* Multimedia Card 0B */
+#define IRQ_PBA8_AACI          (IRQ_PBA8_GIC_START + 19)       /* Audio Codec */
+#define IRQ_PBA8_KMI0          (IRQ_PBA8_GIC_START + 20)       /* Keyboard/Mouse port 0 */
+#define IRQ_PBA8_KMI1          (IRQ_PBA8_GIC_START + 21)       /* Keyboard/Mouse port 1 */
+#define IRQ_PBA8_CHARLCD       (IRQ_PBA8_GIC_START + 22)       /* Character LCD */
+#define IRQ_PBA8_CLCD          (IRQ_PBA8_GIC_START + 23)       /* CLCD controller */
+#define IRQ_PBA8_DMAC          (IRQ_PBA8_GIC_START + 24)       /* DMA controller */
+#define IRQ_PBA8_PWRFAIL       (IRQ_PBA8_GIC_START + 25)       /* Power failure */
+#define IRQ_PBA8_PISMO         (IRQ_PBA8_GIC_START + 26)       /* PISMO interface */
+#define IRQ_PBA8_DoC           (IRQ_PBA8_GIC_START + 27)       /* Disk on Chip memory controller */
+#define IRQ_PBA8_ETH           (IRQ_PBA8_GIC_START + 28)       /* Ethernet controller */
+#define IRQ_PBA8_USB           (IRQ_PBA8_GIC_START + 29)       /* USB controller */
+#define IRQ_PBA8_TSPEN         (IRQ_PBA8_GIC_START + 30)       /* Touchscreen pen */
+#define IRQ_PBA8_TSKPAD                (IRQ_PBA8_GIC_START + 31)       /* Touchscreen keypad */
+
+#define IRQ_PBA8_PMU           (IRQ_PBA8_GIC_START + 47)       /* Cortex-A8 PMU */
+
+/* ... */
+#define IRQ_PBA8_PCI0          (IRQ_PBA8_GIC_START + 50)
+#define IRQ_PBA8_PCI1          (IRQ_PBA8_GIC_START + 51)
+#define IRQ_PBA8_PCI2          (IRQ_PBA8_GIC_START + 52)
+#define IRQ_PBA8_PCI3          (IRQ_PBA8_GIC_START + 53)
+
+#define IRQ_PBA8_SMC           -1
+#define IRQ_PBA8_SCTL          -1
+
+#endif /* __MACH_IRQS_PBA8_H */
diff --git a/arch/arm/mach-realview/irqs-pbx.h b/arch/arm/mach-realview/irqs-pbx.h
new file mode 100644 (file)
index 0000000..4ef0567
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 ARM Limited
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MACH_IRQS_PBX_H
+#define __MACH_IRQS_PBX_H
+
+#define IRQ_LOCALTIMER                         29
+#define IRQ_PBX_GIC_START                      32
+
+/*
+ * PBX on-board gic irq sources
+ */
+#define IRQ_PBX_WATCHDOG       (IRQ_PBX_GIC_START + 0) /* Watchdog timer */
+#define IRQ_PBX_SOFT           (IRQ_PBX_GIC_START + 1) /* Software interrupt */
+#define IRQ_PBX_COMMRx         (IRQ_PBX_GIC_START + 2) /* Debug Comm Rx interrupt */
+#define IRQ_PBX_COMMTx         (IRQ_PBX_GIC_START + 3) /* Debug Comm Tx interrupt */
+#define IRQ_PBX_TIMER0_1       (IRQ_PBX_GIC_START + 4) /* Timer 0/1 (default timer) */
+#define IRQ_PBX_TIMER2_3       (IRQ_PBX_GIC_START + 5) /* Timer 2/3 */
+#define IRQ_PBX_GPIO0          (IRQ_PBX_GIC_START + 6) /* GPIO 0 */
+#define IRQ_PBX_GPIO1          (IRQ_PBX_GIC_START + 7) /* GPIO 1 */
+#define IRQ_PBX_GPIO2          (IRQ_PBX_GIC_START + 8) /* GPIO 2 */
+                                                               /* 9 reserved */
+#define IRQ_PBX_RTC            (IRQ_PBX_GIC_START + 10)        /* Real Time Clock */
+#define IRQ_PBX_SSP            (IRQ_PBX_GIC_START + 11)        /* Synchronous Serial Port */
+#define IRQ_PBX_UART0          (IRQ_PBX_GIC_START + 12)        /* UART 0 on development chip */
+#define IRQ_PBX_UART1          (IRQ_PBX_GIC_START + 13)        /* UART 1 on development chip */
+#define IRQ_PBX_UART2          (IRQ_PBX_GIC_START + 14)        /* UART 2 on development chip */
+#define IRQ_PBX_UART3          (IRQ_PBX_GIC_START + 15)        /* UART 3 on development chip */
+#define IRQ_PBX_SCI            (IRQ_PBX_GIC_START + 16)        /* Smart Card Interface */
+#define IRQ_PBX_MMCI0A         (IRQ_PBX_GIC_START + 17)        /* Multimedia Card 0A */
+#define IRQ_PBX_MMCI0B         (IRQ_PBX_GIC_START + 18)        /* Multimedia Card 0B */
+#define IRQ_PBX_AACI           (IRQ_PBX_GIC_START + 19)        /* Audio Codec */
+#define IRQ_PBX_KMI0           (IRQ_PBX_GIC_START + 20)        /* Keyboard/Mouse port 0 */
+#define IRQ_PBX_KMI1           (IRQ_PBX_GIC_START + 21)        /* Keyboard/Mouse port 1 */
+#define IRQ_PBX_CHARLCD                (IRQ_PBX_GIC_START + 22)        /* Character LCD */
+#define IRQ_PBX_CLCD           (IRQ_PBX_GIC_START + 23)        /* CLCD controller */
+#define IRQ_PBX_DMAC           (IRQ_PBX_GIC_START + 24)        /* DMA controller */
+#define IRQ_PBX_PWRFAIL                (IRQ_PBX_GIC_START + 25)        /* Power failure */
+#define IRQ_PBX_PISMO          (IRQ_PBX_GIC_START + 26)        /* PISMO interface */
+#define IRQ_PBX_DoC            (IRQ_PBX_GIC_START + 27)        /* Disk on Chip memory controller */
+#define IRQ_PBX_ETH            (IRQ_PBX_GIC_START + 28)        /* Ethernet controller */
+#define IRQ_PBX_USB            (IRQ_PBX_GIC_START + 29)        /* USB controller */
+#define IRQ_PBX_TSPEN          (IRQ_PBX_GIC_START + 30)        /* Touchscreen pen */
+#define IRQ_PBX_TSKPAD         (IRQ_PBX_GIC_START + 31)        /* Touchscreen keypad */
+
+#define IRQ_PBX_PMU_SCU0        (IRQ_PBX_GIC_START + 32)        /* SCU PMU Interrupts (11mp) */
+#define IRQ_PBX_PMU_SCU1        (IRQ_PBX_GIC_START + 33)
+#define IRQ_PBX_PMU_SCU2        (IRQ_PBX_GIC_START + 34)
+#define IRQ_PBX_PMU_SCU3        (IRQ_PBX_GIC_START + 35)
+#define IRQ_PBX_PMU_SCU4        (IRQ_PBX_GIC_START + 36)
+#define IRQ_PBX_PMU_SCU5        (IRQ_PBX_GIC_START + 37)
+#define IRQ_PBX_PMU_SCU6        (IRQ_PBX_GIC_START + 38)
+#define IRQ_PBX_PMU_SCU7        (IRQ_PBX_GIC_START + 39)
+
+#define IRQ_PBX_WATCHDOG1       (IRQ_PBX_GIC_START + 40)        /* Watchdog1 timer */
+#define IRQ_PBX_TIMER4_5        (IRQ_PBX_GIC_START + 41)        /* Timer 0/1 (default timer) */
+#define IRQ_PBX_TIMER6_7        (IRQ_PBX_GIC_START + 42)        /* Timer 2/3 */
+/* ... */
+#define IRQ_PBX_PMU_CPU0        (IRQ_PBX_GIC_START + 44)        /* CPU PMU Interrupts */
+#define IRQ_PBX_PMU_CPU1        (IRQ_PBX_GIC_START + 45)
+#define IRQ_PBX_PMU_CPU2        (IRQ_PBX_GIC_START + 46)
+#define IRQ_PBX_PMU_CPU3        (IRQ_PBX_GIC_START + 47)
+
+/* ... */
+#define IRQ_PBX_PCI0           (IRQ_PBX_GIC_START + 50)
+#define IRQ_PBX_PCI1           (IRQ_PBX_GIC_START + 51)
+#define IRQ_PBX_PCI2           (IRQ_PBX_GIC_START + 52)
+#define IRQ_PBX_PCI3           (IRQ_PBX_GIC_START + 53)
+
+#define IRQ_PBX_SMC            -1
+#define IRQ_PBX_SCTL           -1
+
+#endif /* __MACH_IRQS_PBX_H */
diff --git a/arch/arm/mach-realview/platform.h b/arch/arm/mach-realview/platform.h
new file mode 100644 (file)
index 0000000..1112173
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) ARM Limited 2003.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_PLATFORM_H
+#define __ASM_ARCH_PLATFORM_H
+
+/*
+ * Memory definitions
+ */
+#define REALVIEW_BOOT_ROM_LO          0x30000000               /* DoC Base (64Mb)...*/
+#define REALVIEW_BOOT_ROM_HI          0x30000000
+#define REALVIEW_BOOT_ROM_BASE        REALVIEW_BOOT_ROM_HI      /*  Normal position */
+#define REALVIEW_BOOT_ROM_SIZE        SZ_64M
+
+#define REALVIEW_SSRAM_BASE           /* REALVIEW_SSMC_BASE ? */
+#define REALVIEW_SSRAM_SIZE           SZ_2M
+
+/* 
+ *  SDRAM
+ */
+#define REALVIEW_SDRAM_BASE           0x00000000
+
+/* 
+ *  Logic expansion modules
+ * 
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  RealView Registers
+ * ------------------------------------------------------------------------
+ * 
+ */
+#define REALVIEW_SYS_ID_OFFSET               0x00
+#define REALVIEW_SYS_SW_OFFSET               0x04
+#define REALVIEW_SYS_LED_OFFSET              0x08
+#define REALVIEW_SYS_OSC0_OFFSET             0x0C
+
+#define REALVIEW_SYS_OSC1_OFFSET             0x10
+#define REALVIEW_SYS_OSC2_OFFSET             0x14
+#define REALVIEW_SYS_OSC3_OFFSET             0x18
+#define REALVIEW_SYS_OSC4_OFFSET             0x1C      /* OSC1 for RealView/AB */
+
+#define REALVIEW_SYS_LOCK_OFFSET             0x20
+#define REALVIEW_SYS_100HZ_OFFSET            0x24
+#define REALVIEW_SYS_CFGDATA1_OFFSET         0x28
+#define REALVIEW_SYS_CFGDATA2_OFFSET         0x2C
+#define REALVIEW_SYS_FLAGS_OFFSET            0x30
+#define REALVIEW_SYS_FLAGSSET_OFFSET         0x30
+#define REALVIEW_SYS_FLAGSCLR_OFFSET         0x34
+#define REALVIEW_SYS_NVFLAGS_OFFSET          0x38
+#define REALVIEW_SYS_NVFLAGSSET_OFFSET       0x38
+#define REALVIEW_SYS_NVFLAGSCLR_OFFSET       0x3C
+#define REALVIEW_SYS_RESETCTL_OFFSET         0x40
+#define REALVIEW_SYS_PCICTL_OFFSET           0x44
+#define REALVIEW_SYS_MCI_OFFSET              0x48
+#define REALVIEW_SYS_FLASH_OFFSET            0x4C
+#define REALVIEW_SYS_CLCD_OFFSET             0x50
+#define REALVIEW_SYS_CLCDSER_OFFSET          0x54
+#define REALVIEW_SYS_BOOTCS_OFFSET           0x58
+#define REALVIEW_SYS_24MHz_OFFSET            0x5C
+#define REALVIEW_SYS_MISC_OFFSET             0x60
+#define REALVIEW_SYS_IOSEL_OFFSET            0x70
+#define REALVIEW_SYS_PROCID_OFFSET           0x84
+#define REALVIEW_SYS_TEST_OSC0_OFFSET        0xC0
+#define REALVIEW_SYS_TEST_OSC1_OFFSET        0xC4
+#define REALVIEW_SYS_TEST_OSC2_OFFSET        0xC8
+#define REALVIEW_SYS_TEST_OSC3_OFFSET        0xCC
+#define REALVIEW_SYS_TEST_OSC4_OFFSET        0xD0
+
+#define REALVIEW_SYS_BASE                    0x10000000
+#define REALVIEW_SYS_ID                      (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
+#define REALVIEW_SYS_SW                      (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
+#define REALVIEW_SYS_LED                     (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
+#define REALVIEW_SYS_OSC0                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
+#define REALVIEW_SYS_OSC1                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
+
+#define REALVIEW_SYS_LOCK                    (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
+#define REALVIEW_SYS_100HZ                   (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
+#define REALVIEW_SYS_CFGDATA1                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
+#define REALVIEW_SYS_CFGDATA2                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
+#define REALVIEW_SYS_FLAGS                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
+#define REALVIEW_SYS_FLAGSSET                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
+#define REALVIEW_SYS_FLAGSCLR                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
+#define REALVIEW_SYS_NVFLAGS                 (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
+#define REALVIEW_SYS_NVFLAGSSET              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
+#define REALVIEW_SYS_NVFLAGSCLR              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
+#define REALVIEW_SYS_RESETCTL                (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
+#define REALVIEW_SYS_PCICTL                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
+#define REALVIEW_SYS_MCI                     (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
+#define REALVIEW_SYS_FLASH                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
+#define REALVIEW_SYS_CLCD                    (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
+#define REALVIEW_SYS_CLCDSER                 (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
+#define REALVIEW_SYS_BOOTCS                  (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
+#define REALVIEW_SYS_24MHz                   (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
+#define REALVIEW_SYS_MISC                    (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
+#define REALVIEW_SYS_IOSEL                   (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
+#define REALVIEW_SYS_PROCID                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET)
+#define REALVIEW_SYS_TEST_OSC0               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
+#define REALVIEW_SYS_TEST_OSC1               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
+#define REALVIEW_SYS_TEST_OSC2               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
+#define REALVIEW_SYS_TEST_OSC3               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
+#define REALVIEW_SYS_TEST_OSC4               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
+
+/* ------------------------------------------------------------------------
+ *  RealView control registers
+ * ------------------------------------------------------------------------
+ */
+
+/* 
+ * REALVIEW_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4  = build value
+ * 3:0   = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * REALVIEW_SYS_LOCK
+ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
+ *     SYS_CLD, SYS_BOOTCS
+ */
+#define REALVIEW_SYS_LOCK_LOCKED    (1 << 16)
+#define REALVIEW_SYS_LOCK_VAL  0xA05F         /* Enable write access */
+
+/*
+ * REALVIEW_SYS_FLASH
+ */
+#define REALVIEW_FLASHPROG_FLVPPEN     (1 << 0)        /* Enable writing to flash */
+
+/*
+ * REALVIEW_INTREG
+ *     - used to acknowledge and control MMCI and UART interrupts 
+ */
+#define REALVIEW_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
+#define REALVIEW_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
+#define REALVIEW_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
+                                                /* write 1 to acknowledge and clear               */
+#define REALVIEW_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
+#define REALVIEW_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
+
+/*
+ * RealView common peripheral addresses
+ */
+#define REALVIEW_SCTL_BASE            0x10001000       /* System controller */
+#define REALVIEW_I2C_BASE             0x10002000       /* I2C control */
+#define REALVIEW_AACI_BASE            0x10004000       /* Audio */
+#define REALVIEW_MMCI0_BASE           0x10005000       /* MMC interface */
+#define REALVIEW_KMI0_BASE            0x10006000       /* KMI interface */
+#define REALVIEW_KMI1_BASE            0x10007000       /* KMI 2nd interface */
+#define REALVIEW_CHAR_LCD_BASE        0x10008000       /* Character LCD */
+#define REALVIEW_SCI_BASE             0x1000E000       /* Smart card controller */
+#define REALVIEW_GPIO1_BASE           0x10014000       /* GPIO port 1 */
+#define REALVIEW_GPIO2_BASE           0x10015000       /* GPIO port 2 */
+#define REALVIEW_DMC_BASE             0x10018000       /* DMC configuration */
+#define REALVIEW_DMAC_BASE            0x10030000       /* DMA controller */
+
+/* PCI space */
+#define REALVIEW_PCI_BASE             0x41000000       /* PCI Interface */
+#define REALVIEW_PCI_CFG_BASE        0x42000000
+#define REALVIEW_PCI_MEM_BASE0        0x44000000
+#define REALVIEW_PCI_MEM_BASE1        0x50000000
+#define REALVIEW_PCI_MEM_BASE2        0x60000000
+/* Sizes of above maps */
+#define REALVIEW_PCI_BASE_SIZE        0x01000000
+#define REALVIEW_PCI_CFG_BASE_SIZE    0x02000000
+#define REALVIEW_PCI_MEM_BASE0_SIZE   0x0c000000       /* 32Mb */
+#define REALVIEW_PCI_MEM_BASE1_SIZE   0x10000000       /* 256Mb */
+#define REALVIEW_PCI_MEM_BASE2_SIZE   0x10000000       /* 256Mb */
+
+#define REALVIEW_SDRAM67_BASE         0x70000000       /* SDRAM banks 6 and 7 */
+#define REALVIEW_LT_BASE              0x80000000       /* Logic Tile expansion */
+
+/*
+ * CompactFlash
+ */
+#define REALVIEW_CF_BASE               0x18000000      /* CompactFlash */
+#define REALVIEW_CF_MEM_BASE           0x18003000      /* SMC for CompactFlash */
+
+/*
+ * Disk on Chip
+ */
+#define REALVIEW_DOC_BASE             0x2C000000
+#define REALVIEW_DOC_SIZE             (16 << 20)
+#define REALVIEW_DOC_PAGE_SIZE        512
+#define REALVIEW_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES    32
+#define START_PAGE          0x80
+
+/* 
+ *  LED settings, bits [7:0]
+ */
+#define REALVIEW_SYS_LED0             (1 << 0)
+#define REALVIEW_SYS_LED1             (1 << 1)
+#define REALVIEW_SYS_LED2             (1 << 2)
+#define REALVIEW_SYS_LED3             (1 << 3)
+#define REALVIEW_SYS_LED4             (1 << 4)
+#define REALVIEW_SYS_LED5             (1 << 5)
+#define REALVIEW_SYS_LED6             (1 << 6)
+#define REALVIEW_SYS_LED7             (1 << 7)
+
+#define ALL_LEDS                  0xFF
+
+#define LED_BANK                  REALVIEW_SYS_LED
+
+/* 
+ * Control registers
+ */
+#define REALVIEW_IDFIELD_OFFSET        0x0     /* RealView build information */
+#define REALVIEW_FLASHPROG_OFFSET      0x4     /* Flash devices */
+#define REALVIEW_INTREG_OFFSET         0x8     /* Interrupt control */
+#define REALVIEW_DECODE_OFFSET         0xC     /* Fitted logic modules */
+
+/*
+ * System controller bit assignment
+ */
+#define REALVIEW_REFCLK        0
+#define REALVIEW_TIMCLK        1
+
+#define REALVIEW_TIMER1_EnSel  15
+#define REALVIEW_TIMER2_EnSel  17
+#define REALVIEW_TIMER3_EnSel  19
+#define REALVIEW_TIMER4_EnSel  21
+
+
+#define REALVIEW_CSR_BASE             0x10000000
+#define REALVIEW_CSR_SIZE             0x10000000
+
+#endif /* __ASM_ARCH_PLATFORM_H */
diff --git a/arch/arm/mach-realview/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c
new file mode 100644 (file)
index 0000000..6558539
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 Linus Walleij
+ *
+ * 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/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include <plat/platsmp.h>
+
+#include "core.h"
+
+#define REALVIEW_SYS_FLAGSSET_OFFSET   0x30
+
+static const struct of_device_id realview_scu_match[] = {
+       { .compatible = "arm,arm11mp-scu", },
+       { .compatible = "arm,cortex-a9-scu", },
+       { .compatible = "arm,cortex-a5-scu", },
+       { }
+};
+
+static const struct of_device_id realview_syscon_match[] = {
+        { .compatible = "arm,core-module-integrator", },
+        { .compatible = "arm,realview-eb-syscon", },
+        { .compatible = "arm,realview-pb11mp-syscon", },
+        { .compatible = "arm,realview-pbx-syscon", },
+        { },
+};
+
+static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *np;
+       void __iomem *scu_base;
+       struct regmap *map;
+       unsigned int ncores;
+       int i;
+
+       np = of_find_matching_node(NULL, realview_scu_match);
+       if (!np) {
+               pr_err("PLATSMP: No SCU base address\n");
+               return;
+       }
+       scu_base = of_iomap(np, 0);
+       of_node_put(np);
+       if (!scu_base) {
+               pr_err("PLATSMP: No SCU remap\n");
+               return;
+       }
+
+       scu_enable(scu_base);
+       ncores = scu_get_core_count(scu_base);
+       pr_info("SCU: %d cores detected\n", ncores);
+       for (i = 0; i < ncores; i++)
+               set_cpu_possible(i, true);
+       iounmap(scu_base);
+
+       /* The syscon contains the magic SMP start address registers */
+       np = of_find_matching_node(NULL, realview_syscon_match);
+       if (!np) {
+               pr_err("PLATSMP: No syscon match\n");
+               return;
+       }
+       map = syscon_node_to_regmap(np);
+       if (IS_ERR(map)) {
+               pr_err("PLATSMP: No syscon regmap\n");
+               return;
+       }
+       /* Put the boot address in this magic register */
+       regmap_write(map, REALVIEW_SYS_FLAGSSET_OFFSET,
+                    virt_to_phys(versatile_secondary_startup));
+}
+
+struct smp_operations realview_dt_smp_ops __initdata = {
+       .smp_prepare_cpus       = realview_smp_prepare_cpus,
+       .smp_secondary_init     = versatile_secondary_init,
+       .smp_boot_secondary     = versatile_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = realview_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(realview_smp, "arm,realview-smp", &realview_dt_smp_ops);
index 98e3052..e8ab69c 100644 (file)
 #include <linux/smp.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
+#include "hardware.h"
 #include <asm/mach-types.h>
 #include <asm/smp_scu.h>
 
-#include <mach/board-eb.h>
-#include <mach/board-pb11mp.h>
-#include <mach/board-pbx.h>
+#include "board-eb.h"
+#include "board-pb11mp.h"
+#include "board-pbx.h"
 
 #include <plat/platsmp.h>
 
@@ -75,7 +75,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
                     __io_address(REALVIEW_SYS_FLAGSSET));
 }
 
-struct smp_operations realview_smp_ops __initdata = {
+const struct smp_operations realview_smp_ops __initconst = {
        .smp_init_cpus          = realview_smp_init_cpus,
        .smp_prepare_cpus       = realview_smp_prepare_cpus,
        .smp_secondary_init     = versatile_secondary_init,
index 382cc1b..88b6724 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/cache-l2x0.h>
-#include "core.h"
 
 static const char *const realview_dt_platform_compat[] __initconst = {
        "arm,realview-eb",
index b3869cb..b442fa6 100644 (file)
 #include <linux/platform_data/clk-realview.h>
 #include <linux/reboot.h>
 
-#include <mach/hardware.h>
+#include "hardware.h"
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/smp_twd.h>
 #include <asm/system_info.h>
+#include <asm/outercache.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <mach/board-eb.h>
-#include <mach/irqs.h>
+#include "board-eb.h"
+#include "irqs-eb.h"
 
 #include "core.h"
 
@@ -450,6 +451,12 @@ static void __init realview_eb_init(void)
                 * Bits:  .... ...0 0111 1001 0000 .... .... ....
                 */
                l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
+
+               /*
+                * due to a bug in the l220 cache controller, we must not call
+                * the sync function. stub it out here instead!
+                */
+               outer_cache.sync = NULL;
 #endif
                pmu_device.name = core_tile_a9mp() ? "armv7-pmu" : "armv6-pmu";
                platform_device_register(&pmu_device);
index ce92c18..537f387 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/reboot.h>
 #include <linux/memblock.h>
 
-#include <mach/hardware.h>
+#include "hardware.h"
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/pgtable.h>
@@ -45,8 +45,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <mach/board-pb1176.h>
-#include <mach/irqs.h>
+#include "board-pb1176.h"
+#include "irqs-pb1176.h"
 
 #include "core.h"
 
index 15c45e2..a90a075 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/platform_data/clk-realview.h>
 #include <linux/reboot.h>
 
-#include <mach/hardware.h>
+#include "hardware.h"
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/pgtable.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
+#include <asm/outercache.h>
 
-#include <mach/board-pb11mp.h>
-#include <mach/irqs.h>
+#include "board-pb11mp.h"
+#include "irqs-pb11mp.h"
 
 #include "core.h"
 
@@ -345,6 +346,11 @@ static void __init realview_pb11mp_init(void)
         * Bits:  .... ...0 0111 1001 0000 .... .... ....
         */
        l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
+       /*
+        * due to a bug in the l220 cache controller, we must not call
+        * the sync function. stub it out here instead!
+        */
+       outer_cache.sync = NULL;
 #endif
 
        realview_flash_register(realview_pb11mp_flash_resource,
index 4c64662..ddafb67 100644 (file)
@@ -39,9 +39,9 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <mach/hardware.h>
-#include <mach/board-pba8.h>
-#include <mach/irqs.h>
+#include "hardware.h"
+#include "board-pba8.h"
+#include "irqs-pba8.h"
 
 #include "core.h"
 
@@ -77,14 +77,6 @@ static struct map_desc realview_pba8_io_desc[] __initdata = {
                .length         = SZ_4K,
                .type           = MT_DEVICE,
        },
-#ifdef CONFIG_PCI
-       {
-               .virtual        = PCIX_UNIT_BASE,
-               .pfn            = __phys_to_pfn(REALVIEW_PBA8_PCI_BASE),
-               .length         = REALVIEW_PBA8_PCI_BASE_SIZE,
-               .type           = MT_DEVICE
-       },
-#endif
 #ifdef CONFIG_DEBUG_LL
        {
                .virtual        = IO_ADDRESS(REALVIEW_PBA8_UART0_BASE),
index 9a22b86..b9f0757 100644 (file)
@@ -41,9 +41,9 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <mach/hardware.h>
-#include <mach/board-pbx.h>
-#include <mach/irqs.h>
+#include "hardware.h"
+#include "board-pbx.h"
+#include "irqs-pbx.h"
 
 #include "core.h"
 
@@ -79,14 +79,6 @@ static struct map_desc realview_pbx_io_desc[] __initdata = {
                .length         = SZ_4K,
                .type           = MT_DEVICE,
        },
-#ifdef CONFIG_PCI
-       {
-               .virtual        = PCIX_UNIT_BASE,
-               .pfn            = __phys_to_pfn(REALVIEW_PBX_PCI_BASE),
-               .length         = REALVIEW_PBX_PCI_BASE_SIZE,
-               .type           = MT_DEVICE,
-       },
-#endif
 #ifdef CONFIG_DEBUG_LL
        {
                .virtual        = IO_ADDRESS(REALVIEW_PBX_UART0_BASE),
index ae4eb7c..cef42fd 100644 (file)
@@ -1,5 +1,6 @@
 config ARCH_ROCKCHIP
-       bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7
+       bool "Rockchip RK2928 and RK3xxx SOCs"
+       depends on ARCH_MULTI_V7
        select PINCTRL
        select PINCTRL_ROCKCHIP
        select ARCH_HAS_RESET_CONTROLLER
index 3e7a4b7..d42a07e 100644 (file)
@@ -42,6 +42,7 @@ static int ncores;
 #define PMU_PWRDN_SCU          4
 
 static struct regmap *pmu;
+static int has_pmu = true;
 
 static int pmu_power_domain_is_on(int pd)
 {
@@ -89,20 +90,23 @@ static int pmu_set_power_domain(int pd, bool on)
        if (!IS_ERR(rstc) && !on)
                reset_control_assert(rstc);
 
-       ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
-       if (ret < 0) {
-               pr_err("%s: could not update power domain\n", __func__);
-               return ret;
-       }
-
-       ret = -1;
-       while (ret != on) {
-               ret = pmu_power_domain_is_on(pd);
+       if (has_pmu) {
+               ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
                if (ret < 0) {
-                       pr_err("%s: could not read power domain state\n",
+                       pr_err("%s: could not update power domain\n",
                               __func__);
                        return ret;
                }
+
+               ret = -1;
+               while (ret != on) {
+                       ret = pmu_power_domain_is_on(pd);
+                       if (ret < 0) {
+                               pr_err("%s: could not read power domain state\n",
+                                      __func__);
+                               return ret;
+                       }
+               }
        }
 
        if (!IS_ERR(rstc)) {
@@ -122,7 +126,7 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
        int ret;
 
-       if (!sram_base_addr || !pmu) {
+       if (!sram_base_addr || (has_pmu && !pmu)) {
                pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
                return -ENXIO;
        }
@@ -275,7 +279,7 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
                return;
        }
 
-       if (rockchip_smp_prepare_pmu())
+       if (has_pmu && rockchip_smp_prepare_pmu())
                return;
 
        if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
@@ -318,6 +322,13 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
                pmu_set_power_domain(0 + i, false);
 }
 
+static void __init rk3036_smp_prepare_cpus(unsigned int max_cpus)
+{
+       has_pmu = false;
+
+       rockchip_smp_prepare_cpus(max_cpus);
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static int rockchip_cpu_kill(unsigned int cpu)
 {
@@ -340,7 +351,16 @@ static void rockchip_cpu_die(unsigned int cpu)
 }
 #endif
 
-static struct smp_operations rockchip_smp_ops __initdata = {
+static const struct smp_operations rk3036_smp_ops __initconst = {
+       .smp_prepare_cpus       = rk3036_smp_prepare_cpus,
+       .smp_boot_secondary     = rockchip_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_kill               = rockchip_cpu_kill,
+       .cpu_die                = rockchip_cpu_die,
+#endif
+};
+
+static const struct smp_operations rockchip_smp_ops __initconst = {
        .smp_prepare_cpus       = rockchip_smp_prepare_cpus,
        .smp_boot_secondary     = rockchip_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -349,4 +369,5 @@ static struct smp_operations rockchip_smp_ops __initdata = {
 #endif
 };
 
+CPU_METHOD_OF_DECLARE(rk3036_smp, "rockchip,rk3036-smp", &rk3036_smp_ops);
 CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp", &rockchip_smp_ops);
index 251c7b9..3f07cc5 100644 (file)
@@ -82,6 +82,7 @@ static const char * const rockchip_board_dt_compat[] = {
        "rockchip,rk3066a",
        "rockchip,rk3066b",
        "rockchip,rk3188",
+       "rockchip,rk3228",
        "rockchip,rk3288",
        NULL,
 };
index 69459db..712333f 100644 (file)
@@ -85,3 +85,17 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
 
 static inline void s3c_pm_restored_gpios(void) { }
 static inline void samsung_pm_saved_gpios(void) { }
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+#ifdef CONFIG_PM_SLEEP
+#define s3c_irqwake_intallow   (1L << 30 | 0xfL)
+#define s3c_irqwake_eintallow  (0x0000fff0L)
+#else
+#define s3c_irqwake_eintallow 0
+#define s3c_irqwake_intallow  0
+#endif
index b91341e..417b7a2 100644 (file)
 
 #include <mach/regs-irq.h>
 #include <mach/regs-gpio.h>
+#include <mach/pm-core.h>
 
 #include <asm/irq.h>
 
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow     = 1L << 30 | 0xfL;
-unsigned long s3c_irqwake_eintallow    = 0x0000fff0L;
-
 int s3c_irq_wake(struct irq_data *data, unsigned int state)
 {
        unsigned long irqbit = 1 << data->hwirq;
index 28c7097..7c0c420 100644 (file)
@@ -2,6 +2,26 @@
 #      Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
 #
 # Licensed under GPLv2
+menuconfig ARCH_S3C64XX
+       bool "Samsung S3C64XX" if ARCH_MULTI_V6
+       select ARCH_REQUIRE_GPIOLIB
+       select ARM_AMBA
+       select ARM_VIC
+       select CLKSRC_SAMSUNG_PWM
+       select COMMON_CLK_SAMSUNG
+       select GPIO_SAMSUNG if ATAGS
+       select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
+       select HAVE_TCM
+       select PLAT_SAMSUNG
+       select PM_GENERIC_DOMAINS if PM
+       select S3C_DEV_NAND if ATAGS
+       select S3C_GPIO_TRACK if ATAGS
+       select SAMSUNG_ATAGS if ATAGS
+       select SAMSUNG_WAKEMASK if PM
+       select SAMSUNG_WDT_RESET
+       help
+         Samsung S3C64XX series based systems
 
 if ARCH_S3C64XX
 
@@ -90,6 +110,7 @@ config S3C64XX_SETUP_USB_PHY
 
 config MACH_SMDK6400
        bool "SMDK6400"
+       depends on ATAGS
        select CPU_S3C6400
        select S3C64XX_SETUP_SDHCI
        select S3C_DEV_HSMMC1
@@ -100,6 +121,7 @@ config MACH_SMDK6400
 
 config MACH_ANW6410
        bool "A&W6410"
+       depends on ATAGS
        select CPU_S3C6410
        select S3C64XX_SETUP_FB_24BPP
        select S3C_DEV_FB
@@ -108,6 +130,7 @@ config MACH_ANW6410
 
 config MACH_MINI6410
        bool "MINI6410"
+       depends on ATAGS
        select CPU_S3C6410
        select S3C64XX_SETUP_FB_24BPP
        select S3C64XX_SETUP_SDHCI
@@ -123,6 +146,7 @@ config MACH_MINI6410
 
 config MACH_REAL6410
        bool "REAL6410"
+       depends on ATAGS
        select CPU_S3C6410
        select S3C64XX_SETUP_FB_24BPP
        select S3C64XX_SETUP_SDHCI
@@ -138,6 +162,7 @@ config MACH_REAL6410
 
 config MACH_SMDK6410
        bool "SMDK6410"
+       depends on ATAGS
        select CPU_S3C6410
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select S3C64XX_SETUP_FB_24BPP
@@ -225,6 +250,7 @@ config SMDK6410_WM1192_EV1
 
 config MACH_NCP
        bool "NCP"
+       depends on ATAGS
        select CPU_S3C6410
        select S3C64XX_SETUP_I2C1
        select S3C_DEV_HSMMC1
@@ -234,6 +260,7 @@ config MACH_NCP
 
 config MACH_HMT
        bool "Airgoo HMT"
+       depends on ATAGS
        select CPU_S3C6410
        select S3C64XX_SETUP_FB_24BPP
        select S3C_DEV_FB
@@ -265,18 +292,21 @@ config MACH_SMARTQ
 
 config MACH_SMARTQ5
        bool "SmartQ 5"
+       depends on ATAGS
        select MACH_SMARTQ
        help
            Machine support for the SmartQ 5
 
 config MACH_SMARTQ7
        bool "SmartQ 7"
+       depends on ATAGS
        select MACH_SMARTQ
        help
            Machine support for the SmartQ 7
 
 config MACH_WLF_CRAGG_6410
        bool "Wolfson Cragganmore 6410"
+       depends on ATAGS
        depends on I2C=y
        select CPU_S3C6410
        select LEDS_GPIO_REGISTER
@@ -310,7 +340,6 @@ config MACH_S3C64XX_DT
        select CPU_S3C6410
        select PINCTRL
        select PINCTRL_S3C64XX
-       select USE_OF
        help
          Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
          enabled.
index bb233f3..256cd5b 100644 (file)
@@ -5,21 +5,25 @@
 #
 # Licensed under GPLv2
 
-# Core
-
-obj-y                          += common.o
-
-# Core support
-
-obj-$(CONFIG_CPU_S3C6400)      += s3c6400.o
-obj-$(CONFIG_CPU_S3C6410)      += s3c6410.o
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
+asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
 
 # PM
 
 obj-$(CONFIG_PM)               += pm.o
-obj-$(CONFIG_PM_SLEEP)         += irq-pm.o sleep.o
+obj-$(CONFIG_PM_SLEEP)         += sleep.o
 obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
 
+ifdef CONFIG_SAMSUNG_ATAGS
+
+obj-$(CONFIG_PM_SLEEP)          += irq-pm.o
+
+# Core
+
+obj-y                          += common.o
+obj-$(CONFIG_CPU_S3C6400)      += s3c6400.o
+obj-$(CONFIG_CPU_S3C6410)      += s3c6410.o
+
 # DMA support
 
 obj-$(CONFIG_S3C64XX_PL080)    += pl080.o
@@ -55,4 +59,6 @@ obj-$(CONFIG_MACH_SMARTQ7)            += mach-smartq7.o
 obj-$(CONFIG_MACH_SMDK6400)            += mach-smdk6400.o
 obj-$(CONFIG_MACH_SMDK6410)            += mach-smdk6410.o
 obj-$(CONFIG_MACH_WLF_CRAGG_6410)      += mach-crag6410.o mach-crag6410-module.o
+endif
+
 obj-$(CONFIG_MACH_S3C64XX_DT)          += mach-s3c64xx-dt.o
index ddb30b8..7c66ce1 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/system_misc.h>
 
 #include <mach/map.h>
+#include <mach/irqs.h>
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
@@ -208,7 +209,7 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 static __init int s3c64xx_dev_init(void)
 {
        /* Not applicable when using DT. */
-       if (of_have_populated_dt())
+       if (of_have_populated_dt() || !soc_is_s3c64xx())
                return 0;
 
        subsys_system_register(&s3c64xx_subsys, NULL);
@@ -413,7 +414,7 @@ static int __init s3c64xx_init_irq_eint(void)
        int irq;
 
        /* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
-       if (of_have_populated_dt())
+       if (of_have_populated_dt() || !soc_is_s3c64xx())
                return -ENODEV;
 
        for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
index 93aa8cb..5322db5 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <asm/cpuidle.h>
 
+#include <plat/cpu.h>
 #include <mach/map.h>
 
 #include "regs-sys.h"
@@ -57,6 +58,8 @@ static struct cpuidle_driver s3c64xx_cpuidle_driver = {
 
 static int __init s3c64xx_init_cpuidle(void)
 {
-       return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
+       if (soc_is_s3c64xx())
+               return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
+       return 0;
 }
 device_initcall(s3c64xx_init_cpuidle);
index 46e18d7..a0b4f03 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/mach/irq.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
+#include <mach/irqs.h>
 
 #include <plat/devs.h>
 
diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
deleted file mode 100644 (file)
index c9b9532..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@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.
-*/
-
-/* pull in the relevant register and map files. */
-
-#include <linux/serial_s3c.h>
-#include <mach/map.h>
-
-       /* note, for the boot process to work we have to keep the UART
-        * virtual address aligned to an 1MiB boundary for the L1
-        * mapping the head code makes. We keep the UART virtual address
-        * aligned and add in the offset when we load the value here.
-        */
-
-       .macro addruart, rp, rv, tmp
-               ldr     \rp, = S3C_PA_UART
-               ldr     \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
-#if CONFIG_DEBUG_S3C_UART != 0
-               add     \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
-               add     \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
-#endif
-       .endm
-
-/* include the reset of the code which will do the work, we're only
- * compiling for a single cpu processor type so the default of s3c2440
- * will be fine with us.
- */
-
-#include <debug/samsung.S>
index 9c81fac..1d36365 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef GPIO_SAMSUNG_S3C64XX_H
 #define GPIO_SAMSUNG_S3C64XX_H
 
+#ifdef CONFIG_GPIO_SAMSUNG
+
 /* GPIO bank sizes */
 #define S3C64XX_GPIO_A_NR      (8)
 #define S3C64XX_GPIO_B_NR      (7)
@@ -90,5 +92,6 @@ enum s3c_gpio_number {
 /* define the number of gpios we need to the one after the GPQ() range */
 #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
 
+#endif /* GPIO_SAMSUNG */
 #endif /* GPIO_SAMSUNG_S3C64XX_H */
 
index 67bbd1d..3ceb00b 100644 (file)
 
 #define IRQ_EINT_GROUP(group, no)      (IRQ_EINT_GROUP##group##_BASE + (no))
 
-/* Define a group of interrupts for board-specific use (eg, for MFD
- * interrupt controllers). */
+/* Some boards have their own IRQs behind this */
 #define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
 
-#ifdef CONFIG_MACH_WLF_CRAGG_6410
-#define IRQ_BOARD_NR 160
-#elif defined(CONFIG_SMDK6410_WM1190_EV1)
-#define IRQ_BOARD_NR 64
-#elif defined(CONFIG_SMDK6410_WM1192_EV1)
-#define IRQ_BOARD_NR 64
-#else
-#define IRQ_BOARD_NR 16
-#endif
-
-#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
-
-/* Set the default NR_IRQS */
-
-#define NR_IRQS        (IRQ_BOARD_END + 1)
+/* Set the default nr_irqs, boards can override if necessary */
+#define S3C64XX_NR_IRQS        IRQ_BOARD_START
 
 /* Compatibility */
 
index a30a1e3..4a285e9 100644 (file)
 #define __MACH_S3C64XX_PM_CORE_H __FILE__
 
 #include <linux/serial_s3c.h>
+#include <linux/delay.h>
 
 #include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/map.h>
 
 static inline void s3c_pm_debug_init_uart(void)
 {
@@ -56,9 +59,13 @@ static inline void s3c_pm_arch_show_resume_irqs(void)
 
 /* make these defines, we currently do not have any need to change
  * the IRQ wake controls depending on the CPU we are running on */
-
+#ifdef CONFIG_PM_SLEEP
 #define s3c_irqwake_eintallow  ((1 << 28) - 1)
 #define s3c_irqwake_intallow   (~0)
+#else
+#define s3c_irqwake_eintallow 0
+#define s3c_irqwake_intallow  0
+#endif
 
 static inline void s3c_pm_arch_update_uart(void __iomem *regs,
                                           struct pm_uart_save *save)
index ae4ea76..0bbf1fa 100644 (file)
@@ -113,7 +113,7 @@ static struct syscore_ops s3c64xx_irq_syscore_ops = {
 static __init int s3c64xx_syscore_init(void)
 {
        /* Appropriate drivers (pinctrl, uart) handle this when using DT. */
-       if (of_have_populated_dt())
+       if (of_have_populated_dt() || !soc_is_s3c64xx())
                return 0;
 
        register_syscore_ops(&s3c64xx_irq_syscore_ops);
index 6224c67..347ce60 100644 (file)
@@ -47,6 +47,7 @@
 
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <mach/irqs.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
 #include <plat/samsung-time.h>
@@ -229,7 +230,7 @@ static void __init anw6410_machine_init(void)
 MACHINE_START(ANW6410, "A&W6410")
        /* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
        .atag_offset    = 0x100,
-
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = anw6410_map_io,
        .init_machine   = anw6410_machine_init,
index 9c00d83..571f95c 100644 (file)
@@ -29,6 +29,9 @@
 
 #include <linux/platform_data/spi-s3c64xx.h>
 
+#include <plat/cpu.h>
+#include <mach/irqs.h>
+
 #include "crag6410.h"
 
 static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
@@ -399,6 +402,9 @@ static struct i2c_driver wlf_gf_module_driver = {
 
 static int __init wlf_gf_module_register(void)
 {
+       if (!soc_is_s3c64xx())
+               return 0;
+
        return i2c_add_driver(&wlf_gf_module_driver);
 }
 device_initcall(wlf_gf_module_register);
index 723f47f..d9d0440 100644 (file)
@@ -52,6 +52,7 @@
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
+#include <mach/irqs.h>
 
 #include <plat/fb.h>
 #include <plat/sdhci.h>
@@ -860,6 +861,7 @@ static void __init crag6410_machine_init(void)
 MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
        /* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = crag6410_map_io,
        .init_machine   = crag6410_machine_init,
index 816b39d..bc7dc1f 100644 (file)
@@ -31,6 +31,7 @@
 #include <video/samsung_fimd.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
+#include <mach/irqs.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -279,6 +280,7 @@ static void __init hmt_machine_init(void)
 MACHINE_START(HMT, "Airgoo-HMT")
        /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
        .atag_offset    = 0x100,
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = hmt_map_io,
        .init_machine   = hmt_machine_init,
index ab61af5..ae999fb 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/platform_data/mmc-sdhci-s3c.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
+#include <mach/irqs.h>
 
 #include <video/platform_lcd.h>
 #include <video/samsung_fimd.h>
@@ -233,7 +234,6 @@ static struct platform_device *mini6410_devices[] __initdata = {
        &s3c_device_fb,
        &mini6410_lcd_powerdev,
        &s3c_device_adc,
-       &s3c_device_ts,
 };
 
 static void __init mini6410_map_io(void)
@@ -332,7 +332,7 @@ static void __init mini6410_machine_init(void)
        s3c_nand_set_platdata(&mini6410_nand_info);
        s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]);
        s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata);
-       s3c24xx_ts_set_platdata(NULL);
+       s3c64xx_ts_set_platdata(NULL);
 
        /* configure nCS1 width to 16 bits */
 
@@ -363,6 +363,7 @@ static void __init mini6410_machine_init(void)
 MACHINE_START(MINI6410, "MINI6410")
        /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = mini6410_map_io,
        .init_machine   = mini6410_machine_init,
index 80cb144..23baaa0 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/irqs.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
 
@@ -100,6 +101,7 @@ static void __init ncp_machine_init(void)
 MACHINE_START(NCP, "NCP")
        /* Maintainer: Samsung Electronics */
        .atag_offset    = 0x100,
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = ncp_map_io,
        .init_machine   = ncp_machine_init,
index 85fa959..4e240ff 100644 (file)
@@ -33,6 +33,7 @@
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
+#include <mach/irqs.h>
 
 #include <plat/adc.h>
 #include <plat/cpu.h>
@@ -202,7 +203,6 @@ static struct platform_device *real6410_devices[] __initdata = {
        &s3c_device_fb,
        &s3c_device_nand,
        &s3c_device_adc,
-       &s3c_device_ts,
        &s3c_device_ohci,
 };
 
@@ -301,7 +301,7 @@ static void __init real6410_machine_init(void)
 
        s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]);
        s3c_nand_set_platdata(&real6410_nand_info);
-       s3c24xx_ts_set_platdata(NULL);
+       s3c64xx_ts_set_platdata(NULL);
 
        /* configure nCS1 width to 16 bits */
 
@@ -331,7 +331,7 @@ static void __init real6410_machine_init(void)
 MACHINE_START(REAL6410, "REAL6410")
        /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
        .atag_offset    = 0x100,
-
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = real6410_map_io,
        .init_machine   = real6410_machine_init,
index acdfb5f..936a63f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
@@ -252,7 +253,6 @@ static struct platform_device *smartq_devices[] __initdata = {
        &s3c_device_ohci,
        &s3c_device_rtc,
        &samsung_device_pwm,
-       &s3c_device_ts,
        &s3c_device_usb_hsotg,
        &s3c64xx_device_iis0,
        &smartq_backlight_device,
@@ -383,6 +383,15 @@ void __init smartq_map_io(void)
        smartq_lcd_mode_set();
 }
 
+static struct gpiod_lookup_table smartq_audio_gpios = {
+       .dev_id = "smartq-audio",
+       .table = {
+               GPIO_LOOKUP("GPL", 12, "headphone detect", 0),
+               GPIO_LOOKUP("GPK", 12, "amplifiers shutdown", 0),
+               { },
+       },
+};
+
 void __init smartq_machine_init(void)
 {
        s3c_i2c0_set_platdata(NULL);
@@ -390,7 +399,7 @@ void __init smartq_machine_init(void)
        s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
        s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
        s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
-       s3c24xx_ts_set_platdata(&smartq_touchscreen_pdata);
+       s3c64xx_ts_set_platdata(&smartq_touchscreen_pdata);
 
        i2c_register_board_info(0, smartq_i2c_devs,
                                ARRAY_SIZE(smartq_i2c_devs));
@@ -402,4 +411,7 @@ void __init smartq_machine_init(void)
 
        pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
        platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
+
+       gpiod_add_lookup_table(&smartq_audio_gpios);
+       platform_device_register_simple("smartq-audio", -1, NULL, 0);
 }
index 33224ab..0972b6c 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/mach/arch.h>
 
 #include <video/samsung_fimd.h>
+#include <mach/irqs.h>
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
@@ -153,6 +154,7 @@ static void __init smartq5_machine_init(void)
 MACHINE_START(SMARTQ5, "SmartQ 5")
        /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = smartq_map_io,
        .init_machine   = smartq5_machine_init,
index fc7fece..51ac1c6 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/mach/arch.h>
 
 #include <video/samsung_fimd.h>
+#include <mach/irqs.h>
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
@@ -169,6 +170,7 @@ static void __init smartq7_machine_init(void)
 MACHINE_START(SMARTQ7, "SmartQ 7")
        /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
        .atag_offset    = 0x100,
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = smartq_map_io,
        .init_machine   = smartq7_machine_init,
index 6f42512..7d8a74f 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/irqs.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
 
@@ -88,7 +89,7 @@ static void __init smdk6400_machine_init(void)
 MACHINE_START(SMDK6400, "SMDK6400")
        /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .atag_offset    = 0x100,
-
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6400_init_irq,
        .map_io         = smdk6400_map_io,
        .init_machine   = smdk6400_machine_init,
index 30fd278..8a894ee 100644 (file)
@@ -52,6 +52,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <mach/map.h>
 
 #include <asm/irq.h>
@@ -289,7 +290,6 @@ static struct platform_device *smdk6410_devices[] __initdata = {
        &s3c_device_adc,
        &s3c_device_cfcon,
        &s3c_device_rtc,
-       &s3c_device_ts,
        &s3c_device_wdt,
 };
 
@@ -668,7 +668,7 @@ static void __init smdk6410_machine_init(void)
 
        samsung_keypad_set_platdata(&smdk6410_keypad_data);
 
-       s3c24xx_ts_set_platdata(NULL);
+       s3c64xx_ts_set_platdata(NULL);
 
        /* configure nCS1 width to 16 bits */
 
@@ -707,7 +707,7 @@ static void __init smdk6410_machine_init(void)
 MACHINE_START(SMDK6410, "SMDK6410")
        /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .atag_offset    = 0x100,
-
+       .nr_irqs        = S3C64XX_NR_IRQS,
        .init_irq       = s3c6410_init_irq,
        .map_io         = smdk6410_map_io,
        .init_machine   = smdk6410_machine_init,
index 901a984..89c5a62 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/amba/pl08x.h>
 #include <linux/of.h>
 
+#include <plat/cpu.h>
 #include <mach/irqs.h>
 #include <mach/map.h>
 
@@ -230,6 +231,9 @@ static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
 
 static int __init s3c64xx_pl080_init(void)
 {
+       if (!soc_is_s3c64xx())
+               return 0;
+
        /* Set all DMA configuration to be DMA, not SDMA */
        writel(0xffffff, S3C64XX_SDMA_SEL);
 
index 75b14e7..59d91b8 100644 (file)
@@ -22,6 +22,7 @@
 #include <mach/map.h>
 #include <mach/irqs.h>
 
+#include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
 #include <plat/wakeup-mask.h>
@@ -332,6 +333,9 @@ int __init s3c64xx_pm_init(void)
 
 static __init int s3c64xx_pm_initcall(void)
 {
+       if (!soc_is_s3c64xx())
+               return 0;
+
        pm_cpu_prep = s3c64xx_pm_prepare;
        pm_cpu_sleep = s3c64xx_cpu_suspend;
 
index 33273ab..5ea82ac 100644 (file)
@@ -81,7 +81,7 @@ static struct device s3c6400_dev = {
 static int __init s3c6400_core_init(void)
 {
        /* Not applicable when using DT. */
-       if (of_have_populated_dt())
+       if (of_have_populated_dt() || soc_is_s3c64xx())
                return 0;
 
        return subsys_system_register(&s3c6400_subsys, NULL);
index eadc48d..92bb927 100644 (file)
@@ -84,7 +84,7 @@ static struct device s3c6410_dev = {
 static int __init s3c6410_core_init(void)
 {
        /* Not applicable when using DT. */
-       if (of_have_populated_dt())
+       if (of_have_populated_dt() || !soc_is_s3c64xx())
                return 0;
 
        return subsys_system_register(&s3c6410_subsys, NULL);
index 330bfc8..13bc982 100644 (file)
@@ -8,7 +8,8 @@
 # Configuration options for the S5PV210/S5PC110
 
 config ARCH_S5PV210
-       bool "Samsung S5PV210/S5PC110" if ARCH_MULTI_V7
+       bool "Samsung S5PV210/S5PC110"
+       depends on ARCH_MULTI_V7
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_REQUIRE_GPIOLIB
        select ARM_VIC
index 41e476e..d8965c6 100644 (file)
@@ -98,8 +98,8 @@ static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        if (offset > 15)
-               return simpad_get_cs3_ro() & (1 << (offset - 16));
-       return simpad_get_cs3_shadow() & (1 << offset);
+               return !!(simpad_get_cs3_ro() & (1 << (offset - 16)));
+       return !!(simpad_get_cs3_shadow() & (1 << offset));
 };
 
 static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
index 88734a5..cd5f171 100644 (file)
@@ -1,6 +1,8 @@
 config ARCH_SHMOBILE
        bool
-       select ZONE_DMA if ARM_LPAE
+
+config ARCH_SHMOBILE_MULTI
+       bool
 
 config PM_RCAR
        bool
@@ -29,10 +31,11 @@ config ARCH_RMOBILE
        select SYS_SUPPORTS_SH_CMT
        select SYS_SUPPORTS_SH_TMU
 
-menuconfig ARCH_SHMOBILE_MULTI
-       bool "Renesas ARM SoCs" if ARCH_MULTI_V7
-       depends on MMU
+menuconfig ARCH_RENESAS
+       bool "Renesas ARM SoCs"
+       depends on ARCH_MULTI_V7 && MMU
        select ARCH_SHMOBILE
+       select ARCH_SHMOBILE_MULTI
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select ARM_GIC
@@ -40,8 +43,9 @@ menuconfig ARCH_SHMOBILE_MULTI
        select NO_IOPORT_MAP
        select PINCTRL
        select ARCH_REQUIRE_GPIOLIB
+       select ZONE_DMA if ARM_LPAE
 
-if ARCH_SHMOBILE_MULTI
+if ARCH_RENESAS
 
 #comment "Renesas ARM SoCs System Type"
 
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
deleted file mode 100644 (file)
index 5aee83f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __ASM_MACH_IRQS_H
-#define __ASM_MACH_IRQS_H
-
-/* Stuck here until drivers/pinctl/sh-pfc gets rid of legacy code */
-
-/* External IRQ pins */
-#define IRQPIN_BASE            2000
-#define irq_pin(nr)            ((nr) + IRQPIN_BASE)
-
-#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-shmobile/irqs.h b/arch/arm/mach-shmobile/irqs.h
deleted file mode 100644 (file)
index 3070f6d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __SHMOBILE_IRQS_H
-#define __SHMOBILE_IRQS_H
-
-#include "include/mach/irqs.h"
-
-/* GIC */
-#define gic_spi(nr)            ((nr) + 32)
-#define gic_iid(nr)            (nr) /* ICCIAR / interrupt ID */
-
-/* GPIO IRQ */
-#define _GPIO_IRQ_BASE         2500
-#define GPIO_IRQ_BASE(x)       (_GPIO_IRQ_BASE + (32 * x))
-#define GPIO_IRQ(x, y)         (_GPIO_IRQ_BASE + (32 * x) + y)
-
-#endif /* __SHMOBILE_IRQS_H */
index e1aaa2e..2a5f773 100644 (file)
@@ -3,6 +3,6 @@
 
 extern void r8a7779_pm_init(void);
 
-extern struct smp_operations r8a7779_smp_ops;
+extern const struct smp_operations r8a7779_smp_ops;
 
 #endif /* __ASM_R8A7779_H__ */
index 1a46d02..136f345 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __ASM_R8A7790_H__
 #define __ASM_R8A7790_H__
 
-extern struct smp_operations r8a7790_smp_ops;
+extern const struct smp_operations r8a7790_smp_ops;
 
 #endif /* __ASM_R8A7790_H__ */
index 7ca0b7d..cf7a840 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __ASM_R8A7791_H__
 #define __ASM_R8A7791_H__
 
-extern struct smp_operations r8a7791_smp_ops;
+extern const struct smp_operations r8a7791_smp_ops;
 
 #endif /* __ASM_R8A7791_H__ */
index 37f7b15..10b7cb5 100644 (file)
@@ -42,7 +42,7 @@ static const char *const emev2_boards_compat_dt[] __initconst = {
        NULL,
 };
 
-extern struct smp_operations emev2_smp_ops;
+extern const struct smp_operations emev2_smp_ops;
 
 DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
        .smp            = smp_ops(emev2_smp_ops),
index 0ab9d32..fab95d1 100644 (file)
@@ -22,7 +22,6 @@
 #include <asm/mach/arch.h>
 
 #include "common.h"
-#include "irqs.h"
 
 #define MODEMR 0xffcc0020
 
index 3964680..50ef24f 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __ASM_SH73A0_H__
 #define __ASM_SH73A0_H__
 
-extern struct smp_operations sh73a0_smp_ops;
+extern const struct smp_operations sh73a0_smp_ops;
 
 #endif /* __ASM_SH73A0_H__ */
index baff3b5..adbac69 100644 (file)
@@ -49,7 +49,7 @@ static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
        shmobile_smp_scu_prepare_cpus(max_cpus);
 }
 
-struct smp_operations emev2_smp_ops __initdata = {
+const struct smp_operations emev2_smp_ops __initconst = {
        .smp_prepare_cpus       = emev2_smp_prepare_cpus,
        .smp_boot_secondary     = emev2_boot_secondary,
 };
index 353562b..b854fe2 100644 (file)
@@ -117,7 +117,7 @@ static int r8a7779_cpu_kill(unsigned int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-struct smp_operations r8a7779_smp_ops  __initdata = {
+const struct smp_operations r8a7779_smp_ops  __initconst = {
        .smp_prepare_cpus       = r8a7779_smp_prepare_cpus,
        .smp_boot_secondary     = r8a7779_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index 4b33d43..f6426c6 100644 (file)
@@ -60,7 +60,7 @@ static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
        rcar_sysc_power_up(&r8a7790_ca7_scu);
 }
 
-struct smp_operations r8a7790_smp_ops __initdata = {
+const struct smp_operations r8a7790_smp_ops __initconst = {
        .smp_prepare_cpus       = r8a7790_smp_prepare_cpus,
        .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index b2508c0..2d6417a 100644 (file)
@@ -54,7 +54,7 @@ static int r8a7791_smp_boot_secondary(unsigned int cpu,
        return shmobile_smp_apmu_boot_secondary(cpu, idle);
 }
 
-struct smp_operations r8a7791_smp_ops __initdata = {
+const struct smp_operations r8a7791_smp_ops __initconst = {
        .smp_prepare_cpus       = r8a7791_smp_prepare_cpus,
        .smp_boot_secondary     = r8a7791_smp_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index bc2824a..ee1a4b7 100644 (file)
@@ -56,7 +56,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
        shmobile_smp_scu_prepare_cpus(max_cpus);
 }
 
-struct smp_operations sh73a0_smp_ops __initdata = {
+const struct smp_operations sh73a0_smp_ops __initconst = {
        .smp_prepare_cpus       = sh73a0_smp_prepare_cpus,
        .smp_boot_secondary     = sh73a0_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index 90efdeb..d0f62ea 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_SOCFPGA
-       bool "Altera SOCFPGA family" if ARCH_MULTI_V7
+       bool "Altera SOCFPGA family"
+       depends on ARCH_MULTI_V7
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
        select ARM_GIC
index 15c8ce8..cbb0a54 100644 (file)
@@ -117,7 +117,7 @@ static int socfpga_cpu_kill(unsigned int cpu)
        return 1;
 }
 
-static struct smp_operations socfpga_smp_ops __initdata = {
+static const struct smp_operations socfpga_smp_ops __initconst = {
        .smp_prepare_cpus       = socfpga_smp_prepare_cpus,
        .smp_boot_secondary     = socfpga_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static struct smp_operations socfpga_smp_ops __initdata = {
 #endif
 };
 
-static struct smp_operations socfpga_a10_smp_ops __initdata = {
+static const struct smp_operations socfpga_a10_smp_ops __initconst = {
        .smp_prepare_cpus       = socfpga_smp_prepare_cpus,
        .smp_boot_secondary     = socfpga_a10_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index b6f4bda..ea9ea95 100644 (file)
@@ -3,7 +3,8 @@
 #
 
 menuconfig PLAT_SPEAR
-       bool "ST SPEAr Family" if ARCH_MULTI_V7 || ARCH_MULTI_V5
+       bool "ST SPEAr Family"
+       depends on ARCH_MULTI_V7 || ARCH_MULTI_V5
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select CLKSRC_MMIO
index 0664091..909b97c 100644 (file)
@@ -39,7 +39,7 @@ void spear_restart(enum reboot_mode, const char *);
 void spear13xx_secondary_startup(void);
 void spear13xx_cpu_die(unsigned int cpu);
 
-extern struct smp_operations spear13xx_smp_ops;
+extern const struct smp_operations spear13xx_smp_ops;
 
 #ifdef CONFIG_MACH_SPEAR1310
 void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base);
index fd42977..8d1e2d5 100644 (file)
@@ -120,7 +120,7 @@ static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
        __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
 }
 
-struct smp_operations spear13xx_smp_ops __initdata = {
+const struct smp_operations spear13xx_smp_ops __initconst = {
        .smp_init_cpus          = spear13xx_smp_init_cpus,
        .smp_prepare_cpus       = spear13xx_smp_prepare_cpus,
        .smp_secondary_init     = spear13xx_secondary_init,
index 12dd1dc..a196d14 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_STI
-       bool "STMicroelectronics Consumer Electronics SOCs" if ARCH_MULTI_V7
+       bool "STMicroelectronics Consumer Electronics SOCs"
+       depends on ARCH_MULTI_V7
        select ARM_GIC
        select ST_IRQCHIP
        select ARM_GLOBAL_TIMER
index c4ad6ea..ea5a227 100644 (file)
@@ -156,7 +156,7 @@ static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
        }
 }
 
-struct smp_operations __initdata sti_smp_ops = {
+const struct smp_operations sti_smp_ops __initconst = {
        .smp_prepare_cpus       = sti_smp_prepare_cpus,
        .smp_secondary_init     = sti_secondary_init,
        .smp_boot_secondary     = sti_boot_secondary,
index ae22707..d8a2f87 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef __MACH_STI_SMP_H
 #define __MACH_STI_SMP_H
 
-extern struct smp_operations   sti_smp_ops;
+extern const struct smp_operations sti_smp_ops;
 
 void sti_secondary_startup(void);
 
index 4efe2d4..c124d65 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_SUNXI
-       bool "Allwinner SoCs" if ARCH_MULTI_V7
+       bool "Allwinner SoCs"
+       depends on ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_HAS_RESET_CONTROLLER
        select CLKSRC_MMIO
index e8483ec..6642267 100644 (file)
@@ -116,7 +116,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu,
        return 0;
 }
 
-static struct smp_operations sun6i_smp_ops __initdata = {
+static const struct smp_operations sun6i_smp_ops __initconst = {
        .smp_prepare_cpus       = sun6i_smp_prepare_cpus,
        .smp_boot_secondary     = sun6i_smp_boot_secondary,
 };
@@ -185,7 +185,7 @@ static int sun8i_smp_boot_secondary(unsigned int cpu,
        return 0;
 }
 
-struct smp_operations sun8i_smp_ops __initdata = {
+static const struct smp_operations sun8i_smp_ops __initconst = {
        .smp_prepare_cpus       = sun8i_smp_prepare_cpus,
        .smp_boot_secondary     = sun8i_smp_boot_secondary,
 };
diff --git a/arch/arm/mach-tango/Kconfig b/arch/arm/mach-tango/Kconfig
new file mode 100644 (file)
index 0000000..d6a3714
--- /dev/null
@@ -0,0 +1,12 @@
+config ARCH_TANGO
+       bool "Sigma Designs Tango4 (SMP87xx)" if ARCH_MULTI_V7
+       # Cortex-A9 MPCore r3p0, PL310 r3p2
+       select ARCH_HAS_HOLES_MEMORYMODEL
+       select ARM_ERRATA_754322
+       select ARM_ERRATA_764369 if SMP
+       select ARM_ERRATA_775420
+       select ARM_GIC
+       select CLKSRC_TANGO_XTAL
+       select HAVE_ARM_SCU
+       select HAVE_ARM_TWD
+       select TANGO_IRQ
diff --git a/arch/arm/mach-tango/Makefile b/arch/arm/mach-tango/Makefile
new file mode 100644 (file)
index 0000000..f33935e
--- /dev/null
@@ -0,0 +1,5 @@
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_smc.o := -Wa,-march=armv7-a$(plus_sec)
+
+obj-y += setup.o smc.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-tango/platsmp.c b/arch/arm/mach-tango/platsmp.c
new file mode 100644 (file)
index 0000000..a18d5a3
--- /dev/null
@@ -0,0 +1,16 @@
+#include <linux/init.h>
+#include <linux/smp.h>
+#include "smc.h"
+
+static int tango_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       tango_set_aux_boot_addr(virt_to_phys(secondary_startup));
+       tango_start_aux_core(cpu);
+       return 0;
+}
+
+static struct smp_operations tango_smp_ops __initdata = {
+       .smp_boot_secondary     = tango_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(tango4_smp, "sigma,tango4-smp", &tango_smp_ops);
diff --git a/arch/arm/mach-tango/setup.c b/arch/arm/mach-tango/setup.c
new file mode 100644 (file)
index 0000000..f14b6c7
--- /dev/null
@@ -0,0 +1,17 @@
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "smc.h"
+
+static void tango_l2c_write(unsigned long val, unsigned int reg)
+{
+       if (reg == L2X0_CTRL)
+               tango_set_l2_control(val);
+}
+
+static const char *const tango_dt_compat[] = { "sigma,tango4", NULL };
+
+DT_MACHINE_START(TANGO_DT, "Sigma Tango DT")
+       .dt_compat      = tango_dt_compat,
+       .l2c_aux_mask   = ~0,
+       .l2c_write_sec  = tango_l2c_write,
+MACHINE_END
diff --git a/arch/arm/mach-tango/smc.S b/arch/arm/mach-tango/smc.S
new file mode 100644 (file)
index 0000000..5d932ce
--- /dev/null
@@ -0,0 +1,9 @@
+#include <linux/linkage.h>
+
+ENTRY(tango_smc)
+       push    {lr}
+       mov     ip, r1
+       dsb     /* This barrier is probably unnecessary */
+       smc     #0
+       pop     {pc}
+ENDPROC(tango_smc)
diff --git a/arch/arm/mach-tango/smc.h b/arch/arm/mach-tango/smc.h
new file mode 100644 (file)
index 0000000..7a4af35
--- /dev/null
@@ -0,0 +1,5 @@
+extern int tango_smc(unsigned int val, unsigned int service);
+
+#define tango_set_l2_control(val)      tango_smc(val, 0x102)
+#define tango_start_aux_core(val)      tango_smc(val, 0x104)
+#define tango_set_aux_boot_addr(val)   tango_smc((unsigned int)val, 0x105)
index 0fa4c5f..0fa8b84 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_TEGRA
-       bool "NVIDIA Tegra" if ARCH_MULTI_V7
+       bool "NVIDIA Tegra"
+       depends on ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
        select ARM_AMBA
@@ -12,57 +13,5 @@ menuconfig ARCH_TEGRA
        select ARCH_HAS_RESET_CONTROLLER
        select RESET_CONTROLLER
        select SOC_BUS
-       select USB_ULPI if USB_PHY
-       select USB_ULPI_VIEWPORT if USB_PHY
        help
          This enables support for NVIDIA Tegra based systems.
-
-if ARCH_TEGRA
-
-config ARCH_TEGRA_2x_SOC
-       bool "Enable support for Tegra20 family"
-       select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
-       select ARM_ERRATA_720789
-       select ARM_ERRATA_754327 if SMP
-       select ARM_ERRATA_764369 if SMP
-       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
-
-config ARCH_TEGRA_3x_SOC
-       bool "Enable support for Tegra30 family"
-       select ARM_ERRATA_754322
-       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
-
-config ARCH_TEGRA_114_SOC
-       bool "Enable support for Tegra114 family"
-       select ARM_ERRATA_798181 if SMP
-       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
-
-config ARCH_TEGRA_124_SOC
-       bool "Enable support for Tegra124 family"
-       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
-
-endif
index 5900cc4..1f6fb80 100644 (file)
@@ -1,4 +1,4 @@
-extern struct smp_operations tegra_smp_ops;
+extern const struct smp_operations tegra_smp_ops;
 
 extern int tegra_cpu_kill(unsigned int cpu);
 extern void tegra_cpu_die(unsigned int cpu);
index b450866..f3f61db 100644 (file)
@@ -192,7 +192,7 @@ static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
                scu_enable(IO_ADDRESS(scu_a9_get_base()));
 }
 
-struct smp_operations tegra_smp_ops __initdata = {
+const struct smp_operations tegra_smp_ops __initconst = {
        .smp_prepare_cpus       = tegra_smp_prepare_cpus,
        .smp_secondary_init     = tegra_secondary_init,
        .smp_boot_secondary     = tegra_boot_secondary,
index e6b684e..f5d1966 100644 (file)
@@ -231,8 +231,11 @@ ENDPROC(tegra20_cpu_is_resettable_soon)
  * tegra20_tear_down_core in IRAM
  */
 ENTRY(tegra20_sleep_core_finish)
+       mov     r4, r0
        /* Flush, disable the L1 data cache and exit SMP */
+       mov     r0, #TEGRA_FLUSH_CACHE_ALL
        bl      tegra_disable_clean_inv_dcache
+       mov     r0, r4
 
        mov32   r3, tegra_shut_off_mmu
        add     r3, r3, r0
index 9a2f0b0..16e5ff0 100644 (file)
@@ -242,8 +242,11 @@ ENDPROC(tegra30_cpu_shutdown)
  * tegra30_tear_down_core in IRAM
  */
 ENTRY(tegra30_sleep_core_finish)
+       mov     r4, r0
        /* Flush, disable the L1 data cache and exit SMP */
+       mov     r0, #TEGRA_FLUSH_CACHE_ALL
        bl      tegra_disable_clean_inv_dcache
+       mov     r0, r4
 
        /*
         * Preload all the address literals that are needed for the
index bc51a71..301a984 100644 (file)
@@ -1,6 +1,6 @@
 menuconfig ARCH_U300
-       bool "ST-Ericsson U300 Series" if ARCH_MULTI_V5
-       depends on MMU
+       bool "ST-Ericsson U300 Series"
+       depends on ARCH_MULTI_V5 && MMU
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select ARM_VIC
index b640458..82dddee 100644 (file)
@@ -6,6 +6,7 @@ config ARCH_UNIPHIER
        select ARM_GIC
        select HAVE_ARM_SCU
        select HAVE_ARM_TWD if SMP
+       select PINCTRL
        help
          Support for UniPhier SoC family developed by Socionext Inc.
          (formerly, System LSI Business Division of Panasonic Corporation)
index f057766..e1cfc1d 100644 (file)
@@ -201,7 +201,7 @@ static int __init uniphier_smp_boot_secondary(unsigned int cpu,
        return 0;
 }
 
-static struct smp_operations uniphier_smp_ops __initdata = {
+static const struct smp_operations uniphier_smp_ops __initconst = {
        .smp_prepare_cpus       = uniphier_smp_prepare_cpus,
        .smp_boot_secondary     = uniphier_smp_boot_secondary,
 };
index 5eacdd6..3185081 100644 (file)
@@ -1,6 +1,6 @@
 menuconfig ARCH_U8500
-       bool "ST-Ericsson U8500 Series" if ARCH_MULTI_V7
-       depends on MMU
+       bool "ST-Ericsson U8500 Series"
+       depends on ARCH_MULTI_V7 && MMU
        select AB8500_CORE
        select ABX500_CORE
        select ARCH_REQUIRE_GPIOLIB
index c8643ac..edfff1a 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel, U8500 machine.
 #
 
-obj-y                          := cpu.o id.o timer.o pm.o
+obj-y                          := cpu.o id.o pm.o
 obj-$(CONFIG_CACHE_L2X0)       += cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o
 obj-$(CONFIG_MACH_MOP500)      += board-mop500-regulators.o \
index f805603..a0ffaad 100644 (file)
@@ -156,8 +156,6 @@ static const char * stericsson_dt_platform_compat[] = {
 DT_MACHINE_START(U8500_DT, "ST-Ericsson Ux5x0 platform (Device Tree Support)")
        .map_io         = u8500_map_io,
        .init_irq       = ux500_init_irq,
-       /* we re-use nomadik timer here */
-       .init_time      = ux500_timer_init,
        .init_machine   = u8500_init_machine,
        .init_late      = NULL,
        .dt_compat      = stericsson_dt_platform_compat,
index 41b81c4..82156cb 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/mfd/dbx500-prcmu.h>
-#include <linux/clksrc-dbx500-prcmu.h>
 #include <linux/sys_soc.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index 70766b9..88b8ab4 100644 (file)
@@ -98,7 +98,7 @@ static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-struct smp_operations ux500_smp_ops __initdata = {
+static const struct smp_operations ux500_smp_ops __initconst = {
        .smp_prepare_cpus       = ux500_smp_prepare_cpus,
        .smp_boot_secondary     = ux500_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
index 65876ea..c704254 100644 (file)
@@ -12,7 +12,6 @@
 #define __ASM_ARCH_SETUP_H
 
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
 #include <linux/init.h>
 #include <linux/mfd/abx500/ab8500.h>
 
@@ -24,8 +23,6 @@ extern void __init ux500_init_irq(void);
 
 extern struct device *ux500_soc_device_init(const char *soc_id);
 
-extern void ux500_timer_init(void);
-
 extern void ux500_cpu_die(unsigned int cpu);
 
 #endif /*  __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
deleted file mode 100644 (file)
index 8d2d233..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * License Terms: GNU General Public License v2
- * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson
- */
-#include <linux/io.h>
-#include <linux/errno.h>
-#include <linux/clksrc-dbx500-prcmu.h>
-#include <linux/clocksource.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-#include "setup.h"
-
-#include "db8500-regs.h"
-#include "id.h"
-
-static const struct of_device_id prcmu_timer_of_match[] __initconst = {
-       { .compatible = "stericsson,db8500-prcmu-timer-4", },
-       { },
-};
-
-void __init ux500_timer_init(void)
-{
-       void __iomem *prcmu_timer_base;
-       void __iomem *tmp_base;
-       struct device_node *np;
-
-       if (cpu_is_u8500_family() || cpu_is_ux540_family())
-               prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
-       else
-               ux500_unknown_soc();
-
-       np = of_find_matching_node(NULL, prcmu_timer_of_match);
-       if (!np)
-               goto dt_fail;
-
-       tmp_base = of_iomap(np, 0);
-       if (!tmp_base)
-               goto dt_fail;
-
-       prcmu_timer_base = tmp_base;
-
-dt_fail:
-       clksrc_dbx500_prcmu_init(prcmu_timer_base);
-       clocksource_probe();
-}
index 1dba368..e40f777 100644 (file)
@@ -1,33 +1,16 @@
-menu "Versatile platform type"
-       depends on ARCH_VERSATILE
-
-config ARCH_VERSATILE_PB
-       bool "Support Versatile Platform Baseboard for ARM926EJ-S"
-       default y
+config ARCH_VERSATILE
+       bool "ARM Ltd. Versatile family"
+       depends on ARCH_MULTI_V5
+       select ARM_AMBA
+       select ARM_TIMER_SP804
+       select ARM_VIC
+       select CLKSRC_VERSATILE
+       select COMMON_CLK_VERSATILE
        select CPU_ARM926T
+       select ICST
        select MIGHT_HAVE_PCI
+       select PLAT_VERSATILE
+       select VERSATILE_FPGA_IRQ
        help
-         Include support for the ARM(R) Versatile Platform Baseboard
-         for the ARM926EJ-S.
-
-config MACH_VERSATILE_AB
-       bool "Support Versatile Application Baseboard for ARM926EJ-S"
-       select CPU_ARM926T
-       help
-         Include support for the ARM(R) Versatile Application Baseboard
-         for the ARM926EJ-S.
-
-config MACH_VERSATILE_DT
-       bool "Support Versatile platform from device tree"
-       select CPU_ARM926T
-       select USE_OF
-       help
-         Include support for the ARM(R) Versatile/PB platform,
-         using the device tree for discovery
-
-config MACH_VERSATILE_AUTO
-       def_bool y
-       depends on !ARCH_VERSATILE_PB && !MACH_VERSATILE_AB
-       select MACH_VERSATILE_DT
+         This enables support for ARM Ltd Versatile board.
 
-endmenu
index 81fa3fe..41b124b 100644 (file)
@@ -2,8 +2,4 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                                  := core.o
-obj-$(CONFIG_ARCH_VERSATILE_PB)                += versatile_pb.o
-obj-$(CONFIG_MACH_VERSATILE_AB)                += versatile_ab.o
-obj-$(CONFIG_MACH_VERSATILE_DT)                += versatile_dt.o
-obj-$(CONFIG_PCI)                      += pci.o
+obj-y                                  := versatile_dt.o
diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot
deleted file mode 100644 (file)
index ff0a4b5..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-   zreladdr-y  += 0x00008000
-params_phys-y  := 0x00000100
-initrd_phys-y  := 0x00800000
-
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
deleted file mode 100644 (file)
index 23a04fe..0000000
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/core.c
- *
- *  Copyright (C) 1999 - 2003 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/clcd.h>
-#include <linux/platform_data/video-clcd-versatile.h>
-#include <linux/amba/pl061.h>
-#include <linux/amba/mmci.h>
-#include <linux/amba/pl022.h>
-#include <linux/io.h>
-#include <linux/irqchip/arm-vic.h>
-#include <linux/irqchip/versatile-fpga.h>
-#include <linux/gfp.h>
-#include <linux/clkdev.h>
-#include <linux/mtd/physmap.h>
-#include <linux/bitops.h>
-#include <linux/reboot.h>
-
-#include <clocksource/timer-sp804.h>
-
-#include <asm/irq.h>
-#include <asm/hardware/icst.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
-#include <plat/sched_clock.h>
-
-#include "core.h"
-
-/*
- * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
- * is the (PA >> 12).
- *
- * Setup a VA for the Versatile Vectored Interrupt Controller.
- */
-#define VA_VIC_BASE            __io_address(VERSATILE_VIC_BASE)
-#define VA_SIC_BASE            __io_address(VERSATILE_SIC_BASE)
-
-/* These PIC IRQs are valid in each configuration */
-#define PIC_VALID_ALL  BIT(SIC_INT_KMI0) | BIT(SIC_INT_KMI1) | \
-                       BIT(SIC_INT_SCI3) | BIT(SIC_INT_UART3) | \
-                       BIT(SIC_INT_CLCD) | BIT(SIC_INT_TOUCH) | \
-                       BIT(SIC_INT_KEYPAD) | BIT(SIC_INT_DoC) | \
-                       BIT(SIC_INT_USB) | BIT(SIC_INT_PCI0) | \
-                       BIT(SIC_INT_PCI1) | BIT(SIC_INT_PCI2) | \
-                       BIT(SIC_INT_PCI3)
-#if 1
-#define IRQ_MMCI0A     IRQ_VICSOURCE22
-#define IRQ_AACI       IRQ_VICSOURCE24
-#define IRQ_ETH                IRQ_VICSOURCE25
-#define PIC_MASK       0xFFD00000
-#define PIC_VALID      PIC_VALID_ALL
-#else
-#define IRQ_MMCI0A     IRQ_SIC_MMCI0A
-#define IRQ_AACI       IRQ_SIC_AACI
-#define IRQ_ETH                IRQ_SIC_ETH
-#define PIC_MASK       0
-#define PIC_VALID      PIC_VALID_ALL | BIT(SIC_INT_MMCI0A) | \
-                       BIT(SIC_INT_MMCI1A) | BIT(SIC_INT_AACI) | \
-                       BIT(SIC_INT_ETH)
-#endif
-
-/* Lookup table for finding a DT node that represents the vic instance */
-static const struct of_device_id vic_of_match[] __initconst = {
-       { .compatible = "arm,versatile-vic", },
-       {}
-};
-
-static const struct of_device_id sic_of_match[] __initconst = {
-       { .compatible = "arm,versatile-sic", },
-       {}
-};
-
-void __init versatile_init_irq(void)
-{
-       struct device_node *np;
-
-       np = of_find_matching_node_by_address(NULL, vic_of_match,
-                                             VERSATILE_VIC_BASE);
-       __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np);
-
-       writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
-
-       np = of_find_matching_node_by_address(NULL, sic_of_match,
-                                             VERSATILE_SIC_BASE);
-
-       fpga_irq_init(VA_SIC_BASE, "SIC", IRQ_SIC_START,
-               IRQ_VICSOURCE31, PIC_VALID, np);
-
-       /*
-        * Interrupts on secondary controller from 0 to 8 are routed to
-        * source 31 on PIC.
-        * Interrupts from 21 to 31 are routed directly to the VIC on
-        * the corresponding number on primary controller. This is controlled
-        * by setting PIC_ENABLEx.
-        */
-       writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);
-}
-
-static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
-       {
-               .virtual        =  IO_ADDRESS(VERSATILE_SYS_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_SYS_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        =  IO_ADDRESS(VERSATILE_SIC_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_SIC_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        =  IO_ADDRESS(VERSATILE_VIC_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_VIC_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
-               .length         = SZ_4K * 9,
-               .type           = MT_DEVICE
-       },
-#ifdef CONFIG_MACH_VERSATILE_AB
-       {
-               .virtual        =  IO_ADDRESS(VERSATILE_IB2_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_IB2_BASE),
-               .length         = SZ_64M,
-               .type           = MT_DEVICE
-       },
-#endif
-#ifdef CONFIG_DEBUG_LL
-       {
-               .virtual        =  IO_ADDRESS(VERSATILE_UART0_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_UART0_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       },
-#endif
-#ifdef CONFIG_PCI
-       {
-               .virtual        =  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        =  (unsigned long)VERSATILE_PCI_VIRT_BASE,
-               .pfn            = __phys_to_pfn(VERSATILE_PCI_BASE),
-               .length         = VERSATILE_PCI_BASE_SIZE,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        =  (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE,
-               .pfn            = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
-               .length         = VERSATILE_PCI_CFG_BASE_SIZE,
-               .type           = MT_DEVICE
-       },
-#endif
-};
-
-void __init versatile_map_io(void)
-{
-       iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
-}
-
-
-#define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
-
-static void versatile_flash_set_vpp(struct platform_device *pdev, int on)
-{
-       u32 val;
-
-       val = __raw_readl(VERSATILE_FLASHCTRL);
-       if (on)
-               val |= VERSATILE_FLASHPROG_FLVPPEN;
-       else
-               val &= ~VERSATILE_FLASHPROG_FLVPPEN;
-       __raw_writel(val, VERSATILE_FLASHCTRL);
-}
-
-static struct physmap_flash_data versatile_flash_data = {
-       .width                  = 4,
-       .set_vpp                = versatile_flash_set_vpp,
-};
-
-static struct resource versatile_flash_resource = {
-       .start                  = VERSATILE_FLASH_BASE,
-       .end                    = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,
-       .flags                  = IORESOURCE_MEM,
-};
-
-static struct platform_device versatile_flash_device = {
-       .name                   = "physmap-flash",
-       .id                     = 0,
-       .dev                    = {
-               .platform_data  = &versatile_flash_data,
-       },
-       .num_resources          = 1,
-       .resource               = &versatile_flash_resource,
-};
-
-static struct resource smc91x_resources[] = {
-       [0] = {
-               .start          = VERSATILE_ETH_BASE,
-               .end            = VERSATILE_ETH_BASE + SZ_64K - 1,
-               .flags          = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start          = IRQ_ETH,
-               .end            = IRQ_ETH,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device smc91x_device = {
-       .name           = "smc91x",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(smc91x_resources),
-       .resource       = smc91x_resources,
-};
-
-static struct resource versatile_i2c_resource = {
-       .start                  = VERSATILE_I2C_BASE,
-       .end                    = VERSATILE_I2C_BASE + SZ_4K - 1,
-       .flags                  = IORESOURCE_MEM,
-};
-
-static struct platform_device versatile_i2c_device = {
-       .name                   = "versatile-i2c",
-       .id                     = 0,
-       .num_resources          = 1,
-       .resource               = &versatile_i2c_resource,
-};
-
-static struct i2c_board_info versatile_i2c_board_info[] = {
-       {
-               I2C_BOARD_INFO("ds1338", 0xd0 >> 1),
-       },
-};
-
-static int __init versatile_i2c_init(void)
-{
-       return i2c_register_board_info(0, versatile_i2c_board_info,
-                                      ARRAY_SIZE(versatile_i2c_board_info));
-}
-arch_initcall(versatile_i2c_init);
-
-#define VERSATILE_SYSMCI       (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
-
-unsigned int mmc_status(struct device *dev)
-{
-       struct amba_device *adev = container_of(dev, struct amba_device, dev);
-       u32 mask;
-
-       if (adev->res.start == VERSATILE_MMCI0_BASE)
-               mask = 1;
-       else
-               mask = 2;
-
-       return readl(VERSATILE_SYSMCI) & mask;
-}
-
-static struct mmci_platform_data mmc0_plat_data = {
-       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-       .status         = mmc_status,
-       .gpio_wp        = -1,
-       .gpio_cd        = -1,
-};
-
-static struct resource char_lcd_resources[] = {
-       {
-               .start = VERSATILE_CHAR_LCD_BASE,
-               .end   = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1),
-               .flags = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device char_lcd_device = {
-       .name           =       "arm-charlcd",
-       .id             =       -1,
-       .num_resources  =       ARRAY_SIZE(char_lcd_resources),
-       .resource       =       char_lcd_resources,
-};
-
-static struct resource leds_resources[] = {
-       {
-               .start  = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET,
-               .end    = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET + 4,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device leds_device = {
-       .name           = "versatile-leds",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(leds_resources),
-       .resource       = leds_resources,
-};
-
-/*
- * Clock handling
- */
-static const struct icst_params versatile_oscvco_params = {
-       .ref            = 24000000,
-       .vco_max        = ICST307_VCO_MAX,
-       .vco_min        = ICST307_VCO_MIN,
-       .vd_min         = 4 + 8,
-       .vd_max         = 511 + 8,
-       .rd_min         = 1 + 2,
-       .rd_max         = 127 + 2,
-       .s2div          = icst307_s2div,
-       .idx2s          = icst307_idx2s,
-};
-
-static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco)
-{
-       void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
-       u32 val;
-
-       val = readl(clk->vcoreg) & ~0x7ffff;
-       val |= vco.v | (vco.r << 9) | (vco.s << 16);
-
-       writel(0xa05f, sys_lock);
-       writel(val, clk->vcoreg);
-       writel(0, sys_lock);
-}
-
-static const struct clk_ops osc4_clk_ops = {
-       .round  = icst_clk_round,
-       .set    = icst_clk_set,
-       .setvco = versatile_oscvco_set,
-};
-
-static struct clk osc4_clk = {
-       .ops    = &osc4_clk_ops,
-       .params = &versatile_oscvco_params,
-};
-
-/*
- * These are fixed clocks.
- */
-static struct clk ref24_clk = {
-       .rate   = 24000000,
-};
-
-static struct clk sp804_clk = {
-       .rate   = 1000000,
-};
-
-static struct clk dummy_apb_pclk;
-
-static struct clk_lookup lookups[] = {
-       {       /* AMBA bus clock */
-               .con_id         = "apb_pclk",
-               .clk            = &dummy_apb_pclk,
-       }, {    /* UART0 */
-               .dev_id         = "dev:f1",
-               .clk            = &ref24_clk,
-       }, {    /* UART1 */
-               .dev_id         = "dev:f2",
-               .clk            = &ref24_clk,
-       }, {    /* UART2 */
-               .dev_id         = "dev:f3",
-               .clk            = &ref24_clk,
-       }, {    /* UART3 */
-               .dev_id         = "fpga:09",
-               .clk            = &ref24_clk,
-       }, {    /* KMI0 */
-               .dev_id         = "fpga:06",
-               .clk            = &ref24_clk,
-       }, {    /* KMI1 */
-               .dev_id         = "fpga:07",
-               .clk            = &ref24_clk,
-       }, {    /* MMC0 */
-               .dev_id         = "fpga:05",
-               .clk            = &ref24_clk,
-       }, {    /* MMC1 */
-               .dev_id         = "fpga:0b",
-               .clk            = &ref24_clk,
-       }, {    /* SSP */
-               .dev_id         = "dev:f4",
-               .clk            = &ref24_clk,
-       }, {    /* CLCD */
-               .dev_id         = "dev:20",
-               .clk            = &osc4_clk,
-       }, {    /* SP804 timers */
-               .dev_id         = "sp804",
-               .clk            = &sp804_clk,
-       },
-};
-
-/*
- * CLCD support.
- */
-#define SYS_CLCD_MODE_MASK     (3 << 0)
-#define SYS_CLCD_MODE_888      (0 << 0)
-#define SYS_CLCD_MODE_5551     (1 << 0)
-#define SYS_CLCD_MODE_565_RLSB (2 << 0)
-#define SYS_CLCD_MODE_565_BLSB (3 << 0)
-#define SYS_CLCD_NLCDIOON      (1 << 2)
-#define SYS_CLCD_VDDPOSSWITCH  (1 << 3)
-#define SYS_CLCD_PWR3V5SWITCH  (1 << 4)
-#define SYS_CLCD_ID_MASK       (0x1f << 8)
-#define SYS_CLCD_ID_SANYO_3_8  (0x00 << 8)
-#define SYS_CLCD_ID_UNKNOWN_8_4        (0x01 << 8)
-#define SYS_CLCD_ID_EPSON_2_2  (0x02 << 8)
-#define SYS_CLCD_ID_SANYO_2_5  (0x07 << 8)
-#define SYS_CLCD_ID_VGA                (0x1f << 8)
-
-static bool is_sanyo_2_5_lcd;
-
-/*
- * Disable all display connectors on the interface module.
- */
-static void versatile_clcd_disable(struct clcd_fb *fb)
-{
-       void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
-       u32 val;
-
-       val = readl(sys_clcd);
-       val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
-       writel(val, sys_clcd);
-
-#ifdef CONFIG_MACH_VERSATILE_AB
-       /*
-        * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
-        */
-       if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
-               void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
-               unsigned long ctrl;
-
-               ctrl = readl(versatile_ib2_ctrl);
-               ctrl &= ~0x01;
-               writel(ctrl, versatile_ib2_ctrl);
-       }
-#endif
-}
-
-/*
- * Enable the relevant connector on the interface module.
- */
-static void versatile_clcd_enable(struct clcd_fb *fb)
-{
-       struct fb_var_screeninfo *var = &fb->fb.var;
-       void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
-       u32 val;
-
-       val = readl(sys_clcd);
-       val &= ~SYS_CLCD_MODE_MASK;
-
-       switch (var->green.length) {
-       case 5:
-               val |= SYS_CLCD_MODE_5551;
-               break;
-       case 6:
-               if (var->red.offset == 0)
-                       val |= SYS_CLCD_MODE_565_RLSB;
-               else
-                       val |= SYS_CLCD_MODE_565_BLSB;
-               break;
-       case 8:
-               val |= SYS_CLCD_MODE_888;
-               break;
-       }
-
-       /*
-        * Set the MUX
-        */
-       writel(val, sys_clcd);
-
-       /*
-        * And now enable the PSUs
-        */
-       val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
-       writel(val, sys_clcd);
-
-#ifdef CONFIG_MACH_VERSATILE_AB
-       /*
-        * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
-        */
-       if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
-               void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
-               unsigned long ctrl;
-
-               ctrl = readl(versatile_ib2_ctrl);
-               ctrl |= 0x01;
-               writel(ctrl, versatile_ib2_ctrl);
-       }
-#endif
-}
-
-/*
- * Detect which LCD panel is connected, and return the appropriate
- * clcd_panel structure.  Note: we do not have any information on
- * the required timings for the 8.4in panel, so we presently assume
- * VGA timings.
- */
-static int versatile_clcd_setup(struct clcd_fb *fb)
-{
-       void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
-       const char *panel_name;
-       u32 val;
-
-       is_sanyo_2_5_lcd = false;
-
-       val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
-       if (val == SYS_CLCD_ID_SANYO_3_8)
-               panel_name = "Sanyo TM38QV67A02A";
-       else if (val == SYS_CLCD_ID_SANYO_2_5) {
-               panel_name = "Sanyo QVGA Portrait";
-               is_sanyo_2_5_lcd = true;
-       } else if (val == SYS_CLCD_ID_EPSON_2_2)
-               panel_name = "Epson L2F50113T00";
-       else if (val == SYS_CLCD_ID_VGA)
-               panel_name = "VGA";
-       else {
-               printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
-                       val);
-               panel_name = "VGA";
-       }
-
-       fb->panel = versatile_clcd_get_panel(panel_name);
-       if (!fb->panel)
-               return -EINVAL;
-
-       return versatile_clcd_setup_dma(fb, SZ_1M);
-}
-
-static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
-{
-       clcdfb_decode(fb, regs);
-
-       /* Always clear BGR for RGB565: we do the routing externally */
-       if (fb->fb.var.green.length == 6)
-               regs->cntl &= ~CNTL_BGR;
-}
-
-static struct clcd_board clcd_plat_data = {
-       .name           = "Versatile",
-       .caps           = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
-       .check          = clcdfb_check,
-       .decode         = versatile_clcd_decode,
-       .disable        = versatile_clcd_disable,
-       .enable         = versatile_clcd_enable,
-       .setup          = versatile_clcd_setup,
-       .mmap           = versatile_clcd_mmap_dma,
-       .remove         = versatile_clcd_remove_dma,
-};
-
-static struct pl061_platform_data gpio0_plat_data = {
-       .gpio_base      = 0,
-       .irq_base       = IRQ_GPIO0_START,
-};
-
-static struct pl061_platform_data gpio1_plat_data = {
-       .gpio_base      = 8,
-       .irq_base       = IRQ_GPIO1_START,
-};
-
-static struct pl061_platform_data gpio2_plat_data = {
-       .gpio_base      = 16,
-       .irq_base       = IRQ_GPIO2_START,
-};
-
-static struct pl061_platform_data gpio3_plat_data = {
-       .gpio_base      = 24,
-       .irq_base       = IRQ_GPIO3_START,
-};
-
-static struct pl022_ssp_controller ssp0_plat_data = {
-       .bus_id = 0,
-       .enable_dma = 0,
-       .num_chipselect = 1,
-};
-
-#define AACI_IRQ       { IRQ_AACI }
-#define MMCI0_IRQ      { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
-#define KMI0_IRQ       { IRQ_SIC_KMI0 }
-#define KMI1_IRQ       { IRQ_SIC_KMI1 }
-
-/*
- * These devices are connected directly to the multi-layer AHB switch
- */
-#define SMC_IRQ                { }
-#define MPMC_IRQ       { }
-#define CLCD_IRQ       { IRQ_CLCDINT }
-#define DMAC_IRQ       { IRQ_DMAINT }
-
-/*
- * These devices are connected via the core APB bridge
- */
-#define SCTL_IRQ       { }
-#define WATCHDOG_IRQ   { IRQ_WDOGINT }
-#define GPIO0_IRQ      { IRQ_GPIOINT0 }
-#define GPIO1_IRQ      { IRQ_GPIOINT1 }
-#define GPIO2_IRQ      { IRQ_GPIOINT2 }
-#define GPIO3_IRQ      { IRQ_GPIOINT3 }
-#define RTC_IRQ                { IRQ_RTCINT }
-
-/*
- * These devices are connected via the DMA APB bridge
- */
-#define SCI_IRQ                { IRQ_SCIINT }
-#define UART0_IRQ      { IRQ_UARTINT0 }
-#define UART1_IRQ      { IRQ_UARTINT1 }
-#define UART2_IRQ      { IRQ_UARTINT2 }
-#define SSP_IRQ                { IRQ_SSPINT }
-
-/* FPGA Primecells */
-APB_DEVICE(aaci,  "fpga:04", AACI,     NULL);
-APB_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data);
-APB_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);
-APB_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);
-
-/* DevChip Primecells */
-AHB_DEVICE(smc,   "dev:00",  SMC,      NULL);
-AHB_DEVICE(mpmc,  "dev:10",  MPMC,     NULL);
-AHB_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);
-AHB_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
-APB_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
-APB_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
-APB_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data);
-APB_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data);
-APB_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data);
-APB_DEVICE(gpio3, "dev:e7",  GPIO3,    &gpio3_plat_data);
-APB_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
-APB_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
-APB_DEVICE(uart0, "dev:f1",  UART0,    NULL);
-APB_DEVICE(uart1, "dev:f2",  UART1,    NULL);
-APB_DEVICE(uart2, "dev:f3",  UART2,    NULL);
-APB_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data);
-
-static struct amba_device *amba_devs[] __initdata = {
-       &dmac_device,
-       &uart0_device,
-       &uart1_device,
-       &uart2_device,
-       &smc_device,
-       &mpmc_device,
-       &clcd_device,
-       &sctl_device,
-       &wdog_device,
-       &gpio0_device,
-       &gpio1_device,
-       &gpio2_device,
-       &gpio3_device,
-       &rtc_device,
-       &sci0_device,
-       &ssp0_device,
-       &aaci_device,
-       &mmc0_device,
-       &kmi0_device,
-       &kmi1_device,
-};
-
-#ifdef CONFIG_OF
-/*
- * Lookup table for attaching a specific name and platform_data pointer to
- * devices as they get created by of_platform_populate().  Ideally this table
- * would not exist, but the current clock implementation depends on some devices
- * having a specific name.
- */
-struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL),
-       /* FIXME: this is buggy, the platform data is needed for this MMC instance too */
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL),
-
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", &ssp0_plat_data),
-
-#if 0
-       /*
-        * These entries are unnecessary because no clocks referencing
-        * them.  I've left them in for now as place holders in case
-        * any of them need to be added back, but they should be
-        * removed before actually committing this patch.  --gcl
-        */
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_AACI_BASE, "fpga:04", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI1_BASE, "fpga:0a", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SMC_BASE, "dev:00", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MPMC_BASE, "dev:10", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_DMAC_BASE, "dev:30", NULL),
-
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCTL_BASE, "dev:e0", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_WATCHDOG_BASE, "dev:e1", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO0_BASE, "dev:e4", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO1_BASE, "dev:e5", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO2_BASE, "dev:e6", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO3_BASE, "dev:e7", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_RTC_BASE, "dev:e8", NULL),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI_BASE, "dev:f0", NULL),
-#endif
-       {}
-};
-#endif
-
-void versatile_restart(enum reboot_mode mode, const char *cmd)
-{
-       void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
-       u32 val;
-
-       val = __raw_readl(sys + VERSATILE_SYS_RESETCTL_OFFSET);
-       val |= 0x105;
-
-       __raw_writel(0xa05f, sys + VERSATILE_SYS_LOCK_OFFSET);
-       __raw_writel(val, sys + VERSATILE_SYS_RESETCTL_OFFSET);
-       __raw_writel(0, sys + VERSATILE_SYS_LOCK_OFFSET);
-}
-
-/* Early initializations */
-void __init versatile_init_early(void)
-{
-       u32 val;
-       void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
-
-       osc4_clk.vcoreg = sys + VERSATILE_SYS_OSCCLCD_OFFSET;
-       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-       versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
-
-       /*
-        * set clock frequency:
-        *      VERSATILE_REFCLK is 32KHz
-        *      VERSATILE_TIMCLK is 1MHz
-        */
-       val = readl(__io_address(VERSATILE_SCTL_BASE));
-       writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
-              (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
-              (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
-              (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
-              __io_address(VERSATILE_SCTL_BASE));
-}
-
-void __init versatile_init(void)
-{
-       int i;
-
-       platform_device_register(&versatile_flash_device);
-       platform_device_register(&versatile_i2c_device);
-       platform_device_register(&smc91x_device);
-       platform_device_register(&char_lcd_device);
-       platform_device_register(&leds_device);
-
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-               struct amba_device *d = amba_devs[i];
-               amba_device_register(d, &iomem_resource);
-       }
-}
-
-/*
- * Where is the timer (VA)?
- */
-#define TIMER0_VA_BASE          __io_address(VERSATILE_TIMER0_1_BASE)
-#define TIMER1_VA_BASE         (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
-#define TIMER2_VA_BASE          __io_address(VERSATILE_TIMER2_3_BASE)
-#define TIMER3_VA_BASE         (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-void __init versatile_timer_init(void)
-{
-
-       /*
-        * Initialise to a known state (all timers off)
-        */
-       sp804_timer_disable(TIMER0_VA_BASE);
-       sp804_timer_disable(TIMER1_VA_BASE);
-       sp804_timer_disable(TIMER2_VA_BASE);
-       sp804_timer_disable(TIMER3_VA_BASE);
-
-       sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
-       sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
-}
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
deleted file mode 100644 (file)
index f06d576..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/core.h
- *
- *  Copyright (C) 2004 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; 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_VERSATILE_H
-#define __ASM_ARCH_VERSATILE_H
-
-#include <linux/amba/bus.h>
-#include <linux/of_platform.h>
-#include <linux/reboot.h>
-
-extern void __init versatile_init(void);
-extern void __init versatile_init_early(void);
-extern void __init versatile_init_irq(void);
-extern void __init versatile_map_io(void);
-extern void versatile_timer_init(void);
-extern void versatile_restart(enum reboot_mode, const char *);
-extern unsigned int mmc_status(struct device *dev);
-#ifdef CONFIG_OF
-extern struct of_dev_auxdata versatile_auxdata_lookup[];
-#endif
-
-#define APB_DEVICE(name, busid, base, plat)    \
-static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
-
-#define AHB_DEVICE(name, busid, base, plat)    \
-static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
-
-#endif
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
deleted file mode 100644 (file)
index e58d077..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_MACH_CLKDEV_H
-#define __ASM_MACH_CLKDEV_H
-
-#include <plat/clock.h>
-
-struct clk {
-       unsigned long           rate;
-       const struct clk_ops    *ops;
-       const struct icst_params *params;
-       void __iomem            *vcoreg;
-};
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do { } while (0)
-
-#endif
diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h
deleted file mode 100644 (file)
index 3e5d425..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  arch/arm/mach-versatile/include/mach/hardware.h
- *
- *  This file contains the hardware definitions of the Versatile boards.
- *
- *  Copyright (C) 2003 ARM Limited.
- *
- * This program is free software; 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_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/sizes.h>
-
-/*
- * PCI space virtual addresses
- */
-#define VERSATILE_PCI_VIRT_BASE                (void __iomem *)0xe8000000ul
-#define VERSATILE_PCI_CFG_VIRT_BASE    (void __iomem *)0xe9000000ul
-
-/* macro to get at MMIO space when running virtually */
-#define IO_ADDRESS(x)          (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
-
-#define __io_address(n)                ((void __iomem __force *)IO_ADDRESS(n))
-
-#endif
diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h
deleted file mode 100644 (file)
index 0fd771c..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  arch/arm/mach-versatile/include/mach/irqs.h
- *
- *  Copyright (C) 2003 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <mach/platform.h>
-
-/* 
- *  IRQ interrupts definitions are the same as the INT definitions
- *  held within platform.h
- */
-#define IRQ_VIC_START          32
-#define IRQ_WDOGINT            (IRQ_VIC_START + INT_WDOGINT)
-#define IRQ_SOFTINT            (IRQ_VIC_START + INT_SOFTINT)
-#define IRQ_COMMRx             (IRQ_VIC_START + INT_COMMRx)
-#define IRQ_COMMTx             (IRQ_VIC_START + INT_COMMTx)
-#define IRQ_TIMERINT0_1                (IRQ_VIC_START + INT_TIMERINT0_1)
-#define IRQ_TIMERINT2_3                (IRQ_VIC_START + INT_TIMERINT2_3)
-#define IRQ_GPIOINT0           (IRQ_VIC_START + INT_GPIOINT0)
-#define IRQ_GPIOINT1           (IRQ_VIC_START + INT_GPIOINT1)
-#define IRQ_GPIOINT2           (IRQ_VIC_START + INT_GPIOINT2)
-#define IRQ_GPIOINT3           (IRQ_VIC_START + INT_GPIOINT3)
-#define IRQ_RTCINT             (IRQ_VIC_START + INT_RTCINT)
-#define IRQ_SSPINT             (IRQ_VIC_START + INT_SSPINT)
-#define IRQ_UARTINT0           (IRQ_VIC_START + INT_UARTINT0)
-#define IRQ_UARTINT1           (IRQ_VIC_START + INT_UARTINT1)
-#define IRQ_UARTINT2           (IRQ_VIC_START + INT_UARTINT2)
-#define IRQ_SCIINT             (IRQ_VIC_START + INT_SCIINT)
-#define IRQ_CLCDINT            (IRQ_VIC_START + INT_CLCDINT)
-#define IRQ_DMAINT             (IRQ_VIC_START + INT_DMAINT)
-#define IRQ_PWRFAILINT                 (IRQ_VIC_START + INT_PWRFAILINT)
-#define IRQ_MBXINT             (IRQ_VIC_START + INT_MBXINT)
-#define IRQ_GNDINT             (IRQ_VIC_START + INT_GNDINT)
-#define IRQ_VICSOURCE21                (IRQ_VIC_START + INT_VICSOURCE21)
-#define IRQ_VICSOURCE22                (IRQ_VIC_START + INT_VICSOURCE22)
-#define IRQ_VICSOURCE23                (IRQ_VIC_START + INT_VICSOURCE23)
-#define IRQ_VICSOURCE24                (IRQ_VIC_START + INT_VICSOURCE24)
-#define IRQ_VICSOURCE25                (IRQ_VIC_START + INT_VICSOURCE25)
-#define IRQ_VICSOURCE26                (IRQ_VIC_START + INT_VICSOURCE26)
-#define IRQ_VICSOURCE27                (IRQ_VIC_START + INT_VICSOURCE27)
-#define IRQ_VICSOURCE28                (IRQ_VIC_START + INT_VICSOURCE28)
-#define IRQ_VICSOURCE29                (IRQ_VIC_START + INT_VICSOURCE29)
-#define IRQ_VICSOURCE30                (IRQ_VIC_START + INT_VICSOURCE30)
-#define IRQ_VICSOURCE31                (IRQ_VIC_START + INT_VICSOURCE31)
-#define IRQ_VIC_END            (IRQ_VIC_START + 31)
-
-/* 
- *  FIQ interrupts definitions are the same as the INT definitions.
- */
-#define FIQ_WDOGINT            INT_WDOGINT
-#define FIQ_SOFTINT            INT_SOFTINT
-#define FIQ_COMMRx             INT_COMMRx
-#define FIQ_COMMTx             INT_COMMTx
-#define FIQ_TIMERINT0_1                INT_TIMERINT0_1
-#define FIQ_TIMERINT2_3                INT_TIMERINT2_3
-#define FIQ_GPIOINT0           INT_GPIOINT0
-#define FIQ_GPIOINT1           INT_GPIOINT1
-#define FIQ_GPIOINT2           INT_GPIOINT2
-#define FIQ_GPIOINT3           INT_GPIOINT3
-#define FIQ_RTCINT             INT_RTCINT
-#define FIQ_SSPINT             INT_SSPINT
-#define FIQ_UARTINT0           INT_UARTINT0
-#define FIQ_UARTINT1           INT_UARTINT1
-#define FIQ_UARTINT2           INT_UARTINT2
-#define FIQ_SCIINT             INT_SCIINT
-#define FIQ_CLCDINT            INT_CLCDINT
-#define FIQ_DMAINT             INT_DMAINT
-#define FIQ_PWRFAILINT                 INT_PWRFAILINT
-#define FIQ_MBXINT             INT_MBXINT
-#define FIQ_GNDINT             INT_GNDINT
-#define FIQ_VICSOURCE21                INT_VICSOURCE21
-#define FIQ_VICSOURCE22                INT_VICSOURCE22
-#define FIQ_VICSOURCE23                INT_VICSOURCE23
-#define FIQ_VICSOURCE24                INT_VICSOURCE24
-#define FIQ_VICSOURCE25                INT_VICSOURCE25
-#define FIQ_VICSOURCE26                INT_VICSOURCE26
-#define FIQ_VICSOURCE27                INT_VICSOURCE27
-#define FIQ_VICSOURCE28                INT_VICSOURCE28
-#define FIQ_VICSOURCE29                INT_VICSOURCE29
-#define FIQ_VICSOURCE30                INT_VICSOURCE30
-#define FIQ_VICSOURCE31                INT_VICSOURCE31
-
-
-/*
- * Secondary interrupt controller
- */
-#define IRQ_SIC_START          64
-#define IRQ_SIC_MMCI0B                 (IRQ_SIC_START + SIC_INT_MMCI0B)
-#define IRQ_SIC_MMCI1B                 (IRQ_SIC_START + SIC_INT_MMCI1B)
-#define IRQ_SIC_KMI0           (IRQ_SIC_START + SIC_INT_KMI0)
-#define IRQ_SIC_KMI1           (IRQ_SIC_START + SIC_INT_KMI1)
-#define IRQ_SIC_SCI3           (IRQ_SIC_START + SIC_INT_SCI3)
-#define IRQ_SIC_UART3          (IRQ_SIC_START + SIC_INT_UART3)
-#define IRQ_SIC_CLCD           (IRQ_SIC_START + SIC_INT_CLCD)
-#define IRQ_SIC_TOUCH          (IRQ_SIC_START + SIC_INT_TOUCH)
-#define IRQ_SIC_KEYPAD                 (IRQ_SIC_START + SIC_INT_KEYPAD)
-#define IRQ_SIC_DoC            (IRQ_SIC_START + SIC_INT_DoC)
-#define IRQ_SIC_MMCI0A                 (IRQ_SIC_START + SIC_INT_MMCI0A)
-#define IRQ_SIC_MMCI1A                 (IRQ_SIC_START + SIC_INT_MMCI1A)
-#define IRQ_SIC_AACI           (IRQ_SIC_START + SIC_INT_AACI)
-#define IRQ_SIC_ETH            (IRQ_SIC_START + SIC_INT_ETH)
-#define IRQ_SIC_USB            (IRQ_SIC_START + SIC_INT_USB)
-#define IRQ_SIC_PCI0           (IRQ_SIC_START + SIC_INT_PCI0)
-#define IRQ_SIC_PCI1           (IRQ_SIC_START + SIC_INT_PCI1)
-#define IRQ_SIC_PCI2           (IRQ_SIC_START + SIC_INT_PCI2)
-#define IRQ_SIC_PCI3           (IRQ_SIC_START + SIC_INT_PCI3)
-#define IRQ_SIC_END            95
-
-#define IRQ_GPIO0_START                (IRQ_SIC_END + 1)
-#define IRQ_GPIO0_END          (IRQ_GPIO0_START + 31)
-#define IRQ_GPIO1_START                (IRQ_GPIO0_END + 1)
-#define IRQ_GPIO1_END          (IRQ_GPIO1_START + 31)
-#define IRQ_GPIO2_START                (IRQ_GPIO1_END + 1)
-#define IRQ_GPIO2_END          (IRQ_GPIO2_START + 31)
-#define IRQ_GPIO3_START                (IRQ_GPIO2_END + 1)
-#define IRQ_GPIO3_END          (IRQ_GPIO3_START + 31)
-
-#define NR_IRQS                        (IRQ_GPIO3_END + 1)
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
deleted file mode 100644 (file)
index 6f938cc..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * arch/arm/mach-versatile/include/mach/platform.h
- *
- * Copyright (c) ARM Limited 2003.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __address_h
-#define __address_h                     1
-
-/*
- * Memory definitions
- */
-#define VERSATILE_BOOT_ROM_LO          0x30000000              /* DoC Base (64Mb)...*/
-#define VERSATILE_BOOT_ROM_HI          0x30000000
-#define VERSATILE_BOOT_ROM_BASE        VERSATILE_BOOT_ROM_HI    /*  Normal position */
-#define VERSATILE_BOOT_ROM_SIZE        SZ_64M
-
-#define VERSATILE_SSRAM_BASE           /* VERSATILE_SSMC_BASE ? */
-#define VERSATILE_SSRAM_SIZE           SZ_2M
-
-#define VERSATILE_FLASH_BASE           0x34000000
-#define VERSATILE_FLASH_SIZE           SZ_64M
-
-/* 
- *  SDRAM
- */
-#define VERSATILE_SDRAM_BASE           0x00000000
-
-/* 
- *  Logic expansion modules
- * 
- */
-
-
-/* ------------------------------------------------------------------------
- *  Versatile Registers
- * ------------------------------------------------------------------------
- * 
- */
-#define VERSATILE_SYS_ID_OFFSET               0x00
-#define VERSATILE_SYS_SW_OFFSET               0x04
-#define VERSATILE_SYS_LED_OFFSET              0x08
-#define VERSATILE_SYS_OSC0_OFFSET             0x0C
-
-#if defined(CONFIG_ARCH_VERSATILE_PB)
-#define VERSATILE_SYS_OSC1_OFFSET             0x10
-#define VERSATILE_SYS_OSC2_OFFSET             0x14
-#define VERSATILE_SYS_OSC3_OFFSET             0x18
-#define VERSATILE_SYS_OSC4_OFFSET             0x1C
-#elif defined(CONFIG_MACH_VERSATILE_AB)
-#define VERSATILE_SYS_OSC1_OFFSET             0x1C
-#endif
-
-#define VERSATILE_SYS_OSCCLCD_OFFSET          0x1c
-
-#define VERSATILE_SYS_LOCK_OFFSET             0x20
-#define VERSATILE_SYS_100HZ_OFFSET            0x24
-#define VERSATILE_SYS_CFGDATA1_OFFSET         0x28
-#define VERSATILE_SYS_CFGDATA2_OFFSET         0x2C
-#define VERSATILE_SYS_FLAGS_OFFSET            0x30
-#define VERSATILE_SYS_FLAGSSET_OFFSET         0x30
-#define VERSATILE_SYS_FLAGSCLR_OFFSET         0x34
-#define VERSATILE_SYS_NVFLAGS_OFFSET          0x38
-#define VERSATILE_SYS_NVFLAGSSET_OFFSET       0x38
-#define VERSATILE_SYS_NVFLAGSCLR_OFFSET       0x3C
-#define VERSATILE_SYS_RESETCTL_OFFSET         0x40
-#define VERSATILE_SYS_PCICTL_OFFSET           0x44
-#define VERSATILE_SYS_MCI_OFFSET              0x48
-#define VERSATILE_SYS_FLASH_OFFSET            0x4C
-#define VERSATILE_SYS_CLCD_OFFSET             0x50
-#define VERSATILE_SYS_CLCDSER_OFFSET          0x54
-#define VERSATILE_SYS_BOOTCS_OFFSET           0x58
-#define VERSATILE_SYS_24MHz_OFFSET            0x5C
-#define VERSATILE_SYS_MISC_OFFSET             0x60
-#define VERSATILE_SYS_TEST_OSC0_OFFSET        0x80
-#define VERSATILE_SYS_TEST_OSC1_OFFSET        0x84
-#define VERSATILE_SYS_TEST_OSC2_OFFSET        0x88
-#define VERSATILE_SYS_TEST_OSC3_OFFSET        0x8C
-#define VERSATILE_SYS_TEST_OSC4_OFFSET        0x90
-
-#define VERSATILE_SYS_BASE                    0x10000000
-#define VERSATILE_SYS_ID                      (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
-#define VERSATILE_SYS_SW                      (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
-#define VERSATILE_SYS_LED                     (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
-#define VERSATILE_SYS_OSC0                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
-#define VERSATILE_SYS_OSC1                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
-
-#if defined(CONFIG_ARCH_VERSATILE_PB)
-#define VERSATILE_SYS_OSC2                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
-#define VERSATILE_SYS_OSC3                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
-#define VERSATILE_SYS_OSC4                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
-#endif
-
-#define VERSATILE_SYS_LOCK                    (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
-#define VERSATILE_SYS_100HZ                   (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
-#define VERSATILE_SYS_CFGDATA1                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
-#define VERSATILE_SYS_CFGDATA2                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
-#define VERSATILE_SYS_FLAGS                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
-#define VERSATILE_SYS_FLAGSSET                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
-#define VERSATILE_SYS_FLAGSCLR                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
-#define VERSATILE_SYS_NVFLAGS                 (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
-#define VERSATILE_SYS_NVFLAGSSET              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
-#define VERSATILE_SYS_NVFLAGSCLR              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
-#define VERSATILE_SYS_RESETCTL                (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
-#define VERSATILE_SYS_PCICTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
-#define VERSATILE_SYS_MCI                     (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
-#define VERSATILE_SYS_FLASH                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
-#define VERSATILE_SYS_CLCD                    (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
-#define VERSATILE_SYS_CLCDSER                 (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
-#define VERSATILE_SYS_BOOTCS                  (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
-#define VERSATILE_SYS_24MHz                   (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
-#define VERSATILE_SYS_MISC                    (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
-#define VERSATILE_SYS_TEST_OSC0               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
-#define VERSATILE_SYS_TEST_OSC1               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
-#define VERSATILE_SYS_TEST_OSC2               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
-#define VERSATILE_SYS_TEST_OSC3               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
-#define VERSATILE_SYS_TEST_OSC4               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
-
-/* 
- * Values for VERSATILE_SYS_RESET_CTRL
- */
-#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR    0x01
-#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT   0x02
-#define VERSATILE_SYS_CTRL_RESET_DLLRESET     0x03
-#define VERSATILE_SYS_CTRL_RESET_PLLRESET     0x04
-#define VERSATILE_SYS_CTRL_RESET_POR          0x05
-#define VERSATILE_SYS_CTRL_RESET_DoC          0x06
-
-#define VERSATILE_SYS_CTRL_LED         (1 << 0)
-
-
-/* ------------------------------------------------------------------------
- *  Versatile control registers
- * ------------------------------------------------------------------------
- */
-
-/* 
- * VERSATILE_IDFIELD
- *
- * 31:24 = manufacturer (0x41 = ARM)
- * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
- * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
- * 11:4  = build value
- * 3:0   = revision number (0x1 = rev B (AHB))
- */
-
-/*
- * VERSATILE_SYS_LOCK
- *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, 
- *     SYS_CLD, SYS_BOOTCS
- */
-#define VERSATILE_SYS_LOCK_LOCKED    (1 << 16)
-#define VERSATILE_SYS_LOCKVAL_MASK     0xFFFF          /* write 0xA05F to enable write access */
-
-/*
- * VERSATILE_SYS_FLASH
- */
-#define VERSATILE_FLASHPROG_FLVPPEN    (1 << 0)        /* Enable writing to flash */
-
-/*
- * VERSATILE_INTREG
- *     - used to acknowledge and control MMCI and UART interrupts 
- */
-#define VERSATILE_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
-#define VERSATILE_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
-#define VERSATILE_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
-                                                /* write 1 to acknowledge and clear               */
-#define VERSATILE_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
-#define VERSATILE_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
-
-/*
- * VERSATILE peripheral addresses
- */
-#define VERSATILE_PCI_CORE_BASE        0x10001000      /* PCI core control */
-#define VERSATILE_I2C_BASE             0x10002000      /* I2C control */
-#define VERSATILE_SIC_BASE             0x10003000      /* Secondary interrupt controller */
-#define VERSATILE_AACI_BASE            0x10004000      /* Audio */
-#define VERSATILE_MMCI0_BASE           0x10005000      /* MMC interface */
-#define VERSATILE_KMI0_BASE            0x10006000      /* KMI interface */
-#define VERSATILE_KMI1_BASE            0x10007000      /* KMI 2nd interface */
-#define VERSATILE_CHAR_LCD_BASE        0x10008000      /* Character LCD */
-#define VERSATILE_UART3_BASE           0x10009000      /* UART 3 */
-#define VERSATILE_SCI1_BASE            0x1000A000
-#define VERSATILE_MMCI1_BASE           0x1000B000    /* MMC Interface */
-       /* 0x1000C000 - 0x1000CFFF = reserved */
-#define VERSATILE_ETH_BASE             0x10010000      /* Ethernet */
-#define VERSATILE_USB_BASE             0x10020000      /* USB */
-       /* 0x10030000 - 0x100FFFFF = reserved */
-#define VERSATILE_SMC_BASE             0x10100000      /* SMC */
-#define VERSATILE_MPMC_BASE            0x10110000      /* MPMC */
-#define VERSATILE_CLCD_BASE            0x10120000      /* CLCD */
-#define VERSATILE_DMAC_BASE            0x10130000      /* DMA controller */
-#define VERSATILE_VIC_BASE             0x10140000      /* Vectored interrupt controller */
-#define VERSATILE_PERIPH_BASE          0x10150000      /* off-chip peripherals alias from */
-                                                /* 0x10000000 - 0x100FFFFF */
-#define VERSATILE_AHBM_BASE            0x101D0000      /* AHB monitor */
-#define VERSATILE_SCTL_BASE            0x101E0000      /* System controller */
-#define VERSATILE_WATCHDOG_BASE        0x101E1000      /* Watchdog */
-#define VERSATILE_TIMER0_1_BASE        0x101E2000      /* Timer 0 and 1 */
-#define VERSATILE_TIMER2_3_BASE        0x101E3000      /* Timer 2 and 3 */
-#define VERSATILE_GPIO0_BASE           0x101E4000      /* GPIO port 0 */
-#define VERSATILE_GPIO1_BASE           0x101E5000      /* GPIO port 1 */
-#define VERSATILE_GPIO2_BASE           0x101E6000      /* GPIO port 2 */
-#define VERSATILE_GPIO3_BASE           0x101E7000      /* GPIO port 3 */
-#define VERSATILE_RTC_BASE             0x101E8000      /* Real Time Clock */
-       /* 0x101E9000 - reserved */
-#define VERSATILE_SCI_BASE             0x101F0000      /* Smart card controller */
-#define VERSATILE_UART0_BASE           0x101F1000      /* Uart 0 */
-#define VERSATILE_UART1_BASE           0x101F2000      /* Uart 1 */
-#define VERSATILE_UART2_BASE           0x101F3000      /* Uart 2 */
-#define VERSATILE_SSP_BASE             0x101F4000      /* Synchronous Serial Port */
-
-#define VERSATILE_SSMC_BASE            0x20000000      /* SSMC */
-#define VERSATILE_IB2_BASE             0x24000000      /* IB2 module */
-#define VERSATILE_MBX_BASE             0x40000000      /* MBX */
-
-/* PCI space */
-#define VERSATILE_PCI_BASE             0x41000000      /* PCI Interface */
-#define VERSATILE_PCI_CFG_BASE        0x42000000
-#define VERSATILE_PCI_IO_BASE          0x43000000
-#define VERSATILE_PCI_MEM_BASE0        0x44000000
-#define VERSATILE_PCI_MEM_BASE1        0x50000000
-#define VERSATILE_PCI_MEM_BASE2        0x60000000
-/* Sizes of above maps */
-#define VERSATILE_PCI_BASE_SIZE               0x01000000
-#define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000
-#define VERSATILE_PCI_IO_BASE_SIZE     0x01000000
-#define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000      /* 32Mb */
-#define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000      /* 256Mb */
-#define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000      /* 256Mb */
-
-#define VERSATILE_SDRAM67_BASE         0x70000000      /* SDRAM banks 6 and 7 */
-#define VERSATILE_LT_BASE              0x80000000      /* Logic Tile expansion */
-
-/*
- * Disk on Chip
- */
-#define VERSATILE_DOC_BASE             0x2C000000
-#define VERSATILE_DOC_SIZE             (16 << 20)
-#define VERSATILE_DOC_PAGE_SIZE        512
-#define VERSATILE_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
-
-#define ERASE_UNIT_PAGES    32
-#define START_PAGE          0x80
-
-/* 
- *  LED settings, bits [7:0]
- */
-#define VERSATILE_SYS_LED0             (1 << 0)
-#define VERSATILE_SYS_LED1             (1 << 1)
-#define VERSATILE_SYS_LED2             (1 << 2)
-#define VERSATILE_SYS_LED3             (1 << 3)
-#define VERSATILE_SYS_LED4             (1 << 4)
-#define VERSATILE_SYS_LED5             (1 << 5)
-#define VERSATILE_SYS_LED6             (1 << 6)
-#define VERSATILE_SYS_LED7             (1 << 7)
-
-#define ALL_LEDS                  0xFF
-
-#define LED_BANK                  VERSATILE_SYS_LED
-
-/* 
- * Control registers
- */
-#define VERSATILE_IDFIELD_OFFSET       0x0     /* Versatile build information */
-#define VERSATILE_FLASHPROG_OFFSET     0x4     /* Flash devices */
-#define VERSATILE_INTREG_OFFSET                0x8     /* Interrupt control */
-#define VERSATILE_DECODE_OFFSET                0xC     /* Fitted logic modules */
-
-
-/* ------------------------------------------------------------------------
- *  Versatile Interrupt Controller - control registers
- * ------------------------------------------------------------------------
- * 
- *  Offsets from interrupt controller base 
- * 
- *  System Controller interrupt controller base is
- * 
- *     VERSATILE_IC_BASE
- * 
- *  Core Module interrupt controller base is
- * 
- *     VERSATILE_SYS_IC 
- * 
- */
-/* VIC definitions in include/asm-arm/hardware/vic.h */
-
-#define SIC_IRQ_STATUS                  0
-#define SIC_IRQ_RAW_STATUS              0x04
-#define SIC_IRQ_ENABLE                  0x08
-#define SIC_IRQ_ENABLE_SET              0x08
-#define SIC_IRQ_ENABLE_CLEAR            0x0C
-#define SIC_INT_SOFT_SET                0x10
-#define SIC_INT_SOFT_CLEAR              0x14
-#define SIC_INT_PIC_ENABLE              0x20   /* read status of pass through mask */
-#define SIC_INT_PIC_ENABLES             0x20   /* set interrupt pass through bits */
-#define SIC_INT_PIC_ENABLEC             0x24   /* Clear interrupt pass through bits */
-
-/* ------------------------------------------------------------------------
- *  Interrupts - bit assignment (primary)
- * ------------------------------------------------------------------------
- */
-
-#define INT_WDOGINT                     0      /* Watchdog timer */
-#define INT_SOFTINT                     1      /* Software interrupt */
-#define INT_COMMRx                      2      /* Debug Comm Rx interrupt */
-#define INT_COMMTx                      3      /* Debug Comm Tx interrupt */
-#define INT_TIMERINT0_1                 4      /* Timer 0 and 1 */
-#define INT_TIMERINT2_3                 5      /* Timer 2 and 3 */
-#define INT_GPIOINT0                    6      /* GPIO 0 */
-#define INT_GPIOINT1                    7      /* GPIO 1 */
-#define INT_GPIOINT2                    8      /* GPIO 2 */
-#define INT_GPIOINT3                    9      /* GPIO 3 */
-#define INT_RTCINT                      10     /* Real Time Clock */
-#define INT_SSPINT                      11     /* Synchronous Serial Port */
-#define INT_UARTINT0                    12     /* UART 0 on development chip */
-#define INT_UARTINT1                    13     /* UART 1 on development chip */
-#define INT_UARTINT2                    14     /* UART 2 on development chip */
-#define INT_SCIINT                      15     /* Smart Card Interface */
-#define INT_CLCDINT                     16     /* CLCD controller */
-#define INT_DMAINT                      17     /* DMA controller */
-#define INT_PWRFAILINT                  18     /* Power failure */
-#define INT_MBXINT                      19     /* Graphics processor */
-#define INT_GNDINT                      20     /* Reserved */
-       /* External interrupt signals from logic tiles or secondary controller */
-#define INT_VICSOURCE21                 21     /* Disk on Chip */
-#define INT_VICSOURCE22                 22     /* MCI0A */
-#define INT_VICSOURCE23                 23     /* MCI1A */
-#define INT_VICSOURCE24                 24     /* AACI */
-#define INT_VICSOURCE25                 25     /* Ethernet */
-#define INT_VICSOURCE26                 26     /* USB */
-#define INT_VICSOURCE27                 27     /* PCI 0 */
-#define INT_VICSOURCE28                 28     /* PCI 1 */
-#define INT_VICSOURCE29                 29     /* PCI 2 */
-#define INT_VICSOURCE30                 30     /* PCI 3 */
-#define INT_VICSOURCE31                 31     /* SIC source */
-
-#define VERSATILE_SC_VALID_INT               0x003FFFFF
-
-#define MAXIRQNUM                       31
-#define MAXFIQNUM                       31
-#define MAXSWINUM                       31
-
-/* ------------------------------------------------------------------------
- *  Interrupts - bit assignment (secondary)
- * ------------------------------------------------------------------------
- */
-#define SIC_INT_MMCI0B                  1      /* Multimedia Card 0B */
-#define SIC_INT_MMCI1B                  2      /* Multimedia Card 1B */
-#define SIC_INT_KMI0                    3      /* Keyboard/Mouse port 0 */
-#define SIC_INT_KMI1                    4      /* Keyboard/Mouse port 1 */
-#define SIC_INT_SCI3                    5      /* Smart Card interface */
-#define SIC_INT_UART3                   6      /* UART 3 empty or data available */
-#define SIC_INT_CLCD                    7      /* Character LCD */
-#define SIC_INT_TOUCH                   8      /* Touchscreen */
-#define SIC_INT_KEYPAD                  9      /* Key pressed on display keypad */
-       /* 10:20 - reserved */
-#define SIC_INT_DoC                     21     /* Disk on Chip memory controller */
-#define SIC_INT_MMCI0A                  22     /* MMC 0A */
-#define SIC_INT_MMCI1A                  23     /* MMC 1A */
-#define SIC_INT_AACI                    24     /* Audio Codec */
-#define SIC_INT_ETH                     25     /* Ethernet controller */
-#define SIC_INT_USB                     26     /* USB controller */
-#define SIC_INT_PCI0                    27
-#define SIC_INT_PCI1                    28
-#define SIC_INT_PCI2                    29
-#define SIC_INT_PCI3                    30
-
-
-/*
- * System controller bit assignment
- */
-#define VERSATILE_REFCLK       0
-#define VERSATILE_TIMCLK       1
-
-#define VERSATILE_TIMER1_EnSel 15
-#define VERSATILE_TIMER2_EnSel 17
-#define VERSATILE_TIMER3_EnSel 19
-#define VERSATILE_TIMER4_EnSel 21
-
-
-#define VERSATILE_CSR_BASE             0x10000000
-#define VERSATILE_CSR_SIZE             0x10000000
-
-#ifdef CONFIG_MACH_VERSATILE_AB
-/*
- * IB2 Versatile/AB expansion board definitions
- */
-#define VERSATILE_IB2_CAMERA_BANK      VERSATILE_IB2_BASE
-#define VERSATILE_IB2_KBD_DATAREG      (VERSATILE_IB2_BASE + 0x01000000)
-
-/* VICINTSOURCE27 */
-#define VERSATILE_IB2_INT_BASE         (VERSATILE_IB2_BASE + 0x02000000)
-#define VERSATILE_IB2_IER              (VERSATILE_IB2_INT_BASE + 0)
-#define VERSATILE_IB2_ISR              (VERSATILE_IB2_INT_BASE + 4)
-
-#define VERSATILE_IB2_CTL_BASE         (VERSATILE_IB2_BASE + 0x03000000)
-#define VERSATILE_IB2_CTRL             (VERSATILE_IB2_CTL_BASE + 0)
-#define VERSATILE_IB2_STAT             (VERSATILE_IB2_CTL_BASE + 4)
-#endif
-
-#endif
diff --git a/arch/arm/mach-versatile/include/mach/uncompress.h b/arch/arm/mach-versatile/include/mach/uncompress.h
deleted file mode 100644 (file)
index 986e3d3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  arch/arm/mach-versatile/include/mach/uncompress.h
- *
- *  Copyright (C) 2003 ARM Limited
- *
- * This program is free software; 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
- */
-#define AMBA_UART_DR   (*(volatile unsigned char *)0x101F1000)
-#define AMBA_UART_LCRH (*(volatile unsigned char *)0x101F102C)
-#define AMBA_UART_CR   (*(volatile unsigned char *)0x101F1030)
-#define AMBA_UART_FR   (*(volatile unsigned char *)0x101F1018)
-
-/*
- * This does not append a newline
- */
-static inline void putc(int c)
-{
-       while (AMBA_UART_FR & (1 << 5))
-               barrier();
-
-       AMBA_UART_DR = c;
-}
-
-static inline void flush(void)
-{
-       while (AMBA_UART_FR & (1 << 3))
-               barrier();
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
deleted file mode 100644 (file)
index c97be4e..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/pci.c
- *
- * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
- * You can redistribute and/or modify this software under the terms of version 2
- * of the GNU General Public License as published by the Free Software Foundation.
- * THIS SOFTWARE IS PROVIDED "AS IS" 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.
- * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
- *
- * ARM Versatile PCI driver.
- *
- * 14/04/2005 Initial version, colin.king@philips.com
- *
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-
-/*
- * these spaces are mapped using the following base registers:
- *
- * Usage Local Bus Memory         Base/Map registers used
- *
- * Mem   50000000 - 5FFFFFFF      LB_BASE0/LB_MAP0,  non prefetch
- * Mem   60000000 - 6FFFFFFF      LB_BASE1/LB_MAP1,  prefetch
- * IO    44000000 - 4FFFFFFF      LB_BASE2/LB_MAP2,  IO
- * Cfg   42000000 - 42FFFFFF     PCI config
- *
- */
-#define __IO_ADDRESS(n) ((void __iomem *)(unsigned long)IO_ADDRESS(n))
-#define SYS_PCICTL             __IO_ADDRESS(VERSATILE_SYS_PCICTL)
-#define PCI_IMAP0              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
-#define PCI_IMAP1              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
-#define PCI_IMAP2              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
-#define PCI_SMAP0              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
-#define PCI_SMAP1              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
-#define PCI_SMAP2              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c)
-#define PCI_SELFID             __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
-
-#define DEVICE_ID_OFFSET               0x00
-#define CSR_OFFSET                     0x04
-#define CLASS_ID_OFFSET                        0x08
-
-#define VP_PCI_DEVICE_ID               0x030010ee
-#define VP_PCI_CLASS_ID                        0x0b400000
-
-static unsigned long pci_slot_ignore = 0;
-
-static int __init versatile_pci_slot_ignore(char *str)
-{
-       int retval;
-       int slot;
-
-       while ((retval = get_option(&str,&slot))) {
-               if ((slot < 0) || (slot > 31)) {
-                       printk("Illegal slot value: %d\n",slot);
-               } else {
-                       pci_slot_ignore |= (1 << slot);
-               }
-       }
-       return 1;
-}
-
-__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
-
-
-static void __iomem *__pci_addr(struct pci_bus *bus,
-                               unsigned int devfn, int offset)
-{
-       unsigned int busnr = bus->number;
-
-       /*
-        * Trap out illegal values
-        */
-       if (offset > 255)
-               BUG();
-       if (busnr > 255)
-               BUG();
-       if (devfn > 255)
-               BUG();
-
-       return VERSATILE_PCI_CFG_VIRT_BASE + ((busnr << 16) |
-               (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
-}
-
-static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-                                int size, u32 *val)
-{
-       void __iomem *addr = __pci_addr(bus, devfn, where & ~3);
-       u32 v;
-       int slot = PCI_SLOT(devfn);
-
-       if (pci_slot_ignore & (1 << slot)) {
-               /* Ignore this slot */
-               switch (size) {
-               case 1:
-                       v = 0xff;
-                       break;
-               case 2:
-                       v = 0xffff;
-                       break;
-               default:
-                       v = 0xffffffff;
-               }
-       } else {
-               switch (size) {
-               case 1:
-                       v = __raw_readl(addr);
-                       if (where & 2) v >>= 16;
-                       if (where & 1) v >>= 8;
-                       v &= 0xff;
-                       break;
-
-               case 2:
-                       v = __raw_readl(addr);
-                       if (where & 2) v >>= 16;
-                       v &= 0xffff;
-                       break;
-
-               default:
-                       v = __raw_readl(addr);
-                       break;
-               }
-       }
-
-       *val = v;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-                                 int size, u32 val)
-{
-       void __iomem *addr = __pci_addr(bus, devfn, where);
-       int slot = PCI_SLOT(devfn);
-
-       if (pci_slot_ignore & (1 << slot)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       switch (size) {
-       case 1:
-               __raw_writeb((u8)val, addr);
-               break;
-
-       case 2:
-               __raw_writew((u16)val, addr);
-               break;
-
-       case 4:
-               __raw_writel(val, addr);
-               break;
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops pci_versatile_ops = {
-       .read   = versatile_read_config,
-       .write  = versatile_write_config,
-};
-
-static struct resource unused_mem = {
-       .name   = "PCI unused",
-       .start  = VERSATILE_PCI_MEM_BASE0,
-       .end    = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct resource non_mem = {
-       .name   = "PCI non-prefetchable",
-       .start  = VERSATILE_PCI_MEM_BASE1,
-       .end    = VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct resource pre_mem = {
-       .name   = "PCI prefetchable",
-       .start  = VERSATILE_PCI_MEM_BASE2,
-       .end    = VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
-       .flags  = IORESOURCE_MEM | IORESOURCE_PREFETCH,
-};
-
-static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
-{
-       int ret = 0;
-
-       ret = request_resource(&iomem_resource, &unused_mem);
-       if (ret) {
-               printk(KERN_ERR "PCI: unable to allocate unused "
-                      "memory region (%d)\n", ret);
-               goto out;
-       }
-       ret = request_resource(&iomem_resource, &non_mem);
-       if (ret) {
-               printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
-                      "memory region (%d)\n", ret);
-               goto release_unused_mem;
-       }
-       ret = request_resource(&iomem_resource, &pre_mem);
-       if (ret) {
-               printk(KERN_ERR "PCI: unable to allocate prefetchable "
-                      "memory region (%d)\n", ret);
-               goto release_non_mem;
-       }
-
-       /*
-        * the mem resource for this bus
-        * the prefetch mem resource for this bus
-        */
-       pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
-       pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
-
-       goto out;
-
- release_non_mem:
-       release_resource(&non_mem);
- release_unused_mem:
-       release_resource(&unused_mem);
- out:
-       return ret;
-}
-
-int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
-{
-       int ret = 0;
-        int i;
-        int myslot = -1;
-       unsigned long val;
-       void __iomem *local_pci_cfg_base;
-
-       val = __raw_readl(SYS_PCICTL);
-       if (!(val & 1)) {
-               printk("Not plugged into PCI backplane!\n");
-               ret = -EIO;
-               goto out;
-       }
-
-       ret = pci_ioremap_io(0, VERSATILE_PCI_IO_BASE);
-       if (ret)
-               goto out;
-
-       if (nr == 0) {
-               ret = pci_versatile_setup_resources(sys);
-               if (ret < 0) {
-                       printk("pci_versatile_setup: resources... oops?\n");
-                       goto out;
-               }
-       } else {
-               printk("pci_versatile_setup: resources... nr == 0??\n");
-               goto out;
-       }
-
-       /*
-        *  We need to discover the PCI core first to configure itself
-        *  before the main PCI probing is performed
-        */
-       for (i=0; i<32; i++)
-               if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
-                   (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
-                       myslot = i;
-                       break;
-               }
-
-       if (myslot == -1) {
-               printk("Cannot find PCI core!\n");
-               ret = -EIO;
-               goto out;
-       }
-
-       printk("PCI core found (slot %d)\n",myslot);
-
-       __raw_writel(myslot, PCI_SELFID);
-       local_pci_cfg_base = VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11);
-
-       val = __raw_readl(local_pci_cfg_base + CSR_OFFSET);
-       val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
-       __raw_writel(val, local_pci_cfg_base + CSR_OFFSET);
-
-       /*
-        * Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM
-        */
-       __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0);
-       __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1);
-       __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2);
-
-       /*
-        * For many years the kernel and QEMU were symbiotically buggy
-        * in that they both assumed the same broken IRQ mapping.
-        * QEMU therefore attempts to auto-detect old broken kernels
-        * so that they still work on newer QEMU as they did on old
-        * QEMU. Since we now use the correct (ie matching-hardware)
-        * IRQ mapping we write a definitely different value to a
-        * PCI_INTERRUPT_LINE register to tell QEMU that we expect
-        * real hardware behaviour and it need not be backwards
-        * compatible for us. This write is harmless on real hardware.
-        */
-       __raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE);
-
-       /*
-        * Do not to map Versatile FPGA PCI device into memory space
-        */
-       pci_slot_ignore |= (1 << myslot);
-       ret = 1;
-
- out:
-       return ret;
-}
-
-
-void __init pci_versatile_preinit(void)
-{
-       pcibios_min_mem = 0x50000000;
-
-       __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0);
-       __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28, PCI_IMAP1);
-       __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28, PCI_IMAP2);
-
-       __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP0);
-       __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP1);
-       __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP2);
-
-       __raw_writel(1, SYS_PCICTL);
-}
-
-/*
- * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
- */
-static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int irq;
-
-       /*
-        * Slot INTA    INTB    INTC    INTD
-        * 31   PCI1    PCI2    PCI3    PCI0
-        * 30   PCI0    PCI1    PCI2    PCI3
-        * 29   PCI3    PCI0    PCI1    PCI2
-        */
-       irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3);
-
-       return irq;
-}
-
-static struct hw_pci versatile_pci __initdata = {
-       .map_irq                = versatile_map_irq,
-       .nr_controllers         = 1,
-       .ops                    = &pci_versatile_ops,
-       .setup                  = pci_versatile_setup,
-       .preinit                = pci_versatile_preinit,
-};
-
-static int __init versatile_pci_init(void)
-{
-       pci_common_init(&versatile_pci);
-       return 0;
-}
-
-subsys_initcall(versatile_pci_init);
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
deleted file mode 100644 (file)
index 1caef10..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/versatile_ab.c
- *
- *  Copyright (C) 2004 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-#include "core.h"
-
-MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
-       /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-       .atag_offset    = 0x100,
-       .map_io         = versatile_map_io,
-       .init_early     = versatile_init_early,
-       .init_irq       = versatile_init_irq,
-       .init_time      = versatile_timer_init,
-       .init_machine   = versatile_init,
-       .restart        = versatile_restart,
-MACHINE_END
index 7de3e92..c448718 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/platform_data/video-clcd-versatile.h>
+#include <linux/amba/mmci.h>
+#include <linux/mtd/physmap.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/map.h>
 
-#include "core.h"
+/* macro to get at MMIO space when running virtually */
+#define IO_ADDRESS(x)          (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+#define __io_address(n)                ((void __iomem __force *)IO_ADDRESS(n))
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_FLASH_BASE           0x34000000
+#define VERSATILE_FLASH_SIZE           SZ_64M
+
+/*
+ * ------------------------------------------------------------------------
+ *  Versatile Registers
+ * ------------------------------------------------------------------------
+ */
+#define VERSATILE_SYS_LOCK_OFFSET             0x20
+#define VERSATILE_SYS_RESETCTL_OFFSET         0x40
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
+#define VERSATILE_SYS_MCI_OFFSET              0x48
+#define VERSATILE_SYS_FLASH_OFFSET            0x4C
+#define VERSATILE_SYS_CLCD_OFFSET             0x50
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN    (1 << 0)        /* Enable writing to flash */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_MMCI0_BASE           0x10005000      /* MMC interface */
+#define VERSATILE_MMCI1_BASE           0x1000B000      /* MMC Interface */
+#define VERSATILE_CLCD_BASE            0x10120000      /* CLCD */
+#define VERSATILE_SCTL_BASE            0x101E0000      /* System controller */
+#define VERSATILE_IB2_BASE             0x24000000      /* IB2 module */
+#define VERSATILE_IB2_CTL_BASE         (VERSATILE_IB2_BASE + 0x03000000)
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK       0
+#define VERSATILE_TIMCLK       1
+
+#define VERSATILE_TIMER1_EnSel 15
+#define VERSATILE_TIMER2_EnSel 17
+#define VERSATILE_TIMER3_EnSel 19
+#define VERSATILE_TIMER4_EnSel 21
+
+static void __iomem *versatile_sys_base;
+static void __iomem *versatile_ib2_ctrl;
+
+static void versatile_flash_set_vpp(struct platform_device *pdev, int on)
+{
+       u32 val;
+
+       val = readl(versatile_sys_base + VERSATILE_SYS_FLASH_OFFSET);
+       if (on)
+               val |= VERSATILE_FLASHPROG_FLVPPEN;
+       else
+               val &= ~VERSATILE_FLASHPROG_FLVPPEN;
+       writel(val, versatile_sys_base + VERSATILE_SYS_FLASH_OFFSET);
+}
+
+static struct physmap_flash_data versatile_flash_data = {
+       .width                  = 4,
+       .set_vpp                = versatile_flash_set_vpp,
+};
+
+static struct resource versatile_flash_resource = {
+       .start                  = VERSATILE_FLASH_BASE,
+       .end                    = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,
+       .flags                  = IORESOURCE_MEM,
+};
+
+struct platform_device versatile_flash_device = {
+       .name                   = "physmap-flash",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data  = &versatile_flash_data,
+       },
+       .num_resources          = 1,
+       .resource               = &versatile_flash_resource,
+};
+
+unsigned int mmc_status(struct device *dev)
+{
+       struct amba_device *adev = container_of(dev, struct amba_device, dev);
+       u32 mask;
+
+       if (adev->res.start == VERSATILE_MMCI0_BASE)
+               mask = 1;
+       else
+               mask = 2;
+
+       return readl(versatile_sys_base + VERSATILE_SYS_MCI_OFFSET) & mask;
+}
+
+static struct mmci_platform_data mmc0_plat_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = mmc_status,
+       .gpio_wp        = -1,
+       .gpio_cd        = -1,
+};
+
+static struct mmci_platform_data mmc1_plat_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = mmc_status,
+       .gpio_wp        = -1,
+       .gpio_cd        = -1,
+};
+
+/*
+ * CLCD support.
+ */
+#define SYS_CLCD_MODE_MASK     (3 << 0)
+#define SYS_CLCD_MODE_888      (0 << 0)
+#define SYS_CLCD_MODE_5551     (1 << 0)
+#define SYS_CLCD_MODE_565_RLSB (2 << 0)
+#define SYS_CLCD_MODE_565_BLSB (3 << 0)
+#define SYS_CLCD_NLCDIOON      (1 << 2)
+#define SYS_CLCD_VDDPOSSWITCH  (1 << 3)
+#define SYS_CLCD_PWR3V5SWITCH  (1 << 4)
+#define SYS_CLCD_ID_MASK       (0x1f << 8)
+#define SYS_CLCD_ID_SANYO_3_8  (0x00 << 8)
+#define SYS_CLCD_ID_UNKNOWN_8_4        (0x01 << 8)
+#define SYS_CLCD_ID_EPSON_2_2  (0x02 << 8)
+#define SYS_CLCD_ID_SANYO_2_5  (0x07 << 8)
+#define SYS_CLCD_ID_VGA                (0x1f << 8)
+
+static bool is_sanyo_2_5_lcd;
+
+/*
+ * Disable all display connectors on the interface module.
+ */
+static void versatile_clcd_disable(struct clcd_fb *fb)
+{
+       void __iomem *sys_clcd = versatile_sys_base + VERSATILE_SYS_CLCD_OFFSET;
+       u32 val;
+
+       val = readl(sys_clcd);
+       val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+       writel(val, sys_clcd);
+
+       /*
+        * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
+        */
+       if (of_machine_is_compatible("arm,versatile-ab") && is_sanyo_2_5_lcd) {
+               unsigned long ctrl;
+
+               ctrl = readl(versatile_ib2_ctrl);
+               ctrl &= ~0x01;
+               writel(ctrl, versatile_ib2_ctrl);
+       }
+}
+
+/*
+ * Enable the relevant connector on the interface module.
+ */
+static void versatile_clcd_enable(struct clcd_fb *fb)
+{
+       struct fb_var_screeninfo *var = &fb->fb.var;
+       void __iomem *sys_clcd = versatile_sys_base + VERSATILE_SYS_CLCD_OFFSET;
+       u32 val;
+
+       val = readl(sys_clcd);
+       val &= ~SYS_CLCD_MODE_MASK;
+
+       switch (var->green.length) {
+       case 5:
+               val |= SYS_CLCD_MODE_5551;
+               break;
+       case 6:
+               if (var->red.offset == 0)
+                       val |= SYS_CLCD_MODE_565_RLSB;
+               else
+                       val |= SYS_CLCD_MODE_565_BLSB;
+               break;
+       case 8:
+               val |= SYS_CLCD_MODE_888;
+               break;
+       }
+
+       /*
+        * Set the MUX
+        */
+       writel(val, sys_clcd);
+
+       /*
+        * And now enable the PSUs
+        */
+       val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+       writel(val, sys_clcd);
+
+       /*
+        * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
+        */
+       if (of_machine_is_compatible("arm,versatile-ab") && is_sanyo_2_5_lcd) {
+               unsigned long ctrl;
+
+               ctrl = readl(versatile_ib2_ctrl);
+               ctrl |= 0x01;
+               writel(ctrl, versatile_ib2_ctrl);
+       }
+}
+
+/*
+ * Detect which LCD panel is connected, and return the appropriate
+ * clcd_panel structure.  Note: we do not have any information on
+ * the required timings for the 8.4in panel, so we presently assume
+ * VGA timings.
+ */
+static int versatile_clcd_setup(struct clcd_fb *fb)
+{
+       void __iomem *sys_clcd = versatile_sys_base + VERSATILE_SYS_CLCD_OFFSET;
+       const char *panel_name;
+       u32 val;
+
+       is_sanyo_2_5_lcd = false;
+
+       val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
+       if (val == SYS_CLCD_ID_SANYO_3_8)
+               panel_name = "Sanyo TM38QV67A02A";
+       else if (val == SYS_CLCD_ID_SANYO_2_5) {
+               panel_name = "Sanyo QVGA Portrait";
+               is_sanyo_2_5_lcd = true;
+       } else if (val == SYS_CLCD_ID_EPSON_2_2)
+               panel_name = "Epson L2F50113T00";
+       else if (val == SYS_CLCD_ID_VGA)
+               panel_name = "VGA";
+       else {
+               printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
+                       val);
+               panel_name = "VGA";
+       }
+
+       fb->panel = versatile_clcd_get_panel(panel_name);
+       if (!fb->panel)
+               return -EINVAL;
+
+       return versatile_clcd_setup_dma(fb, SZ_1M);
+}
+
+static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
+{
+       clcdfb_decode(fb, regs);
+
+       /* Always clear BGR for RGB565: we do the routing externally */
+       if (fb->fb.var.green.length == 6)
+               regs->cntl &= ~CNTL_BGR;
+}
+
+static struct clcd_board clcd_plat_data = {
+       .name           = "Versatile",
+       .caps           = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
+       .check          = clcdfb_check,
+       .decode         = versatile_clcd_decode,
+       .disable        = versatile_clcd_disable,
+       .enable         = versatile_clcd_enable,
+       .setup          = versatile_clcd_setup,
+       .mmap           = versatile_clcd_mmap_dma,
+       .remove         = versatile_clcd_remove_dma,
+};
+
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate().  Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", &mmc1_plat_data),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data),
+       {}
+};
+
+static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
+       {
+               .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
+               .length         = SZ_4K * 9,
+               .type           = MT_DEVICE
+       }
+};
+
+static void __init versatile_map_io(void)
+{
+       debug_ll_io_init();
+       iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
+}
+
+static void __init versatile_init_early(void)
+{
+       u32 val;
+
+       /*
+        * set clock frequency:
+        *      VERSATILE_REFCLK is 32KHz
+        *      VERSATILE_TIMCLK is 1MHz
+        */
+       val = readl(__io_address(VERSATILE_SCTL_BASE));
+       writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+              __io_address(VERSATILE_SCTL_BASE));
+}
+
+static void versatile_restart(enum reboot_mode mode, const char *cmd)
+{
+       u32 val;
+
+       val = readl(versatile_sys_base + VERSATILE_SYS_RESETCTL_OFFSET);
+       val |= 0x105;
+
+       writel(0xa05f, versatile_sys_base + VERSATILE_SYS_LOCK_OFFSET);
+       writel(val, versatile_sys_base + VERSATILE_SYS_RESETCTL_OFFSET);
+       writel(0, versatile_sys_base + VERSATILE_SYS_LOCK_OFFSET);
+}
+
+static void __init versatile_dt_pci_init(void)
+{
+       u32 val;
+       struct device_node *np;
+       struct property *newprop;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
+       if (!np)
+               return;
+
+       /* Check if PCI backplane is detected */
+       val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+       if (val & 1) {
+               /*
+                * Enable PCI accesses. Note that the documentaton is
+                * inconsistent whether or not this is needed, but the old
+                * driver had it so we will keep it.
+                */
+               writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+               return;
+       }
+
+       newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
+       if (!newprop)
+               return;
+
+       newprop->name = kstrdup("status", GFP_KERNEL);
+       newprop->value = kstrdup("disabled", GFP_KERNEL);
+       newprop->length = sizeof("disabled");
+       of_update_property(np, newprop);
+
+       pr_info("Not plugged into PCI backplane!\n");
+}
 
 static void __init versatile_dt_init(void)
 {
+       struct device_node *np;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
+       if (np)
+               versatile_sys_base = of_iomap(np, 0);
+       WARN_ON(!versatile_sys_base);
+
+       versatile_ib2_ctrl = ioremap(VERSATILE_IB2_CTL_BASE, SZ_4K);
+
+       versatile_dt_pci_init();
+
+       platform_device_register(&versatile_flash_device);
        of_platform_populate(NULL, of_default_bus_match_table,
                             versatile_auxdata_lookup, NULL);
 }
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
deleted file mode 100644 (file)
index 9a53d0b..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/versatile_pb.c
- *
- *  Copyright (C) 2004 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/pl061.h>
-#include <linux/amba/mmci.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-#include "core.h"
-
-#if 1
-#define IRQ_MMCI1A     IRQ_VICSOURCE23
-#else
-#define IRQ_MMCI1A     IRQ_SIC_MMCI1A
-#endif
-
-static struct mmci_platform_data mmc1_plat_data = {
-       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-       .status         = mmc_status,
-       .gpio_wp        = -1,
-       .gpio_cd        = -1,
-};
-
-#define UART3_IRQ      { IRQ_SIC_UART3 }
-#define SCI1_IRQ       { IRQ_SIC_SCI3 }
-#define MMCI1_IRQ      { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
-
-/*
- * These devices are connected via the DMA APB bridge
- */
-
-/* FPGA Primecells */
-APB_DEVICE(uart3, "fpga:09", UART3,    NULL);
-APB_DEVICE(sci1,  "fpga:0a", SCI1,     NULL);
-APB_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data);
-
-
-static struct amba_device *amba_devs[] __initdata = {
-       &uart3_device,
-       &sci1_device,
-       &mmc1_device,
-};
-
-static void __init versatile_pb_init(void)
-{
-       int i;
-
-       versatile_init();
-
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-               struct amba_device *d = amba_devs[i];
-               amba_device_register(d, &iomem_resource);
-       }
-}
-
-MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
-       /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-       .atag_offset    = 0x100,
-       .map_io         = versatile_map_io,
-       .init_early     = versatile_init_early,
-       .init_irq       = versatile_init_irq,
-       .init_time      = versatile_timer_init,
-       .init_machine   = versatile_pb_init,
-       .restart        = versatile_restart,
-MACHINE_END
index 10f9389..398a297 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_VEXPRESS
-       bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
+       bool "ARM Ltd. Versatile Express family"
+       depends on ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
index 2a11d3a..a162ab4 100644 (file)
@@ -1,5 +1,5 @@
 bool vexpress_smp_init_ops(void);
 
-extern struct smp_operations   vexpress_smp_dt_ops;
+extern const struct smp_operations vexpress_smp_dt_ops;
 
 extern void vexpress_cpu_die(unsigned int cpu);
index 83188cf..8b8d072 100644 (file)
@@ -64,7 +64,7 @@ static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
        vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
 }
 
-struct smp_operations __initdata vexpress_smp_dt_ops = {
+const struct smp_operations vexpress_smp_dt_ops __initconst = {
        .smp_prepare_cpus       = vexpress_smp_dt_prepare_cpus,
        .smp_secondary_init     = versatile_secondary_init,
        .smp_boot_secondary     = versatile_boot_secondary,
index 213230e..ca76325 100644 (file)
@@ -33,8 +33,8 @@
 #include <mach/hardware.h>
 #include <mach/regs-serial.h>
 #include <mach/regs-clock.h>
-#include <mach/regs-ebi.h>
-#include <mach/regs-timer.h>
+#include "regs-ebi.h"
+#include "regs-timer.h"
 
 #include "cpu.h"
 #include "clock.h"
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
deleted file mode 100644 (file)
index b68455e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/regs-ebi.h
- *
- * Copyright (c) 2009 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#ifndef __ASM_ARCH_REGS_EBI_H
-#define __ASM_ARCH_REGS_EBI_H
-
-/* EBI Control Registers */
-
-#define EBI_BA         W90X900_VA_EBI
-#define REG_EBICON     (EBI_BA + 0x00)
-#define REG_ROMCON     (EBI_BA + 0x04)
-#define REG_SDCONF0    (EBI_BA + 0x08)
-#define REG_SDCONF1    (EBI_BA + 0x0C)
-#define REG_SDTIME0    (EBI_BA + 0x10)
-#define REG_SDTIME1    (EBI_BA + 0x14)
-#define REG_EXT0CON    (EBI_BA + 0x18)
-#define REG_EXT1CON    (EBI_BA + 0x1C)
-#define REG_EXT2CON    (EBI_BA + 0x20)
-#define REG_EXT3CON    (EBI_BA + 0x24)
-#define REG_EXT4CON    (EBI_BA + 0x28)
-#define REG_CKSKEW     (EBI_BA + 0x2C)
-
-#endif /*  __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-gcr.h b/arch/arm/mach-w90x900/include/mach/regs-gcr.h
deleted file mode 100644 (file)
index 6087abd..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/regs-gcr.h
- *
- * Copyright (c) 2010 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#ifndef __ASM_ARCH_REGS_GCR_H
-#define __ASM_ARCH_REGS_GCR_H
-
-/* Global control registers */
-
-#define GCR_BA         W90X900_VA_GCR
-#define REG_PDID       (GCR_BA+0x000)
-#define REG_PWRON      (GCR_BA+0x004)
-#define REG_ARBCON     (GCR_BA+0x008)
-#define REG_MFSEL      (GCR_BA+0x00C)
-#define REG_EBIDPE     (GCR_BA+0x010)
-#define REG_LCDDPE     (GCR_BA+0x014)
-#define REG_GPIOCPE    (GCR_BA+0x018)
-#define REG_GPIODPE    (GCR_BA+0x01C)
-#define REG_GPIOEPE    (GCR_BA+0x020)
-#define REG_GPIOFPE    (GCR_BA+0x024)
-#define REG_GPIOGPE    (GCR_BA+0x028)
-#define REG_GPIOHPE    (GCR_BA+0x02C)
-#define REG_GPIOIPE    (GCR_BA+0x030)
-#define REG_GTMP1      (GCR_BA+0x034)
-#define REG_GTMP2      (GCR_BA+0x038)
-#define REG_GTMP3      (GCR_BA+0x03C)
-
-#endif /*  __ASM_ARCH_REGS_GCR_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-timer.h b/arch/arm/mach-w90x900/include/mach/regs-timer.h
deleted file mode 100644 (file)
index 8f39062..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/regs-timer.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/regs-timer.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#ifndef __ASM_ARCH_REGS_TIMER_H
-#define __ASM_ARCH_REGS_TIMER_H
-
-/* Timer Registers */
-
-#define TMR_BA                 W90X900_VA_TIMER
-#define REG_TCSR0              (TMR_BA+0x00)
-#define REG_TCSR1              (TMR_BA+0x04)
-#define REG_TICR0              (TMR_BA+0x08)
-#define REG_TICR1              (TMR_BA+0x0C)
-#define REG_TDR0               (TMR_BA+0x10)
-#define REG_TDR1               (TMR_BA+0x14)
-#define REG_TISR               (TMR_BA+0x18)
-#define REG_WTCR               (TMR_BA+0x1C)
-#define REG_TCSR2              (TMR_BA+0x20)
-#define REG_TCSR3              (TMR_BA+0x24)
-#define REG_TICR2              (TMR_BA+0x28)
-#define REG_TICR3              (TMR_BA+0x2C)
-#define REG_TDR2               (TMR_BA+0x30)
-#define REG_TDR3               (TMR_BA+0x34)
-#define REG_TCSR4              (TMR_BA+0x40)
-#define REG_TICR4              (TMR_BA+0x48)
-#define REG_TDR4               (TMR_BA+0x50)
-
-#endif /*  __ASM_ARCH_REGS_TIMER_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-usb.h b/arch/arm/mach-w90x900/include/mach/regs-usb.h
deleted file mode 100644 (file)
index ab74b0c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/regs-usb.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#ifndef __ASM_ARCH_REGS_USB_H
-#define __ASM_ARCH_REGS_USB_H
-
-/* usb Control Registers  */
-#define USBH_BA                W90X900_VA_USBEHCIHOST
-#define USBD_BA                W90X900_VA_USBDEV
-#define USBO_BA                W90X900_VA_USBOHCIHOST
-
-/* USB Host Control Registers */
-#define REG_UPSCR0     (USBH_BA+0x064)
-#define REG_UPSCR1     (USBH_BA+0x068)
-#define REG_USBPCR0    (USBH_BA+0x0C4)
-#define REG_USBPCR1    (USBH_BA+0x0C8)
-
-/* USBH OHCI Control Registers */
-#define REG_OpModEn    (USBO_BA+0x204)
-/*This bit controls the polarity of over
-*current flag from external power IC.
-*/
-#define OCALow         0x08
-
-#endif /*  __ASM_ARCH_REGS_USB_H */
diff --git a/arch/arm/mach-w90x900/regs-ebi.h b/arch/arm/mach-w90x900/regs-ebi.h
new file mode 100644 (file)
index 0000000..b68455e
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-ebi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_EBI_H
+#define __ASM_ARCH_REGS_EBI_H
+
+/* EBI Control Registers */
+
+#define EBI_BA         W90X900_VA_EBI
+#define REG_EBICON     (EBI_BA + 0x00)
+#define REG_ROMCON     (EBI_BA + 0x04)
+#define REG_SDCONF0    (EBI_BA + 0x08)
+#define REG_SDCONF1    (EBI_BA + 0x0C)
+#define REG_SDTIME0    (EBI_BA + 0x10)
+#define REG_SDTIME1    (EBI_BA + 0x14)
+#define REG_EXT0CON    (EBI_BA + 0x18)
+#define REG_EXT1CON    (EBI_BA + 0x1C)
+#define REG_EXT2CON    (EBI_BA + 0x20)
+#define REG_EXT3CON    (EBI_BA + 0x24)
+#define REG_EXT4CON    (EBI_BA + 0x28)
+#define REG_CKSKEW     (EBI_BA + 0x2C)
+
+#endif /*  __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-w90x900/regs-gcr.h b/arch/arm/mach-w90x900/regs-gcr.h
new file mode 100644 (file)
index 0000000..6087abd
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-gcr.h
+ *
+ * Copyright (c) 2010 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_GCR_H
+#define __ASM_ARCH_REGS_GCR_H
+
+/* Global control registers */
+
+#define GCR_BA         W90X900_VA_GCR
+#define REG_PDID       (GCR_BA+0x000)
+#define REG_PWRON      (GCR_BA+0x004)
+#define REG_ARBCON     (GCR_BA+0x008)
+#define REG_MFSEL      (GCR_BA+0x00C)
+#define REG_EBIDPE     (GCR_BA+0x010)
+#define REG_LCDDPE     (GCR_BA+0x014)
+#define REG_GPIOCPE    (GCR_BA+0x018)
+#define REG_GPIODPE    (GCR_BA+0x01C)
+#define REG_GPIOEPE    (GCR_BA+0x020)
+#define REG_GPIOFPE    (GCR_BA+0x024)
+#define REG_GPIOGPE    (GCR_BA+0x028)
+#define REG_GPIOHPE    (GCR_BA+0x02C)
+#define REG_GPIOIPE    (GCR_BA+0x030)
+#define REG_GTMP1      (GCR_BA+0x034)
+#define REG_GTMP2      (GCR_BA+0x038)
+#define REG_GTMP3      (GCR_BA+0x03C)
+
+#endif /*  __ASM_ARCH_REGS_GCR_H */
diff --git a/arch/arm/mach-w90x900/regs-timer.h b/arch/arm/mach-w90x900/regs-timer.h
new file mode 100644 (file)
index 0000000..8f39062
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-timer.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/regs-timer.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+/* Timer Registers */
+
+#define TMR_BA                 W90X900_VA_TIMER
+#define REG_TCSR0              (TMR_BA+0x00)
+#define REG_TCSR1              (TMR_BA+0x04)
+#define REG_TICR0              (TMR_BA+0x08)
+#define REG_TICR1              (TMR_BA+0x0C)
+#define REG_TDR0               (TMR_BA+0x10)
+#define REG_TDR1               (TMR_BA+0x14)
+#define REG_TISR               (TMR_BA+0x18)
+#define REG_WTCR               (TMR_BA+0x1C)
+#define REG_TCSR2              (TMR_BA+0x20)
+#define REG_TCSR3              (TMR_BA+0x24)
+#define REG_TICR2              (TMR_BA+0x28)
+#define REG_TICR3              (TMR_BA+0x2C)
+#define REG_TDR2               (TMR_BA+0x30)
+#define REG_TDR3               (TMR_BA+0x34)
+#define REG_TCSR4              (TMR_BA+0x40)
+#define REG_TICR4              (TMR_BA+0x48)
+#define REG_TDR4               (TMR_BA+0x50)
+
+#endif /*  __ASM_ARCH_REGS_TIMER_H */
diff --git a/arch/arm/mach-w90x900/regs-usb.h b/arch/arm/mach-w90x900/regs-usb.h
new file mode 100644 (file)
index 0000000..ab74b0c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-usb.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_H
+#define __ASM_ARCH_REGS_USB_H
+
+/* usb Control Registers  */
+#define USBH_BA                W90X900_VA_USBEHCIHOST
+#define USBD_BA                W90X900_VA_USBDEV
+#define USBO_BA                W90X900_VA_USBOHCIHOST
+
+/* USB Host Control Registers */
+#define REG_UPSCR0     (USBH_BA+0x064)
+#define REG_UPSCR1     (USBH_BA+0x068)
+#define REG_USBPCR0    (USBH_BA+0x0C4)
+#define REG_USBPCR1    (USBH_BA+0x0C8)
+
+/* USBH OHCI Control Registers */
+#define REG_OpModEn    (USBO_BA+0x204)
+/*This bit controls the polarity of over
+*current flag from external power IC.
+*/
+#define OCALow         0x08
+
+#endif /*  __ASM_ARCH_REGS_USB_H */
index cd1966e..cda0852 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/mach/time.h>
 
 #include <mach/map.h>
-#include <mach/regs-timer.h>
+#include "regs-timer.h"
 
 #include "nuc9xx.h"
 
index 446334a..209c979 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ARCH_ZX
-       bool "ZTE ZX family" if ARCH_MULTI_V7
+       bool "ZTE ZX family"
+       depends on ARCH_MULTI_V7
        help
          Support for ZTE ZX-based family of processors. TV
          set-top-box processor is supported. More will be
index a369398..0297f92 100644 (file)
@@ -176,7 +176,7 @@ static void zx_secondary_init(unsigned int cpu)
        scu_power_mode(scu_base, SCU_PM_NORMAL);
 }
 
-struct smp_operations zx_smp_ops __initdata = {
+static const struct smp_operations zx_smp_ops __initconst = {
        .smp_prepare_cpus       = zx_smp_prepare_cpus,
        .smp_secondary_init     = zx_secondary_init,
        .smp_boot_secondary     = zx_boot_secondary,
index 78e5e00..fd0aeeb 100644 (file)
@@ -1,5 +1,7 @@
 config ARCH_ZYNQ
-       bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
+       bool "Xilinx Zynq ARM Cortex A9 Platform"
+       depends on ARCH_MULTI_V7
+       select ARCH_HAS_RESET_CONTROLLER
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
        select ARM_GIC
index 79cda2e..e771933 100644 (file)
@@ -30,7 +30,7 @@ extern char zynq_secondary_trampoline;
 extern char zynq_secondary_trampoline_jump;
 extern char zynq_secondary_trampoline_end;
 extern int zynq_cpun_start(u32 address, int cpu);
-extern struct smp_operations zynq_smp_ops __initdata;
+extern const struct smp_operations zynq_smp_ops;
 #endif
 
 extern void __iomem *zynq_scu_base;
index f66816c..7cd9865 100644 (file)
@@ -157,7 +157,7 @@ static void zynq_cpu_die(unsigned int cpu)
 }
 #endif
 
-struct smp_operations zynq_smp_ops __initdata = {
+const struct smp_operations zynq_smp_ops __initconst = {
        .smp_init_cpus          = zynq_smp_init_cpus,
        .smp_prepare_cpus       = zynq_smp_prepare_cpus,
        .smp_boot_secondary     = zynq_boot_secondary,
index 4121886..549f6d3 100644 (file)
@@ -21,7 +21,7 @@ config CPU_ARM7TDMI
 
 # ARM720T
 config CPU_ARM720T
-       bool "Support ARM720T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+       bool
        select CPU_32v4T
        select CPU_ABRT_LV4T
        select CPU_CACHE_V4
@@ -39,7 +39,7 @@ config CPU_ARM720T
 
 # ARM740T
 config CPU_ARM740T
-       bool "Support ARM740T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+       bool
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_LV4T
@@ -71,7 +71,7 @@ config CPU_ARM9TDMI
 
 # ARM920T
 config CPU_ARM920T
-       bool "Support ARM920T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+       bool
        select CPU_32v4T
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
@@ -89,7 +89,7 @@ config CPU_ARM920T
 
 # ARM922T
 config CPU_ARM922T
-       bool "Support ARM922T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+       bool
        select CPU_32v4T
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
@@ -108,7 +108,7 @@ config CPU_ARM922T
 
 # ARM925T
 config CPU_ARM925T
-       bool "Support ARM925T processor" if ARCH_OMAP1
+       bool
        select CPU_32v4T
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
@@ -127,7 +127,7 @@ config CPU_ARM925T
 
 # ARM926T
 config CPU_ARM926T
-       bool "Support ARM926T processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V5) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB)
+       bool
        select CPU_32v5
        select CPU_ABRT_EV5TJ
        select CPU_CACHE_VIVT
@@ -163,7 +163,7 @@ config CPU_FA526
 
 # ARM940T
 config CPU_ARM940T
-       bool "Support ARM940T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+       bool
        depends on !MMU
        select CPU_32v4T
        select CPU_ABRT_NOMMU
@@ -181,7 +181,7 @@ config CPU_ARM940T
 
 # ARM946E-S
 config CPU_ARM946E
-       bool "Support ARM946E-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+       bool
        depends on !MMU
        select CPU_32v5
        select CPU_ABRT_NOMMU
@@ -198,7 +198,7 @@ config CPU_ARM946E
 
 # ARM1020 - needs validating
 config CPU_ARM1020
-       bool "Support ARM1020T (rev 0) processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+       bool
        select CPU_32v5
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
@@ -216,7 +216,7 @@ config CPU_ARM1020
 
 # ARM1020E - needs validating
 config CPU_ARM1020E
-       bool "Support ARM1020E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+       bool
        depends on n
        select CPU_32v5
        select CPU_ABRT_EV4T
@@ -229,7 +229,7 @@ config CPU_ARM1020E
 
 # ARM1022E
 config CPU_ARM1022
-       bool "Support ARM1022E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+       bool
        select CPU_32v5
        select CPU_ABRT_EV4T
        select CPU_CACHE_VIVT
@@ -247,7 +247,7 @@ config CPU_ARM1022
 
 # ARM1026EJ-S
 config CPU_ARM1026
-       bool "Support ARM1026EJ-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+       bool
        select CPU_32v5
        select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
        select CPU_CACHE_VIVT
@@ -358,7 +358,7 @@ config CPU_PJ4B
 
 # ARMv6
 config CPU_V6
-       bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+       bool
        select CPU_32v6
        select CPU_ABRT_EV6
        select CPU_CACHE_V6
@@ -371,7 +371,7 @@ config CPU_V6
 
 # ARMv6k
 config CPU_V6K
-       bool "Support ARM V6K processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+       bool
        select CPU_32v6
        select CPU_32v6K
        select CPU_ABRT_EV6
@@ -385,7 +385,7 @@ config CPU_V6K
 
 # ARMv7
 config CPU_V7
-       bool "Support ARM V7 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V7) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+       bool
        select CPU_32v6K
        select CPU_32v7
        select CPU_ABRT_EV7
@@ -1005,8 +1005,6 @@ config ARM_L1_CACHE_SHIFT
 
 config ARM_DMA_MEM_BUFFERABLE
        bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
-       depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
-                    MACH_REALVIEW_PB11MP)
        default y if CPU_V6 || CPU_V6K || CPU_V7
        help
          Historically, the kernel has used strongly ordered mappings to
index 534a60a..0eca381 100644 (file)
@@ -1200,10 +1200,7 @@ error:
        while (i--)
                if (pages[i])
                        __free_pages(pages[i], 0);
-       if (array_size <= PAGE_SIZE)
-               kfree(pages);
-       else
-               vfree(pages);
+       kvfree(pages);
        return NULL;
 }
 
@@ -1211,7 +1208,6 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages,
                               size_t size, struct dma_attrs *attrs)
 {
        int count = size >> PAGE_SHIFT;
-       int array_size = count * sizeof(struct page *);
        int i;
 
        if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs)) {
@@ -1222,10 +1218,7 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages,
                                __free_pages(pages[i], 0);
        }
 
-       if (array_size <= PAGE_SIZE)
-               kfree(pages);
-       else
-               vfree(pages);
+       kvfree(pages);
        return 0;
 }
 
index e7a81ce..d659096 100644 (file)
@@ -86,7 +86,7 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
 
        prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
 
-       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale_family())
                prot |= PMD_BIT4;
 
        pgd += pgd_index(addr);
index a87f6cc..434d76f 100644 (file)
@@ -477,7 +477,7 @@ static void __init build_mem_type_table(void)
         * "update-able on write" bit on ARM610).  However, Xscale and
         * Xscale3 require this bit to be cleared.
         */
-       if (cpu_is_xscale() || cpu_is_xsc3()) {
+       if (cpu_is_xscale_family()) {
                for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
                        mem_types[i].prot_sect &= ~PMD_BIT4;
                        mem_types[i].prot_l1 &= ~PMD_BIT4;
index d65edf7..6f07d2e 100644 (file)
@@ -342,11 +342,13 @@ ENTRY(cpu_mohawk_switch_mm)
  */
        .align  5
 ENTRY(cpu_mohawk_set_pte_ext)
+#ifdef CONFIG_MMU
        armv3_set_pte_ext
        mov     r0, r0
        mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        ret     lr
+#endif
 
 .globl cpu_mohawk_suspend_size
 .equ   cpu_mohawk_suspend_size, 4 * 6
index 8ca94d3..7a327bd 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/device.h>
@@ -137,6 +138,31 @@ static int omap_dm_timer_reset(struct omap_dm_timer *timer)
        return 0;
 }
 
+static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
+{
+       int ret;
+       struct clk *parent;
+
+       /*
+        * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
+        * do not call clk_get() for these devices.
+        */
+       if (!timer->fclk)
+               return -ENODEV;
+
+       parent = clk_get(&timer->pdev->dev, NULL);
+       if (IS_ERR(parent))
+               return -ENODEV;
+
+       ret = clk_set_parent(timer->fclk, parent);
+       if (ret < 0)
+               pr_err("%s: failed to set parent\n", __func__);
+
+       clk_put(parent);
+
+       return ret;
+}
+
 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
        int rc;
@@ -166,7 +192,11 @@ static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
        __omap_dm_timer_enable_posted(timer);
        omap_dm_timer_disable(timer);
 
-       return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+       rc = omap_dm_timer_of_set_source(timer);
+       if (rc == -ENODEV)
+               return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+
+       return rc;
 }
 
 static inline u32 omap_dm_timer_reserved_systimer(int id)
@@ -504,6 +534,12 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
        if (IS_ERR(timer->fclk))
                return -EINVAL;
 
+#if defined(CONFIG_COMMON_CLK)
+       /* Check if the clock has configurable parents */
+       if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
+               return 0;
+#endif
+
        switch (source) {
        case OMAP_TIMER_SRC_SYS_CLK:
                parent_name = "timer_sys_ck";
@@ -943,6 +979,10 @@ static const struct of_device_id omap_timer_match[] = {
                .compatible = "ti,am335x-timer-1ms",
                .data = &omap3plus_pdata,
        },
+       {
+               .compatible = "ti,dm816-timer",
+               .data = &omap3plus_pdata,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, omap_timer_match);
index 8861c36..78c8bf4 100644 (file)
@@ -21,7 +21,6 @@
 #include <net/dsa.h>
 #include <linux/platform_data/dma-mv_xor.h>
 #include <linux/platform_data/usb-ehci-orion.h>
-#include <mach/bridge-regs.h>
 #include <plat/common.h>
 
 /* Create a clkdev entry for a given device/clk */
@@ -588,26 +587,6 @@ void __init orion_spi_1_init(unsigned long mapbase)
        platform_device_register(&orion_spi_1);
 }
 
-/*****************************************************************************
- * Watchdog
- ****************************************************************************/
-static struct resource orion_wdt_resource[] = {
-               DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04),
-               DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04),
-};
-
-static struct platform_device orion_wdt_device = {
-       .name           = "orion_wdt",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(orion_wdt_resource),
-       .resource       = orion_wdt_resource,
-};
-
-void __init orion_wdt_init(void)
-{
-       platform_device_register(&orion_wdt_device);
-}
-
 /*****************************************************************************
  * XOR
  ****************************************************************************/
index d9a24f6..9e6d76a 100644 (file)
@@ -75,8 +75,6 @@ void __init orion_spi_init(unsigned long mapbase);
 
 void __init orion_spi_1_init(unsigned long mapbase);
 
-void __init orion_wdt_init(void);
-
 void __init orion_xor0_init(unsigned long mapbase_low,
                            unsigned long mapbase_high,
                            unsigned long irq_0,
index 8c1fc06..5b63b28 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/exception.h>
 #include <plat/irq.h>
 #include <plat/orion-gpio.h>
-#include <mach/bridge-regs.h>
 
 void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
 {
index 7310bcf..5b4ff93 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/mbus.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
-#include <mach/hardware.h>
 #include <plat/orion-gpio.h>
 #include <plat/mpp.h>
 
index 1fc9419..557b134 100644 (file)
@@ -1,8 +1,9 @@
 #
 # Makefile for code common across different PXA processor families
 #
+ccflags-$(CONFIG_ARCH_MMP) := -I$(srctree)/$(src)/include
 
-obj-y  := dma.o
+obj-$(CONFIG_ARCH_PXA)         := dma.o
 
 obj-$(CONFIG_PXA3xx)           += mfp.o
 obj-$(CONFIG_ARCH_MMP)         += mfp.o
index daa1a65..ba13f79 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/of_device.h>
 
 #include <asm/irq.h>
-#include <mach/hardware.h>
 
 static DEFINE_MUTEX(ssp_lock);
 static LIST_HEAD(ssp_list);
index 57729b9..e8229b9 100644 (file)
@@ -39,7 +39,6 @@ config S3C_LOWLEVEL_UART_PORT
 
 config SAMSUNG_ATAGS
        def_bool n
-       depends on !ARCH_MULTIPLATFORM
        depends on ATAGS
        help
           This option enables ATAGS based boot support code for
@@ -70,6 +69,7 @@ config S3C_GPIO_TRACK
 
 config S3C_ADC
        bool "ADC common driver support"
+       depends on !ARCH_MULTIPLATFORM
        help
          Core support for the ADC block found in the Samsung SoC systems
          for drivers such as the touchscreen and hwmon to use to share
@@ -225,6 +225,9 @@ config S3C24XX_PWM
          Support for exporting the PWM timer blocks via the pwm device
          system
 
+config GPIO_SAMSUNG
+       def_bool y
+
 config SAMSUNG_PM_GPIO
        bool
        default y if GPIO_SAMSUNG && PM
index 8c91176..be172ef 100644 (file)
@@ -4,7 +4,8 @@
 #
 # Licensed under GPLv2
 
-ccflags-$(CONFIG_ARCH_MULTI_V7) += -I$(srctree)/$(src)/include
+ccflags-$(CONFIG_ARCH_S3C64XX) := -I$(srctree)/arch/arm/mach-s3c64xx/include
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include
 
 # Objects we always build independent of SoC choice
 
@@ -21,6 +22,8 @@ obj-$(CONFIG_SAMSUNG_ATAGS)   += platformdata.o
 obj-$(CONFIG_SAMSUNG_ATAGS)    += devs.o
 obj-$(CONFIG_SAMSUNG_ATAGS)    += dev-uart.o
 
+obj-$(CONFIG_GPIO_SAMSUNG)     += gpio-samsung.o
+
 # PM support
 
 obj-$(CONFIG_PM_SLEEP)         += pm-common.o
index f39938f..b53d4ff 100644 (file)
@@ -119,12 +119,12 @@ struct platform_device s3c_device_adc = {
 #if defined(CONFIG_SAMSUNG_DEV_ADC)
 static struct resource s3c_adc_resource[] = {
        [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
-       [1] = DEFINE_RES_IRQ(IRQ_TC),
-       [2] = DEFINE_RES_IRQ(IRQ_ADC),
+       [1] = DEFINE_RES_IRQ(IRQ_ADC),
+       [2] = DEFINE_RES_IRQ(IRQ_TC),
 };
 
 struct platform_device s3c_device_adc = {
-       .name           = "samsung-adc",
+       .name           = "exynos-adc",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(s3c_adc_resource),
        .resource       = s3c_adc_resource,
@@ -956,31 +956,19 @@ void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_
 #endif /* CONFIG_PLAT_S3C24XX */
 
 #ifdef CONFIG_SAMSUNG_DEV_TS
-static struct resource s3c_ts_resource[] = {
-       [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
-       [1] = DEFINE_RES_IRQ(IRQ_TC),
-};
-
 static struct s3c2410_ts_mach_info default_ts_data __initdata = {
        .delay                  = 10000,
        .presc                  = 49,
        .oversampling_shift     = 2,
 };
 
-struct platform_device s3c_device_ts = {
-       .name           = "s3c64xx-ts",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_ts_resource),
-       .resource       = s3c_ts_resource,
-};
-
-void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
+void __init s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
 {
        if (!pd)
                pd = &default_ts_data;
 
        s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
-                        &s3c_device_ts);
+                        &s3c_device_adc);
 }
 #endif /* CONFIG_SAMSUNG_DEV_TS */
 
diff --git a/arch/arm/plat-samsung/gpio-samsung.c b/arch/arm/plat-samsung/gpio-samsung.c
new file mode 100644 (file)
index 0000000..7861488
--- /dev/null
@@ -0,0 +1,1328 @@
+/*
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * SAMSUNG - GPIOlib 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+
+#include <asm/irq.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/pm.h>
+
+int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
+                               unsigned int off, samsung_gpio_pull_t pull)
+{
+       void __iomem *reg = chip->base + 0x08;
+       int shift = off * 2;
+       u32 pup;
+
+       pup = __raw_readl(reg);
+       pup &= ~(3 << shift);
+       pup |= pull << shift;
+       __raw_writel(pup, reg);
+
+       return 0;
+}
+
+samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
+                                               unsigned int off)
+{
+       void __iomem *reg = chip->base + 0x08;
+       int shift = off * 2;
+       u32 pup = __raw_readl(reg);
+
+       pup >>= shift;
+       pup &= 0x3;
+
+       return (__force samsung_gpio_pull_t)pup;
+}
+
+int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
+                        unsigned int off, samsung_gpio_pull_t pull)
+{
+       switch (pull) {
+       case S3C_GPIO_PULL_NONE:
+               pull = 0x01;
+               break;
+       case S3C_GPIO_PULL_UP:
+               pull = 0x00;
+               break;
+       case S3C_GPIO_PULL_DOWN:
+               pull = 0x02;
+               break;
+       }
+       return samsung_gpio_setpull_updown(chip, off, pull);
+}
+
+samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
+                                        unsigned int off)
+{
+       samsung_gpio_pull_t pull;
+
+       pull = samsung_gpio_getpull_updown(chip, off);
+
+       switch (pull) {
+       case 0x00:
+               pull = S3C_GPIO_PULL_UP;
+               break;
+       case 0x01:
+       case 0x03:
+               pull = S3C_GPIO_PULL_NONE;
+               break;
+       case 0x02:
+               pull = S3C_GPIO_PULL_DOWN;
+               break;
+       }
+
+       return pull;
+}
+
+static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
+                                 unsigned int off, samsung_gpio_pull_t pull,
+                                 samsung_gpio_pull_t updown)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       if (pull == updown)
+               pup &= ~(1 << off);
+       else if (pull == S3C_GPIO_PULL_NONE)
+               pup |= (1 << off);
+       else
+               return -EINVAL;
+
+       __raw_writel(pup, reg);
+       return 0;
+}
+
+static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
+                                                 unsigned int off,
+                                                 samsung_gpio_pull_t updown)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       pup &= (1 << off);
+       return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+
+samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
+                                            unsigned int off)
+{
+       return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
+                            unsigned int off, samsung_gpio_pull_t pull)
+{
+       return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
+}
+
+samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
+                                              unsigned int off)
+{
+       return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
+                              unsigned int off, samsung_gpio_pull_t pull)
+{
+       return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+
+/*
+ * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has two bits of configuration per gpio, which have the following
+ * functions:
+ *     00 = input
+ *     01 = output
+ *     1x = special function
+ */
+
+static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
+                                   unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = off * 2;
+       u32 con;
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+               if (cfg > 3)
+                       return -EINVAL;
+
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0x3 << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+/*
+ * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
+ * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+
+static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
+                                            unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off * 2;
+       con &= 3;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
+
+/*
+ * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *     0000 = Input
+ *     0001 = Output
+ *     others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of functions for
+ * each case.
+ */
+
+static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
+                                   unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio > 8)
+               reg -= 4;
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0xf << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+/*
+ * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to samsung_gpio_setcfg_4bit().
+ *
+ * @sa samsung_gpio_getcfg_2bit
+ */
+
+static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
+                                        unsigned int off)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio > 8)
+               reg -= 4;
+
+       con = __raw_readl(reg);
+       con >>= shift;
+       con &= 0xf;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+/*
+ * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+ */
+
+static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
+                                    unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = off;
+       u32 con;
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+
+               /* Map output to 0, and SFN2 to 1 */
+               cfg -= 1;
+               if (cfg > 1)
+                       return -EINVAL;
+
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0x1 << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+/*
+ * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa samsung_gpio_getcfg_2bit
+ * @sa samsung_gpio_getcfg_4bit
+ */
+
+static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
+                                         unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off;
+       con &= 1;
+       con++;
+
+       return S3C_GPIO_SFN(con);
+}
+#endif
+
+static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
+                                          int nr_chips)
+{
+       for (; nr_chips > 0; nr_chips--, chipcfg++) {
+               if (!chipcfg->set_config)
+                       chipcfg->set_config = samsung_gpio_setcfg_4bit;
+               if (!chipcfg->get_config)
+                       chipcfg->get_config = samsung_gpio_getcfg_4bit;
+               if (!chipcfg->set_pull)
+                       chipcfg->set_pull = samsung_gpio_setpull_updown;
+               if (!chipcfg->get_pull)
+                       chipcfg->get_pull = samsung_gpio_getpull_updown;
+       }
+}
+
+struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
+       .set_config     = samsung_gpio_setcfg_2bit,
+       .get_config     = samsung_gpio_getcfg_2bit,
+};
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
+       .set_config     = s3c24xx_gpio_setcfg_abank,
+       .get_config     = s3c24xx_gpio_getcfg_abank,
+};
+#endif
+
+static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
+       [0] = {
+               .cfg_eint       = 0x0,
+       },
+       [1] = {
+               .cfg_eint       = 0x3,
+       },
+       [2] = {
+               .cfg_eint       = 0x7,
+       },
+       [3] = {
+               .cfg_eint       = 0xF,
+       },
+       [4] = {
+               .cfg_eint       = 0x0,
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       },
+       [5] = {
+               .cfg_eint       = 0x2,
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       },
+       [6] = {
+               .cfg_eint       = 0x3,
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       },
+       [7] = {
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       },
+};
+
+/*
+ * Default routines for controlling GPIO, based on the original S3C24XX
+ * GPIO functions which deal with the case where each gpio bank of the
+ * chip is as following:
+ *
+ * base + 0x00: Control register, 2 bits per gpio
+ *             gpio n: 2 bits starting at (2*n)
+ *             00 = input, 01 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *             bit n: data bit n
+*/
+
+static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long con;
+
+       samsung_gpio_lock(ourchip, flags);
+
+       con = __raw_readl(base + 0x00);
+       con &= ~(3 << (offset * 2));
+
+       __raw_writel(con, base + 0x00);
+
+       samsung_gpio_unlock(ourchip, flags);
+       return 0;
+}
+
+static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
+                                      unsigned offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long dat;
+       unsigned long con;
+
+       samsung_gpio_lock(ourchip, flags);
+
+       dat = __raw_readl(base + 0x04);
+       dat &= ~(1 << offset);
+       if (value)
+               dat |= 1 << offset;
+       __raw_writel(dat, base + 0x04);
+
+       con = __raw_readl(base + 0x00);
+       con &= ~(3 << (offset * 2));
+       con |= 1 << (offset * 2);
+
+       __raw_writel(con, base + 0x00);
+       __raw_writel(dat, base + 0x04);
+
+       samsung_gpio_unlock(ourchip, flags);
+       return 0;
+}
+
+/*
+ * The samsung_gpiolib_4bit routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ *             gpio n: 4 bits starting at (4*n)
+ *             0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *             bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
+ * state of the output.
+ */
+
+static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
+                                     unsigned int offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long con;
+
+       con = __raw_readl(base + GPIOCON_OFF);
+       if (ourchip->bitmap_gpio_int & BIT(offset))
+               con |= 0xf << con_4bit_shift(offset);
+       else
+               con &= ~(0xf << con_4bit_shift(offset));
+       __raw_writel(con, base + GPIOCON_OFF);
+
+       pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
+
+       return 0;
+}
+
+static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
+                                      unsigned int offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long con;
+       unsigned long dat;
+
+       con = __raw_readl(base + GPIOCON_OFF);
+       con &= ~(0xf << con_4bit_shift(offset));
+       con |= 0x1 << con_4bit_shift(offset);
+
+       dat = __raw_readl(base + GPIODAT_OFF);
+
+       if (value)
+               dat |= 1 << offset;
+       else
+               dat &= ~(1 << offset);
+
+       __raw_writel(dat, base + GPIODAT_OFF);
+       __raw_writel(con, base + GPIOCON_OFF);
+       __raw_writel(dat, base + GPIODAT_OFF);
+
+       pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+       return 0;
+}
+
+/*
+ * The next set of routines are for the case where the GPIO configuration
+ * registers are 4 bits per GPIO but there is more than one register (the
+ * bank has more than 8 GPIOs.
+ *
+ * This case is the similar to the 4 bit case, but the registers are as
+ * follows:
+ *
+ * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
+ *             gpio n: 4 bits starting at (4*n)
+ *             0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
+ *             gpio n: 4 bits starting at (4*n)
+ *             0000 = input, 0001 = output, others mean special-function
+ * base + 0x08: Data register, 1 bit per gpio
+ *             bit n: data bit n
+ *
+ * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
+ * routines we store the 'base + 0x4' address so that these routines see
+ * the data register at ourchip->base + 0x04.
+ */
+
+static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
+                                      unsigned int offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       void __iomem *regcon = base;
+       unsigned long con;
+
+       if (offset > 7)
+               offset -= 8;
+       else
+               regcon -= 4;
+
+       con = __raw_readl(regcon);
+       con &= ~(0xf << con_4bit_shift(offset));
+       __raw_writel(con, regcon);
+
+       pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
+
+       return 0;
+}
+
+static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
+                                       unsigned int offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       void __iomem *regcon = base;
+       unsigned long con;
+       unsigned long dat;
+       unsigned con_offset = offset;
+
+       if (con_offset > 7)
+               con_offset -= 8;
+       else
+               regcon -= 4;
+
+       con = __raw_readl(regcon);
+       con &= ~(0xf << con_4bit_shift(con_offset));
+       con |= 0x1 << con_4bit_shift(con_offset);
+
+       dat = __raw_readl(base + GPIODAT_OFF);
+
+       if (value)
+               dat |= 1 << offset;
+       else
+               dat &= ~(1 << offset);
+
+       __raw_writel(dat, base + GPIODAT_OFF);
+       __raw_writel(con, regcon);
+       __raw_writel(dat, base + GPIODAT_OFF);
+
+       pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+       return 0;
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+/* The next set of routines are for the case of s3c24xx bank a */
+
+static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
+{
+       return -EINVAL;
+}
+
+static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long dat;
+       unsigned long con;
+
+       local_irq_save(flags);
+
+       con = __raw_readl(base + 0x00);
+       dat = __raw_readl(base + 0x04);
+
+       dat &= ~(1 << offset);
+       if (value)
+               dat |= 1 << offset;
+
+       __raw_writel(dat, base + 0x04);
+
+       con &= ~(1 << offset);
+
+       __raw_writel(con, base + 0x00);
+       __raw_writel(dat, base + 0x04);
+
+       local_irq_restore(flags);
+       return 0;
+}
+#endif
+
+static void samsung_gpiolib_set(struct gpio_chip *chip,
+                               unsigned offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long dat;
+
+       samsung_gpio_lock(ourchip, flags);
+
+       dat = __raw_readl(base + 0x04);
+       dat &= ~(1 << offset);
+       if (value)
+               dat |= 1 << offset;
+       __raw_writel(dat, base + 0x04);
+
+       samsung_gpio_unlock(ourchip, flags);
+}
+
+static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       unsigned long val;
+
+       val = __raw_readl(ourchip->base + 0x04);
+       val >>= offset;
+       val &= 1;
+
+       return val;
+}
+
+/*
+ * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
+ * for use with the configuration calls, and other parts of the s3c gpiolib
+ * support code.
+ *
+ * Not all s3c support code will need this, as some configurations of cpu
+ * may only support one or two different configuration options and have an
+ * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
+ * the machine support file should provide its own samsung_gpiolib_getchip()
+ * and any other necessary functions.
+ */
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
+{
+       unsigned int gpn;
+       int i;
+
+       gpn = chip->chip.base;
+       for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
+               BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
+               s3c_gpios[gpn] = chip;
+       }
+}
+#endif /* CONFIG_S3C_GPIO_TRACK */
+
+/*
+ * samsung_gpiolib_add() - add the Samsung gpio_chip.
+ * @chip: The chip to register
+ *
+ * This is a wrapper to gpiochip_add() that takes our specific gpio chip
+ * information and makes the necessary alterations for the platform and
+ * notes the information for use with the configuration systems and any
+ * other parts of the system.
+ */
+
+static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
+{
+       struct gpio_chip *gc = &chip->chip;
+       int ret;
+
+       BUG_ON(!chip->base);
+       BUG_ON(!gc->label);
+       BUG_ON(!gc->ngpio);
+
+       spin_lock_init(&chip->lock);
+
+       if (!gc->direction_input)
+               gc->direction_input = samsung_gpiolib_2bit_input;
+       if (!gc->direction_output)
+               gc->direction_output = samsung_gpiolib_2bit_output;
+       if (!gc->set)
+               gc->set = samsung_gpiolib_set;
+       if (!gc->get)
+               gc->get = samsung_gpiolib_get;
+
+#ifdef CONFIG_PM
+       if (chip->pm != NULL) {
+               if (!chip->pm->save || !chip->pm->resume)
+                       pr_err("gpio: %s has missing PM functions\n",
+                              gc->label);
+       } else
+               pr_err("gpio: %s has no PM function\n", gc->label);
+#endif
+
+       /* gpiochip_add() prints own failure message on error. */
+       ret = gpiochip_add_data(gc, chip);
+       if (ret >= 0)
+               s3c_gpiolib_track(chip);
+}
+
+static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
+                                            int nr_chips, void __iomem *base)
+{
+       int i;
+       struct gpio_chip *gc = &chip->chip;
+
+       for (i = 0 ; i < nr_chips; i++, chip++) {
+               /* skip banks not present on SoC */
+               if (chip->chip.base >= S3C_GPIO_END)
+                       continue;
+
+               if (!chip->config)
+                       chip->config = &s3c24xx_gpiocfg_default;
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
+               if ((base != NULL) && (chip->base == NULL))
+                       chip->base = base + ((i) * 0x10);
+
+               if (!gc->direction_input)
+                       gc->direction_input = samsung_gpiolib_2bit_input;
+               if (!gc->direction_output)
+                       gc->direction_output = samsung_gpiolib_2bit_output;
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
+                                                 int nr_chips, void __iomem *base,
+                                                 unsigned int offset)
+{
+       int i;
+
+       for (i = 0 ; i < nr_chips; i++, chip++) {
+               chip->chip.direction_input = samsung_gpiolib_2bit_input;
+               chip->chip.direction_output = samsung_gpiolib_2bit_output;
+
+               if (!chip->config)
+                       chip->config = &samsung_gpio_cfgs[7];
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
+               if ((base != NULL) && (chip->base == NULL))
+                       chip->base = base + ((i) * offset);
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+/*
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+
+static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
+                                                 int nr_chips, void __iomem *base)
+{
+       int i;
+
+       for (i = 0 ; i < nr_chips; i++, chip++) {
+               chip->chip.direction_input = samsung_gpiolib_4bit_input;
+               chip->chip.direction_output = samsung_gpiolib_4bit_output;
+
+               if (!chip->config)
+                       chip->config = &samsung_gpio_cfgs[2];
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+               if ((base != NULL) && (chip->base == NULL))
+                       chip->base = base + ((i) * 0x20);
+
+               chip->bitmap_gpio_int = 0;
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
+                                                  int nr_chips)
+{
+       for (; nr_chips > 0; nr_chips--, chip++) {
+               chip->chip.direction_input = samsung_gpiolib_4bit2_input;
+               chip->chip.direction_output = samsung_gpiolib_4bit2_output;
+
+               if (!chip->config)
+                       chip->config = &samsung_gpio_cfgs[2];
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
+
+       return samsung_chip->irq_base + offset;
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       if (offset < 4) {
+               if (soc_is_s3c2412())
+                       return IRQ_EINT0_2412 + offset;
+               else
+                       return IRQ_EINT0 + offset;
+       }
+
+       if (offset < 8)
+               return IRQ_EINT4 + offset - 4;
+
+       return -EINVAL;
+}
+#endif
+
+#ifdef CONFIG_ARCH_S3C64XX
+static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+       return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
+static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+       return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+#endif
+
+struct samsung_gpio_chip s3c24xx_gpios[] = {
+#ifdef CONFIG_PLAT_S3C24XX
+       {
+               .config = &s3c24xx_gpiocfg_banka,
+               .chip   = {
+                       .base                   = S3C2410_GPA(0),
+                       .owner                  = THIS_MODULE,
+                       .label                  = "GPIOA",
+                       .ngpio                  = 27,
+                       .direction_input        = s3c24xx_gpiolib_banka_input,
+                       .direction_output       = s3c24xx_gpiolib_banka_output,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPB(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOB",
+                       .ngpio  = 11,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPC(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOC",
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPD(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOD",
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPE(0),
+                       .label  = "GPIOE",
+                       .owner  = THIS_MODULE,
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPF(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOF",
+                       .ngpio  = 8,
+                       .to_irq = s3c24xx_gpiolib_fbank_to_irq,
+               },
+       }, {
+               .irq_base = IRQ_EINT8,
+               .chip   = {
+                       .base   = S3C2410_GPG(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOG",
+                       .ngpio  = 16,
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPH(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOH",
+                       .ngpio  = 15,
+               },
+       },
+               /* GPIOS for the S3C2443 and later devices. */
+       {
+               .base   = S3C2440_GPJCON,
+               .chip   = {
+                       .base   = S3C2410_GPJ(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOJ",
+                       .ngpio  = 16,
+               },
+       }, {
+               .base   = S3C2443_GPKCON,
+               .chip   = {
+                       .base   = S3C2410_GPK(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOK",
+                       .ngpio  = 16,
+               },
+       }, {
+               .base   = S3C2443_GPLCON,
+               .chip   = {
+                       .base   = S3C2410_GPL(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOL",
+                       .ngpio  = 15,
+               },
+       }, {
+               .base   = S3C2443_GPMCON,
+               .chip   = {
+                       .base   = S3C2410_GPM(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOM",
+                       .ngpio  = 2,
+               },
+       },
+#endif
+};
+
+/*
+ * GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   SlpCon  ExtInt Group
+ * A   8       4Bit    Yes     1
+ * B   7       4Bit    Yes     1
+ * C   8       4Bit    Yes     2
+ * D   5       4Bit    Yes     3
+ * E   5       4Bit    Yes     None
+ * F   16      2Bit    Yes     4 [1]
+ * G   7       4Bit    Yes     5
+ * H   10      4Bit[2] Yes     6
+ * I   16      2Bit    Yes     None
+ * J   12      2Bit    Yes     None
+ * K   16      4Bit[2] No      None
+ * L   15      4Bit[2] No      None
+ * M   6       4Bit    No      IRQ_EINT
+ * N   16      2Bit    No      IRQ_EINT
+ * O   16      2Bit    Yes     7
+ * P   15      2Bit    Yes     8
+ * Q   9       2Bit    Yes     9
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
+#ifdef CONFIG_ARCH_S3C64XX
+       {
+               .chip   = {
+                       .base   = S3C64XX_GPA(0),
+                       .ngpio  = S3C64XX_GPIO_A_NR,
+                       .label  = "GPA",
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C64XX_GPB(0),
+                       .ngpio  = S3C64XX_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C64XX_GPC(0),
+                       .ngpio  = S3C64XX_GPIO_C_NR,
+                       .label  = "GPC",
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C64XX_GPD(0),
+                       .ngpio  = S3C64XX_GPIO_D_NR,
+                       .label  = "GPD",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[0],
+               .chip   = {
+                       .base   = S3C64XX_GPE(0),
+                       .ngpio  = S3C64XX_GPIO_E_NR,
+                       .label  = "GPE",
+               },
+       }, {
+               .base   = S3C64XX_GPG_BASE,
+               .chip   = {
+                       .base   = S3C64XX_GPG(0),
+                       .ngpio  = S3C64XX_GPIO_G_NR,
+                       .label  = "GPG",
+               },
+       }, {
+               .base   = S3C64XX_GPM_BASE,
+               .config = &samsung_gpio_cfgs[1],
+               .chip   = {
+                       .base   = S3C64XX_GPM(0),
+                       .ngpio  = S3C64XX_GPIO_M_NR,
+                       .label  = "GPM",
+                       .to_irq = s3c64xx_gpiolib_mbank_to_irq,
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
+#ifdef CONFIG_ARCH_S3C64XX
+       {
+               .base   = S3C64XX_GPH_BASE + 0x4,
+               .chip   = {
+                       .base   = S3C64XX_GPH(0),
+                       .ngpio  = S3C64XX_GPIO_H_NR,
+                       .label  = "GPH",
+               },
+       }, {
+               .base   = S3C64XX_GPK_BASE + 0x4,
+               .config = &samsung_gpio_cfgs[0],
+               .chip   = {
+                       .base   = S3C64XX_GPK(0),
+                       .ngpio  = S3C64XX_GPIO_K_NR,
+                       .label  = "GPK",
+               },
+       }, {
+               .base   = S3C64XX_GPL_BASE + 0x4,
+               .config = &samsung_gpio_cfgs[1],
+               .chip   = {
+                       .base   = S3C64XX_GPL(0),
+                       .ngpio  = S3C64XX_GPIO_L_NR,
+                       .label  = "GPL",
+                       .to_irq = s3c64xx_gpiolib_lbank_to_irq,
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
+#ifdef CONFIG_ARCH_S3C64XX
+       {
+               .base   = S3C64XX_GPF_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPF(0),
+                       .ngpio  = S3C64XX_GPIO_F_NR,
+                       .label  = "GPF",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[7],
+               .chip   = {
+                       .base   = S3C64XX_GPI(0),
+                       .ngpio  = S3C64XX_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[7],
+               .chip   = {
+                       .base   = S3C64XX_GPJ(0),
+                       .ngpio  = S3C64XX_GPIO_J_NR,
+                       .label  = "GPJ",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPO(0),
+                       .ngpio  = S3C64XX_GPIO_O_NR,
+                       .label  = "GPO",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPP(0),
+                       .ngpio  = S3C64XX_GPIO_P_NR,
+                       .label  = "GPP",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPQ(0),
+                       .ngpio  = S3C64XX_GPIO_Q_NR,
+                       .label  = "GPQ",
+               },
+       }, {
+               .base   = S3C64XX_GPN_BASE,
+               .irq_base = IRQ_EINT(0),
+               .config = &samsung_gpio_cfgs[5],
+               .chip   = {
+                       .base   = S3C64XX_GPN(0),
+                       .ngpio  = S3C64XX_GPIO_N_NR,
+                       .label  = "GPN",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+#endif
+};
+
+/* TODO: cleanup soc_is_* */
+static __init int samsung_gpiolib_init(void)
+{
+       /*
+        * Currently there are two drivers that can provide GPIO support for
+        * Samsung SoCs. For device tree enabled platforms, the new
+        * pinctrl-samsung driver is used, providing both GPIO and pin control
+        * interfaces. For legacy (non-DT) platforms this driver is used.
+        */
+       if (of_have_populated_dt())
+               return 0;
+
+       if (soc_is_s3c24xx()) {
+               samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
+                               ARRAY_SIZE(samsung_gpio_cfgs));
+               s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
+                               ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
+       } else if (soc_is_s3c64xx()) {
+               samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
+                               ARRAY_SIZE(samsung_gpio_cfgs));
+               samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
+                               ARRAY_SIZE(s3c64xx_gpios_2bit),
+                               S3C64XX_VA_GPIO + 0xE0, 0x20);
+               samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
+                               ARRAY_SIZE(s3c64xx_gpios_4bit),
+                               S3C64XX_VA_GPIO);
+               samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
+                               ARRAY_SIZE(s3c64xx_gpios_4bit2));
+       }
+
+       return 0;
+}
+core_initcall(samsung_gpiolib_init);
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset;
+       int ret;
+
+       if (!chip)
+               return -EINVAL;
+
+       offset = pin - chip->chip.base;
+
+       samsung_gpio_lock(chip, flags);
+       ret = samsung_gpio_do_setcfg(chip, offset, config);
+       samsung_gpio_unlock(chip, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
+
+int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+                         unsigned int cfg)
+{
+       int ret;
+
+       for (; nr > 0; nr--, start++) {
+               ret = s3c_gpio_cfgpin(start, cfg);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
+
+int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+                         unsigned int cfg, samsung_gpio_pull_t pull)
+{
+       int ret;
+
+       for (; nr > 0; nr--, start++) {
+               s3c_gpio_setpull(start, pull);
+               ret = s3c_gpio_cfgpin(start, cfg);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
+
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       unsigned ret = 0;
+       int offset;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               samsung_gpio_lock(chip, flags);
+               ret = samsung_gpio_do_getcfg(chip, offset);
+               samsung_gpio_unlock(chip, flags);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset, ret;
+
+       if (!chip)
+               return -EINVAL;
+
+       offset = pin - chip->chip.base;
+
+       samsung_gpio_lock(chip, flags);
+       ret = samsung_gpio_do_setpull(chip, offset, pull);
+       samsung_gpio_unlock(chip, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_setpull);
+
+samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset;
+       u32 pup = 0;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               samsung_gpio_lock(chip, flags);
+               pup = samsung_gpio_do_getpull(chip, offset);
+               samsung_gpio_unlock(chip, flags);
+       }
+
+       return (__force samsung_gpio_pull_t)pup;
+}
+EXPORT_SYMBOL(s3c_gpio_getpull);
+
+#ifdef CONFIG_PLAT_S3C24XX
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+       unsigned long flags;
+       unsigned long misccr;
+
+       local_irq_save(flags);
+       misccr = __raw_readl(S3C24XX_MISCCR);
+       misccr &= ~clear;
+       misccr ^= change;
+       __raw_writel(misccr, S3C24XX_MISCCR);
+       local_irq_restore(flags);
+
+       return misccr;
+}
+EXPORT_SYMBOL(s3c2410_modify_misccr);
+#endif
index 7f415ce..9dd562a 100644 (file)
@@ -41,14 +41,6 @@ static inline int s3c64xx_pm_init(void)
 extern unsigned long s3c_irqwake_intmask;
 extern unsigned long s3c_irqwake_eintmask;
 
-/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
-extern unsigned long s3c_irqwake_intallow;
-#ifdef CONFIG_PM_SLEEP
-extern unsigned long s3c_irqwake_eintallow;
-#else
-#define s3c_irqwake_eintallow 0
-#endif
-
 /* per-cpu sleep functions */
 
 extern void (*pm_cpu_prep)(void);
index 11fbbc2..3776f7e 100644 (file)
@@ -152,6 +152,11 @@ static int __init s3c_arch_init(void)
 {
        int ret;
 
+       /* init is only needed for ATAGS based platforms */
+       if (!IS_ENABLED(CONFIG_ATAGS) ||
+           (!soc_is_s3c24xx() && !soc_is_s3c64xx()))
+               return 0;
+
        // do the correct init for cpu
 
        if (cpu == NULL) {
index 82777c6..d7803b4 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/suspend.h>
 
-#ifdef CONFIG_SAMSUNG_ATAGS
 #include <mach/map.h>
-#ifndef CONFIG_ARCH_EXYNOS
 #include <mach/regs-clock.h>
 #include <mach/regs-irq.h>
-#endif
 #include <mach/irqs.h>
-#endif
 
 #include <asm/irq.h>
 
index 6be3fa2..8cc6228 100644 (file)
@@ -64,7 +64,6 @@ config ARM64
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_API_DEBUG
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_CONTIGUOUS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
index 4043c35..21074f6 100644 (file)
@@ -9,6 +9,7 @@ config ARCH_BERLIN
        bool "Marvell Berlin SoC Family"
        select ARCH_REQUIRE_GPIOLIB
        select DW_APB_ICTL
+       select PINCTRL
        help
          This enables support for Marvell Berlin SoC Family
 
@@ -43,6 +44,7 @@ config ARCH_MEDIATEK
        bool "Mediatek MT65xx & MT81xx ARMv8 SoC"
        select ARM_GIC
        select PINCTRL
+       select MTK_TIMER
        help
          Support for Mediatek MT65xx & MT81xx ARMv8 SoCs
 
@@ -67,6 +69,23 @@ config ARCH_SEATTLE
        help
          This enables support for AMD Seattle SOC Family
 
+config ARCH_SHMOBILE
+       bool
+
+config ARCH_RENESAS
+       bool "Renesas SoC Platforms"
+       select ARCH_SHMOBILE
+       select PINCTRL
+       select PM_GENERIC_DOMAINS if PM
+       help
+         This enables support for the ARMv8 based Renesas SoCs.
+
+config ARCH_R8A7795
+       bool "Renesas R-Car H3 SoC Platform"
+       depends on ARCH_RENESAS
+       help
+         This enables support for the Renesas R-Car H3 SoC.
+
 config ARCH_STRATIX10
        bool "Altera's Stratix 10 SoCFPGA Family"
        help
@@ -86,18 +105,6 @@ config ARCH_TEGRA
        help
          This enables support for the NVIDIA Tegra SoC family.
 
-config ARCH_TEGRA_132_SOC
-       bool "NVIDIA Tegra132 SoC"
-       depends on ARCH_TEGRA
-       select PINCTRL_TEGRA124
-       select USB_ULPI if USB_PHY
-       select USB_ULPI_VIEWPORT if USB_PHY
-       help
-         Enable support for NVIDIA Tegra132 SoC, based on the Denver
-         ARMv8 CPU.  The Tegra132 SoC is similar to the Tegra124 SoC,
-         but contains an NVIDIA Denver CPU complex in place of
-         Tegra124's "4+1" Cortex-A15 CPU complex.
-
 config ARCH_SPRD
        bool "Spreadtrum SoC platform"
        help
@@ -108,6 +115,12 @@ config ARCH_THUNDER
        help
          This enables support for Cavium's Thunder Family of SoCs.
 
+config ARCH_UNIPHIER
+       bool "Socionext UniPhier SoC Family"
+       select PINCTRL
+       help
+         This enables support for Socionext UniPhier SoC family.
+
 config ARCH_VEXPRESS
        bool "ARMv8 software model (Versatile Express)"
        select ARCH_REQUIRE_GPIOLIB
index eb3c42d..f832b8a 100644 (file)
@@ -9,8 +9,11 @@ dts-dirs += freescale
 dts-dirs += hisilicon
 dts-dirs += marvell
 dts-dirs += mediatek
+dts-dirs += nvidia
 dts-dirs += qcom
+dts-dirs += renesas
 dts-dirs += rockchip
+dts-dirs += socionext
 dts-dirs += sprd
 dts-dirs += xilinx
 
index 119a469..e5ba8d5 100644 (file)
 &xgenet1 {
        status = "ok";
 };
+
+&mmc0 {
+       status = "ok";
+};
+
+&i2c4 {
+       rtc68: rtc@68 {
+               compatible = "dallas,ds1337";
+               reg = <0x68>;
+               status = "ok";
+       };
+};
index 01cdeda..178aef2 100644 (file)
@@ -74,3 +74,7 @@
 &xgenet {
        status = "ok";
 };
+
+&mmc0 {
+       status = "ok";
+};
index c804f8f..5d87a3d 100644 (file)
@@ -25,6 +25,7 @@
                        reg = <0x0 0x000>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_0>;
                };
                cpu@001 {
                        device_type = "cpu";
@@ -32,6 +33,7 @@
                        reg = <0x0 0x001>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_0>;
                };
                cpu@100 {
                        device_type = "cpu";
@@ -39,6 +41,7 @@
                        reg = <0x0 0x100>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_1>;
                };
                cpu@101 {
                        device_type = "cpu";
@@ -46,6 +49,7 @@
                        reg = <0x0 0x101>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_1>;
                };
                cpu@200 {
                        device_type = "cpu";
@@ -53,6 +57,7 @@
                        reg = <0x0 0x200>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_2>;
                };
                cpu@201 {
                        device_type = "cpu";
@@ -60,6 +65,7 @@
                        reg = <0x0 0x201>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_2>;
                };
                cpu@300 {
                        device_type = "cpu";
@@ -67,6 +73,7 @@
                        reg = <0x0 0x300>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_3>;
                };
                cpu@301 {
                        device_type = "cpu";
                        reg = <0x0 0x301>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_3>;
+               };
+               xgene_L2_0: l2-cache-0 {
+                       compatible = "cache";
+               };
+               xgene_L2_1: l2-cache-1 {
+                       compatible = "cache";
+               };
+               xgene_L2_2: l2-cache-2 {
+                       compatible = "cache";
+               };
+               xgene_L2_3: l2-cache-3 {
+                       compatible = "cache";
                };
        };
 
                      <0x0 0x780A0000 0x0 0x20000>,     /* GIC CPU */
                      <0x0 0x780C0000 0x0 0x10000>,     /* GIC VCPU Control */
                      <0x0 0x780E0000 0x0 0x20000>;     /* GIC VCPU */
+               v2m0: v2m@0x00000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x0 0x0 0x1000>;
+               };
+               v2m1: v2m@0x10000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x10000 0x0 0x1000>;
+               };
+               v2m2: v2m@0x20000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x20000 0x0 0x1000>;
+               };
+               v2m3: v2m@0x30000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x30000 0x0 0x1000>;
+               };
+               v2m4: v2m@0x40000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x40000 0x0 0x1000>;
+               };
+               v2m5: v2m@0x50000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x50000 0x0 0x1000>;
+               };
+               v2m6: v2m@0x60000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x60000 0x0 0x1000>;
+               };
+               v2m7: v2m@0x70000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x70000 0x0 0x1000>;
+               };
+               v2m8: v2m@0x80000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x80000 0x0 0x1000>;
+               };
+               v2m9: v2m@0x90000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0x90000 0x0 0x1000>;
+               };
+               v2m10: v2m@0xA0000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0xA0000 0x0 0x1000>;
+               };
+               v2m11: v2m@0xB0000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0xB0000 0x0 0x1000>;
+               };
+               v2m12: v2m@0xC0000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0xC0000 0x0 0x1000>;
+               };
+               v2m13: v2m@0xD0000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0xD0000 0x0 0x1000>;
+               };
+               v2m14: v2m@0xE0000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0xE0000 0x0 0x1000>;
+               };
+               v2m15: v2m@0xF0000 {
+                       compatible = "arm,gic-v2m-frame";
+                       msi-controller;
+                       reg = <0x0 0xF0000 0x0 0x1000>;
+               };
        };
 
        pmu {
                                clock-output-names = "socplldiv2";
                        };
 
+                       ahbclk: ahbclk@17000000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&socplldiv2 0>;
+                               reg = <0x0 0x17000000 0x0 0x2000>;
+                               reg-names = "div-reg";
+                               divider-offset = <0x164>;
+                               divider-width = <0x5>;
+                               divider-shift = <0x0>;
+                               clock-output-names = "ahbclk";
+                       };
+
+                       sbapbclk: sbapbclk@1704c000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&ahbclk 0>;
+                               reg = <0x0 0x1704c000 0x0 0x2000>;
+                               reg-names = "div-reg";
+                               divider-offset = <0x10>;
+                               divider-width = <0x2>;
+                               divider-shift = <0x0>;
+                               clock-output-names = "sbapbclk";
+                       };
+
+                       sdioclk: sdioclk@1f2ac000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&socplldiv2 0>;
+                               reg = <0x0 0x1f2ac000 0x0 0x1000
+                                       0x0 0x17000000 0x0 0x2000>;
+                               reg-names = "csr-reg", "div-reg";
+                               csr-offset = <0x0>;
+                               csr-mask = <0x2>;
+                               enable-offset = <0x8>;
+                               enable-mask = <0x2>;
+                               divider-offset = <0x178>;
+                               divider-width = <0x8>;
+                               divider-shift = <0x0>;
+                               clock-output-names = "sdioclk";
+                       };
+
                        pcie0clk: pcie0clk@1f2bc000 {
                                compatible = "apm,xgene-device-clock";
                                #clock-cells = <1>;
                                clock-output-names = "pcie0clk";
                        };
 
+                       pcie1clk: pcie1clk@1f2cc000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&socplldiv2 0>;
+                               reg = <0x0 0x1f2cc000 0x0 0x1000>;
+                               reg-names = "csr-reg";
+                               clock-output-names = "pcie1clk";
+                       };
+
                        xge0clk: xge0clk@1f61c000 {
                                compatible = "apm,xgene-device-clock";
                                #clock-cells = <1>;
                                csr-mask = <0x3>;
                                clock-output-names = "xge1clk";
                        };
+
+                       rngpkaclk: rngpkaclk@17000000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&socplldiv2 0>;
+                               reg = <0x0 0x17000000 0x0 0x2000>;
+                               reg-names = "csr-reg";
+                               csr-offset = <0xc>;
+                               csr-mask = <0x10>;
+                               enable-offset = <0x10>;
+                               enable-mask = <0x10>;
+                               clock-output-names = "rngpkaclk";
+                       };
+
+                       i2c4clk: i2c4clk@1704c000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&sbapbclk 0>;
+                               reg = <0x0 0x1704c000 0x0 0x1000>;
+                               reg-names = "csr-reg";
+                               csr-offset = <0x0>;
+                               csr-mask = <0x40>;
+                               enable-offset = <0x8>;
+                               enable-mask = <0x40>;
+                               clock-output-names = "i2c4clk";
+                       };
                };
 
                scu: system-clk-controller@17000000 {
                        mask = <0x1>;
                };
 
+               csw: csw@7e200000 {
+                       compatible = "apm,xgene-csw", "syscon";
+                       reg = <0x0 0x7e200000 0x0 0x1000>;
+               };
+
+               mcba: mcba@7e700000 {
+                       compatible = "apm,xgene-mcb", "syscon";
+                       reg = <0x0 0x7e700000 0x0 0x1000>;
+               };
+
+               mcbb: mcbb@7e720000 {
+                       compatible = "apm,xgene-mcb", "syscon";
+                       reg = <0x0 0x7e720000 0x0 0x1000>;
+               };
+
+               efuse: efuse@1054a000 {
+                       compatible = "apm,xgene-efuse", "syscon";
+                       reg = <0x0 0x1054a000 0x0 0x20>;
+               };
+
+               edac@78800000 {
+                       compatible = "apm,xgene-edac";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       regmap-csw = <&csw>;
+                       regmap-mcba = <&mcba>;
+                       regmap-mcbb = <&mcbb>;
+                       regmap-efuse = <&efuse>;
+                       reg = <0x0 0x78800000 0x0 0x100>;
+                       interrupts = <0x0 0x20 0x4>,
+                                    <0x0 0x21 0x4>,
+                                    <0x0 0x27 0x4>;
+
+                       edacmc@7e800000 {
+                               compatible = "apm,xgene-edac-mc";
+                               reg = <0x0 0x7e800000 0x0 0x1000>;
+                               memory-controller = <0>;
+                       };
+
+                       edacmc@7e840000 {
+                               compatible = "apm,xgene-edac-mc";
+                               reg = <0x0 0x7e840000 0x0 0x1000>;
+                               memory-controller = <1>;
+                       };
+
+                       edacmc@7e880000 {
+                               compatible = "apm,xgene-edac-mc";
+                               reg = <0x0 0x7e880000 0x0 0x1000>;
+                               memory-controller = <2>;
+                       };
+
+                       edacmc@7e8c0000 {
+                               compatible = "apm,xgene-edac-mc";
+                               reg = <0x0 0x7e8c0000 0x0 0x1000>;
+                               memory-controller = <3>;
+                       };
+
+                       edacpmd@7c000000 {
+                               compatible = "apm,xgene-edac-pmd";
+                               reg = <0x0 0x7c000000 0x0 0x200000>;
+                               pmd-controller = <0>;
+                       };
+
+                       edacpmd@7c200000 {
+                               compatible = "apm,xgene-edac-pmd";
+                               reg = <0x0 0x7c200000 0x0 0x200000>;
+                               pmd-controller = <1>;
+                       };
+
+                       edacpmd@7c400000 {
+                               compatible = "apm,xgene-edac-pmd";
+                               reg = <0x0 0x7c400000 0x0 0x200000>;
+                               pmd-controller = <2>;
+                       };
+
+                       edacpmd@7c600000 {
+                               compatible = "apm,xgene-edac-pmd";
+                               reg = <0x0 0x7c600000 0x0 0x200000>;
+                               pmd-controller = <3>;
+                       };
+
+                       edacl3@7e600000 {
+                               compatible = "apm,xgene-edac-l3-v2";
+                               reg = <0x0 0x7e600000 0x0 0x1000>;
+                       };
+
+                       edacsoc@7e930000 {
+                               compatible = "apm,xgene-edac-soc";
+                               reg = <0x0 0x7e930000 0x0 0x1000>;
+                       };
+               };
+
                serial0: serial@10600000 {
                        device_type = "serial";
                        compatible = "ns16550";
                        interrupts = <0x0 0x4c 0x4>;
                };
 
+               /* Do not change dwusb name, coded for backward compatibility */
+               usb0: dwusb@19000000 {
+                       status = "disabled";
+                       compatible = "snps,dwc3";
+                       reg =  <0x0 0x19000000 0x0 0x100000>;
+                       interrupts = <0x0 0x5d 0x4>;
+                       dma-coherent;
+                       dr_mode = "host";
+               };
+
+               pcie0: pcie@1f2b0000 {
+                       status = "disabled";
+                       device_type = "pci";
+                       compatible = "apm,xgene-pcie", "apm,xgene2-pcie";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = < 0x00 0x1f2b0000 0x0 0x00010000   /* Controller registers */
+                               0xc0 0xd0000000 0x0 0x00040000>; /* PCI config space */
+                       reg-names = "csr", "cfg";
+                       ranges = <0x01000000 0x00 0x00000000 0xc0 0x10000000 0x00 0x00010000   /* io */
+                                 0x02000000 0x00 0x20000000 0xc1 0x20000000 0x00 0x20000000   /* mem */
+                                 0x43000000 0xe0 0x00000000 0xe0 0x00000000 0x20 0x00000000>; /* mem */
+                       dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
+                                     0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x10 0x1
+                                        0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x11 0x1
+                                        0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x12 0x1
+                                        0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x13 0x1>;
+                       dma-coherent;
+                       clocks = <&pcie0clk 0>;
+                       msi-parent = <&v2m0>;
+               };
+
+               pcie1: pcie@1f2c0000 {
+                       status = "disabled";
+                       device_type = "pci";
+                       compatible = "apm,xgene-pcie", "apm,xgene2-pcie";
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = < 0x00 0x1f2c0000 0x0 0x00010000   /* Controller registers */
+                               0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */
+                       reg-names = "csr", "cfg";
+                       ranges = <0x01000000 0x00 0x00000000 0xa0 0x10000000 0x00 0x00010000   /* io */
+                                 0x02000000 0x00 0x20000000 0xa1 0x20000000 0x00 0x20000000   /* mem */
+                                 0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */
+                       dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
+                                     0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x16 0x1
+                                        0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x17 0x1
+                                        0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x18 0x1
+                                        0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x19 0x1>;
+                       dma-coherent;
+                       clocks = <&pcie1clk 0>;
+                       msi-parent = <&v2m0>;
+               };
+
                sata1: sata@1a000000 {
                        compatible = "apm,xgene-ahci";
                        reg = <0x0 0x1a000000 0x0 0x1000>,
                        dma-coherent;
                };
 
-               sbgpio: sbgpio@17001000{
+               mmc0: mmc@1c000000 {
+                       compatible = "arasan,sdhci-4.9a";
+                       reg = <0x0 0x1c000000 0x0 0x100>;
+                       interrupts = <0x0 0x49 0x4>;
+                       dma-coherent;
+                       no-1-8-v;
+                       clock-names = "clk_xin", "clk_ahb";
+                       clocks = <&sdioclk 0>, <&ahbclk 0>;
+               };
+
+               gfcgpio: gpio@1f63c000 {
+                       compatible = "apm,xgene-gpio";
+                       reg = <0x0 0x1f63c000 0x0 0x40>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               dwgpio: gpio@1c024000 {
+                       compatible = "snps,dw-apb-gpio";
+                       reg = <0x0 0x1c024000 0x0 0x1000>;
+                       reg-io-width = <4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       porta: gpio-controller@0 {
+                               compatible = "snps,dw-apb-gpio-port";
+                               gpio-controller;
+                               snps,nr-gpios = <32>;
+                               reg = <0>;
+                       };
+               };
+
+               sbgpio: gpio@17001000{
                        compatible = "apm,xgene-gpio-sb";
                        reg = <0x0 0x17001000 0x0 0x400>;
                        #gpio-cells = <2>;
                        local-mac-address = [00 01 73 00 00 02];
                        phy-connection-type = "xgmii";
                };
+
+               rng: rng@10520000 {
+                       compatible = "apm,xgene-rng";
+                       reg = <0x0 0x10520000 0x0 0x100>;
+                       interrupts = <0x0 0x41 0x4>;
+                       clocks = <&rngpkaclk 0>;
+               };
+
+               i2c1: i2c@10511000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "snps,designware-i2c";
+                       reg = <0x0 0x10511000 0x0 0x1000>;
+                       interrupts = <0 0x45 0x4>;
+                       #clock-cells = <1>;
+                       clocks = <&sbapbclk 0>;
+                       bus_num = <1>;
+               };
+
+               i2c4: i2c@10640000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "snps,designware-i2c";
+                       reg = <0x0 0x10640000 0x0 0x1000>;
+                       interrupts = <0 0x3A 0x4>;
+                       clocks = <&i2c4clk 0>;
+                       bus_num = <4>;
+               };
        };
 };
index 6c5ed11..fe30f76 100644 (file)
@@ -25,6 +25,7 @@
                        reg = <0x0 0x000>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_0>;
                };
                cpu@001 {
                        device_type = "cpu";
@@ -32,6 +33,7 @@
                        reg = <0x0 0x001>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_0>;
                };
                cpu@100 {
                        device_type = "cpu";
@@ -39,6 +41,7 @@
                        reg = <0x0 0x100>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_1>;
                };
                cpu@101 {
                        device_type = "cpu";
@@ -46,6 +49,7 @@
                        reg = <0x0 0x101>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_1>;
                };
                cpu@200 {
                        device_type = "cpu";
@@ -53,6 +57,7 @@
                        reg = <0x0 0x200>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_2>;
                };
                cpu@201 {
                        device_type = "cpu";
@@ -60,6 +65,7 @@
                        reg = <0x0 0x201>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_2>;
                };
                cpu@300 {
                        device_type = "cpu";
@@ -67,6 +73,7 @@
                        reg = <0x0 0x300>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_3>;
                };
                cpu@301 {
                        device_type = "cpu";
                        reg = <0x0 0x301>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0x1 0x0000fff8>;
+                       next-level-cache = <&xgene_L2_3>;
+               };
+               xgene_L2_0: l2-cache-0 {
+                       compatible = "cache";
+               };
+               xgene_L2_1: l2-cache-1 {
+                       compatible = "cache";
+               };
+               xgene_L2_2: l2-cache-2 {
+                       compatible = "cache";
+               };
+               xgene_L2_3: l2-cache-3 {
+                       compatible = "cache";
                };
        };
 
                                clock-output-names = "socplldiv2";
                        };
 
+                       ahbclk: ahbclk@17000000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&socplldiv2 0>;
+                               reg = <0x0 0x17000000 0x0 0x2000>;
+                               reg-names = "div-reg";
+                               divider-offset = <0x164>;
+                               divider-width = <0x5>;
+                               divider-shift = <0x0>;
+                               clock-output-names = "ahbclk";
+                       };
+
+                       sdioclk: sdioclk@1f2ac000 {
+                               compatible = "apm,xgene-device-clock";
+                               #clock-cells = <1>;
+                               clocks = <&socplldiv2 0>;
+                               reg = <0x0 0x1f2ac000 0x0 0x1000
+                                       0x0 0x17000000 0x0 0x2000>;
+                               reg-names = "csr-reg", "div-reg";
+                               csr-offset = <0x0>;
+                               csr-mask = <0x2>;
+                               enable-offset = <0x8>;
+                               enable-mask = <0x2>;
+                               divider-offset = <0x178>;
+                               divider-width = <0x8>;
+                               divider-shift = <0x0>;
+                               clock-output-names = "sdioclk";
+                       };
+
                        qmlclk: qmlclk {
                                compatible = "apm,xgene-device-clock";
                                #clock-cells = <1>;
                        interrupts = <0x0 0x4f 0x4>;
                };
 
+               mmc0: mmc@1c000000 {
+                       compatible = "arasan,sdhci-4.9a";
+                       reg = <0x0 0x1c000000 0x0 0x100>;
+                       interrupts = <0x0 0x49 0x4>;
+                       dma-coherent;
+                       no-1-8-v;
+                       clock-names = "clk_xin", "clk_ahb";
+                       clocks = <&sdioclk 0>, <&ahbclk 0>;
+               };
+
+               gfcgpio: gpio0@1701c000 {
+                       compatible = "apm,xgene-gpio";
+                       reg = <0x0 0x1701c000 0x0 0x40>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               dwgpio: gpio@1c024000 {
+                       compatible = "snps,dw-apb-gpio";
+                       reg = <0x0 0x1c024000 0x0 0x1000>;
+                       reg-io-width = <4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       porta: gpio-controller@0 {
+                               compatible = "snps,dw-apb-gpio-port";
+                               gpio-controller;
+                               snps,nr-gpios = <32>;
+                               reg = <0>;
+                       };
+               };
+
+               i2c0: i2c@10512000 {
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "snps,designware-i2c";
+                       reg = <0x0 0x10512000 0x0 0x1000>;
+                       interrupts = <0 0x44 0x4>;
+                       #clock-cells = <1>;
+                       clocks = <&ahbclk 0>;
+                       bus_num = <0>;
+               };
+
                phy1: phy@1f21a000 {
                        compatible = "apm,xgene-phy";
                        reg = <0x0 0x1f21a000 0x0 0x100>;
                        phy-names = "sata-phy";
                };
 
-               sbgpio: sbgpio@17001000{
+               /* Do not change dwusb name, coded for backward compatibility */
+               usb0: dwusb@19000000 {
+                       status = "disabled";
+                       compatible = "snps,dwc3";
+                       reg =  <0x0 0x19000000 0x0 0x100000>;
+                       interrupts = <0x0 0x89 0x4>;
+                       dma-coherent;
+                       dr_mode = "host";
+               };
+
+               usb1: dwusb@19800000 {
+                       status = "disabled";
+                       compatible = "snps,dwc3";
+                       reg =  <0x0 0x19800000 0x0 0x100000>;
+                       interrupts = <0x0 0x8a 0x4>;
+                       dma-coherent;
+                       dr_mode = "host";
+               };
+
+               sbgpio: gpio@17001000{
                        compatible = "apm,xgene-gpio-sb";
                        reg = <0x0 0x17001000 0x0 0x400>;
                        #gpio-cells = <2>;
index 93bc3d7..8826f83 100644 (file)
                        };
                };
 
+               idle-states {
+                       entry-method = "arm,psci";
+
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <300>;
+                               exit-latency-us = <1200>;
+                               min-residency-us = <2000>;
+                       };
+
+                       CLUSTER_SLEEP_0: cluster-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x1010000>;
+                               local-timer-stop;
+                               entry-latency-us = <300>;
+                               exit-latency-us = <1200>;
+                               min-residency-us = <2500>;
+                       };
+               };
+
                A57_0: cpu@0 {
                        compatible = "arm,cortex-a57","arm,armv8";
                        reg = <0x0 0x0>;
@@ -67,6 +89,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A57_L2>;
                        clocks = <&scpi_dvfs 0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A57_1: cpu@1 {
@@ -76,6 +99,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A57_L2>;
                        clocks = <&scpi_dvfs 0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_0: cpu@100 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_1: cpu@101 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_2: cpu@102 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_3: cpu@103 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A57_L2: l2-cache0 {
index 53442b5..dcfcf15 100644 (file)
                        };
                };
 
+               idle-states {
+                       entry-method = "arm,psci";
+
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <300>;
+                               exit-latency-us = <1200>;
+                               min-residency-us = <2000>;
+                       };
+
+                       CLUSTER_SLEEP_0: cluster-sleep-0 {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x1010000>;
+                               local-timer-stop;
+                               entry-latency-us = <300>;
+                               exit-latency-us = <1200>;
+                               min-residency-us = <2500>;
+                       };
+               };
+
                A57_0: cpu@0 {
                        compatible = "arm,cortex-a57","arm,armv8";
                        reg = <0x0 0x0>;
@@ -67,6 +89,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A57_L2>;
                        clocks = <&scpi_dvfs 0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A57_1: cpu@1 {
@@ -76,6 +99,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A57_L2>;
                        clocks = <&scpi_dvfs 0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_0: cpu@100 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_1: cpu@101 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_2: cpu@102 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A53_3: cpu@103 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        clocks = <&scpi_dvfs 1>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                };
 
                A57_L2: l2-cache0 {
index 244baf8..6bb3d4d 100644 (file)
                device_type = "memory";
                reg = <0x000000000 0x80000000 0x00000000 0x40000000>;
        };
+};
+
+&i2c0 {
+       status = "ok";
+};
+
+&i2c1 {
+       status = "ok";
+};
+
+&uart3 {
+       status = "ok";
+};
 
-       soc: soc {
-               uart3: serial@66130000 {
-                       status = "ok";
-               };
+&nand {
+       nandcs@0 {
+               compatible = "brcm,nandcs";
+               reg = <0>;
+               nand-ecc-mode = "hw";
+               nand-ecc-strength = <8>;
+               nand-ecc-step-size = <512>;
+               #address-cells = <1>;
+               #size-cells = <1>;
        };
 };
index 3c92d92..a510d3a 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/bcm-ns2.h>
 
 /memreserve/ 0x84b00000 0x00000008;
 
                #address-cells = <2>;
                #size-cells = <0>;
 
-               cpu@0 {
+               A57_0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a57", "arm,armv8";
                        reg = <0 0>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0 0x84b00000>;
+                       next-level-cache = <&CLUSTER0_L2>;
                };
 
-               cpu@1 {
+               A57_1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a57", "arm,armv8";
                        reg = <0 1>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0 0x84b00000>;
+                       next-level-cache = <&CLUSTER0_L2>;
                };
 
-               cpu@2 {
+               A57_2: cpu@2 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a57", "arm,armv8";
                        reg = <0 2>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0 0x84b00000>;
+                       next-level-cache = <&CLUSTER0_L2>;
                };
 
-               cpu@3 {
+               A57_3: cpu@3 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a57", "arm,armv8";
                        reg = <0 3>;
                        enable-method = "spin-table";
                        cpu-release-addr = <0 0x84b00000>;
+                       next-level-cache = <&CLUSTER0_L2>;
+               };
+
+               CLUSTER0_L2: l2-cache@000 {
+                       compatible = "cache";
                };
        };
 
                              IRQ_TYPE_EDGE_RISING)>;
        };
 
+       pmu {
+               compatible = "arm,armv8-pmuv3";
+               interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&A57_0>,
+                                    <&A57_1>,
+                                    <&A57_2>,
+                                    <&A57_3>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               osc: oscillator {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+               };
+
+               iprocmed: iprocmed {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&genpll_scr BCM_NS2_GENPLL_SCR_SCR_CLK>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+               };
+
+               iprocslow: iprocslow {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clocks = <&genpll_scr BCM_NS2_GENPLL_SCR_SCR_CLK>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+               };
+       };
+
        soc: soc {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
                ranges = <0 0 0 0xffffffff>;
 
+               smmu: mmu@64000000 {
+                       compatible = "arm,mmu-500";
+                       reg = <0x64000000 0x40000>;
+                       #global-interrupts = <2>;
+                       interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+                       mmu-masters;
+               };
+
+               lcpll_ddr: lcpll_ddr@6501d058 {
+                       #clock-cells = <1>;
+                       compatible = "brcm,ns2-lcpll-ddr";
+                       reg = <0x6501d058 0x20>,
+                             <0x6501c020 0x4>,
+                             <0x6501d04c 0x4>;
+                       clocks = <&osc>;
+                       clock-output-names = "lcpll_ddr", "pcie_sata_usb",
+                                            "ddr", "ddr_ch2_unused",
+                                            "ddr_ch3_unused", "ddr_ch4_unused",
+                                            "ddr_ch5_unused";
+               };
+
+               lcpll_ports: lcpll_ports@6501d078 {
+                       #clock-cells = <1>;
+                       compatible = "brcm,ns2-lcpll-ports";
+                       reg = <0x6501d078 0x20>,
+                             <0x6501c020 0x4>,
+                             <0x6501d054 0x4>;
+                       clocks = <&osc>;
+                       clock-output-names = "lcpll_ports", "wan", "rgmii",
+                                            "ports_ch2_unused",
+                                            "ports_ch3_unused",
+                                            "ports_ch4_unused",
+                                            "ports_ch5_unused";
+               };
+
+               genpll_scr: genpll_scr@6501d098 {
+                       #clock-cells = <1>;
+                       compatible = "brcm,ns2-genpll-scr";
+                       reg = <0x6501d098 0x32>,
+                             <0x6501c020 0x4>,
+                             <0x6501d044 0x4>;
+                       clocks = <&osc>;
+                       clock-output-names = "genpll_scr", "scr", "fs",
+                                            "audio_ref", "scr_ch3_unused",
+                                            "scr_ch4_unused", "scr_ch5_unused";
+               };
+
+               genpll_sw: genpll_sw@6501d0c4 {
+                       #clock-cells = <1>;
+                       compatible = "brcm,ns2-genpll-sw";
+                       reg = <0x6501d0c4 0x32>,
+                             <0x6501c020 0x4>,
+                             <0x6501d044 0x4>;
+                       clocks = <&osc>;
+                       clock-output-names = "genpll_sw", "rpe", "250", "nic",
+                                            "chimp", "port", "sdio";
+               };
+
+               crmu: crmu@65024000 {
+                       compatible = "syscon";
+                       reg = <0x65024000 0x100>;
+               };
+
+               reboot@65024000 {
+                       compatible ="syscon-reboot";
+                       regmap = <&crmu>;
+                       offset = <0x90>;
+                       mask = <0xfffffffd>;
+               };
+
                gic: interrupt-controller@65210000 {
                        compatible = "arm,gic-400";
                        #interrupt-cells = <3>;
                              <0x65260000 0x1000>;
                };
 
+               i2c0: i2c@66080000 {
+                       compatible = "brcm,iproc-i2c";
+                       reg = <0x66080000 0x100>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <GIC_SPI 394 IRQ_TYPE_NONE>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@660b0000 {
+                       compatible = "brcm,iproc-i2c";
+                       reg = <0x660b0000 0x100>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <GIC_SPI 395 IRQ_TYPE_NONE>;
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
+
                uart3: serial@66130000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x66130000 0x100>;
                        interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
-                       clock-frequency = <23961600>;
+                       clocks = <&osc>;
                        status = "disabled";
                };
+
+               hwrng: hwrng@66220000 {
+                       compatible = "brcm,iproc-rng200";
+                       reg = <0x66220000 0x28>;
+               };
+
+               nand: nand@66460000 {
+                       compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1";
+                       reg = <0x66460000 0x600>,
+                             <0x67015408 0x600>,
+                             <0x66460f00 0x20>;
+                       reg-names = "nand", "iproc-idm", "iproc-ext";
+                       interrupts = <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>;
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       brcm,nand-has-wp;
+               };
        };
 };
index 5424cc4..d8767b0 100644 (file)
@@ -11,6 +11,7 @@
 
 /dts-v1/;
 #include "exynos7.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "Samsung Exynos7 Espresso board based on EXYNOS7";
        status = "okay";
 };
 
+&hsi2c_4 {
+       samsung,i2c-sda-delay = <100>;
+       samsung,i2c-max-bus-freq = <200000>;
+       status = "okay";
+
+       s2mps15_pmic@66 {
+               compatible = "samsung,s2mps15-pmic";
+               reg = <0x66>;
+               interrupts = <2 IRQ_TYPE_NONE>;
+               interrupt-parent = <&gpa0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_irq>;
+               wakeup-source;
+
+               s2mps15_osc: clocks {
+                       compatible = "samsung,s2mps13-clk";
+                       #clock-cells = <1>;
+                       clock-output-names = "s2mps13_ap", "s2mps13_cp",
+                               "s2mps13_bt";
+               };
+
+               regulators {
+                       ldo1_reg: LDO1 {
+                               regulator-name = "vdd_ldo1";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-always-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo2_reg: LDO2 {
+                               regulator-name = "vqmmc-sdcard";
+                               regulator-min-microvolt = <1620000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo3_reg: LDO3 {
+                               regulator-name = "vdd_ldo3";
+                               regulator-min-microvolt = <1620000>;
+                               regulator-max-microvolt = <1980000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo4_reg: LDO4 {
+                               regulator-name = "vdd_ldo4";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1110000>;
+                               regulator-always-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo5_reg: LDO5 {
+                               regulator-name = "vdd_ldo5";
+                               regulator-min-microvolt = <1620000>;
+                               regulator-max-microvolt = <1980000>;
+                               regulator-always-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo6_reg: LDO6 {
+                               regulator-name = "vdd_ldo6";
+                               regulator-min-microvolt = <2250000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo7_reg: LDO7 {
+                               regulator-name = "vdd_ldo7";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1150000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo8_reg: LDO8 {
+                               regulator-name = "vdd_ldo8";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo9_reg: LDO9 {
+                               regulator-name = "vdd_ldo9";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo10_reg: LDO10 {
+                               regulator-name = "vdd_ldo10";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo11_reg: LDO11 {
+                               regulator-name = "vdd_ldo11";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-always-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo12_reg: LDO12 {
+                               regulator-name = "vdd_ldo12";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo13_reg: LDO13 {
+                               regulator-name = "vdd_ldo13";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-always-on;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo14_reg: LDO14 {
+                               regulator-name = "vdd_ldo14";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3375000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo17_reg: LDO17 {
+                               regulator-name = "vmmc-sdcard";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3375000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo18_reg: LDO18 {
+                               regulator-name = "vdd_ldo18";
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <2275000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo19_reg: LDO19 {
+                               regulator-name = "vdd_ldo19";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3375000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo21_reg: LDO21 {
+                               regulator-name = "vdd_ldo21";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3375000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo23_reg: LDO23 {
+                               regulator-name = "vdd_ldo23";
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <2275000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo25_reg: LDO25 {
+                               regulator-name = "vdd_ldo25";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3375000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo26_reg: LDO26 {
+                               regulator-name = "vdd_ldo26";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1470000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       ldo27_reg: LDO27 {
+                               regulator-name = "vdd_ldo27";
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <2275000>;
+                               regulator-enable-ramp-delay = <125>;
+                       };
+
+                       buck1_reg: BUCK1 {
+                               regulator-name = "vdd_mif";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <25000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck2_reg: BUCK2 {
+                               regulator-name = "vdd_atlas";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck4_reg: BUCK4 {
+                               regulator-name = "vdd_int";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck5_reg: BUCK5 {
+                               regulator-name = "vdd_buck5";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-ramp-delay = <25000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck6_reg: BUCK6 {
+                               regulator-name = "vdd_g3d";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1400000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck7_reg: BUCK7 {
+                               regulator-name = "vdd_buck7";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-ramp-delay = <25000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck8_reg: BUCK8 {
+                               regulator-name = "vdd_buck8";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-ramp-delay = <25000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck9_reg: BUCK9 {
+                               regulator-name = "vdd_buck9";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <2100000>;
+                               regulator-always-on;
+                               regulator-ramp-delay = <25000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       buck10_reg: BUCK10 {
+                               regulator-name = "vdd_buck10";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-ramp-delay = <25000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+               };
+       };
+};
+
+&pinctrl_alive {
+       pmic_irq: pmic-irq {
+               samsung,pins = "gpa0-2";
+               samsung,pin-pud = <3>;
+               samsung,pin-drv = <3>;
+       };
+};
+
 &mmc_0 {
        status = "okay";
        num-slots = <1>;
-       broken-cd;
        cap-mmc-highspeed;
+       mmc-hs200-1_8v;
        non-removable;
        card-detect-delay = <200>;
        clock-frequency = <800000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
        bus-width = <4>;
+       vmmc-supply = <&ldo17_reg>;
+       vqmmc-supply = <&ldo2_reg>;
        disable-wp;
 };
index f9c5a54..93108f1 100644 (file)
                        reg = <0x105c0000 0x5000>;
                };
 
+               reboot: syscon-reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&pmu_system_controller>;
+                       offset = <0x0400>;
+                       mask = <0x1>;
+               };
+
                rtc: rtc@10590000 {
                        compatible = "samsung,s3c6410-rtc";
                        reg = <0x10590000 0x100>;
index c4957a4..f3c2516 100644 (file)
@@ -1,6 +1,7 @@
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
  
 always         := $(dtb-y)
 subdir-y       := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
new file mode 100644 (file)
index 0000000..ce23557
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1043A family SoC.
+ *
+ * Copyright 2014-2015, Freescale Semiconductor
+ *
+ * Mingkai Hu <Mingkai.hu@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; 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 library 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+/include/ "fsl-ls1043a.dtsi"
+
+/ {
+       model = "LS1043A RDB Board";
+};
+
+&i2c0 {
+       status = "okay";
+       ina220@40 {
+               compatible = "ti,ina220";
+               reg = <0x40>;
+               shunt-resistor = <1000>;
+       };
+       adt7461a@4c {
+               compatible = "adi,adt7461";
+               reg = <0x4c>;
+       };
+       eeprom@52 {
+               compatible = "at24,24c512";
+               reg = <0x52>;
+       };
+       eeprom@53 {
+               compatible = "at24,24c512";
+               reg = <0x53>;
+       };
+       rtc@68 {
+               compatible = "pericom,pt7c4338";
+               reg = <0x68>;
+       };
+};
+
+&ifc {
+       status = "okay";
+       #address-cells = <2>;
+       #size-cells = <1>;
+       /* NOR, NAND Flashes and FPGA on board */
+       ranges = <0x0 0x0 0x0 0x60000000 0x08000000
+                 0x1 0x0 0x0 0x7e800000 0x00010000
+                 0x2 0x0 0x0 0x7fb00000 0x00000100>;
+
+               nor@0,0 {
+                       compatible = "cfi-flash";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x0 0x0 0x8000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+
+               nand@1,0 {
+                       compatible = "fsl,ifc-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x1 0x0 0x10000>;
+               };
+
+               cpld: board-control@2,0 {
+                       compatible = "fsl,ls1043ardb-cpld";
+                       reg = <0x2 0x0 0x0000100>;
+               };
+};
+
+&duart0 {
+       status = "okay";
+};
+
+&duart1 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
new file mode 100644 (file)
index 0000000..42a6154
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1043A family SoC.
+ *
+ * Copyright 2014-2015, Freescale Semiconductor
+ *
+ * Mingkai Hu <Mingkai.hu@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; 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 library 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+       compatible = "fsl,ls1043a";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               /*
+                * We expect the enable-method for cpu's to be "psci", but this
+                * is dependent on the SoC FW, which will fill this in.
+                *
+                * Currently supported enable-method is psci v0.2
+                */
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x0>;
+                       clocks = <&clockgen 1 0>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x1>;
+                       clocks = <&clockgen 1 0>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x2>;
+                       clocks = <&clockgen 1 0>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x3>;
+                       clocks = <&clockgen 1 0>;
+               };
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0 0x80000000>;
+                     /* DRAM space 1, size: 2GiB DRAM */
+       };
+
+       sysclk: sysclk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <100000000>;
+               clock-output-names = "sysclk";
+       };
+
+       reboot {
+               compatible ="syscon-reboot";
+               regmap = <&dcfg>;
+               offset = <0xb0>;
+               mask = <0x02>;
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <1 13 0x1>, /* Physical Secure PPI */
+                            <1 14 0x1>, /* Physical Non-Secure PPI */
+                            <1 11 0x1>, /* Virtual PPI */
+                            <1 10 0x1>; /* Hypervisor PPI */
+       };
+
+       pmu {
+               compatible = "arm,armv8-pmuv3";
+               interrupts = <0 106 0x4>,
+                            <0 107 0x4>,
+                            <0 95 0x4>,
+                            <0 97 0x4>;
+               interrupt-affinity = <&cpu0>,
+                                    <&cpu1>,
+                                    <&cpu2>,
+                                    <&cpu3>;
+       };
+
+       gic: interrupt-controller@1400000 {
+               compatible = "arm,gic-400";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x0 0x1401000 0 0x1000>, /* GICD */
+                     <0x0 0x1402000 0 0x2000>, /* GICC */
+                     <0x0 0x1404000 0 0x2000>, /* GICH */
+                     <0x0 0x1406000 0 0x2000>; /* GICV */
+               interrupts = <1 9 0xf08>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               clockgen: clocking@1ee1000 {
+                       compatible = "fsl,ls1043a-clockgen";
+                       reg = <0x0 0x1ee1000 0x0 0x1000>;
+                       #clock-cells = <2>;
+                       clocks = <&sysclk>;
+               };
+
+               scfg: scfg@1570000 {
+                       compatible = "fsl,ls1043a-scfg", "syscon";
+                       reg = <0x0 0x1570000 0x0 0x10000>;
+                       big-endian;
+               };
+
+               dcfg: dcfg@1ee0000 {
+                       compatible = "fsl,ls1043a-dcfg", "syscon";
+                       reg = <0x0 0x1ee0000 0x0 0x10000>;
+                       big-endian;
+               };
+
+               ifc: ifc@1530000 {
+                       compatible = "fsl,ifc", "simple-bus";
+                       reg = <0x0 0x1530000 0x0 0x10000>;
+                       interrupts = <0 43 0x4>;
+               };
+
+               esdhc: esdhc@1560000 {
+                       compatible = "fsl,ls1043a-esdhc", "fsl,esdhc";
+                       reg = <0x0 0x1560000 0x0 0x10000>;
+                       interrupts = <0 62 0x4>;
+                       clock-frequency = <0>;
+                       voltage-ranges = <1800 1800 3300 3300>;
+                       sdhci,auto-cmd12;
+                       big-endian;
+                       bus-width = <4>;
+               };
+
+               dspi0: dspi@2100000 {
+                       compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x2100000 0x0 0x10000>;
+                       interrupts = <0 64 0x4>;
+                       clock-names = "dspi";
+                       clocks = <&clockgen 4 0>;
+                       spi-num-chipselects = <5>;
+                       big-endian;
+                       status = "disabled";
+               };
+
+               dspi1: dspi@2110000 {
+                       compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x2110000 0x0 0x10000>;
+                       interrupts = <0 65 0x4>;
+                       clock-names = "dspi";
+                       clocks = <&clockgen 4 0>;
+                       spi-num-chipselects = <5>;
+                       big-endian;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@2180000 {
+                       compatible = "fsl,vf610-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x2180000 0x0 0x10000>;
+                       interrupts = <0 56 0x4>;
+                       clock-names = "i2c";
+                       clocks = <&clockgen 4 0>;
+                       dmas = <&edma0 1 39>,
+                              <&edma0 1 38>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               i2c1: i2c@2190000 {
+                       compatible = "fsl,vf610-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x2190000 0x0 0x10000>;
+                       interrupts = <0 57 0x4>;
+                       clock-names = "i2c";
+                       clocks = <&clockgen 4 0>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@21a0000 {
+                       compatible = "fsl,vf610-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x21a0000 0x0 0x10000>;
+                       interrupts = <0 58 0x4>;
+                       clock-names = "i2c";
+                       clocks = <&clockgen 4 0>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@21b0000 {
+                       compatible = "fsl,vf610-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x21b0000 0x0 0x10000>;
+                       interrupts = <0 59 0x4>;
+                       clock-names = "i2c";
+                       clocks = <&clockgen 4 0>;
+                       status = "disabled";
+               };
+
+               duart0: serial@21c0500 {
+                       compatible = "fsl,ns16550", "ns16550a";
+                       reg = <0x00 0x21c0500 0x0 0x100>;
+                       interrupts = <0 54 0x4>;
+                       clocks = <&clockgen 4 0>;
+               };
+
+               duart1: serial@21c0600 {
+                       compatible = "fsl,ns16550", "ns16550a";
+                       reg = <0x00 0x21c0600 0x0 0x100>;
+                       interrupts = <0 54 0x4>;
+                       clocks = <&clockgen 4 0>;
+               };
+
+               duart2: serial@21d0500 {
+                       compatible = "fsl,ns16550", "ns16550a";
+                       reg = <0x0 0x21d0500 0x0 0x100>;
+                       interrupts = <0 55 0x4>;
+                       clocks = <&clockgen 4 0>;
+               };
+
+               duart3: serial@21d0600 {
+                       compatible = "fsl,ns16550", "ns16550a";
+                       reg = <0x0 0x21d0600 0x0 0x100>;
+                       interrupts = <0 55 0x4>;
+                       clocks = <&clockgen 4 0>;
+               };
+
+               gpio1: gpio@2300000 {
+                       compatible = "fsl,ls1043a-gpio";
+                       reg = <0x0 0x2300000 0x0 0x10000>;
+                       interrupts = <0 66 0x4>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio2: gpio@2310000 {
+                       compatible = "fsl,ls1043a-gpio";
+                       reg = <0x0 0x2310000 0x0 0x10000>;
+                       interrupts = <0 67 0x4>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio3: gpio@2320000 {
+                       compatible = "fsl,ls1043a-gpio";
+                       reg = <0x0 0x2320000 0x0 0x10000>;
+                       interrupts = <0 68 0x4>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio4: gpio@2330000 {
+                       compatible = "fsl,ls1043a-gpio";
+                       reg = <0x0 0x2330000 0x0 0x10000>;
+                       interrupts = <0 134 0x4>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               lpuart0: serial@2950000 {
+                       compatible = "fsl,ls1021a-lpuart";
+                       reg = <0x0 0x2950000 0x0 0x1000>;
+                       interrupts = <0 48 0x4>;
+                       clocks = <&clockgen 0 0>;
+                       clock-names = "ipg";
+                       status = "disabled";
+               };
+
+               lpuart1: serial@2960000 {
+                       compatible = "fsl,ls1021a-lpuart";
+                       reg = <0x0 0x2960000 0x0 0x1000>;
+                       interrupts = <0 49 0x4>;
+                       clocks = <&clockgen 4 0>;
+                       clock-names = "ipg";
+                       status = "disabled";
+               };
+
+               lpuart2: serial@2970000 {
+                       compatible = "fsl,ls1021a-lpuart";
+                       reg = <0x0 0x2970000 0x0 0x1000>;
+                       interrupts = <0 50 0x4>;
+                       clocks = <&clockgen 4 0>;
+                       clock-names = "ipg";
+                       status = "disabled";
+               };
+
+               lpuart3: serial@2980000 {
+                       compatible = "fsl,ls1021a-lpuart";
+                       reg = <0x0 0x2980000 0x0 0x1000>;
+                       interrupts = <0 51 0x4>;
+                       clocks = <&clockgen 4 0>;
+                       clock-names = "ipg";
+                       status = "disabled";
+               };
+
+               lpuart4: serial@2990000 {
+                       compatible = "fsl,ls1021a-lpuart";
+                       reg = <0x0 0x2990000 0x0 0x1000>;
+                       interrupts = <0 52 0x4>;
+                       clocks = <&clockgen 4 0>;
+                       clock-names = "ipg";
+                       status = "disabled";
+               };
+
+               lpuart5: serial@29a0000 {
+                       compatible = "fsl,ls1021a-lpuart";
+                       reg = <0x0 0x29a0000 0x0 0x1000>;
+                       interrupts = <0 53 0x4>;
+                       clocks = <&clockgen 4 0>;
+                       clock-names = "ipg";
+                       status = "disabled";
+               };
+
+               wdog0: wdog@2ad0000 {
+                       compatible = "fsl,ls1043a-wdt", "fsl,imx21-wdt";
+                       reg = <0x0 0x2ad0000 0x0 0x10000>;
+                       interrupts = <0 83 0x4>;
+                       clocks = <&clockgen 4 0>;
+                       clock-names = "wdog";
+                       big-endian;
+               };
+
+               edma0: edma@2c00000 {
+                       #dma-cells = <2>;
+                       compatible = "fsl,vf610-edma";
+                       reg = <0x0 0x2c00000 0x0 0x10000>,
+                             <0x0 0x2c10000 0x0 0x10000>,
+                             <0x0 0x2c20000 0x0 0x10000>;
+                       interrupts = <0 103 0x4>,
+                                    <0 103 0x4>;
+                       interrupt-names = "edma-tx", "edma-err";
+                       dma-channels = <32>;
+                       big-endian;
+                       clock-names = "dmamux0", "dmamux1";
+                       clocks = <&clockgen 4 0>,
+                                <&clockgen 4 0>;
+               };
+
+               usb0: usb3@2f00000 {
+                       compatible = "snps,dwc3";
+                       reg = <0x0 0x2f00000 0x0 0x10000>;
+                       interrupts = <0 60 0x4>;
+                       dr_mode = "host";
+               };
+
+               usb1: usb3@3000000 {
+                       compatible = "snps,dwc3";
+                       reg = <0x0 0x3000000 0x0 0x10000>;
+                       interrupts = <0 61 0x4>;
+                       dr_mode = "host";
+               };
+
+               usb2: usb3@3100000 {
+                       compatible = "snps,dwc3";
+                       reg = <0x0 0x3100000 0x0 0x10000>;
+                       interrupts = <0 63 0x4>;
+                       dr_mode = "host";
+               };
+
+               sata: sata@3200000 {
+                       compatible = "fsl,ls1043a-ahci", "fsl,ls1021a-ahci";
+                       reg = <0x0 0x3200000 0x0 0x10000>;
+                       interrupts = <0 69 0x4>;
+                       clocks = <&clockgen 4 0>;
+               };
+
+               msi1: msi-controller1@1571000 {
+                       compatible = "fsl,1s1043a-msi";
+                       reg = <0x0 0x1571000 0x0 0x8>;
+                       msi-controller;
+                       interrupts = <0 116 0x4>;
+               };
+
+               msi2: msi-controller2@1572000 {
+                       compatible = "fsl,1s1043a-msi";
+                       reg = <0x0 0x1572000 0x0 0x8>;
+                       msi-controller;
+                       interrupts = <0 126 0x4>;
+               };
+
+               msi3: msi-controller3@1573000 {
+                       compatible = "fsl,1s1043a-msi";
+                       reg = <0x0 0x1573000 0x0 0x8>;
+                       msi-controller;
+                       interrupts = <0 160 0x4>;
+               };
+
+               pcie@3400000 {
+                       compatible = "fsl,ls1043a-pcie", "snps,dw-pcie";
+                       reg = <0x00 0x03400000 0x0 0x00100000   /* controller registers */
+                              0x40 0x00000000 0x0 0x00002000>; /* configuration space */
+                       reg-names = "regs", "config";
+                       interrupts = <0 118 0x4>, /* controller interrupt */
+                                    <0 117 0x4>; /* PME interrupt */
+                       interrupt-names = "intr", "pme";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       num-lanes = <4>;
+                       bus-range = <0x0 0xff>;
+                       ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000   /* downstream I/O */
+                                 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+                       msi-parent = <&msi1>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 7>;
+                       interrupt-map = <0000 0 0 1 &gic 0 110 0x4>,
+                                       <0000 0 0 2 &gic 0 111 0x4>,
+                                       <0000 0 0 3 &gic 0 112 0x4>,
+                                       <0000 0 0 4 &gic 0 113 0x4>;
+               };
+
+               pcie@3500000 {
+                       compatible = "fsl,ls1043a-pcie", "snps,dw-pcie";
+                       reg = <0x00 0x03500000 0x0 0x00100000   /* controller registers */
+                              0x48 0x00000000 0x0 0x00002000>; /* configuration space */
+                       reg-names = "regs", "config";
+                       interrupts = <0 128 0x4>,
+                                    <0 127 0x4>;
+                       interrupt-names = "intr", "pme";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       num-lanes = <2>;
+                       bus-range = <0x0 0xff>;
+                       ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000   /* downstream I/O */
+                                 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+                       msi-parent = <&msi2>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 7>;
+                       interrupt-map = <0000 0 0 1 &gic 0 120  0x4>,
+                                       <0000 0 0 2 &gic 0 121 0x4>,
+                                       <0000 0 0 3 &gic 0 122 0x4>,
+                                       <0000 0 0 4 &gic 0 123 0x4>;
+               };
+
+               pcie@3600000 {
+                       compatible = "fsl,ls1043a-pcie", "snps,dw-pcie";
+                       reg = <0x00 0x03600000 0x0 0x00100000   /* controller registers */
+                              0x50 0x00000000 0x0 0x00002000>; /* configuration space */
+                       reg-names = "regs", "config";
+                       interrupts = <0 162 0x4>,
+                                    <0 161 0x4>;
+                       interrupt-names = "intr", "pme";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       num-lanes = <2>;
+                       bus-range = <0x0 0xff>;
+                       ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000   /* downstream I/O */
+                                 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+                       msi-parent = <&msi3>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 7>;
+                       interrupt-map = <0000 0 0 1 &gic 0 154 0x4>,
+                                       <0000 0 0 2 &gic 0 155 0x4>,
+                                       <0000 0 0 3 &gic 0 156 0x4>,
+                                       <0000 0 0 4 &gic 0 157 0x4>;
+               };
+       };
+
+};
index 925552e..2b23d03 100644 (file)
                };
        };
 
+       rstcr: syscon@1e60000 {
+               compatible = "fsl,ls2080a-rstcr", "syscon";
+               reg = <0x0 0x1e60000 0x0 0x4>;
+       };
+
+       reboot {
+               compatible ="syscon-reboot";
+               regmap = <&rstcr>;
+               offset = <0x0>;
+               mask = <0x2>;
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
                        interrupts = <0 32 0x4>; /* Level high type */
                };
 
+               cluster1_core0_watchdog: wdt@c000000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc000000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster1_core1_watchdog: wdt@c010000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc010000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster2_core0_watchdog: wdt@c100000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc100000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster2_core1_watchdog: wdt@c110000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc110000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster3_core0_watchdog: wdt@c200000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc200000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster3_core1_watchdog: wdt@c210000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc210000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster4_core0_watchdog: wdt@c300000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc300000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
+               cluster4_core1_watchdog: wdt@c310000 {
+                       compatible = "arm,sp805-wdt", "arm,primecell";
+                       reg = <0x0 0xc310000 0x0 0x1000>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "apb_pclk", "wdog_clk";
+               };
+
                fsl_mc: fsl-mc@80c000000 {
                        compatible = "fsl,qoriq-mc";
                        reg = <0x00000008 0x0c000000 0 0x40>,    /* MC portal base */
index 8d43a0f..8185251 100644 (file)
                reg = <0x0 0x0 0x0 0x40000000>;
        };
 };
+
+&uart2 {
+       label = "LS-UART0";
+};
+&uart3 {
+       label = "LS-UART1";
+};
index 82d2488..ad1f1eb 100644 (file)
                        compatible = "hisilicon,hi6220-sysctrl", "syscon";
                        reg = <0x0 0xf7030000 0x0 0x2000>;
                        #clock-cells = <1>;
+                       #reset-cells = <1>;
                };
 
                media_ctrl: media_ctrl@f4410000 {
index a3b5f1d..099ad93 100644 (file)
@@ -55,7 +55,7 @@
        };
 
        psci {
-               compatible = "arm,psci-0.2";
+               compatible = "arm,psci-1.0", "arm,psci-0.2";
                method = "smc";
        };
 
@@ -68,6 +68,7 @@
                        device_type = "cpu";
                        reg = <0x0>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
 
                cpu1: cpu@1 {
@@ -75,6 +76,7 @@
                        device_type = "cpu";
                        reg = <0x1>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
 
                cpu2: cpu@2 {
@@ -82,6 +84,7 @@
                        device_type = "cpu";
                        reg = <0x2>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
 
                cpu3: cpu@3 {
                        device_type = "cpu";
                        reg = <0x3>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               idle-states {
+                       entry-method = "psci";
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <75>;
+                               exit-latency-us = <155>;
+                               min-residency-us = <1000>;
+                       };
                };
        };
 
                        };
                };
 
+               soc_pinctrl: pin-controller@ea8000 {
+                       compatible = "marvell,berlin4ct-soc-pinctrl";
+                       reg = <0xea8000 0x14>;
+               };
+
+               avio_pinctrl: pin-controller@ea8400 {
+                       compatible = "marvell,berlin4ct-avio-pinctrl";
+                       reg = <0xea8400 0x8>;
+               };
+
                apb@fc0000 {
                        compatible = "simple-bus";
                        #address-cells = <1>;
                                interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
+                       wdt0: watchdog@3000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x3000 0x100>;
+                               clocks = <&osc>;
+                               interrupts = <0>;
+                       };
+
+                       wdt1: watchdog@4000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x4000 0x100>;
+                               clocks = <&osc>;
+                               interrupts = <1>;
+                               status = "disabled";
+                       };
+
+                       wdt2: watchdog@5000 {
+                               compatible = "snps,dw-wdt";
+                               reg = <0x5000 0x100>;
+                               clocks = <&osc>;
+                               interrupts = <2>;
+                               status = "disabled";
+                       };
+
                        sm_gpio0: gpio@8000 {
                                compatible = "snps,dw-apb-gpio";
                                reg = <0x8000 0x400>;
                                clocks = <&osc>;
                                reg-shift = <2>;
                                status = "disabled";
+                               pinctrl-0 = <&uart0_pmux>;
+                               pinctrl-names = "default";
+                       };
+               };
+
+               system_pinctrl: pin-controller@fe2200 {
+                       compatible = "marvell,berlin4ct-system-pinctrl";
+                       reg = <0xfe2200 0xc>;
+
+                       uart0_pmux: uart0-pmux {
+                               groups = "SM_URT0_TXD", "SM_URT0_RXD";
+                               function = "uart0";
                        };
                };
        };
index 9b1482a..e427f04 100644 (file)
 };
 
 &pio {
+       disp_pwm0_pins: disp_pwm0_pins {
+               pins1 {
+                       pinmux = <MT8173_PIN_87_DISP_PWM0__FUNC_DISP_PWM0>;
+                       output-low;
+               };
+       };
+
        mmc0_pins_default: mmc0default {
                pins_cmd_dat {
                        pinmux = <MT8173_PIN_57_MSDC0_DAT0__FUNC_MSDC0_DAT0>,
        };
 };
 
+&pwm0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&disp_pwm0_pins>;
+       status = "okay";
+};
+
 &pwrap {
        pmic: mt6397 {
                compatible = "mediatek,mt6397";
index c1fd275..ec135ea 100644 (file)
@@ -16,7 +16,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/power/mt8173-power.h>
-#include <dt-bindings/reset-controller/mt8173-resets.h>
+#include <dt-bindings/reset/mt8173-resets.h>
 #include "mt8173-pinfunc.h"
 
 / {
@@ -96,7 +96,7 @@
        };
 
        psci {
-               compatible = "arm,psci";
+               compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
                method = "smc";
                cpu_suspend   = <0x84000001>;
                cpu_off       = <0x84000002>;
                        reg = <0 0x10007000 0 0x100>;
                };
 
+               timer: timer@10008000 {
+                       compatible = "mediatek,mt8173-timer",
+                                    "mediatek,mt6577-timer";
+                       reg = <0 0x10008000 0 0x1000>;
+                       interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_CLK_13M>,
+                                <&topckgen CLK_TOP_RTC_SEL>;
+               };
+
                pwrap: pwrap@1000d000 {
                        compatible = "mediatek,mt8173-pwrap";
                        reg = <0 0x1000d000 0 0x1000>;
                        #clock-cells = <1>;
                };
 
+               pwm0: pwm@1401e000 {
+                       compatible = "mediatek,mt8173-disp-pwm",
+                                    "mediatek,mt6595-disp-pwm";
+                       reg = <0 0x1401e000 0 0x1000>;
+                       #pwm-cells = <2>;
+                       clocks = <&mmsys CLK_MM_DISP_PWM026M>,
+                                <&mmsys CLK_MM_DISP_PWM0MM>;
+                       clock-names = "main", "mm";
+                       status = "disabled";
+               };
+
+               pwm1: pwm@1401f000 {
+                       compatible = "mediatek,mt8173-disp-pwm",
+                                    "mediatek,mt6595-disp-pwm";
+                       reg = <0 0x1401f000 0 0x1000>;
+                       #pwm-cells = <2>;
+                       clocks = <&mmsys CLK_MM_DISP_PWM126M>,
+                                <&mmsys CLK_MM_DISP_PWM1MM>;
+                       clock-names = "main", "mm";
+                       status = "disabled";
+               };
+
                imgsys: clock-controller@15000000 {
                        compatible = "mediatek,mt8173-imgsys", "syscon";
                        reg = <0 0x15000000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
new file mode 100644 (file)
index 0000000..a7e865d
--- /dev/null
@@ -0,0 +1,7 @@
+dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
+dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-0000.dtb
+dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
+dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
+
+always         := $(dtb-y)
+clean-files    := *.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
new file mode 100644 (file)
index 0000000..7dfe1c0
--- /dev/null
@@ -0,0 +1,1130 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra132.dtsi"
+
+/ {
+       model = "NVIDIA Tegra132 Norrin";
+       compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124";
+
+       aliases {
+               rtc0 = "/i2c@0,7000d000/as3722@40";
+               rtc1 = "/rtc@0,7000e000";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x0 0x80000000>;
+       };
+
+       host1x@0,50000000 {
+               hdmi@0,54280000 {
+                       status = "disabled";
+
+                       vdd-supply = <&vdd_3v3_hdmi>;
+                       pll-supply = <&vdd_hdmi_pll>;
+                       hdmi-supply = <&vdd_5v0_hdmi>;
+
+                       nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+                       nvidia,hpd-gpio =
+                               <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+               };
+
+               sor@0,54540000 {
+                       status = "okay";
+
+                       nvidia,dpaux = <&dpaux>;
+                       nvidia,panel = <&panel>;
+               };
+
+               dpaux: dpaux@0,545c0000 {
+                       vdd-supply = <&vdd_3v3_panel>;
+                       status = "okay";
+               };
+       };
+
+       gpu@0,57000000 {
+               status = "okay";
+
+               vdd-supply = <&vdd_gpu>;
+       };
+
+       pinmux@0,70000868 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinmux_default>;
+
+               pinmux_default: pinmux@0 {
+                       dap_mclk1_pw4 {
+                               nvidia,pins = "dap_mclk1_pw4";
+                               nvidia,function = "extperiph1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_din_pa4 {
+                               nvidia,pins = "dap2_din_pa4";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       dap2_dout_pa5 {
+                               nvidia,pins = "dap2_dout_pa5",
+                                             "dap2_fs_pa2",
+                                             "dap2_sclk_pa3";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap3_dout_pp2 {
+                               nvidia,pins = "dap3_dout_pp2";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_pwm_px0 {
+                               nvidia,pins = "dvfs_pwm_px0",
+                                             "dvfs_clk_px2";
+                               nvidia,function = "cldvfs";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       ulpi_clk_py0 {
+                               nvidia,pins = "ulpi_clk_py0",
+                                             "ulpi_nxt_py2",
+                                             "ulpi_stp_py3";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       ulpi_dir_py1 {
+                               nvidia,pins = "ulpi_dir_py1";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       cam_i2c_scl_pbb1 {
+                               nvidia,pins = "cam_i2c_scl_pbb1",
+                                             "cam_i2c_sda_pbb2";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+                       gen2_i2c_scl_pt5 {
+                               nvidia,pins = "gen2_i2c_scl_pt5",
+                                             "gen2_i2c_sda_pt6";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+                       pj7 {
+                               nvidia,pins = "pj7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_in_pk6 {
+                               nvidia,pins = "spdif_in_pk6";
+                               nvidia,function = "spdif";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk7 {
+                               nvidia,pins = "pk7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pg4 {
+                               nvidia,pins = "pg4",
+                                             "pg5",
+                                             "pg6",
+                                             "pi3";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pg7 {
+                               nvidia,pins = "pg7";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       ph1 {
+                               nvidia,pins = "ph1";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk0 {
+                               nvidia,pins = "pk0",
+                                             "kb_row15_ps7",
+                                             "clk_32k_out_pa0";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc1_clk_pz0 {
+                               nvidia,pins = "sdmmc1_clk_pz0";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc1_cmd_pz1 {
+                               nvidia,pins = "sdmmc1_cmd_pz1",
+                                             "sdmmc1_dat0_py7",
+                                             "sdmmc1_dat1_py6",
+                                             "sdmmc1_dat2_py5",
+                                             "sdmmc1_dat3_py4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc3_clk_pa6 {
+                               nvidia,pins = "sdmmc3_clk_pa6";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc3_cmd_pa7 {
+                               nvidia,pins = "sdmmc3_cmd_pa7",
+                                             "sdmmc3_dat0_pb7",
+                                             "sdmmc3_dat1_pb6",
+                                             "sdmmc3_dat2_pb5",
+                                             "sdmmc3_dat3_pb4",
+                                             "kb_col4_pq4",
+                                             "sdmmc3_clk_lb_out_pee4",
+                                             "sdmmc3_clk_lb_in_pee5",
+                                             "sdmmc3_cd_n_pv2";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc4_clk_pcc4 {
+                               nvidia,pins = "sdmmc4_clk_pcc4";
+                               nvidia,function = "sdmmc4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc4_cmd_pt7 {
+                               nvidia,pins = "sdmmc4_cmd_pt7",
+                                             "sdmmc4_dat0_paa0",
+                                             "sdmmc4_dat1_paa1",
+                                             "sdmmc4_dat2_paa2",
+                                             "sdmmc4_dat3_paa3",
+                                             "sdmmc4_dat4_paa4",
+                                             "sdmmc4_dat5_paa5",
+                                             "sdmmc4_dat6_paa6",
+                                             "sdmmc4_dat7_paa7";
+                               nvidia,function = "sdmmc4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       mic_det_l {
+                               nvidia,pins = "kb_row7_pr7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       kb_row10_ps2 {
+                               nvidia,pins = "kb_row10_ps2";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       kb_row9_ps1 {
+                               nvidia,pins = "kb_row9_ps1";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_scl_pz6 {
+                               nvidia,pins = "pwr_i2c_scl_pz6",
+                                             "pwr_i2c_sda_pz7";
+                               nvidia,function = "i2cpwr";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+                       jtag_rtck {
+                               nvidia,pins = "jtag_rtck";
+                               nvidia,function = "rtck";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_in {
+                               nvidia,pins = "clk_32k_in";
+                               nvidia,function = "clk";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       core_pwr_req {
+                               nvidia,pins = "core_pwr_req";
+                               nvidia,function = "pwron";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       cpu_pwr_req {
+                               nvidia,pins = "cpu_pwr_req";
+                               nvidia,function = "cpu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb_col0_ap {
+                               nvidia,pins = "kb_col0_pq0";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       en_vdd_sd {
+                               nvidia,pins = "kb_row0_pr0";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       lid_open {
+                               nvidia,pins = "kb_row4_pr4";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       pwr_int_n {
+                               nvidia,pins = "pwr_int_n";
+                               nvidia,function = "pmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       reset_out_n {
+                               nvidia,pins = "reset_out_n";
+                               nvidia,function = "reset_out_n";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk3_out_pee0 {
+                               nvidia,pins = "clk3_out_pee0";
+                               nvidia,function = "extperiph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_scl_pc4 {
+                               nvidia,pins = "gen1_i2c_scl_pc4",
+                                             "gen1_i2c_sda_pc5";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+                       hdmi_cec_pee3 {
+                               nvidia,pins = "hdmi_cec_pee3";
+                               nvidia,function = "cec";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdmi_int_pn7 {
+                               nvidia,pins = "hdmi_int_pn7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       ddc_scl_pv4 {
+                               nvidia,pins = "ddc_scl_pv4",
+                                             "ddc_sda_pv5";
+                               nvidia,function = "i2c4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+                       };
+                       usb_vbus_en0_pn4 {
+                               nvidia,pins = "usb_vbus_en0_pn4",
+                                             "usb_vbus_en1_pn5",
+                                             "usb_vbus_en2_pff1";
+                               nvidia,function = "usb";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       drive_sdio1 {
+                               nvidia,pins = "drive_sdio1";
+                               nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+                               nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+                               nvidia,pull-down-strength = <36>;
+                               nvidia,pull-up-strength = <20>;
+                               nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOW>;
+                               nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOW>;
+                       };
+                       drive_sdio3 {
+                               nvidia,pins = "drive_sdio3";
+                               nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+                               nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+                               nvidia,pull-down-strength = <22>;
+                               nvidia,pull-up-strength = <36>;
+                               nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+                               nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+                       };
+                       drive_gma {
+                               nvidia,pins = "drive_gma";
+                               nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+                               nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+                               nvidia,pull-down-strength = <2>;
+                               nvidia,pull-up-strength = <1>;
+                               nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+                               nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+                               nvidia,drive-type = <1>;
+                       };
+                       ac_ok {
+                               nvidia,pins = "pj0";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       codec_irq_l {
+                               nvidia,pins = "ph4";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       lcd_bl_en {
+                               nvidia,pins = "ph2";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_irq_l {
+                               nvidia,pins = "gpio_w3_aud_pw3";
+                               nvidia,function = "spi6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       tpm_davint_l {
+                               nvidia,pins = "ph6";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       ts_irq_l {
+                               nvidia,pins = "pk2";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       ts_reset_l {
+                               nvidia,pins = "pk4";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       ts_shdn_l {
+                               nvidia,pins = "pk1";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       ph7 {
+                               nvidia,pins = "ph7";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sensor_irq_l {
+                               nvidia,pins = "pi6";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       wifi_en {
+                               nvidia,pins = "gpio_x7_aud_px7";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       chromeos_write_protect {
+                               nvidia,pins = "kb_row1_pr1";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       hp_det_l {
+                               nvidia,pins = "pi7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       soc_warm_reset_l {
+                               nvidia,pins = "pi5";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+               };
+       };
+
+       serial@0,70006000 {
+               status = "okay";
+       };
+
+       pwm: pwm@0,7000a000 {
+               status = "okay";
+       };
+
+       /* HDMI DDC */
+       hdmi_ddc: i2c@0,7000c700 {
+               status = "okay";
+               clock-frequency = <100000>;
+       };
+
+       i2c@0,7000d000 {
+               status = "okay";
+               clock-frequency = <400000>;
+
+               as3722: pmic@40 {
+                       compatible = "ams,as3722";
+                       reg = <0x40>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+                       ams,system-power-controller;
+
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+
+                       #gpio-cells = <2>;
+                       gpio-controller;
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&as3722_default>;
+
+                       as3722_default: pinmux@0 {
+                               gpio0 {
+                                       pins = "gpio0";
+                                       function = "gpio";
+                                       bias-pull-down;
+                               };
+
+                               gpio1 {
+                                       pins = "gpio1";
+                                       function = "gpio";
+                                       bias-pull-up;
+                               };
+
+                               gpio2_4_7 {
+                                       pins = "gpio2", "gpio4", "gpio7";
+                                       function = "gpio";
+                                       bias-pull-up;
+                               };
+
+                               gpio3 {
+                                       pins = "gpio3";
+                                       function = "gpio";
+                                       bias-high-impedance;
+                               };
+
+                               gpio5 {
+                                       pins = "gpio5";
+                                       function = "clk32k-out";
+                                       bias-pull-down;
+                               };
+
+                               gpio6 {
+                                       pins = "gpio6";
+                                       function = "clk32k-out";
+                                       bias-pull-down;
+                               };
+                       };
+
+                       regulators {
+                               vsup-sd2-supply = <&vdd_5v0_sys>;
+                               vsup-sd3-supply = <&vdd_5v0_sys>;
+                               vsup-sd4-supply = <&vdd_5v0_sys>;
+                               vsup-sd5-supply = <&vdd_5v0_sys>;
+                               vin-ldo0-supply = <&vdd_1v35_lp0>;
+                               vin-ldo1-6-supply = <&vdd_3v3_sys>;
+                               vin-ldo2-5-7-supply = <&vddio_1v8>;
+                               vin-ldo3-4-supply = <&vdd_3v3_sys>;
+                               vin-ldo9-10-supply = <&vdd_5v0_sys>;
+                               vin-ldo11-supply = <&vdd_3v3_run>;
+
+                               sd0 {
+                                       regulator-name = "+VDD_CPU_AP";
+                                       regulator-min-microvolt = <700000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-max-microamp = <3500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       ams,ext-control = <2>;
+                               };
+
+                               sd1 {
+                                       regulator-name = "+VDD_CORE";
+                                       regulator-min-microvolt = <700000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-max-microamp = <4000000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       ams,ext-control = <1>;
+                               };
+
+                               vdd_1v35_lp0: sd2 {
+                                       regulator-name = "+1.35V_LP0(sd2)";
+                                       regulator-min-microvolt = <1350000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               sd3 {
+                                       regulator-name = "+1.35V_LP0(sd3)";
+                                       regulator-min-microvolt = <1350000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               vdd_1v05_run: sd4 {
+                                       regulator-name = "+1.05V_RUN";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                               };
+
+                               vddio_1v8: sd5 {
+                                       regulator-name = "+1.8V_VDDIO";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               vdd_gpu: sd6 {
+                                       regulator-name = "+VDD_GPU_AP";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-min-microamp = <3500000>;
+                                       regulator-max-microamp = <3500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo0 {
+                                       regulator-name = "+1.05_RUN_AVDD";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       ams,ext-control = <1>;
+                               };
+
+                               ldo1 {
+                                       regulator-name = "+1.8V_RUN_CAM";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo2 {
+                                       regulator-name = "+1.2V_GEN_AVDD";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo3 {
+                                       regulator-name = "+1.00V_LP0_VDD_RTC";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       ams,enable-tracking;
+                               };
+
+                               vdd_run_cam: ldo4 {
+                                       regulator-name = "+2.8V_RUN_CAM";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo5 {
+                                       regulator-name = "+1.2V_RUN_CAM_FRONT";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                               };
+
+                               vddio_sdmmc3: ldo6 {
+                                       regulator-name = "+VDDIO_SDMMC3";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <3300000>;
+                               };
+
+                               ldo7 {
+                                       regulator-name = "+1.05V_RUN_CAM_REAR";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                               };
+
+                               ldo9 {
+                                       regulator-name = "+2.8V_RUN_TOUCH";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo10 {
+                                       regulator-name = "+2.8V_RUN_CAM_AF";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo11 {
+                                       regulator-name = "+1.8V_RUN_VPP_FUSE";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+                       };
+               };
+       };
+
+       spi@0,7000d400 {
+               status = "okay";
+
+               ec: cros-ec@0 {
+                       compatible = "google,cros-ec-spi";
+                       spi-max-frequency = <3000000>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
+                       reg = <0>;
+
+                       google,cros-ec-spi-msg-delay = <2000>;
+
+                       i2c_20: i2c-tunnel {
+                               compatible = "google,cros-ec-i2c-tunnel";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               google,remote-bus = <0>;
+
+                               charger: bq24735 {
+                                       compatible = "ti,bq24735";
+                                       reg = <0x9>;
+                                       interrupt-parent = <&gpio>;
+                                       interrupts = <TEGRA_GPIO(J, 0)
+                                                       GPIO_ACTIVE_HIGH>;
+                                       ti,ac-detect-gpios = <&gpio
+                                                       TEGRA_GPIO(J, 0)
+                                                       GPIO_ACTIVE_HIGH>;
+                               };
+
+                               battery: smart-battery {
+                                       compatible = "sbs,sbs-battery";
+                                       reg = <0xb>;
+                                       battery-name = "battery";
+                                       sbs,i2c-retry-count = <2>;
+                                       sbs,poll-retry-count = <10>;
+                               /*      power-supplies = <&charger>; */
+                               };
+                       };
+
+                       keyboard-controller {
+                               compatible = "google,cros-ec-keyb";
+                               keypad,num-rows = <8>;
+                               keypad,num-columns = <13>;
+                               google,needs-ghost-filter;
+                               linux,keymap =
+                                       <MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA)
+                                        MATRIX_KEY(0x00, 0x02, KEY_F1)
+                                        MATRIX_KEY(0x00, 0x03, KEY_B)
+                                        MATRIX_KEY(0x00, 0x04, KEY_F10)
+                                        MATRIX_KEY(0x00, 0x06, KEY_N)
+                                        MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
+                                        MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
+
+                                        MATRIX_KEY(0x01, 0x01, KEY_ESC)
+                                        MATRIX_KEY(0x01, 0x02, KEY_F4)
+                                        MATRIX_KEY(0x01, 0x03, KEY_G)
+                                        MATRIX_KEY(0x01, 0x04, KEY_F7)
+                                        MATRIX_KEY(0x01, 0x06, KEY_H)
+                                        MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
+                                        MATRIX_KEY(0x01, 0x09, KEY_F9)
+                                        MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
+
+                                        MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
+                                        MATRIX_KEY(0x02, 0x01, KEY_TAB)
+                                        MATRIX_KEY(0x02, 0x02, KEY_F3)
+                                        MATRIX_KEY(0x02, 0x03, KEY_T)
+                                        MATRIX_KEY(0x02, 0x04, KEY_F6)
+                                        MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)
+                                        MATRIX_KEY(0x02, 0x06, KEY_Y)
+                                        MATRIX_KEY(0x02, 0x07, KEY_102ND)
+                                        MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
+                                        MATRIX_KEY(0x02, 0x09, KEY_F8)
+
+                                        MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
+                                        MATRIX_KEY(0x03, 0x02, KEY_F2)
+                                        MATRIX_KEY(0x03, 0x03, KEY_5)
+                                        MATRIX_KEY(0x03, 0x04, KEY_F5)
+                                        MATRIX_KEY(0x03, 0x06, KEY_6)
+                                        MATRIX_KEY(0x03, 0x08, KEY_MINUS)
+                                        MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
+
+                                        MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
+                                        MATRIX_KEY(0x04, 0x01, KEY_A)
+                                        MATRIX_KEY(0x04, 0x02, KEY_D)
+                                        MATRIX_KEY(0x04, 0x03, KEY_F)
+                                        MATRIX_KEY(0x04, 0x04, KEY_S)
+                                        MATRIX_KEY(0x04, 0x05, KEY_K)
+                                        MATRIX_KEY(0x04, 0x06, KEY_J)
+                                        MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
+                                        MATRIX_KEY(0x04, 0x09, KEY_L)
+                                        MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
+                                        MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
+
+                                        MATRIX_KEY(0x05, 0x01, KEY_Z)
+                                        MATRIX_KEY(0x05, 0x02, KEY_C)
+                                        MATRIX_KEY(0x05, 0x03, KEY_V)
+                                        MATRIX_KEY(0x05, 0x04, KEY_X)
+                                        MATRIX_KEY(0x05, 0x05, KEY_COMMA)
+                                        MATRIX_KEY(0x05, 0x06, KEY_M)
+                                        MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)
+                                        MATRIX_KEY(0x05, 0x08, KEY_SLASH)
+                                        MATRIX_KEY(0x05, 0x09, KEY_DOT)
+                                        MATRIX_KEY(0x05, 0x0b, KEY_SPACE)
+
+                                        MATRIX_KEY(0x06, 0x01, KEY_1)
+                                        MATRIX_KEY(0x06, 0x02, KEY_3)
+                                        MATRIX_KEY(0x06, 0x03, KEY_4)
+                                        MATRIX_KEY(0x06, 0x04, KEY_2)
+                                        MATRIX_KEY(0x06, 0x05, KEY_8)
+                                        MATRIX_KEY(0x06, 0x06, KEY_7)
+                                        MATRIX_KEY(0x06, 0x08, KEY_0)
+                                        MATRIX_KEY(0x06, 0x09, KEY_9)
+                                        MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT)
+                                        MATRIX_KEY(0x06, 0x0b, KEY_DOWN)
+                                        MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)
+
+                                        MATRIX_KEY(0x07, 0x01, KEY_Q)
+                                        MATRIX_KEY(0x07, 0x02, KEY_E)
+                                        MATRIX_KEY(0x07, 0x03, KEY_R)
+                                        MATRIX_KEY(0x07, 0x04, KEY_W)
+                                        MATRIX_KEY(0x07, 0x05, KEY_I)
+                                        MATRIX_KEY(0x07, 0x06, KEY_U)
+                                        MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)
+                                        MATRIX_KEY(0x07, 0x08, KEY_P)
+                                        MATRIX_KEY(0x07, 0x09, KEY_O)
+                                        MATRIX_KEY(0x07, 0x0b, KEY_UP)
+                                        MATRIX_KEY(0x07, 0x0c, KEY_LEFT)>;
+                       };
+               };
+       };
+
+       pmc@0,7000e400 {
+               nvidia,invert-interrupt;
+               nvidia,suspend-mode = <0>;
+               #wake-cells = <3>;
+               nvidia,cpu-pwr-good-time = <500>;
+               nvidia,cpu-pwr-off-time = <300>;
+               nvidia,core-pwr-good-time = <641 3845>;
+               nvidia,core-pwr-off-time = <61036>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
+               nvidia,reset-gpio = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+       };
+
+       /* WIFI/BT module */
+       sdhci@0,700b0000 {
+               status = "disabled";
+       };
+
+       /* external SD/MMC */
+       sdhci@0,700b0400 {
+               cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+               power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+               wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>;
+               status = "okay";
+               bus-width = <4>;
+               vqmmc-supply = <&vddio_sdmmc3>;
+       };
+
+       /* EMMC 4.51 */
+       sdhci@0,700b0600 {
+               status = "okay";
+               bus-width = <8>;
+               non-removable;
+       };
+
+       usb@0,7d000000 {
+               status = "okay";
+       };
+
+       usb-phy@0,7d000000 {
+               status = "okay";
+               vbus-supply = <&vdd_usb1_vbus>;
+       };
+
+       usb@0,7d004000 {
+               status = "okay";
+       };
+
+       usb-phy@0,7d004000 {
+               status = "okay";
+               vbus-supply = <&vdd_run_cam>;
+       };
+
+       usb@0,7d008000 {
+               status = "okay";
+       };
+
+       usb-phy@0,7d008000 {
+               status = "okay";
+               vbus-supply = <&vdd_usb3_vbus>;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+
+               enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+               power-supply = <&vdd_led>;
+               pwms = <&pwm 1 1000000>;
+
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+
+               backlight-boot-off;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock@0 {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               lid {
+                       label = "Lid";
+                       gpios = <&gpio TEGRA_GPIO(R, 4) GPIO_ACTIVE_LOW>;
+                       linux,input-type = <5>;
+                       linux,code = <0>;
+                       debounce-interval = <1>;
+                       gpio-key,wakeup;
+               };
+
+               power {
+                       label = "Power";
+                       gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       debounce-interval = <10>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       panel: panel {
+               compatible = "innolux,n116bge", "simple-panel";
+               backlight = <&backlight>;
+               ddc-i2c-bus = <&dpaux>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vdd_mux: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "+VDD_MUX";
+                       regulator-min-microvolt = <19000000>;
+                       regulator-max-microvolt = <19000000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               vdd_5v0_sys: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "+5V_SYS";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       vin-supply = <&vdd_mux>;
+               };
+
+               vdd_3v3_sys: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "+3.3V_SYS";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       vin-supply = <&vdd_mux>;
+               };
+
+               vdd_3v3_run: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "+3.3V_RUN";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       gpio = <&as3722 1 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       vin-supply = <&vdd_3v3_sys>;
+               };
+
+               vdd_3v3_hdmi: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "+3.3V_AVDD_HDMI_AP_GATED";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       vin-supply = <&vdd_3v3_run>;
+               };
+
+               vdd_led: regulator@5 {
+                       compatible = "regulator-fixed";
+                       reg = <5>;
+                       regulator-name = "+VDD_LED";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       vin-supply = <&vdd_mux>;
+               };
+
+               vdd_usb1_vbus: regulator@6 {
+                       compatible = "regulator-fixed";
+                       reg = <6>;
+                       regulator-name = "+5V_USB_HS";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       gpio-open-drain;
+                       vin-supply = <&vdd_5v0_sys>;
+               };
+
+               vdd_usb3_vbus: regulator@7 {
+                       compatible = "regulator-fixed";
+                       reg = <7>;
+                       regulator-name = "+5V_USB_SS";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       gpio-open-drain;
+                       vin-supply = <&vdd_5v0_sys>;
+               };
+
+               vdd_3v3_panel: regulator@8 {
+                       compatible = "regulator-fixed";
+                       reg = <8>;
+                       regulator-name = "+3.3V_PANEL";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&as3722 4 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       vin-supply = <&vdd_3v3_sys>;
+               };
+
+               vdd_hdmi_pll: regulator@9 {
+                       compatible = "regulator-fixed";
+                       reg = <9>;
+                       regulator-name = "+1.05V_RUN_AVDD_HDMI_PLL_AP_GATE";
+                       regulator-min-microvolt = <1050000>;
+                       regulator-max-microvolt = <1050000>;
+                       gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
+                       vin-supply = <&vdd_1v05_run>;
+               };
+
+               vdd_5v0_hdmi: regulator@10 {
+                       compatible = "regulator-fixed";
+                       reg = <10>;
+                       regulator-name = "+5V_HDMI_CON";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       vin-supply = <&vdd_5v0_sys>;
+               };
+
+               vdd_5v0_ts: regulator@11 {
+                       compatible = "regulator-fixed";
+                       reg = <11>;
+                       regulator-name = "+5V_VDD_TS";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
new file mode 100644 (file)
index 0000000..e8bb460
--- /dev/null
@@ -0,0 +1,990 @@
+#include <dt-bindings/clock/tegra124-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra124-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "nvidia,tegra132", "nvidia,tegra124";
+       interrupt-parent = <&lic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       pcie-controller@0,01003000 {
+               compatible = "nvidia,tegra124-pcie";
+               device_type = "pci";
+               reg = <0x0 0x01003000 0x0 0x00000800   /* PADS registers */
+                      0x0 0x01003800 0x0 0x00000800   /* AFI registers */
+                      0x0 0x02000000 0x0 0x10000000>; /* configuration space */
+               reg-names = "pads", "afi", "cs";
+               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
+                            <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
+               interrupt-names = "intr", "msi";
+
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
+               bus-range = <0x00 0xff>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+
+               ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000   /* port 0 configuration space */
+                         0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000   /* port 1 configuration space */
+                         0x81000000 0 0x0        0x0 0x12000000 0 0x00010000   /* downstream I/O (64 KiB) */
+                         0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000   /* non-prefetchable memory (208 MiB) */
+                         0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */
+
+               clocks = <&tegra_car TEGRA124_CLK_PCIE>,
+                        <&tegra_car TEGRA124_CLK_AFI>,
+                        <&tegra_car TEGRA124_CLK_PLL_E>,
+                        <&tegra_car TEGRA124_CLK_CML0>;
+               clock-names = "pex", "afi", "pll_e", "cml";
+               resets = <&tegra_car 70>,
+                        <&tegra_car 72>,
+                        <&tegra_car 74>;
+               reset-names = "pex", "afi", "pcie_x";
+               status = "disabled";
+
+               phys = <&padctl TEGRA_XUSB_PADCTL_PCIE>;
+               phy-names = "pcie";
+
+               pci@1,0 {
+                       device_type = "pci";
+                       assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
+                       reg = <0x000800 0 0 0 0>;
+                       status = "disabled";
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       nvidia,num-lanes = <2>;
+               };
+
+               pci@2,0 {
+                       device_type = "pci";
+                       assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
+                       reg = <0x001000 0 0 0 0>;
+                       status = "disabled";
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       nvidia,num-lanes = <1>;
+               };
+       };
+
+       host1x@0,50000000 {
+               compatible = "nvidia,tegra124-host1x", "simple-bus";
+               reg = <0x0 0x50000000 0x0 0x00034000>;
+               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+                            <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+               clocks = <&tegra_car TEGRA124_CLK_HOST1X>;
+               clock-names = "host1x";
+               resets = <&tegra_car 28>;
+               reset-names = "host1x";
+
+               #address-cells = <2>;
+               #size-cells = <2>;
+
+               ranges = <0 0x54000000 0 0x54000000 0 0x01000000>;
+
+               dc@0,54200000 {
+                       compatible = "nvidia,tegra124-dc";
+                       reg = <0x0 0x54200000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_DISP1>,
+                                <&tegra_car TEGRA124_CLK_PLL_P>;
+                       clock-names = "dc", "parent";
+                       resets = <&tegra_car 27>;
+                       reset-names = "dc";
+
+                       iommus = <&mc TEGRA_SWGROUP_DC>;
+
+                       nvidia,head = <0>;
+               };
+
+               dc@0,54240000 {
+                       compatible = "nvidia,tegra124-dc";
+                       reg = <0x0 0x54240000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_DISP2>,
+                                <&tegra_car TEGRA124_CLK_PLL_P>;
+                       clock-names = "dc", "parent";
+                       resets = <&tegra_car 26>;
+                       reset-names = "dc";
+
+                       iommus = <&mc TEGRA_SWGROUP_DCB>;
+
+                       nvidia,head = <1>;
+               };
+
+               hdmi@0,54280000 {
+                       compatible = "nvidia,tegra124-hdmi";
+                       reg = <0x0 0x54280000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_HDMI>,
+                                <&tegra_car TEGRA124_CLK_PLL_D2_OUT0>;
+                       clock-names = "hdmi", "parent";
+                       resets = <&tegra_car 51>;
+                       reset-names = "hdmi";
+                       status = "disabled";
+               };
+
+               sor@0,54540000 {
+                       compatible = "nvidia,tegra124-sor";
+                       reg = <0x0 0x54540000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_SOR0>,
+                                <&tegra_car TEGRA124_CLK_PLL_D_OUT0>,
+                                <&tegra_car TEGRA124_CLK_PLL_DP>,
+                                <&tegra_car TEGRA124_CLK_CLK_M>;
+                       clock-names = "sor", "parent", "dp", "safe";
+                       resets = <&tegra_car 182>;
+                       reset-names = "sor";
+                       status = "disabled";
+               };
+
+               dpaux: dpaux@0,545c0000 {
+                       compatible = "nvidia,tegra124-dpaux";
+                       reg = <0x0 0x545c0000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_DPAUX>,
+                                <&tegra_car TEGRA124_CLK_PLL_DP>;
+                       clock-names = "dpaux", "parent";
+                       resets = <&tegra_car 181>;
+                       reset-names = "dpaux";
+                       status = "disabled";
+               };
+       };
+
+       gic: interrupt-controller@0,50041000 {
+               compatible = "arm,cortex-a15-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x0 0x50041000 0x0 0x1000>,
+                     <0x0 0x50042000 0x0 0x2000>,
+                     <0x0 0x50044000 0x0 0x2000>,
+                     <0x0 0x50046000 0x0 0x2000>;
+               interrupts = <GIC_PPI 9
+                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               interrupt-parent = <&gic>;
+       };
+
+       gpu@0,57000000 {
+               compatible = "nvidia,gk20a";
+               reg = <0x0 0x57000000 0x0 0x01000000>,
+                     <0x0 0x58000000 0x0 0x01000000>;
+               interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "stall", "nonstall";
+               clocks = <&tegra_car TEGRA124_CLK_GPU>,
+                        <&tegra_car TEGRA124_CLK_PLL_P_OUT5>;
+               clock-names = "gpu", "pwr";
+               resets = <&tegra_car 184>;
+               reset-names = "gpu";
+               status = "disabled";
+       };
+
+       lic: interrupt-controller@60004000 {
+               compatible = "nvidia,tegra124-ictlr", "nvidia,tegra30-ictlr";
+               reg = <0x0 0x60004000 0x0 0x100>,
+                     <0x0 0x60004100 0x0 0x100>,
+                     <0x0 0x60004200 0x0 0x100>,
+                     <0x0 0x60004300 0x0 0x100>,
+                     <0x0 0x60004400 0x0 0x100>;
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               interrupt-parent = <&gic>;
+       };
+
+       timer@0,60005000 {
+               compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer";
+               reg = <0x0 0x60005000 0x0 0x400>;
+               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_TIMER>;
+               clock-names = "timer";
+       };
+
+       tegra_car: clock@0,60006000 {
+               compatible = "nvidia,tegra132-car";
+               reg = <0x0 0x60006000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               nvidia,external-memory-controller = <&emc>;
+       };
+
+       flow-controller@0,60007000 {
+               compatible = "nvidia,tegra124-flowctrl";
+               reg = <0x0 0x60007000 0x0 0x1000>;
+       };
+
+       actmon@0,6000c800 {
+               compatible = "nvidia,tegra124-actmon";
+               reg = <0x0 0x6000c800 0x0 0x400>;
+               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_ACTMON>,
+                        <&tegra_car TEGRA124_CLK_EMC>;
+               clock-names = "actmon", "emc";
+               resets = <&tegra_car 119>;
+               reset-names = "actmon";
+       };
+
+       gpio: gpio@0,6000d000 {
+               compatible = "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
+               reg = <0x0 0x6000d000 0x0 0x1000>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       apbdma: dma@0,60020000 {
+               compatible = "nvidia,tegra124-apbdma", "nvidia,tegra148-apbdma";
+               reg = <0x0 0x60020000 0x0 0x1400>;
+               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_APBDMA>;
+               clock-names = "dma";
+               resets = <&tegra_car 34>;
+               reset-names = "dma";
+               #dma-cells = <1>;
+       };
+
+       apbmisc@0,70000800 {
+               compatible = "nvidia,tegra124-apbmisc", "nvidia,tegra20-apbmisc";
+               reg = <0x0 0x70000800 0x0 0x64>,   /* Chip revision */
+                     <0x0 0x7000e864 0x0 0x04>;   /* Strapping options */
+       };
+
+       pinmux: pinmux@0,70000868 {
+               compatible = "nvidia,tegra124-pinmux";
+               reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
+                     <0x0 0x70003000 0x0 0x434>, /* Mux registers */
+                     <0x0 0x70000820 0x0 0x008>; /* MIPI pad control */
+       };
+
+       /*
+        * There are two serial driver i.e. 8250 based simple serial
+        * driver and APB DMA based serial driver for higher baudrate
+        * and performace. To enable the 8250 based driver, the compatible
+        * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable
+        * the APB DMA based serial driver, the comptible is
+        * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart".
+        */
+       uarta: serial@0,70006000 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006000 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_UARTA>;
+               clock-names = "serial";
+               resets = <&tegra_car 6>;
+               reset-names = "serial";
+               dmas = <&apbdma 8>, <&apbdma 8>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       uartb: serial@0,70006040 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006040 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_UARTB>;
+               clock-names = "serial";
+               resets = <&tegra_car 7>;
+               reset-names = "serial";
+               dmas = <&apbdma 9>, <&apbdma 9>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       uartc: serial@0,70006200 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006200 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_UARTC>;
+               clock-names = "serial";
+               resets = <&tegra_car 55>;
+               reset-names = "serial";
+               dmas = <&apbdma 10>, <&apbdma 10>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       uartd: serial@0,70006300 {
+               compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006300 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_UARTD>;
+               clock-names = "serial";
+               resets = <&tegra_car 65>;
+               reset-names = "serial";
+               dmas = <&apbdma 19>, <&apbdma 19>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       pwm: pwm@0,7000a000 {
+               compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
+               reg = <0x0 0x7000a000 0x0 0x100>;
+               #pwm-cells = <2>;
+               clocks = <&tegra_car TEGRA124_CLK_PWM>;
+               clock-names = "pwm";
+               resets = <&tegra_car 17>;
+               reset-names = "pwm";
+               status = "disabled";
+       };
+
+       i2c@0,7000c000 {
+               compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c000 0x0 0x100>;
+               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_I2C1>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 12>;
+               reset-names = "i2c";
+               dmas = <&apbdma 21>, <&apbdma 21>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000c400 {
+               compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c400 0x0 0x100>;
+               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_I2C2>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 54>;
+               reset-names = "i2c";
+               dmas = <&apbdma 22>, <&apbdma 22>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000c500 {
+               compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c500 0x0 0x100>;
+               interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_I2C3>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 67>;
+               reset-names = "i2c";
+               dmas = <&apbdma 23>, <&apbdma 23>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000c700 {
+               compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c700 0x0 0x100>;
+               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_I2C4>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 103>;
+               reset-names = "i2c";
+               dmas = <&apbdma 26>, <&apbdma 26>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000d000 {
+               compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000d000 0x0 0x100>;
+               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_I2C5>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 47>;
+               reset-names = "i2c";
+               dmas = <&apbdma 24>, <&apbdma 24>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000d100 {
+               compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000d100 0x0 0x100>;
+               interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_I2C6>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 166>;
+               reset-names = "i2c";
+               dmas = <&apbdma 30>, <&apbdma 30>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000d400 {
+               compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000d400 0x0 0x200>;
+               interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_SBC1>;
+               clock-names = "spi";
+               resets = <&tegra_car 41>;
+               reset-names = "spi";
+               dmas = <&apbdma 15>, <&apbdma 15>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000d600 {
+               compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000d600 0x0 0x200>;
+               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_SBC2>;
+               clock-names = "spi";
+               resets = <&tegra_car 44>;
+               reset-names = "spi";
+               dmas = <&apbdma 16>, <&apbdma 16>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000d800 {
+               compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000d800 0x0 0x200>;
+               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_SBC3>;
+               clock-names = "spi";
+               resets = <&tegra_car 46>;
+               reset-names = "spi";
+               dmas = <&apbdma 17>, <&apbdma 17>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000da00 {
+               compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000da00 0x0 0x200>;
+               interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_SBC4>;
+               clock-names = "spi";
+               resets = <&tegra_car 68>;
+               reset-names = "spi";
+               dmas = <&apbdma 18>, <&apbdma 18>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000dc00 {
+               compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000dc00 0x0 0x200>;
+               interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_SBC5>;
+               clock-names = "spi";
+               resets = <&tegra_car 104>;
+               reset-names = "spi";
+               dmas = <&apbdma 27>, <&apbdma 27>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000de00 {
+               compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000de00 0x0 0x200>;
+               interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA124_CLK_SBC6>;
+               clock-names = "spi";
+               resets = <&tegra_car 105>;
+               reset-names = "spi";
+               dmas = <&apbdma 28>, <&apbdma 28>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       rtc@0,7000e000 {
+               compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
+               reg = <0x0 0x7000e000 0x0 0x100>;
+               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_RTC>;
+               clock-names = "rtc";
+       };
+
+       pmc@0,7000e400 {
+               compatible = "nvidia,tegra124-pmc";
+               reg = <0x0 0x7000e400 0x0 0x400>;
+               clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
+               clock-names = "pclk", "clk32k_in";
+       };
+
+       fuse@0,7000f800 {
+               compatible = "nvidia,tegra124-efuse";
+               reg = <0x0 0x7000f800 0x0 0x400>;
+               clocks = <&tegra_car TEGRA124_CLK_FUSE>;
+               clock-names = "fuse";
+               resets = <&tegra_car 39>;
+               reset-names = "fuse";
+       };
+
+       mc: memory-controller@0,70019000 {
+               compatible = "nvidia,tegra132-mc";
+               reg = <0x0 0x70019000 0x0 0x1000>;
+               clocks = <&tegra_car TEGRA124_CLK_MC>;
+               clock-names = "mc";
+
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+
+               #iommu-cells = <1>;
+       };
+
+       emc: emc@0,7001b000 {
+               compatible = "nvidia,tegra132-emc", "nvidia,tegra124-emc";
+               reg = <0x0 0x7001b000 0x0 0x1000>;
+
+               nvidia,memory-controller = <&mc>;
+       };
+
+       sata@0,70020000 {
+               compatible = "nvidia,tegra124-ahci";
+               reg = <0x0 0x70027000 0x0 0x2000>, /* AHCI */
+                     <0x0 0x70020000 0x0 0x7000>; /* SATA */
+               interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_SATA>,
+                        <&tegra_car TEGRA124_CLK_SATA_OOB>,
+                        <&tegra_car TEGRA124_CLK_CML1>,
+                        <&tegra_car TEGRA124_CLK_PLL_E>;
+               clock-names = "sata", "sata-oob", "cml1", "pll_e";
+               resets = <&tegra_car 124>,
+                        <&tegra_car 123>,
+                        <&tegra_car 129>;
+               reset-names = "sata", "sata-oob", "sata-cold";
+               phys = <&padctl TEGRA_XUSB_PADCTL_SATA>;
+               phy-names = "sata-phy";
+               status = "disabled";
+       };
+
+       hda@0,70030000 {
+               compatible = "nvidia,tegra132-hda", "nvidia,tegra124-hda",
+                            "nvidia,tegra30-hda";
+               reg = <0x0 0x70030000 0x0 0x10000>;
+               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_HDA>,
+                        <&tegra_car TEGRA124_CLK_HDA2HDMI>,
+                        <&tegra_car TEGRA124_CLK_HDA2CODEC_2X>;
+               clock-names = "hda", "hda2hdmi", "hda2codec_2x";
+               resets = <&tegra_car 125>, /* hda */
+                        <&tegra_car 128>, /* hda2hdmi */
+                        <&tegra_car 111>; /* hda2codec_2x */
+               reset-names = "hda", "hda2hdmi", "hda2codec_2x";
+               status = "disabled";
+       };
+
+       padctl: padctl@0,7009f000 {
+               compatible = "nvidia,tegra132-xusb-padctl",
+                            "nvidia,tegra124-xusb-padctl";
+               reg = <0x0 0x7009f000 0x0 0x1000>;
+               resets = <&tegra_car 142>;
+               reset-names = "padctl";
+
+               #phy-cells = <1>;
+
+               phys {
+                       pcie-0 {
+                               status = "disabled";
+                       };
+
+                       sata-0 {
+                               status = "disabled";
+                       };
+
+                       usb3-0 {
+                               status = "disabled";
+                       };
+
+                       usb3-1 {
+                               status = "disabled";
+                       };
+
+                       utmi-0 {
+                               status = "disabled";
+                       };
+
+                       utmi-1 {
+                               status = "disabled";
+                       };
+
+                       utmi-2 {
+                               status = "disabled";
+                       };
+               };
+       };
+
+       sdhci@0,700b0000 {
+               compatible = "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0000 0x0 0x200>;
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_SDMMC1>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 14>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0200 {
+               compatible = "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0200 0x0 0x200>;
+               interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_SDMMC2>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 9>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0400 {
+               compatible = "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0400 0x0 0x200>;
+               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_SDMMC3>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 69>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0600 {
+               compatible = "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0600 0x0 0x200>;
+               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_SDMMC4>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 15>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       soctherm: thermal-sensor@0,700e2000 {
+               compatible = "nvidia,tegra124-soctherm";
+               reg = <0x0 0x700e2000 0x0 0x1000>;
+               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_TSENSOR>,
+                       <&tegra_car TEGRA124_CLK_SOC_THERM>;
+               clock-names = "tsensor", "soctherm";
+               resets = <&tegra_car 78>;
+               reset-names = "soctherm";
+               #thermal-sensor-cells = <1>;
+       };
+
+       ahub@0,70300000 {
+               compatible = "nvidia,tegra124-ahub";
+               reg = <0x0 0x70300000 0x0 0x200>,
+                     <0x0 0x70300800 0x0 0x800>,
+                     <0x0 0x70300200 0x0 0x600>;
+               interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA124_CLK_D_AUDIO>,
+                        <&tegra_car TEGRA124_CLK_APBIF>;
+               clock-names = "d_audio", "apbif";
+               resets = <&tegra_car 106>, /* d_audio */
+                        <&tegra_car 107>, /* apbif */
+                        <&tegra_car 30>,  /* i2s0 */
+                        <&tegra_car 11>,  /* i2s1 */
+                        <&tegra_car 18>,  /* i2s2 */
+                        <&tegra_car 101>, /* i2s3 */
+                        <&tegra_car 102>, /* i2s4 */
+                        <&tegra_car 108>, /* dam0 */
+                        <&tegra_car 109>, /* dam1 */
+                        <&tegra_car 110>, /* dam2 */
+                        <&tegra_car 10>,  /* spdif */
+                        <&tegra_car 153>, /* amx */
+                        <&tegra_car 185>, /* amx1 */
+                        <&tegra_car 154>, /* adx */
+                        <&tegra_car 180>, /* adx1 */
+                        <&tegra_car 186>, /* afc0 */
+                        <&tegra_car 187>, /* afc1 */
+                        <&tegra_car 188>, /* afc2 */
+                        <&tegra_car 189>, /* afc3 */
+                        <&tegra_car 190>, /* afc4 */
+                        <&tegra_car 191>; /* afc5 */
+               reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
+                             "i2s3", "i2s4", "dam0", "dam1", "dam2",
+                             "spdif", "amx", "amx1", "adx", "adx1",
+                             "afc0", "afc1", "afc2", "afc3", "afc4", "afc5";
+               dmas = <&apbdma 1>, <&apbdma 1>,
+                      <&apbdma 2>, <&apbdma 2>,
+                      <&apbdma 3>, <&apbdma 3>,
+                      <&apbdma 4>, <&apbdma 4>,
+                      <&apbdma 6>, <&apbdma 6>,
+                      <&apbdma 7>, <&apbdma 7>,
+                      <&apbdma 12>, <&apbdma 12>,
+                      <&apbdma 13>, <&apbdma 13>,
+                      <&apbdma 14>, <&apbdma 14>,
+                      <&apbdma 29>, <&apbdma 29>;
+               dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2",
+                           "rx3", "tx3", "rx4", "tx4", "rx5", "tx5",
+                           "rx6", "tx6", "rx7", "tx7", "rx8", "tx8",
+                           "rx9", "tx9";
+               ranges;
+               #address-cells = <2>;
+               #size-cells = <2>;
+
+               tegra_i2s0: i2s@0,70301000 {
+                       compatible = "nvidia,tegra124-i2s";
+                       reg = <0x0 0x70301000 0x0 0x100>;
+                       nvidia,ahub-cif-ids = <4 4>;
+                       clocks = <&tegra_car TEGRA124_CLK_I2S0>;
+                       clock-names = "i2s";
+                       resets = <&tegra_car 30>;
+                       reset-names = "i2s";
+                       status = "disabled";
+               };
+
+               tegra_i2s1: i2s@0,70301100 {
+                       compatible = "nvidia,tegra124-i2s";
+                       reg = <0x0 0x70301100 0x0 0x100>;
+                       nvidia,ahub-cif-ids = <5 5>;
+                       clocks = <&tegra_car TEGRA124_CLK_I2S1>;
+                       clock-names = "i2s";
+                       resets = <&tegra_car 11>;
+                       reset-names = "i2s";
+                       status = "disabled";
+               };
+
+               tegra_i2s2: i2s@0,70301200 {
+                       compatible = "nvidia,tegra124-i2s";
+                       reg = <0x0 0x70301200 0x0 0x100>;
+                       nvidia,ahub-cif-ids = <6 6>;
+                       clocks = <&tegra_car TEGRA124_CLK_I2S2>;
+                       clock-names = "i2s";
+                       resets = <&tegra_car 18>;
+                       reset-names = "i2s";
+                       status = "disabled";
+               };
+
+               tegra_i2s3: i2s@0,70301300 {
+                       compatible = "nvidia,tegra124-i2s";
+                       reg = <0x0 0x70301300 0x0 0x100>;
+                       nvidia,ahub-cif-ids = <7 7>;
+                       clocks = <&tegra_car TEGRA124_CLK_I2S3>;
+                       clock-names = "i2s";
+                       resets = <&tegra_car 101>;
+                       reset-names = "i2s";
+                       status = "disabled";
+               };
+
+               tegra_i2s4: i2s@0,70301400 {
+                       compatible = "nvidia,tegra124-i2s";
+                       reg = <0x0 0x70301400 0x0 0x100>;
+                       nvidia,ahub-cif-ids = <8 8>;
+                       clocks = <&tegra_car TEGRA124_CLK_I2S4>;
+                       clock-names = "i2s";
+                       resets = <&tegra_car 102>;
+                       reset-names = "i2s";
+                       status = "disabled";
+               };
+       };
+
+       usb@0,7d000000 {
+               compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d000000 0x0 0x4000>;
+               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "usb";
+               resets = <&tegra_car 22>;
+               reset-names = "usb";
+               nvidia,phy = <&phy1>;
+               status = "disabled";
+       };
+
+       phy1: usb-phy@0,7d000000 {
+               compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d000000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USBD>,
+                        <&tegra_car TEGRA124_CLK_PLL_U>,
+                        <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               resets = <&tegra_car 22>, <&tegra_car 22>;
+               reset-names = "usb", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               nvidia,has-utmi-pad-registers;
+               status = "disabled";
+       };
+
+       usb@0,7d004000 {
+               compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d004000 0x0 0x4000>;
+               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB2>;
+               clock-names = "usb";
+               resets = <&tegra_car 58>;
+               reset-names = "usb";
+               nvidia,phy = <&phy2>;
+               status = "disabled";
+       };
+
+       phy2: usb-phy@0,7d004000 {
+               compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d004000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB2>,
+                        <&tegra_car TEGRA124_CLK_PLL_U>,
+                        <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               resets = <&tegra_car 58>, <&tegra_car 22>;
+               reset-names = "usb", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               status = "disabled";
+       };
+
+       usb@0,7d008000 {
+               compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d008000 0x0 0x4000>;
+               interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB3>;
+               clock-names = "usb";
+               resets = <&tegra_car 59>;
+               reset-names = "usb";
+               nvidia,phy = <&phy3>;
+               status = "disabled";
+       };
+
+       phy3: usb-phy@0,7d008000 {
+               compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d008000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB3>,
+                        <&tegra_car TEGRA124_CLK_PLL_U>,
+                        <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               resets = <&tegra_car 59>, <&tegra_car 22>;
+               reset-names = "usb", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               status = "disabled";
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "nvidia,denver", "arm,armv8";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "nvidia,denver", "arm,armv8";
+                       reg = <1>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <GIC_PPI 13
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+               interrupt-parent = <&gic>;
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
new file mode 100644 (file)
index 0000000..2b7f889
--- /dev/null
@@ -0,0 +1,45 @@
+#include "tegra210.dtsi"
+
+/ {
+       model = "NVIDIA Jetson TX1";
+       compatible = "nvidia,p2180", "nvidia,tegra210";
+
+       aliases {
+               rtc1 = "/rtc@0,7000e000";
+               serial0 = &uarta;
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x1 0x0>;
+       };
+
+       /* debug port */
+       serial@0,70006000 {
+               status = "okay";
+       };
+
+       pmc@0,7000e400 {
+               nvidia,invert-interrupt;
+       };
+
+       /* eMMC */
+       sdhci@0,700b0600 {
+               status = "okay";
+               bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts
new file mode 100644 (file)
index 0000000..1ddd851
--- /dev/null
@@ -0,0 +1,9 @@
+/dts-v1/;
+
+#include "tegra210-p2530.dtsi"
+#include "tegra210-p2595.dtsi"
+
+/ {
+       model = "NVIDIA Tegra210 P2371 (P2530/P2595) reference design";
+       compatible = "nvidia,p2371-0000", "nvidia,tegra210";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
new file mode 100644 (file)
index 0000000..683b339
--- /dev/null
@@ -0,0 +1,9 @@
+/dts-v1/;
+
+#include "tegra210-p2180.dtsi"
+#include "tegra210-p2597.dtsi"
+
+/ {
+       model = "NVIDIA Jetson TX1 Developer Kit";
+       compatible = "nvidia,p2371-2180", "nvidia,tegra210";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi
new file mode 100644 (file)
index 0000000..ece0dec
--- /dev/null
@@ -0,0 +1,50 @@
+#include "tegra210.dtsi"
+
+/ {
+       model = "NVIDIA Tegra210 P2530 main board";
+       compatible = "nvidia,p2530", "nvidia,tegra210";
+
+       aliases {
+               rtc1 = "/rtc@0,7000e000";
+               serial0 = &uarta;
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x0 0xc0000000>;
+       };
+
+       /* debug port */
+       serial@0,70006000 {
+               status = "okay";
+       };
+
+       i2c@0,7000d000 {
+               status = "okay";
+               clock-frequency = <400000>;
+       };
+
+       pmc@0,7000e400 {
+               nvidia,invert-interrupt;
+       };
+
+       /* eMMC */
+       sdhci@0,700b0600 {
+               status = "okay";
+               bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts
new file mode 100644 (file)
index 0000000..58d27dd
--- /dev/null
@@ -0,0 +1,1302 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra210-p2530.dtsi"
+
+/ {
+       model = "NVIDIA Tegra210 P2571 reference design";
+       compatible = "nvidia,p2571", "nvidia,tegra210";
+
+       pinmux: pinmux@0,700008d4 {
+               pinctrl-names = "boot";
+               pinctrl-0 = <&state_boot>;
+
+               state_boot: pinmux {
+                       pex_l0_rst_n_pa0 {
+                               nvidia,pins = "pex_l0_rst_n_pa0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pex_l0_clkreq_n_pa1 {
+                               nvidia,pins = "pex_l0_clkreq_n_pa1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pex_wake_n_pa2 {
+                               nvidia,pins = "pex_wake_n_pa2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pex_l1_rst_n_pa3 {
+                               nvidia,pins = "pex_l1_rst_n_pa3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pex_l1_clkreq_n_pa4 {
+                               nvidia,pins = "pex_l1_clkreq_n_pa4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       sata_led_active_pa5 {
+                               nvidia,pins = "sata_led_active_pa5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pa6 {
+                               nvidia,pins = "pa6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_fs_pb0 {
+                               nvidia,pins = "dap1_fs_pb0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_din_pb1 {
+                               nvidia,pins = "dap1_din_pb1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_dout_pb2 {
+                               nvidia,pins = "dap1_dout_pb2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_sclk_pb3 {
+                               nvidia,pins = "dap1_sclk_pb3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_mosi_pb4 {
+                               nvidia,pins = "spi2_mosi_pb4";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_miso_pb5 {
+                               nvidia,pins = "spi2_miso_pb5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_sck_pb6 {
+                               nvidia,pins = "spi2_sck_pb6";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_cs0_pb7 {
+                               nvidia,pins = "spi2_cs0_pb7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_mosi_pc0 {
+                               nvidia,pins = "spi1_mosi_pc0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_miso_pc1 {
+                               nvidia,pins = "spi1_miso_pc1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_sck_pc2 {
+                               nvidia,pins = "spi1_sck_pc2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_cs0_pc3 {
+                               nvidia,pins = "spi1_cs0_pc3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_cs1_pc4 {
+                               nvidia,pins = "spi1_cs1_pc4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_sck_pc5 {
+                               nvidia,pins = "spi4_sck_pc5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_cs0_pc6 {
+                               nvidia,pins = "spi4_cs0_pc6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_mosi_pc7 {
+                               nvidia,pins = "spi4_mosi_pc7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_miso_pd0 {
+                               nvidia,pins = "spi4_miso_pd0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_tx_pd1 {
+                               nvidia,pins = "uart3_tx_pd1";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_rx_pd2 {
+                               nvidia,pins = "uart3_rx_pd2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_rts_pd3 {
+                               nvidia,pins = "uart3_rts_pd3";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_cts_pd4 {
+                               nvidia,pins = "uart3_cts_pd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic1_clk_pe0 {
+                               nvidia,pins = "dmic1_clk_pe0";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic1_dat_pe1 {
+                               nvidia,pins = "dmic1_dat_pe1";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic2_clk_pe2 {
+                               nvidia,pins = "dmic2_clk_pe2";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic2_dat_pe3 {
+                               nvidia,pins = "dmic2_dat_pe3";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic3_clk_pe4 {
+                               nvidia,pins = "dmic3_clk_pe4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic3_dat_pe5 {
+                               nvidia,pins = "dmic3_dat_pe5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pe6 {
+                               nvidia,pins = "pe6";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pe7 {
+                               nvidia,pins = "pe7";
+                               nvidia,function = "pwm3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen3_i2c_scl_pf0 {
+                               nvidia,pins = "gen3_i2c_scl_pf0";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen3_i2c_sda_pf1 {
+                               nvidia,pins = "gen3_i2c_sda_pf1";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_tx_pg0 {
+                               nvidia,pins = "uart2_tx_pg0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_rx_pg1 {
+                               nvidia,pins = "uart2_rx_pg1";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_rts_pg2 {
+                               nvidia,pins = "uart2_rts_pg2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_cts_pg3 {
+                               nvidia,pins = "uart2_cts_pg3";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_en_ph0 {
+                               nvidia,pins = "wifi_en_ph0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_rst_ph1 {
+                               nvidia,pins = "wifi_rst_ph1";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_wake_ap_ph2 {
+                               nvidia,pins = "wifi_wake_ap_ph2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_wake_bt_ph3 {
+                               nvidia,pins = "ap_wake_bt_ph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       bt_rst_ph4 {
+                               nvidia,pins = "bt_rst_ph4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       bt_wake_ap_ph5 {
+                               nvidia,pins = "bt_wake_ap_ph5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ph6 {
+                               nvidia,pins = "ph6";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_wake_nfc_ph7 {
+                               nvidia,pins = "ap_wake_nfc_ph7";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       nfc_en_pi0 {
+                               nvidia,pins = "nfc_en_pi0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       nfc_int_pi1 {
+                               nvidia,pins = "nfc_int_pi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gps_en_pi2 {
+                               nvidia,pins = "gps_en_pi2";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gps_rst_pi3 {
+                               nvidia,pins = "gps_rst_pi3";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_tx_pi4 {
+                               nvidia,pins = "uart4_tx_pi4";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_rx_pi5 {
+                               nvidia,pins = "uart4_rx_pi5";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_rts_pi6 {
+                               nvidia,pins = "uart4_rts_pi6";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_cts_pi7 {
+                               nvidia,pins = "uart4_cts_pi7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_sda_pj0 {
+                               nvidia,pins = "gen1_i2c_sda_pj0";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_scl_pj1 {
+                               nvidia,pins = "gen1_i2c_scl_pj1";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen2_i2c_scl_pj2 {
+                               nvidia,pins = "gen2_i2c_scl_pj2";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       gen2_i2c_sda_pj3 {
+                               nvidia,pins = "gen2_i2c_sda_pj3";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       dap4_fs_pj4 {
+                               nvidia,pins = "dap4_fs_pj4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_din_pj5 {
+                               nvidia,pins = "dap4_din_pj5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_dout_pj6 {
+                               nvidia,pins = "dap4_dout_pj6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_sclk_pj7 {
+                               nvidia,pins = "dap4_sclk_pj7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk0 {
+                               nvidia,pins = "pk0";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk1 {
+                               nvidia,pins = "pk1";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk2 {
+                               nvidia,pins = "pk2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk3 {
+                               nvidia,pins = "pk3";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk4 {
+                               nvidia,pins = "pk4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk5 {
+                               nvidia,pins = "pk5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk6 {
+                               nvidia,pins = "pk6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk7 {
+                               nvidia,pins = "pk7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pl0 {
+                               nvidia,pins = "pl0";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pl1 {
+                               nvidia,pins = "pl1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_clk_pm0 {
+                               nvidia,pins = "sdmmc1_clk_pm0";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_cmd_pm1 {
+                               nvidia,pins = "sdmmc1_cmd_pm1";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat3_pm2 {
+                               nvidia,pins = "sdmmc1_dat3_pm2";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat2_pm3 {
+                               nvidia,pins = "sdmmc1_dat2_pm3";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat1_pm4 {
+                               nvidia,pins = "sdmmc1_dat1_pm4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat0_pm5 {
+                               nvidia,pins = "sdmmc1_dat0_pm5";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_clk_pp0 {
+                               nvidia,pins = "sdmmc3_clk_pp0";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_cmd_pp1 {
+                               nvidia,pins = "sdmmc3_cmd_pp1";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat3_pp2 {
+                               nvidia,pins = "sdmmc3_dat3_pp2";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat2_pp3 {
+                               nvidia,pins = "sdmmc3_dat2_pp3";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat1_pp4 {
+                               nvidia,pins = "sdmmc3_dat1_pp4";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat0_pp5 {
+                               nvidia,pins = "sdmmc3_dat0_pp5";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_mclk_ps0 {
+                               nvidia,pins = "cam1_mclk_ps0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam2_mclk_ps1 {
+                               nvidia,pins = "cam2_mclk_ps1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_i2c_scl_ps2 {
+                               nvidia,pins = "cam_i2c_scl_ps2";
+                               nvidia,function = "i2cvi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_i2c_sda_ps3 {
+                               nvidia,pins = "cam_i2c_sda_ps3";
+                               nvidia,function = "i2cvi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_rst_ps4 {
+                               nvidia,pins = "cam_rst_ps4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_af_en_ps5 {
+                               nvidia,pins = "cam_af_en_ps5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_flash_en_ps6 {
+                               nvidia,pins = "cam_flash_en_ps6";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_pwdn_ps7 {
+                               nvidia,pins = "cam1_pwdn_ps7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam2_pwdn_pt0 {
+                               nvidia,pins = "cam2_pwdn_pt0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_strobe_pt1 {
+                               nvidia,pins = "cam1_strobe_pt1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_tx_pu0 {
+                               nvidia,pins = "uart1_tx_pu0";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_rx_pu1 {
+                               nvidia,pins = "uart1_rx_pu1";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_rts_pu2 {
+                               nvidia,pins = "uart1_rts_pu2";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_cts_pu3 {
+                               nvidia,pins = "uart1_cts_pu3";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_bl_pwm_pv0 {
+                               nvidia,pins = "lcd_bl_pwm_pv0";
+                               nvidia,function = "pwm0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_bl_en_pv1 {
+                               nvidia,pins = "lcd_bl_en_pv1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_rst_pv2 {
+                               nvidia,pins = "lcd_rst_pv2";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_gpio1_pv3 {
+                               nvidia,pins = "lcd_gpio1_pv3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_gpio2_pv4 {
+                               nvidia,pins = "lcd_gpio2_pv4";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_ready_pv5 {
+                               nvidia,pins = "ap_ready_pv5";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_rst_pv6 {
+                               nvidia,pins = "touch_rst_pv6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_clk_pv7 {
+                               nvidia,pins = "touch_clk_pv7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       modem_wake_ap_px0 {
+                               nvidia,pins = "modem_wake_ap_px0";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_int_px1 {
+                               nvidia,pins = "touch_int_px1";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       motion_int_px2 {
+                               nvidia,pins = "motion_int_px2";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       als_prox_int_px3 {
+                               nvidia,pins = "als_prox_int_px3";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       temp_alert_px4 {
+                               nvidia,pins = "temp_alert_px4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_power_on_px5 {
+                               nvidia,pins = "button_power_on_px5";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_vol_up_px6 {
+                               nvidia,pins = "button_vol_up_px6";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_vol_down_px7 {
+                               nvidia,pins = "button_vol_down_px7";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_slide_sw_py0 {
+                               nvidia,pins = "button_slide_sw_py0";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_home_py1 {
+                               nvidia,pins = "button_home_py1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_te_py2 {
+                               nvidia,pins = "lcd_te_py2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_scl_py3 {
+                               nvidia,pins = "pwr_i2c_scl_py3";
+                               nvidia,function = "i2cpmu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_sda_py4 {
+                               nvidia,pins = "pwr_i2c_sda_py4";
+                               nvidia,function = "i2cpmu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_out_py5 {
+                               nvidia,pins = "clk_32k_out_py5";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz0 {
+                               nvidia,pins = "pz0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz1 {
+                               nvidia,pins = "pz1";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz2 {
+                               nvidia,pins = "pz2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz3 {
+                               nvidia,pins = "pz3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz4 {
+                               nvidia,pins = "pz4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz5 {
+                               nvidia,pins = "pz5";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_fs_paa0 {
+                               nvidia,pins = "dap2_fs_paa0";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_sclk_paa1 {
+                               nvidia,pins = "dap2_sclk_paa1";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_din_paa2 {
+                               nvidia,pins = "dap2_din_paa2";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_dout_paa3 {
+                               nvidia,pins = "dap2_dout_paa3";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       aud_mclk_pbb0 {
+                               nvidia,pins = "aud_mclk_pbb0";
+                               nvidia,function = "aud";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_pwm_pbb1 {
+                               nvidia,pins = "dvfs_pwm_pbb1";
+                               nvidia,function = "cldvfs";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_clk_pbb2 {
+                               nvidia,pins = "dvfs_clk_pbb2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_x1_aud_pbb3 {
+                               nvidia,pins = "gpio_x1_aud_pbb3";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_x3_aud_pbb4 {
+                               nvidia,pins = "gpio_x3_aud_pbb4";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdmi_cec_pcc0 {
+                               nvidia,pins = "hdmi_cec_pcc0";
+                               nvidia,function = "cec";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       hdmi_int_dp_hpd_pcc1 {
+                               nvidia,pins = "hdmi_int_dp_hpd_pcc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_out_pcc2 {
+                               nvidia,pins = "spdif_out_pcc2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_in_pcc3 {
+                               nvidia,pins = "spdif_in_pcc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       usb_vbus_en0_pcc4 {
+                               nvidia,pins = "usb_vbus_en0_pcc4";
+                               nvidia,function = "usb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       usb_vbus_en1_pcc5 {
+                               nvidia,pins = "usb_vbus_en1_pcc5";
+                               nvidia,function = "usb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       dp_hpd0_pcc6 {
+                               nvidia,pins = "dp_hpd0_pcc6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pcc7 {
+                               nvidia,pins = "pcc7";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_cs1_pdd0 {
+                               nvidia,pins = "spi2_cs1_pdd0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_sck_pee0 {
+                               nvidia,pins = "qspi_sck_pee0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_cs_n_pee1 {
+                               nvidia,pins = "qspi_cs_n_pee1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io0_pee2 {
+                               nvidia,pins = "qspi_io0_pee2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io1_pee3 {
+                               nvidia,pins = "qspi_io1_pee3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io2_pee4 {
+                               nvidia,pins = "qspi_io2_pee4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io3_pee5 {
+                               nvidia,pins = "qspi_io3_pee5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       core_pwr_req {
+                               nvidia,pins = "core_pwr_req";
+                               nvidia,function = "core";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cpu_pwr_req {
+                               nvidia,pins = "cpu_pwr_req";
+                               nvidia,function = "cpu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_int_n {
+                               nvidia,pins = "pwr_int_n";
+                               nvidia,function = "pmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_in {
+                               nvidia,pins = "clk_32k_in";
+                               nvidia,function = "clk";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       jtag_rtck {
+                               nvidia,pins = "jtag_rtck";
+                               nvidia,function = "jtag";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_req {
+                               nvidia,pins = "clk_req";
+                               nvidia,function = "sys";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       shutdown {
+                               nvidia,pins = "shutdown";
+                               nvidia,function = "shutdown";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi
new file mode 100644 (file)
index 0000000..f3f9139
--- /dev/null
@@ -0,0 +1,1272 @@
+/ {
+       model = "NVIDIA Tegra210 P2595 I/O board";
+       compatible = "nvidia,p2595", "nvidia,tegra210";
+
+       pinmux: pinmux@0,700008d4 {
+               pinctrl-names = "boot";
+               pinctrl-0 = <&state_boot>;
+
+               state_boot: pinmux {
+                       pex_l0_rst_n_pa0 {
+                               nvidia,pins = "pex_l0_rst_n_pa0";
+                               nvidia,function = "pe0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_l0_clkreq_n_pa1 {
+                               nvidia,pins = "pex_l0_clkreq_n_pa1";
+                               nvidia,function = "pe0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_wake_n_pa2 {
+                               nvidia,pins = "pex_wake_n_pa2";
+                               nvidia,function = "pe";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_l1_rst_n_pa3 {
+                               nvidia,pins = "pex_l1_rst_n_pa3";
+                               nvidia,function = "pe1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_l1_clkreq_n_pa4 {
+                               nvidia,pins = "pex_l1_clkreq_n_pa4";
+                               nvidia,function = "pe1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       sata_led_active_pa5 {
+                               nvidia,pins = "sata_led_active_pa5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pa6 {
+                               nvidia,pins = "pa6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_fs_pb0 {
+                               nvidia,pins = "dap1_fs_pb0";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_din_pb1 {
+                               nvidia,pins = "dap1_din_pb1";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_dout_pb2 {
+                               nvidia,pins = "dap1_dout_pb2";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_sclk_pb3 {
+                               nvidia,pins = "dap1_sclk_pb3";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_mosi_pb4 {
+                               nvidia,pins = "spi2_mosi_pb4";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_miso_pb5 {
+                               nvidia,pins = "spi2_miso_pb5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_sck_pb6 {
+                               nvidia,pins = "spi2_sck_pb6";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_cs0_pb7 {
+                               nvidia,pins = "spi2_cs0_pb7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_mosi_pc0 {
+                               nvidia,pins = "spi1_mosi_pc0";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_miso_pc1 {
+                               nvidia,pins = "spi1_miso_pc1";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_sck_pc2 {
+                               nvidia,pins = "spi1_sck_pc2";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_cs0_pc3 {
+                               nvidia,pins = "spi1_cs0_pc3";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_cs1_pc4 {
+                               nvidia,pins = "spi1_cs1_pc4";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_sck_pc5 {
+                               nvidia,pins = "spi4_sck_pc5";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_cs0_pc6 {
+                               nvidia,pins = "spi4_cs0_pc6";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_mosi_pc7 {
+                               nvidia,pins = "spi4_mosi_pc7";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_miso_pd0 {
+                               nvidia,pins = "spi4_miso_pd0";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_tx_pd1 {
+                               nvidia,pins = "uart3_tx_pd1";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_rx_pd2 {
+                               nvidia,pins = "uart3_rx_pd2";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_rts_pd3 {
+                               nvidia,pins = "uart3_rts_pd3";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_cts_pd4 {
+                               nvidia,pins = "uart3_cts_pd4";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic1_clk_pe0 {
+                               nvidia,pins = "dmic1_clk_pe0";
+                               nvidia,function = "dmic1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic1_dat_pe1 {
+                               nvidia,pins = "dmic1_dat_pe1";
+                               nvidia,function = "dmic1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic2_clk_pe2 {
+                               nvidia,pins = "dmic2_clk_pe2";
+                               nvidia,function = "dmic2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic2_dat_pe3 {
+                               nvidia,pins = "dmic2_dat_pe3";
+                               nvidia,function = "dmic2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic3_clk_pe4 {
+                               nvidia,pins = "dmic3_clk_pe4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic3_dat_pe5 {
+                               nvidia,pins = "dmic3_dat_pe5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pe6 {
+                               nvidia,pins = "pe6";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pe7 {
+                               nvidia,pins = "pe7";
+                               nvidia,function = "pwm3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen3_i2c_scl_pf0 {
+                               nvidia,pins = "gen3_i2c_scl_pf0";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen3_i2c_sda_pf1 {
+                               nvidia,pins = "gen3_i2c_sda_pf1";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_tx_pg0 {
+                               nvidia,pins = "uart2_tx_pg0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_rx_pg1 {
+                               nvidia,pins = "uart2_rx_pg1";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_rts_pg2 {
+                               nvidia,pins = "uart2_rts_pg2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_cts_pg3 {
+                               nvidia,pins = "uart2_cts_pg3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_en_ph0 {
+                               nvidia,pins = "wifi_en_ph0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_rst_ph1 {
+                               nvidia,pins = "wifi_rst_ph1";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_wake_ap_ph2 {
+                               nvidia,pins = "wifi_wake_ap_ph2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_wake_bt_ph3 {
+                               nvidia,pins = "ap_wake_bt_ph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       bt_rst_ph4 {
+                               nvidia,pins = "bt_rst_ph4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       bt_wake_ap_ph5 {
+                               nvidia,pins = "bt_wake_ap_ph5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ph6 {
+                               nvidia,pins = "ph6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_wake_nfc_ph7 {
+                               nvidia,pins = "ap_wake_nfc_ph7";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       nfc_en_pi0 {
+                               nvidia,pins = "nfc_en_pi0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       nfc_int_pi1 {
+                               nvidia,pins = "nfc_int_pi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gps_en_pi2 {
+                               nvidia,pins = "gps_en_pi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gps_rst_pi3 {
+                               nvidia,pins = "gps_rst_pi3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_tx_pi4 {
+                               nvidia,pins = "uart4_tx_pi4";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_rx_pi5 {
+                               nvidia,pins = "uart4_rx_pi5";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_rts_pi6 {
+                               nvidia,pins = "uart4_rts_pi6";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_cts_pi7 {
+                               nvidia,pins = "uart4_cts_pi7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_sda_pj0 {
+                               nvidia,pins = "gen1_i2c_sda_pj0";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_scl_pj1 {
+                               nvidia,pins = "gen1_i2c_scl_pj1";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen2_i2c_scl_pj2 {
+                               nvidia,pins = "gen2_i2c_scl_pj2";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       gen2_i2c_sda_pj3 {
+                               nvidia,pins = "gen2_i2c_sda_pj3";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       dap4_fs_pj4 {
+                               nvidia,pins = "dap4_fs_pj4";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_din_pj5 {
+                               nvidia,pins = "dap4_din_pj5";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_dout_pj6 {
+                               nvidia,pins = "dap4_dout_pj6";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_sclk_pj7 {
+                               nvidia,pins = "dap4_sclk_pj7";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk0 {
+                               nvidia,pins = "pk0";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk1 {
+                               nvidia,pins = "pk1";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk2 {
+                               nvidia,pins = "pk2";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk3 {
+                               nvidia,pins = "pk3";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk4 {
+                               nvidia,pins = "pk4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk5 {
+                               nvidia,pins = "pk5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk6 {
+                               nvidia,pins = "pk6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk7 {
+                               nvidia,pins = "pk7";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pl0 {
+                               nvidia,pins = "pl0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pl1 {
+                               nvidia,pins = "pl1";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_clk_pm0 {
+                               nvidia,pins = "sdmmc1_clk_pm0";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_cmd_pm1 {
+                               nvidia,pins = "sdmmc1_cmd_pm1";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat3_pm2 {
+                               nvidia,pins = "sdmmc1_dat3_pm2";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat2_pm3 {
+                               nvidia,pins = "sdmmc1_dat2_pm3";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat1_pm4 {
+                               nvidia,pins = "sdmmc1_dat1_pm4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat0_pm5 {
+                               nvidia,pins = "sdmmc1_dat0_pm5";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_clk_pp0 {
+                               nvidia,pins = "sdmmc3_clk_pp0";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_cmd_pp1 {
+                               nvidia,pins = "sdmmc3_cmd_pp1";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat3_pp2 {
+                               nvidia,pins = "sdmmc3_dat3_pp2";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat2_pp3 {
+                               nvidia,pins = "sdmmc3_dat2_pp3";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat1_pp4 {
+                               nvidia,pins = "sdmmc3_dat1_pp4";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat0_pp5 {
+                               nvidia,pins = "sdmmc3_dat0_pp5";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_mclk_ps0 {
+                               nvidia,pins = "cam1_mclk_ps0";
+                               nvidia,function = "extperiph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam2_mclk_ps1 {
+                               nvidia,pins = "cam2_mclk_ps1";
+                               nvidia,function = "extperiph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_i2c_scl_ps2 {
+                               nvidia,pins = "cam_i2c_scl_ps2";
+                               nvidia,function = "i2cvi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_i2c_sda_ps3 {
+                               nvidia,pins = "cam_i2c_sda_ps3";
+                               nvidia,function = "i2cvi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_rst_ps4 {
+                               nvidia,pins = "cam_rst_ps4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_af_en_ps5 {
+                               nvidia,pins = "cam_af_en_ps5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_flash_en_ps6 {
+                               nvidia,pins = "cam_flash_en_ps6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_pwdn_ps7 {
+                               nvidia,pins = "cam1_pwdn_ps7";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam2_pwdn_pt0 {
+                               nvidia,pins = "cam2_pwdn_pt0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_strobe_pt1 {
+                               nvidia,pins = "cam1_strobe_pt1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_tx_pu0 {
+                               nvidia,pins = "uart1_tx_pu0";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_rx_pu1 {
+                               nvidia,pins = "uart1_rx_pu1";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_rts_pu2 {
+                               nvidia,pins = "uart1_rts_pu2";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_cts_pu3 {
+                               nvidia,pins = "uart1_cts_pu3";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_bl_pwm_pv0 {
+                               nvidia,pins = "lcd_bl_pwm_pv0";
+                               nvidia,function = "pwm0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_bl_en_pv1 {
+                               nvidia,pins = "lcd_bl_en_pv1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_rst_pv2 {
+                               nvidia,pins = "lcd_rst_pv2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_gpio1_pv3 {
+                               nvidia,pins = "lcd_gpio1_pv3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_gpio2_pv4 {
+                               nvidia,pins = "lcd_gpio2_pv4";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_ready_pv5 {
+                               nvidia,pins = "ap_ready_pv5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_rst_pv6 {
+                               nvidia,pins = "touch_rst_pv6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_clk_pv7 {
+                               nvidia,pins = "touch_clk_pv7";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       modem_wake_ap_px0 {
+                               nvidia,pins = "modem_wake_ap_px0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_int_px1 {
+                               nvidia,pins = "touch_int_px1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       motion_int_px2 {
+                               nvidia,pins = "motion_int_px2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       als_prox_int_px3 {
+                               nvidia,pins = "als_prox_int_px3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       temp_alert_px4 {
+                               nvidia,pins = "temp_alert_px4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_power_on_px5 {
+                               nvidia,pins = "button_power_on_px5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_vol_up_px6 {
+                               nvidia,pins = "button_vol_up_px6";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_vol_down_px7 {
+                               nvidia,pins = "button_vol_down_px7";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_slide_sw_py0 {
+                               nvidia,pins = "button_slide_sw_py0";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_home_py1 {
+                               nvidia,pins = "button_home_py1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_te_py2 {
+                               nvidia,pins = "lcd_te_py2";
+                               nvidia,function = "displaya";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_scl_py3 {
+                               nvidia,pins = "pwr_i2c_scl_py3";
+                               nvidia,function = "i2cpmu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_sda_py4 {
+                               nvidia,pins = "pwr_i2c_sda_py4";
+                               nvidia,function = "i2cpmu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_out_py5 {
+                               nvidia,pins = "clk_32k_out_py5";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz0 {
+                               nvidia,pins = "pz0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz1 {
+                               nvidia,pins = "pz1";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz2 {
+                               nvidia,pins = "pz2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz3 {
+                               nvidia,pins = "pz3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz4 {
+                               nvidia,pins = "pz4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz5 {
+                               nvidia,pins = "pz5";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_fs_paa0 {
+                               nvidia,pins = "dap2_fs_paa0";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_sclk_paa1 {
+                               nvidia,pins = "dap2_sclk_paa1";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_din_paa2 {
+                               nvidia,pins = "dap2_din_paa2";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_dout_paa3 {
+                               nvidia,pins = "dap2_dout_paa3";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       aud_mclk_pbb0 {
+                               nvidia,pins = "aud_mclk_pbb0";
+                               nvidia,function = "aud";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_pwm_pbb1 {
+                               nvidia,pins = "dvfs_pwm_pbb1";
+                               nvidia,function = "cldvfs";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_clk_pbb2 {
+                               nvidia,pins = "dvfs_clk_pbb2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_x1_aud_pbb3 {
+                               nvidia,pins = "gpio_x1_aud_pbb3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_x3_aud_pbb4 {
+                               nvidia,pins = "gpio_x3_aud_pbb4";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdmi_cec_pcc0 {
+                               nvidia,pins = "hdmi_cec_pcc0";
+                               nvidia,function = "cec";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       hdmi_int_dp_hpd_pcc1 {
+                               nvidia,pins = "hdmi_int_dp_hpd_pcc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_out_pcc2 {
+                               nvidia,pins = "spdif_out_pcc2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_in_pcc3 {
+                               nvidia,pins = "spdif_in_pcc3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       usb_vbus_en0_pcc4 {
+                               nvidia,pins = "usb_vbus_en0_pcc4";
+                               nvidia,function = "usb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       usb_vbus_en1_pcc5 {
+                               nvidia,pins = "usb_vbus_en1_pcc5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       dp_hpd0_pcc6 {
+                               nvidia,pins = "dp_hpd0_pcc6";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pcc7 {
+                               nvidia,pins = "pcc7";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_cs1_pdd0 {
+                               nvidia,pins = "spi2_cs1_pdd0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_sck_pee0 {
+                               nvidia,pins = "qspi_sck_pee0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_cs_n_pee1 {
+                               nvidia,pins = "qspi_cs_n_pee1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io0_pee2 {
+                               nvidia,pins = "qspi_io0_pee2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io1_pee3 {
+                               nvidia,pins = "qspi_io1_pee3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io2_pee4 {
+                               nvidia,pins = "qspi_io2_pee4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io3_pee5 {
+                               nvidia,pins = "qspi_io3_pee5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       core_pwr_req {
+                               nvidia,pins = "core_pwr_req";
+                               nvidia,function = "core";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cpu_pwr_req {
+                               nvidia,pins = "cpu_pwr_req";
+                               nvidia,function = "cpu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_int_n {
+                               nvidia,pins = "pwr_int_n";
+                               nvidia,function = "pmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_in {
+                               nvidia,pins = "clk_32k_in";
+                               nvidia,function = "clk";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       jtag_rtck {
+                               nvidia,pins = "jtag_rtck";
+                               nvidia,function = "jtag";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_req {
+                               nvidia,pins = "clk_req";
+                               nvidia,function = "sys";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       shutdown {
+                               nvidia,pins = "shutdown";
+                               nvidia,function = "shutdown";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
new file mode 100644 (file)
index 0000000..be3eccb
--- /dev/null
@@ -0,0 +1,1270 @@
+/ {
+       model = "NVIDIA Tegra210 P2597 I/O board";
+       compatible = "nvidia,p2597", "nvidia,tegra210";
+
+       pinmux: pinmux@0,700008d4 {
+               pinctrl-names = "boot";
+               pinctrl-0 = <&state_boot>;
+
+               state_boot: pinmux {
+                       pex_l0_rst_n_pa0 {
+                               nvidia,pins = "pex_l0_rst_n_pa0";
+                               nvidia,function = "pe0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_l0_clkreq_n_pa1 {
+                               nvidia,pins = "pex_l0_clkreq_n_pa1";
+                               nvidia,function = "pe0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_wake_n_pa2 {
+                               nvidia,pins = "pex_wake_n_pa2";
+                               nvidia,function = "pe";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_l1_rst_n_pa3 {
+                               nvidia,pins = "pex_l1_rst_n_pa3";
+                               nvidia,function = "pe1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       pex_l1_clkreq_n_pa4 {
+                               nvidia,pins = "pex_l1_clkreq_n_pa4";
+                               nvidia,function = "pe1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       sata_led_active_pa5 {
+                               nvidia,pins = "sata_led_active_pa5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pa6 {
+                               nvidia,pins = "pa6";
+                               nvidia,function = "sata";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_fs_pb0 {
+                               nvidia,pins = "dap1_fs_pb0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_din_pb1 {
+                               nvidia,pins = "dap1_din_pb1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_dout_pb2 {
+                               nvidia,pins = "dap1_dout_pb2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1_sclk_pb3 {
+                               nvidia,pins = "dap1_sclk_pb3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_mosi_pb4 {
+                               nvidia,pins = "spi2_mosi_pb4";
+                               nvidia,function = "spi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_miso_pb5 {
+                               nvidia,pins = "spi2_miso_pb5";
+                               nvidia,function = "spi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_sck_pb6 {
+                               nvidia,pins = "spi2_sck_pb6";
+                               nvidia,function = "spi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_cs0_pb7 {
+                               nvidia,pins = "spi2_cs0_pb7";
+                               nvidia,function = "spi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_mosi_pc0 {
+                               nvidia,pins = "spi1_mosi_pc0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_miso_pc1 {
+                               nvidia,pins = "spi1_miso_pc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_sck_pc2 {
+                               nvidia,pins = "spi1_sck_pc2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_cs0_pc3 {
+                               nvidia,pins = "spi1_cs0_pc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi1_cs1_pc4 {
+                               nvidia,pins = "spi1_cs1_pc4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_sck_pc5 {
+                               nvidia,pins = "spi4_sck_pc5";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_cs0_pc6 {
+                               nvidia,pins = "spi4_cs0_pc6";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_mosi_pc7 {
+                               nvidia,pins = "spi4_mosi_pc7";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi4_miso_pd0 {
+                               nvidia,pins = "spi4_miso_pd0";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_tx_pd1 {
+                               nvidia,pins = "uart3_tx_pd1";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_rx_pd2 {
+                               nvidia,pins = "uart3_rx_pd2";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_rts_pd3 {
+                               nvidia,pins = "uart3_rts_pd3";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart3_cts_pd4 {
+                               nvidia,pins = "uart3_cts_pd4";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic1_clk_pe0 {
+                               nvidia,pins = "dmic1_clk_pe0";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic1_dat_pe1 {
+                               nvidia,pins = "dmic1_dat_pe1";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic2_clk_pe2 {
+                               nvidia,pins = "dmic2_clk_pe2";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic2_dat_pe3 {
+                               nvidia,pins = "dmic2_dat_pe3";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic3_clk_pe4 {
+                               nvidia,pins = "dmic3_clk_pe4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dmic3_dat_pe5 {
+                               nvidia,pins = "dmic3_dat_pe5";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pe6 {
+                               nvidia,pins = "pe6";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pe7 {
+                               nvidia,pins = "pe7";
+                               nvidia,function = "pwm3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen3_i2c_scl_pf0 {
+                               nvidia,pins = "gen3_i2c_scl_pf0";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen3_i2c_sda_pf1 {
+                               nvidia,pins = "gen3_i2c_sda_pf1";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_tx_pg0 {
+                               nvidia,pins = "uart2_tx_pg0";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_rx_pg1 {
+                               nvidia,pins = "uart2_rx_pg1";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_rts_pg2 {
+                               nvidia,pins = "uart2_rts_pg2";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2_cts_pg3 {
+                               nvidia,pins = "uart2_cts_pg3";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_en_ph0 {
+                               nvidia,pins = "wifi_en_ph0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_rst_ph1 {
+                               nvidia,pins = "wifi_rst_ph1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       wifi_wake_ap_ph2 {
+                               nvidia,pins = "wifi_wake_ap_ph2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_wake_bt_ph3 {
+                               nvidia,pins = "ap_wake_bt_ph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       bt_rst_ph4 {
+                               nvidia,pins = "bt_rst_ph4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       bt_wake_ap_ph5 {
+                               nvidia,pins = "bt_wake_ap_ph5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ph6 {
+                               nvidia,pins = "ph6";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_wake_nfc_ph7 {
+                               nvidia,pins = "ap_wake_nfc_ph7";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       nfc_en_pi0 {
+                               nvidia,pins = "nfc_en_pi0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       nfc_int_pi1 {
+                               nvidia,pins = "nfc_int_pi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gps_en_pi2 {
+                               nvidia,pins = "gps_en_pi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gps_rst_pi3 {
+                               nvidia,pins = "gps_rst_pi3";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_tx_pi4 {
+                               nvidia,pins = "uart4_tx_pi4";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_rx_pi5 {
+                               nvidia,pins = "uart4_rx_pi5";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_rts_pi6 {
+                               nvidia,pins = "uart4_rts_pi6";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart4_cts_pi7 {
+                               nvidia,pins = "uart4_cts_pi7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_sda_pj0 {
+                               nvidia,pins = "gen1_i2c_sda_pj0";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen1_i2c_scl_pj1 {
+                               nvidia,pins = "gen1_i2c_scl_pj1";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       gen2_i2c_scl_pj2 {
+                               nvidia,pins = "gen2_i2c_scl_pj2";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       gen2_i2c_sda_pj3 {
+                               nvidia,pins = "gen2_i2c_sda_pj3";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       dap4_fs_pj4 {
+                               nvidia,pins = "dap4_fs_pj4";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_din_pj5 {
+                               nvidia,pins = "dap4_din_pj5";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_dout_pj6 {
+                               nvidia,pins = "dap4_dout_pj6";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap4_sclk_pj7 {
+                               nvidia,pins = "dap4_sclk_pj7";
+                               nvidia,function = "i2s4b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk0 {
+                               nvidia,pins = "pk0";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk1 {
+                               nvidia,pins = "pk1";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk2 {
+                               nvidia,pins = "pk2";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk3 {
+                               nvidia,pins = "pk3";
+                               nvidia,function = "i2s5b";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk4 {
+                               nvidia,pins = "pk4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk5 {
+                               nvidia,pins = "pk5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk6 {
+                               nvidia,pins = "pk6";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pk7 {
+                               nvidia,pins = "pk7";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pl0 {
+                               nvidia,pins = "pl0";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pl1 {
+                               nvidia,pins = "pl1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_clk_pm0 {
+                               nvidia,pins = "sdmmc1_clk_pm0";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_cmd_pm1 {
+                               nvidia,pins = "sdmmc1_cmd_pm1";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat3_pm2 {
+                               nvidia,pins = "sdmmc1_dat3_pm2";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat2_pm3 {
+                               nvidia,pins = "sdmmc1_dat2_pm3";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat1_pm4 {
+                               nvidia,pins = "sdmmc1_dat1_pm4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1_dat0_pm5 {
+                               nvidia,pins = "sdmmc1_dat0_pm5";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_clk_pp0 {
+                               nvidia,pins = "sdmmc3_clk_pp0";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_cmd_pp1 {
+                               nvidia,pins = "sdmmc3_cmd_pp1";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat3_pp2 {
+                               nvidia,pins = "sdmmc3_dat3_pp2";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat2_pp3 {
+                               nvidia,pins = "sdmmc3_dat2_pp3";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat1_pp4 {
+                               nvidia,pins = "sdmmc3_dat1_pp4";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3_dat0_pp5 {
+                               nvidia,pins = "sdmmc3_dat0_pp5";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_mclk_ps0 {
+                               nvidia,pins = "cam1_mclk_ps0";
+                               nvidia,function = "extperiph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam2_mclk_ps1 {
+                               nvidia,pins = "cam2_mclk_ps1";
+                               nvidia,function = "extperiph3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_i2c_scl_ps2 {
+                               nvidia,pins = "cam_i2c_scl_ps2";
+                               nvidia,function = "i2cvi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_i2c_sda_ps3 {
+                               nvidia,pins = "cam_i2c_sda_ps3";
+                               nvidia,function = "i2cvi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_rst_ps4 {
+                               nvidia,pins = "cam_rst_ps4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_af_en_ps5 {
+                               nvidia,pins = "cam_af_en_ps5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam_flash_en_ps6 {
+                               nvidia,pins = "cam_flash_en_ps6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_pwdn_ps7 {
+                               nvidia,pins = "cam1_pwdn_ps7";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam2_pwdn_pt0 {
+                               nvidia,pins = "cam2_pwdn_pt0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam1_strobe_pt1 {
+                               nvidia,pins = "cam1_strobe_pt1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_tx_pu0 {
+                               nvidia,pins = "uart1_tx_pu0";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_rx_pu1 {
+                               nvidia,pins = "uart1_rx_pu1";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_rts_pu2 {
+                               nvidia,pins = "uart1_rts_pu2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart1_cts_pu3 {
+                               nvidia,pins = "uart1_cts_pu3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_bl_pwm_pv0 {
+                               nvidia,pins = "lcd_bl_pwm_pv0";
+                               nvidia,function = "pwm0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_bl_en_pv1 {
+                               nvidia,pins = "lcd_bl_en_pv1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_rst_pv2 {
+                               nvidia,pins = "lcd_rst_pv2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_gpio1_pv3 {
+                               nvidia,pins = "lcd_gpio1_pv3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_gpio2_pv4 {
+                               nvidia,pins = "lcd_gpio2_pv4";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       ap_ready_pv5 {
+                               nvidia,pins = "ap_ready_pv5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_rst_pv6 {
+                               nvidia,pins = "touch_rst_pv6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_clk_pv7 {
+                               nvidia,pins = "touch_clk_pv7";
+                               nvidia,function = "touch";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       modem_wake_ap_px0 {
+                               nvidia,pins = "modem_wake_ap_px0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       touch_int_px1 {
+                               nvidia,pins = "touch_int_px1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       motion_int_px2 {
+                               nvidia,pins = "motion_int_px2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       als_prox_int_px3 {
+                               nvidia,pins = "als_prox_int_px3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       temp_alert_px4 {
+                               nvidia,pins = "temp_alert_px4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_power_on_px5 {
+                               nvidia,pins = "button_power_on_px5";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_vol_up_px6 {
+                               nvidia,pins = "button_vol_up_px6";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_vol_down_px7 {
+                               nvidia,pins = "button_vol_down_px7";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_slide_sw_py0 {
+                               nvidia,pins = "button_slide_sw_py0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       button_home_py1 {
+                               nvidia,pins = "button_home_py1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd_te_py2 {
+                               nvidia,pins = "lcd_te_py2";
+                               nvidia,function = "displaya";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_scl_py3 {
+                               nvidia,pins = "pwr_i2c_scl_py3";
+                               nvidia,function = "i2cpmu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_i2c_sda_py4 {
+                               nvidia,pins = "pwr_i2c_sda_py4";
+                               nvidia,function = "i2cpmu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_out_py5 {
+                               nvidia,pins = "clk_32k_out_py5";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz0 {
+                               nvidia,pins = "pz0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz1 {
+                               nvidia,pins = "pz1";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz2 {
+                               nvidia,pins = "pz2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz3 {
+                               nvidia,pins = "pz3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz4 {
+                               nvidia,pins = "pz4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pz5 {
+                               nvidia,pins = "pz5";
+                               nvidia,function = "soc";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_fs_paa0 {
+                               nvidia,pins = "dap2_fs_paa0";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_sclk_paa1 {
+                               nvidia,pins = "dap2_sclk_paa1";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_din_paa2 {
+                               nvidia,pins = "dap2_din_paa2";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2_dout_paa3 {
+                               nvidia,pins = "dap2_dout_paa3";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       aud_mclk_pbb0 {
+                               nvidia,pins = "aud_mclk_pbb0";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_pwm_pbb1 {
+                               nvidia,pins = "dvfs_pwm_pbb1";
+                               nvidia,function = "cldvfs";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       dvfs_clk_pbb2 {
+                               nvidia,pins = "dvfs_clk_pbb2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_x1_aud_pbb3 {
+                               nvidia,pins = "gpio_x1_aud_pbb3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_x3_aud_pbb4 {
+                               nvidia,pins = "gpio_x3_aud_pbb4";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdmi_cec_pcc0 {
+                               nvidia,pins = "hdmi_cec_pcc0";
+                               nvidia,function = "cec";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       hdmi_int_dp_hpd_pcc1 {
+                               nvidia,pins = "hdmi_int_dp_hpd_pcc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_out_pcc2 {
+                               nvidia,pins = "spdif_out_pcc2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       spdif_in_pcc3 {
+                               nvidia,pins = "spdif_in_pcc3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       usb_vbus_en0_pcc4 {
+                               nvidia,pins = "usb_vbus_en0_pcc4";
+                               nvidia,function = "usb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       usb_vbus_en1_pcc5 {
+                               nvidia,pins = "usb_vbus_en1_pcc5";
+                               nvidia,function = "usb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+                       };
+                       dp_hpd0_pcc6 {
+                               nvidia,pins = "dp_hpd0_pcc6";
+                               nvidia,function = "dp";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pcc7 {
+                               nvidia,pins = "pcc7";
+                               nvidia,function = "rsvd0";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+                       };
+                       spi2_cs1_pdd0 {
+                               nvidia,pins = "spi2_cs1_pdd0";
+                               nvidia,function = "spi2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_sck_pee0 {
+                               nvidia,pins = "qspi_sck_pee0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_cs_n_pee1 {
+                               nvidia,pins = "qspi_cs_n_pee1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io0_pee2 {
+                               nvidia,pins = "qspi_io0_pee2";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io1_pee3 {
+                               nvidia,pins = "qspi_io1_pee3";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io2_pee4 {
+                               nvidia,pins = "qspi_io2_pee4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       qspi_io3_pee5 {
+                               nvidia,pins = "qspi_io3_pee5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       core_pwr_req {
+                               nvidia,pins = "core_pwr_req";
+                               nvidia,function = "core";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       cpu_pwr_req {
+                               nvidia,pins = "cpu_pwr_req";
+                               nvidia,function = "cpu";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwr_int_n {
+                               nvidia,pins = "pwr_int_n";
+                               nvidia,function = "pmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_32k_in {
+                               nvidia,pins = "clk_32k_in";
+                               nvidia,function = "clk";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       jtag_rtck {
+                               nvidia,pins = "jtag_rtck";
+                               nvidia,function = "jtag";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk_req {
+                               nvidia,pins = "clk_req";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       shutdown {
+                               nvidia,pins = "shutdown";
+                               nvidia,function = "shutdown";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+               };
+       };
+
+       /* MMC/SD */
+       sdhci@0,700b0000 {
+               status = "okay";
+               bus-width = <4>;
+               no-1-8-v;
+
+               cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
+       };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
new file mode 100644 (file)
index 0000000..bc23f4d
--- /dev/null
@@ -0,0 +1,805 @@
+#include <dt-bindings/clock/tegra210-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra210-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "nvidia,tegra210";
+       interrupt-parent = <&lic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       host1x@0,50000000 {
+               compatible = "nvidia,tegra210-host1x", "simple-bus";
+               reg = <0x0 0x50000000 0x0 0x00034000>;
+               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+                            <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+               clocks = <&tegra_car TEGRA210_CLK_HOST1X>;
+               clock-names = "host1x";
+               resets = <&tegra_car 28>;
+               reset-names = "host1x";
+
+               #address-cells = <2>;
+               #size-cells = <2>;
+
+               ranges = <0x0 0x54000000 0x0 0x54000000 0x0 0x01000000>;
+
+               dpaux1: dpaux@0,54040000 {
+                       compatible = "nvidia,tegra210-dpaux";
+                       reg = <0x0 0x54040000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA210_CLK_DPAUX1>,
+                                <&tegra_car TEGRA210_CLK_PLL_DP>;
+                       clock-names = "dpaux", "parent";
+                       resets = <&tegra_car 207>;
+                       reset-names = "dpaux";
+                       status = "disabled";
+               };
+
+               vi@0,54080000 {
+                       compatible = "nvidia,tegra210-vi";
+                       reg = <0x0 0x54080000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               tsec@0,54100000 {
+                       compatible = "nvidia,tegra210-tsec";
+                       reg = <0x0 0x54100000 0x0 0x00040000>;
+               };
+
+               dc@0,54200000 {
+                       compatible = "nvidia,tegra210-dc";
+                       reg = <0x0 0x54200000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA210_CLK_DISP1>,
+                                <&tegra_car TEGRA210_CLK_PLL_P>;
+                       clock-names = "dc", "parent";
+                       resets = <&tegra_car 27>;
+                       reset-names = "dc";
+
+                       iommus = <&mc TEGRA_SWGROUP_DC>;
+
+                       nvidia,head = <0>;
+               };
+
+               dc@0,54240000 {
+                       compatible = "nvidia,tegra210-dc";
+                       reg = <0x0 0x54240000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA210_CLK_DISP2>,
+                                <&tegra_car TEGRA210_CLK_PLL_P>;
+                       clock-names = "dc", "parent";
+                       resets = <&tegra_car 26>;
+                       reset-names = "dc";
+
+                       iommus = <&mc TEGRA_SWGROUP_DCB>;
+
+                       nvidia,head = <1>;
+               };
+
+               dsi@0,54300000 {
+                       compatible = "nvidia,tegra210-dsi";
+                       reg = <0x0 0x54300000 0x0 0x00040000>;
+                       clocks = <&tegra_car TEGRA210_CLK_DSIA>,
+                                <&tegra_car TEGRA210_CLK_DSIALP>,
+                                <&tegra_car TEGRA210_CLK_PLL_D_OUT0>;
+                       clock-names = "dsi", "lp", "parent";
+                       resets = <&tegra_car 48>;
+                       reset-names = "dsi";
+                       nvidia,mipi-calibrate = <&mipi 0x0c0>; /* DSIA & DSIB pads */
+
+                       status = "disabled";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               vic@0,54340000 {
+                       compatible = "nvidia,tegra210-vic";
+                       reg = <0x0 0x54340000 0x0 0x00040000>;
+                       status = "disabled";
+               };
+
+               nvjpg@0,54380000 {
+                       compatible = "nvidia,tegra210-nvjpg";
+                       reg = <0x0 0x54380000 0x0 0x00040000>;
+                       status = "disabled";
+               };
+
+               dsi@0,54400000 {
+                       compatible = "nvidia,tegra210-dsi";
+                       reg = <0x0 0x54400000 0x0 0x00040000>;
+                       clocks = <&tegra_car TEGRA210_CLK_DSIB>,
+                                <&tegra_car TEGRA210_CLK_DSIBLP>,
+                                <&tegra_car TEGRA210_CLK_PLL_D_OUT0>;
+                       clock-names = "dsi", "lp", "parent";
+                       resets = <&tegra_car 82>;
+                       reset-names = "dsi";
+                       nvidia,mipi-calibrate = <&mipi 0x300>; /* DSIC & DSID pads */
+
+                       status = "disabled";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               nvdec@0,54480000 {
+                       compatible = "nvidia,tegra210-nvdec";
+                       reg = <0x0 0x54480000 0x0 0x00040000>;
+                       status = "disabled";
+               };
+
+               nvenc@0,544c0000 {
+                       compatible = "nvidia,tegra210-nvenc";
+                       reg = <0x0 0x544c0000 0x0 0x00040000>;
+                       status = "disabled";
+               };
+
+               tsec@0,54500000 {
+                       compatible = "nvidia,tegra210-tsec";
+                       reg = <0x0 0x54500000 0x0 0x00040000>;
+                       status = "disabled";
+               };
+
+               sor@0,54540000 {
+                       compatible = "nvidia,tegra210-sor";
+                       reg = <0x0 0x54540000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA210_CLK_SOR0>,
+                                <&tegra_car TEGRA210_CLK_PLL_D_OUT0>,
+                                <&tegra_car TEGRA210_CLK_PLL_DP>,
+                                <&tegra_car TEGRA210_CLK_SOR_SAFE>;
+                       clock-names = "sor", "parent", "dp", "safe";
+                       resets = <&tegra_car 182>;
+                       reset-names = "sor";
+                       status = "disabled";
+               };
+
+               sor@0,54580000 {
+                       compatible = "nvidia,tegra210-sor1";
+                       reg = <0x0 0x54580000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA210_CLK_SOR1>,
+                                <&tegra_car TEGRA210_CLK_PLL_D2_OUT0>,
+                                <&tegra_car TEGRA210_CLK_PLL_DP>,
+                                <&tegra_car TEGRA210_CLK_SOR_SAFE>;
+                       clock-names = "sor", "parent", "dp", "safe";
+                       resets = <&tegra_car 183>;
+                       reset-names = "sor";
+                       status = "disabled";
+               };
+
+               dpaux: dpaux@0,545c0000 {
+                       compatible = "nvidia,tegra124-dpaux";
+                       reg = <0x0 0x545c0000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA210_CLK_DPAUX>,
+                                <&tegra_car TEGRA210_CLK_PLL_DP>;
+                       clock-names = "dpaux", "parent";
+                       resets = <&tegra_car 181>;
+                       reset-names = "dpaux";
+                       status = "disabled";
+               };
+
+               isp@0,54600000 {
+                       compatible = "nvidia,tegra210-isp";
+                       reg = <0x0 0x54600000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               isp@0,54680000 {
+                       compatible = "nvidia,tegra210-isp";
+                       reg = <0x0 0x54680000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               i2c@0,546c0000 {
+                       compatible = "nvidia,tegra210-i2c-vi";
+                       reg = <0x0 0x546c0000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+       };
+
+       gic: interrupt-controller@0,50041000 {
+               compatible = "arm,gic-400";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x0 0x50041000 0x0 0x1000>,
+                     <0x0 0x50042000 0x0 0x2000>,
+                     <0x0 0x50044000 0x0 0x2000>,
+                     <0x0 0x50046000 0x0 0x2000>;
+               interrupts = <GIC_PPI 9
+                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               interrupt-parent = <&gic>;
+       };
+
+       gpu@0,57000000 {
+               compatible = "nvidia,gm20b";
+               reg = <0x0 0x57000000 0x0 0x01000000>,
+                     <0x0 0x58000000 0x0 0x01000000>;
+               interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "stall", "nonstall";
+               clocks = <&tegra_car TEGRA210_CLK_GPU>,
+                        <&tegra_car TEGRA210_CLK_PLL_P_OUT5>;
+               clock-names = "gpu", "pwr";
+               resets = <&tegra_car 184>;
+               reset-names = "gpu";
+               status = "disabled";
+       };
+
+       lic: interrupt-controller@0,60004000 {
+               compatible = "nvidia,tegra210-ictlr";
+               reg = <0x0 0x60004000 0x0 0x40>, /* primary controller */
+                     <0x0 0x60004100 0x0 0x40>, /* secondary controller */
+                     <0x0 0x60004200 0x0 0x40>, /* tertiary controller */
+                     <0x0 0x60004300 0x0 0x40>, /* quaternary controller */
+                     <0x0 0x60004400 0x0 0x40>, /* quinary controller */
+                     <0x0 0x60004500 0x0 0x40>; /* senary controller */
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               interrupt-parent = <&gic>;
+       };
+
+       timer@0,60005000 {
+               compatible = "nvidia,tegra210-timer", "nvidia,tegra20-timer";
+               reg = <0x0 0x60005000 0x0 0x400>;
+               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_TIMER>;
+               clock-names = "timer";
+       };
+
+       tegra_car: clock@0,60006000 {
+               compatible = "nvidia,tegra210-car";
+               reg = <0x0 0x60006000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+       flow-controller@0,60007000 {
+               compatible = "nvidia,tegra210-flowctrl";
+               reg = <0x0 0x60007000 0x0 0x1000>;
+       };
+
+       gpio: gpio@0,6000d000 {
+               compatible = "nvidia,tegra210-gpio", "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
+               reg = <0x0 0x6000d000 0x0 0x1000>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+       };
+
+       apbdma: dma@0,60020000 {
+               compatible = "nvidia,tegra210-apbdma", "nvidia,tegra148-apbdma";
+               reg = <0x0 0x60020000 0x0 0x1400>;
+               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_APBDMA>;
+               clock-names = "dma";
+               resets = <&tegra_car 34>;
+               reset-names = "dma";
+               #dma-cells = <1>;
+       };
+
+       apbmisc@0,70000800 {
+               compatible = "nvidia,tegra210-apbmisc", "nvidia,tegra20-apbmisc";
+               reg = <0x0 0x70000800 0x0 0x64>,   /* Chip revision */
+                     <0x0 0x7000e864 0x0 0x04>;   /* Strapping options */
+       };
+
+       pinmux: pinmux@0,700008d4 {
+               compatible = "nvidia,tegra210-pinmux";
+               reg = <0x0 0x700008d4 0x0 0x29c>, /* Pad control registers */
+                     <0x0 0x70003000 0x0 0x294>; /* Mux registers */
+       };
+
+       /*
+        * There are two serial driver i.e. 8250 based simple serial
+        * driver and APB DMA based serial driver for higher baudrate
+        * and performace. To enable the 8250 based driver, the compatible
+        * is "nvidia,tegra124-uart", "nvidia,tegra20-uart" and to enable
+        * the APB DMA based serial driver, the comptible is
+        * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart".
+        */
+       uarta: serial@0,70006000 {
+               compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006000 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_UARTA>;
+               clock-names = "serial";
+               resets = <&tegra_car 6>;
+               reset-names = "serial";
+               dmas = <&apbdma 8>, <&apbdma 8>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       uartb: serial@0,70006040 {
+               compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006040 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_UARTB>;
+               clock-names = "serial";
+               resets = <&tegra_car 7>;
+               reset-names = "serial";
+               dmas = <&apbdma 9>, <&apbdma 9>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       uartc: serial@0,70006200 {
+               compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006200 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_UARTC>;
+               clock-names = "serial";
+               resets = <&tegra_car 55>;
+               reset-names = "serial";
+               dmas = <&apbdma 10>, <&apbdma 10>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       uartd: serial@0,70006300 {
+               compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+               reg = <0x0 0x70006300 0x0 0x40>;
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_UARTD>;
+               clock-names = "serial";
+               resets = <&tegra_car 65>;
+               reset-names = "serial";
+               dmas = <&apbdma 19>, <&apbdma 19>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       pwm: pwm@0,7000a000 {
+               compatible = "nvidia,tegra210-pwm", "nvidia,tegra20-pwm";
+               reg = <0x0 0x7000a000 0x0 0x100>;
+               #pwm-cells = <2>;
+               clocks = <&tegra_car TEGRA210_CLK_PWM>;
+               clock-names = "pwm";
+               resets = <&tegra_car 17>;
+               reset-names = "pwm";
+               status = "disabled";
+       };
+
+       i2c@0,7000c000 {
+               compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c000 0x0 0x100>;
+               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_I2C1>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 12>;
+               reset-names = "i2c";
+               dmas = <&apbdma 21>, <&apbdma 21>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000c400 {
+               compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c400 0x0 0x100>;
+               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_I2C2>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 54>;
+               reset-names = "i2c";
+               dmas = <&apbdma 22>, <&apbdma 22>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000c500 {
+               compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c500 0x0 0x100>;
+               interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_I2C3>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 67>;
+               reset-names = "i2c";
+               dmas = <&apbdma 23>, <&apbdma 23>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000c700 {
+               compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000c700 0x0 0x100>;
+               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_I2C4>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 103>;
+               reset-names = "i2c";
+               dmas = <&apbdma 26>, <&apbdma 26>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000d000 {
+               compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000d000 0x0 0x100>;
+               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_I2C5>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 47>;
+               reset-names = "i2c";
+               dmas = <&apbdma 24>, <&apbdma 24>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       i2c@0,7000d100 {
+               compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+               reg = <0x0 0x7000d100 0x0 0x100>;
+               interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_I2C6>;
+               clock-names = "div-clk";
+               resets = <&tegra_car 166>;
+               reset-names = "i2c";
+               dmas = <&apbdma 30>, <&apbdma 30>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000d400 {
+               compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000d400 0x0 0x200>;
+               interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_SBC1>;
+               clock-names = "spi";
+               resets = <&tegra_car 41>;
+               reset-names = "spi";
+               dmas = <&apbdma 15>, <&apbdma 15>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000d600 {
+               compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000d600 0x0 0x200>;
+               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_SBC2>;
+               clock-names = "spi";
+               resets = <&tegra_car 44>;
+               reset-names = "spi";
+               dmas = <&apbdma 16>, <&apbdma 16>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000d800 {
+               compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000d800 0x0 0x200>;
+               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_SBC3>;
+               clock-names = "spi";
+               resets = <&tegra_car 46>;
+               reset-names = "spi";
+               dmas = <&apbdma 17>, <&apbdma 17>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       spi@0,7000da00 {
+               compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+               reg = <0x0 0x7000da00 0x0 0x200>;
+               interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_SBC4>;
+               clock-names = "spi";
+               resets = <&tegra_car 68>;
+               reset-names = "spi";
+               dmas = <&apbdma 18>, <&apbdma 18>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       rtc@0,7000e000 {
+               compatible = "nvidia,tegra210-rtc", "nvidia,tegra20-rtc";
+               reg = <0x0 0x7000e000 0x0 0x100>;
+               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_RTC>;
+               clock-names = "rtc";
+       };
+
+       pmc: pmc@0,7000e400 {
+               compatible = "nvidia,tegra210-pmc";
+               reg = <0x0 0x7000e400 0x0 0x400>;
+               clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
+               clock-names = "pclk", "clk32k_in";
+
+               #power-domain-cells = <1>;
+       };
+
+       fuse@0,7000f800 {
+               compatible = "nvidia,tegra210-efuse";
+               reg = <0x0 0x7000f800 0x0 0x400>;
+               clocks = <&tegra_car TEGRA210_CLK_FUSE>;
+               clock-names = "fuse";
+               resets = <&tegra_car 39>;
+               reset-names = "fuse";
+       };
+
+       mc: memory-controller@0,70019000 {
+               compatible = "nvidia,tegra210-mc";
+               reg = <0x0 0x70019000 0x0 0x1000>;
+               clocks = <&tegra_car TEGRA210_CLK_MC>;
+               clock-names = "mc";
+
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+
+               #iommu-cells = <1>;
+       };
+
+       hda@0,70030000 {
+               compatible = "nvidia,tegra210-hda", "nvidia,tegra30-hda";
+               reg = <0x0 0x70030000 0x0 0x10000>;
+               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_HDA>,
+                        <&tegra_car TEGRA210_CLK_HDA2HDMI>,
+                        <&tegra_car TEGRA210_CLK_HDA2CODEC_2X>;
+               clock-names = "hda", "hda2hdmi", "hda2codec_2x";
+               resets = <&tegra_car 125>, /* hda */
+                        <&tegra_car 128>, /* hda2hdmi */
+                        <&tegra_car 111>; /* hda2codec_2x */
+               reset-names = "hda", "hda2hdmi", "hda2codec_2x";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0000 {
+               compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0000 0x0 0x200>;
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 14>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0200 {
+               compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0200 0x0 0x200>;
+               interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_SDMMC2>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 9>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0400 {
+               compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0400 0x0 0x200>;
+               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_SDMMC3>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 69>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       sdhci@0,700b0600 {
+               compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+               reg = <0x0 0x700b0600 0x0 0x200>;
+               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA210_CLK_SDMMC4>;
+               clock-names = "sdhci";
+               resets = <&tegra_car 15>;
+               reset-names = "sdhci";
+               status = "disabled";
+       };
+
+       mipi: mipi@0,700e3000 {
+               compatible = "nvidia,tegra210-mipi";
+               reg = <0x0 0x700e3000 0x0 0x100>;
+               clocks = <&tegra_car TEGRA210_CLK_MIPI_CAL>;
+               clock-names = "mipi-cal";
+               #nvidia,mipi-calibrate-cells = <1>;
+       };
+
+       spi@0,70410000 {
+               compatible = "nvidia,tegra210-qspi";
+               reg = <0x0 0x70410000 0x0 0x1000>;
+               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car TEGRA210_CLK_QSPI>;
+               clock-names = "qspi";
+               resets = <&tegra_car 211>;
+               reset-names = "qspi";
+               dmas = <&apbdma 5>, <&apbdma 5>;
+               dma-names = "rx", "tx";
+               status = "disabled";
+       };
+
+       usb@0,7d000000 {
+               compatible = "nvidia,tegra210-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d000000 0x0 0x4000>;
+               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA210_CLK_USBD>;
+               clock-names = "usb";
+               resets = <&tegra_car 22>;
+               reset-names = "usb";
+               nvidia,phy = <&phy1>;
+               status = "disabled";
+       };
+
+       phy1: usb-phy@0,7d000000 {
+               compatible = "nvidia,tegra210-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d000000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA210_CLK_USBD>,
+                        <&tegra_car TEGRA210_CLK_PLL_U>,
+                        <&tegra_car TEGRA210_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               resets = <&tegra_car 22>, <&tegra_car 22>;
+               reset-names = "usb", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               nvidia,has-utmi-pad-registers;
+               status = "disabled";
+       };
+
+       usb@0,7d004000 {
+               compatible = "nvidia,tegra210-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d004000 0x0 0x4000>;
+               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA210_CLK_USB2>;
+               clock-names = "usb";
+               resets = <&tegra_car 58>;
+               reset-names = "usb";
+               nvidia,phy = <&phy2>;
+               status = "disabled";
+       };
+
+       phy2: usb-phy@0,7d004000 {
+               compatible = "nvidia,tegra210-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d004000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA210_CLK_USB2>,
+                        <&tegra_car TEGRA210_CLK_PLL_U>,
+                        <&tegra_car TEGRA210_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               resets = <&tegra_car 58>, <&tegra_car 22>;
+               reset-names = "usb", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               status = "disabled";
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a57";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a57";
+                       reg = <1>;
+               };
+
+               cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a57";
+                       reg = <2>;
+               };
+
+               cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a57";
+                       reg = <3>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                               (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+               interrupt-parent = <&gic>;
+       };
+};
index 6b8abbe..db17c5d 100644 (file)
        aliases {
                serial0 = &blsp1_uart2;
                serial1 = &blsp1_uart1;
+               usid0 = &pm8916_0;
+               i2c0    = &blsp_i2c2;
+               i2c1    = &blsp_i2c6;
+               i2c3    = &blsp_i2c4;
        };
 
        chosen {
        };
 
        soc {
+               serial@78af000 {
+                       label = "LS-UART0";
+                       status = "okay";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp1_uart1_default>;
+                       pinctrl-1 = <&blsp1_uart1_sleep>;
+               };
+
                serial@78b0000 {
+                       label = "LS-UART1";
                        status = "okay";
                        pinctrl-names = "default", "sleep";
                        pinctrl-0 = <&blsp1_uart2_default>;
 
                i2c@78b6000 {
                /* On Low speed expansion */
+                       label = "LS-I2C0";
                        status = "okay";
                };
 
                i2c@78b8000 {
                /* On High speed expansion */
+                       label = "HS-I2C2";
                        status = "okay";
                };
 
                i2c@78ba000 {
                /* On Low speed expansion */
+                       label = "LS-I2C1";
                        status = "okay";
                };
 
                spi@78b7000 {
                /* On High speed expansion */
+                       label = "HS-SPI1";
                        status = "okay";
                };
 
                spi@78b9000 {
                /* On Low speed expansion */
+                       label = "LS-SPI0";
                        status = "okay";
                };
 
index fced77f..b0a064d 100644 (file)
@@ -17,6 +17,6 @@
 
 / {
        model = "Qualcomm Technologies, Inc. MSM 8916 MTP";
-       compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp-smb1360",
+       compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp/1",
                        "qcom,msm8916", "qcom,mtp";
 };
index a1aa0b2..ceeb8a6 100644 (file)
@@ -17,6 +17,7 @@
 / {
        aliases {
                serial0 = &blsp1_uart2;
+               usid0 = &pm8916_0;
        };
 
        chosen {
index 49ec55a..955c6f1 100644 (file)
        blsp1_uart1_default: blsp1_uart1_default {
                pinmux {
                        function = "blsp_uart1";
-                       pins = "gpio0", "gpio1";
+                       //      TX, RX, CTS_N, RTS_N
+                       pins = "gpio0", "gpio1",
+                              "gpio2", "gpio3";
                };
                pinconf {
-                       pins = "gpio0", "gpio1";
+                       pins = "gpio0", "gpio1",
+                              "gpio2", "gpio3";
                        drive-strength = <16>;
                        bias-disable;
                };
        blsp1_uart1_sleep: blsp1_uart1_sleep {
                pinmux {
                        function = "gpio";
-                       pins = "gpio0", "gpio1";
+                       pins = "gpio0", "gpio1",
+                              "gpio2", "gpio3";
                };
                pinconf {
-                       pins = "gpio0", "gpio1";
+                       pins = "gpio0", "gpio1",
+                              "gpio2", "gpio3";
                        drive-strength = <2>;
                        bias-pull-down;
                };
                };
                pinconf {
                        pins = "gpio6", "gpio7";
-                       drive-strength = <2>;
+                       drive-strength = <16>;
                        bias-disable = <0>;
                };
        };
                };
                pinconf {
                        pins = "gpio14", "gpio15";
-                       drive-strength = <2>;
+                       drive-strength = <16>;
                        bias-disable = <0>;
                };
        };
                };
                pinconf {
                        pins = "gpio22", "gpio23";
-                       drive-strength = <2>;
+                       drive-strength = <16>;
                        bias-disable = <0>;
                };
        };
index 8d184ff..9153214 100644 (file)
                reg = <0 0 0 0>;
        };
 
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               reserve_aligned@86000000 {
+                       reg = <0x0 0x86000000 0x0 0x0300000>;
+                       no-map;
+               };
+
+               smem_mem: smem_region@86300000 {
+                       reg = <0x0 0x86300000 0x0 0x0100000>;
+                       no-map;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                             <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
+       clocks {
+               xo_board: xo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <19200000>;
+               };
+
+               sleep_clk: sleep_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       smem {
+               compatible = "qcom,smem";
+
+               memory-region = <&smem_mem>;
+               qcom,rpm-msg-ram = <&rpm_msg_ram>;
+
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
                        reg = <0x1800000 0x80000>;
                };
 
+               tcsr_mutex_regs: syscon@1905000 {
+                       compatible = "syscon";
+                       reg = <0x1905000 0x20000>;
+               };
+
+               tcsr_mutex: hwlock {
+                       compatible = "qcom,tcsr-mutex";
+                       syscon = <&tcsr_mutex_regs 0 0x1000>;
+                       #hwlock-cells = <1>;
+               };
+
+               rpm_msg_ram: memory@60000 {
+                       compatible = "qcom,rpm-msg-ram";
+                       reg = <0x60000 0x8000>;
+               };
+
                blsp1_uart1: serial@78af000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0x78af000 0x200>;
                        interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
                        clock-names = "core", "iface";
+                       dmas = <&blsp_dma 1>, <&blsp_dma 0>;
+                       dma-names = "rx", "tx";
                        status = "disabled";
                };
 
+               apcs: syscon@b011000 {
+                       compatible = "syscon";
+                       reg = <0x0b011000 0x1000>;
+               };
+
                blsp1_uart2: serial@78b0000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0x78b0000 0x200>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
                        clock-names = "core", "iface";
+                       dmas = <&blsp_dma 3>, <&blsp_dma 2>;
+                       dma-names = "rx", "tx";
                        status = "disabled";
                };
 
                        clock-names = "core";
                };
        };
+
+       smd {
+               compatible = "qcom,smd";
+
+               rpm {
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+                       qcom,ipc = <&apcs 8 0>;
+                       qcom,smd-edge = <15>;
+
+                       rpm_requests {
+                               compatible = "qcom,rpm-msm8916";
+                               qcom,smd-channels = "rpm_requests";
+
+                               pm8916-regulators {
+                                       compatible = "qcom,rpm-pm8916-regulators";
+
+                                       pm8916_s1: s1 {};
+                                       pm8916_s2: s2 {};
+                                       pm8916_s3: s3 {};
+                                       pm8916_s4: s4 {};
+
+                                       pm8916_l1: l1 {};
+                                       pm8916_l2: l2 {};
+                                       pm8916_l3: l3 {};
+                                       pm8916_l4: l4 {};
+                                       pm8916_l5: l5 {};
+                                       pm8916_l6: l6 {};
+                                       pm8916_l7: l7 {};
+                                       pm8916_l8: l8 {};
+                                       pm8916_l9: l9 {};
+                                       pm8916_l10: l10 {};
+                                       pm8916_l11: l11 {};
+                                       pm8916_l12: l12 {};
+                                       pm8916_l13: l13 {};
+                                       pm8916_l14: l14 {};
+                                       pm8916_l15: l15 {};
+                                       pm8916_l16: l16 {};
+                                       pm8916_l17: l17 {};
+                                       pm8916_l18: l18 {};
+                               };
+                       };
+               };
+       };
 };
 
 #include "msm8916-pins.dtsi"
index b222ece..3743245 100644 (file)
@@ -4,8 +4,8 @@
 
 &spmi_bus {
 
-       usid0: pm8916@0 {
-               compatible = "qcom,spmi-pmic";
+       pm8916_0: pm8916@0 {
+               compatible = "qcom,pm8916", "qcom,spmi-pmic";
                reg = <0x0 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
@@ -90,7 +90,7 @@
                };
        };
 
-       usid1: pm8916@1 {
+       pm8916_1: pm8916@1 {
                compatible = "qcom,spmi-pmic";
                reg = <0x1 SPMI_USID>;
                #address-cells = <1>;
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
new file mode 100644 (file)
index 0000000..9ce1890
--- /dev/null
@@ -0,0 +1,4 @@
+dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb
+
+always         := $(dtb-y)
+clean-files    := *.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
new file mode 100644 (file)
index 0000000..265d12f
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Device Tree Source for the Salvator-X board
+ *
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/*
+ * SSI-AK4613
+ *
+ * This command is required when Playback/Capture
+ *
+ *     amixer set "DVC Out" 100%
+ *     amixer set "DVC In" 100%
+ *
+ * You can use Mute
+ *
+ *     amixer set "DVC Out Mute" on
+ *     amixer set "DVC In Mute" on
+ *
+ * You can use Volume Ramp
+ *
+ *     amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
+ *     amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
+ *     amixer set "DVC Out Ramp" on
+ *     aplay xxx.wav &
+ *     amixer set "DVC Out"  80%  // Volume Down
+ *     amixer set "DVC Out" 100%  // Volume Up
+ */
+
+/dts-v1/;
+#include "r8a7795.dtsi"
+
+/ {
+       model = "Renesas Salvator-X board based on r8a7795";
+       compatible = "renesas,salvator-x", "renesas,r8a7795";
+
+       aliases {
+               serial0 = &scif2;
+               serial1 = &scif1;
+               ethernet0 = &avb;
+       };
+
+       chosen {
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x38000000>;
+       };
+
+       x12_clk: x12_clk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24576000>;
+       };
+
+       audio_clkout: audio_clkout {
+               /*
+                * This is same as <&rcar_sound 0>
+                * but needed to avoid cs2000/rcar_sound probe dead-lock
+                */
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <11289600>;
+       };
+
+       rsnd_ak4613: sound {
+               compatible = "simple-audio-card";
+
+               simple-audio-card,format = "left_j";
+               simple-audio-card,bitclock-master = <&sndcpu>;
+               simple-audio-card,frame-master = <&sndcpu>;
+
+               sndcpu: simple-audio-card,cpu {
+                       sound-dai = <&rcar_sound>;
+               };
+
+               sndcodec: simple-audio-card,codec {
+                       sound-dai = <&ak4613>;
+               };
+       };
+};
+
+&extal_clk {
+       clock-frequency = <16666666>;
+};
+
+&pfc {
+       scif1_pins: scif1 {
+               renesas,groups = "scif1_data_a", "scif1_ctrl";
+               renesas,function = "scif1";
+       };
+       scif2_pins: scif2 {
+               renesas,groups = "scif2_data_a";
+               renesas,function = "scif2";
+       };
+
+       i2c2_pins: i2c2 {
+               renesas,groups = "i2c2_a";
+               renesas,function = "i2c2";
+       };
+
+       avb_pins: avb {
+               renesas,groups = "avb_mdc";
+               renesas,function = "avb";
+       };
+
+       sound_pins: sound {
+               renesas,groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
+               renesas,function = "ssi";
+       };
+
+       sound_clk_pins: sound_clk {
+               renesas,groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
+                                "audio_clkout_a", "audio_clkout3_a";
+               renesas,function = "audio_clk";
+       };
+};
+
+&scif1 {
+       pinctrl-0 = <&scif1_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&scif2 {
+       pinctrl-0 = <&scif2_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-0 = <&i2c2_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       clock-frequency = <100000>;
+
+       ak4613: codec@10 {
+               compatible = "asahi-kasei,ak4613";
+               #sound-dai-cells = <0>;
+               reg = <0x10>;
+               clocks = <&rcar_sound 3>;
+
+               asahi-kasei,in1-single-end;
+               asahi-kasei,in2-single-end;
+               asahi-kasei,out1-single-end;
+               asahi-kasei,out2-single-end;
+               asahi-kasei,out3-single-end;
+               asahi-kasei,out4-single-end;
+               asahi-kasei,out5-single-end;
+               asahi-kasei,out6-single-end;
+       };
+
+       cs2000: clk_multiplier@4f {
+               #clock-cells = <0>;
+               compatible = "cirrus,cs2000-cp";
+               reg = <0x4f>;
+               clocks = <&audio_clkout>, <&x12_clk>;
+               clock-names = "clk_in", "ref_clk";
+
+               assigned-clocks = <&cs2000>;
+               assigned-clock-rates = <24576000>; /* 1/1 divide */
+       };
+};
+
+&rcar_sound {
+       pinctrl-0 = <&sound_pins &sound_clk_pins>;
+       pinctrl-names = "default";
+
+       /* Single DAI */
+       #sound-dai-cells = <0>;
+
+       /* audio_clkout0/1/2/3 */
+       #clock-cells = <1>;
+       clock-frequency = <11289600>;
+
+       status = "okay";
+
+       /* update <audio_clk_b> to <cs2000> */
+       clocks = <&cpg CPG_MOD 1005>,
+                <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+                <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+                <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+                <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+                <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+                <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+                <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+                <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+                <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+                <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+                <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+                <&audio_clk_a>, <&cs2000>,
+                <&audio_clk_c>,
+                <&cpg CPG_CORE R8A7795_CLK_S0D4>;
+
+       rcar_sound,dai {
+               dai0 {
+                       playback = <&ssi0 &src0 &dvc0>;
+                       capture  = <&ssi1 &src1 &dvc1>;
+               };
+       };
+};
+
+&sata {
+       status = "okay";
+};
+
+&ssi1 {
+       shared-pin;
+};
+
+&audio_clk_a {
+       clock-frequency = <22579200>;
+};
+
+&avb {
+       pinctrl-0 = <&avb_pins>;
+       pinctrl-names = "default";
+       renesas,no-ether-link;
+       phy-handle = <&phy0>;
+       status = "okay";
+
+       phy0: ethernet-phy@0 {
+               rxc-skew-ps = <900>;
+               rxdv-skew-ps = <0>;
+               rxd0-skew-ps = <0>;
+               rxd1-skew-ps = <0>;
+               rxd2-skew-ps = <0>;
+               rxd3-skew-ps = <0>;
+               txc-skew-ps = <900>;
+               txen-skew-ps = <0>;
+               txd0-skew-ps = <0>;
+               txd1-skew-ps = <0>;
+               txd2-skew-ps = <0>;
+               txd3-skew-ps = <0>;
+               reg = <0>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
new file mode 100644 (file)
index 0000000..bb353cd
--- /dev/null
@@ -0,0 +1,779 @@
+/*
+ * Device Tree Source for the r8a7795 SoC
+ *
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "renesas,r8a7795";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+       };
+
+       psci {
+               compatible = "arm,psci-0.2";
+               method = "smc";
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               a57_0: cpu@0 {
+                       compatible = "arm,cortex-a57", "arm,armv8";
+                       reg = <0x0>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+               };
+
+               a57_1: cpu@1 {
+                       compatible = "arm,cortex-a57","arm,armv8";
+                       reg = <0x1>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+               };
+               a57_2: cpu@2 {
+                       compatible = "arm,cortex-a57","arm,armv8";
+                       reg = <0x2>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+               };
+               a57_3: cpu@3 {
+                       compatible = "arm,cortex-a57","arm,armv8";
+                       reg = <0x3>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+               };
+       };
+
+       extal_clk: extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       extalr_clk: extalr {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       /*
+        * The external audio clocks are configured as 0 Hz fixed frequency
+        * clocks by default.
+        * Boards that provide audio clocks should override them.
+        */
+       audio_clk_a: audio_clk_a {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_b: audio_clk_b {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_c: audio_clk_c {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               gic: interrupt-controller@0xf1010000 {
+                       compatible = "arm,gic-400";
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+                       interrupt-controller;
+                       reg = <0x0 0xf1010000 0 0x1000>,
+                             <0x0 0xf1020000 0 0x2000>;
+                       interrupts = <GIC_PPI 9
+                                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               };
+
+               gpio0: gpio@e6050000 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6050000 0 0x50>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 0 16>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 912>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio1: gpio@e6051000 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6051000 0 0x50>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 32 28>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 911>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio2: gpio@e6052000 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6052000 0 0x50>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 64 15>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 910>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio3: gpio@e6053000 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6053000 0 0x50>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 96 16>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 909>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio4: gpio@e6054000 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6054000 0 0x50>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 128 18>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 908>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio5: gpio@e6055000 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6055000 0 0x50>;
+                       interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 160 26>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 907>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio6: gpio@e6055400 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6055400 0 0x50>;
+                       interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 192 32>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 906>;
+                       power-domains = <&cpg>;
+               };
+
+               gpio7: gpio@e6055800 {
+                       compatible = "renesas,gpio-r8a7795",
+                                    "renesas,gpio-rcar";
+                       reg = <0 0xe6055800 0 0x50>;
+                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 224 4>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 905>;
+                       power-domains = <&cpg>;
+               };
+
+               pmu {
+                       compatible = "arm,armv8-pmuv3";
+                       interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-affinity = <&a57_0>,
+                                            <&a57_1>,
+                                            <&a57_2>,
+                                            <&a57_3>;
+               };
+
+               timer {
+                       compatible = "arm,armv8-timer";
+                       interrupts = <GIC_PPI 13
+                                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                                    <GIC_PPI 14
+                                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                                    <GIC_PPI 11
+                                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                                    <GIC_PPI 10
+                                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+               };
+
+               cpg: clock-controller@e6150000 {
+                       compatible = "renesas,r8a7795-cpg-mssr";
+                       reg = <0 0xe6150000 0 0x1000>;
+                       clocks = <&extal_clk>, <&extalr_clk>;
+                       clock-names = "extal", "extalr";
+                       #clock-cells = <2>;
+                       #power-domain-cells = <0>;
+               };
+
+               audma0: dma-controller@ec700000 {
+                       compatible = "renesas,rcar-dmac";
+                       reg = <0 0xec700000 0 0x10000>;
+                       interrupts =    <0 350 IRQ_TYPE_LEVEL_HIGH
+                                        0 320 IRQ_TYPE_LEVEL_HIGH
+                                        0 321 IRQ_TYPE_LEVEL_HIGH
+                                        0 322 IRQ_TYPE_LEVEL_HIGH
+                                        0 323 IRQ_TYPE_LEVEL_HIGH
+                                        0 324 IRQ_TYPE_LEVEL_HIGH
+                                        0 325 IRQ_TYPE_LEVEL_HIGH
+                                        0 326 IRQ_TYPE_LEVEL_HIGH
+                                        0 327 IRQ_TYPE_LEVEL_HIGH
+                                        0 328 IRQ_TYPE_LEVEL_HIGH
+                                        0 329 IRQ_TYPE_LEVEL_HIGH
+                                        0 330 IRQ_TYPE_LEVEL_HIGH
+                                        0 331 IRQ_TYPE_LEVEL_HIGH
+                                        0 332 IRQ_TYPE_LEVEL_HIGH
+                                        0 333 IRQ_TYPE_LEVEL_HIGH
+                                        0 334 IRQ_TYPE_LEVEL_HIGH
+                                        0 335 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 502>;
+                       clock-names = "fck";
+                       power-domains = <&cpg>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               audma1: dma-controller@ec720000 {
+                       compatible = "renesas,rcar-dmac";
+                       reg = <0 0xec720000 0 0x10000>;
+                       interrupts =    <0 351 IRQ_TYPE_LEVEL_HIGH
+                                        0 336 IRQ_TYPE_LEVEL_HIGH
+                                        0 337 IRQ_TYPE_LEVEL_HIGH
+                                        0 338 IRQ_TYPE_LEVEL_HIGH
+                                        0 339 IRQ_TYPE_LEVEL_HIGH
+                                        0 340 IRQ_TYPE_LEVEL_HIGH
+                                        0 341 IRQ_TYPE_LEVEL_HIGH
+                                        0 342 IRQ_TYPE_LEVEL_HIGH
+                                        0 343 IRQ_TYPE_LEVEL_HIGH
+                                        0 344 IRQ_TYPE_LEVEL_HIGH
+                                        0 345 IRQ_TYPE_LEVEL_HIGH
+                                        0 346 IRQ_TYPE_LEVEL_HIGH
+                                        0 347 IRQ_TYPE_LEVEL_HIGH
+                                        0 348 IRQ_TYPE_LEVEL_HIGH
+                                        0 349 IRQ_TYPE_LEVEL_HIGH
+                                        0 382 IRQ_TYPE_LEVEL_HIGH
+                                        0 383 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 501>;
+                       clock-names = "fck";
+                       power-domains = <&cpg>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               pfc: pfc@e6060000 {
+                       compatible = "renesas,pfc-r8a7795";
+                       reg = <0 0xe6060000 0 0x50c>;
+               };
+
+               dmac0: dma-controller@e6700000 {
+                       /* Empty node for now */
+               };
+
+               dmac1: dma-controller@e7300000 {
+                       /* Empty node for now */
+               };
+
+               dmac2: dma-controller@e7310000 {
+                       /* Empty node for now */
+               };
+
+               avb: ethernet@e6800000 {
+                       compatible = "renesas,etheravb-r8a7795";
+                       reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1", "ch2", "ch3",
+                                         "ch4", "ch5", "ch6", "ch7",
+                                         "ch8", "ch9", "ch10", "ch11",
+                                         "ch12", "ch13", "ch14", "ch15",
+                                         "ch16", "ch17", "ch18", "ch19",
+                                         "ch20", "ch21", "ch22", "ch23",
+                                         "ch24";
+                       clocks = <&cpg CPG_MOD 812>;
+                       power-domains = <&cpg>;
+                       phy-mode = "rgmii-id";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               hscif0: serial@e6540000 {
+                       compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+                       reg = <0 0xe6540000 0 96>;
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 520>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x31>, <&dmac1 0x30>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               hscif1: serial@e6550000 {
+                       compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+                       reg = <0 0xe6550000 0 96>;
+                       interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 519>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x33>, <&dmac1 0x32>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               hscif2: serial@e6560000 {
+                       compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+                       reg = <0 0xe6560000 0 96>;
+                       interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 518>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x35>, <&dmac1 0x34>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+                       reg = <0 0xe66a0000 0 96>;
+                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 517>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               hscif4: serial@e66b0000 {
+                       compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+                       reg = <0 0xe66b0000 0 96>;
+                       interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 516>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               scif0: serial@e6e60000 {
+                       compatible = "renesas,scif-r8a7795", "renesas,scif";
+                       reg = <0 0xe6e60000 0 64>;
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 207>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x51>, <&dmac1 0x50>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               scif1: serial@e6e68000 {
+                       compatible = "renesas,scif-r8a7795", "renesas,scif";
+                       reg = <0 0xe6e68000 0 64>;
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 206>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x53>, <&dmac1 0x52>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               scif2: serial@e6e88000 {
+                       compatible = "renesas,scif-r8a7795", "renesas,scif";
+                       reg = <0 0xe6e88000 0 64>;
+                       interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 310>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x13>, <&dmac1 0x12>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               scif3: serial@e6c50000 {
+                       compatible = "renesas,scif-r8a7795", "renesas,scif";
+                       reg = <0 0xe6c50000 0 64>;
+                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 204>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               scif4: serial@e6c40000 {
+                       compatible = "renesas,scif-r8a7795", "renesas,scif";
+                       reg = <0 0xe6c40000 0 64>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 203>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               scif5: serial@e6f30000 {
+                       compatible = "renesas,scif-r8a7795", "renesas,scif";
+                       reg = <0 0xe6f30000 0 64>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 202>;
+                       clock-names = "sci_ick";
+                       dmas = <&dmac1 0x5b>, <&dmac1 0x5a>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@e6500000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe6500000 0 0x40>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 931>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@e6508000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe6508000 0 0x40>;
+                       interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 930>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@e6510000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe6510000 0 0x40>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 929>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@e66d0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe66d0000 0 0x40>;
+                       interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 928>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@e66d8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe66d8000 0 0x40>;
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@e66e0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe66e0000 0 0x40>;
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 919>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c6: i2c@e66e8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a7795";
+                       reg = <0 0xe66e8000 0 0x40>;
+                       interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 918>;
+                       power-domains = <&cpg>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               rcar_sound: sound@ec500000 {
+                       /*
+                        * #sound-dai-cells is required
+                        *
+                        * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+                        * Multi  DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+                        */
+                       /*
+                        * #clock-cells is required for audio_clkout0/1/2/3
+                        *
+                        * clkout       : #clock-cells = <0>;   <&rcar_sound>;
+                        * clkout0/1/2/3: #clock-cells = <1>;   <&rcar_sound N>;
+                        */
+                       compatible =  "renesas,rcar_sound-r8a7795", "renesas,rcar_sound-gen3";
+                       reg =   <0 0xec500000 0 0x1000>, /* SCU */
+                               <0 0xec5a0000 0 0x100>,  /* ADG */
+                               <0 0xec540000 0 0x1000>, /* SSIU */
+                               <0 0xec541000 0 0x280>,  /* SSI */
+                               <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+                       reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+                       clocks = <&cpg CPG_MOD 1005>,
+                                <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+                                <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+                                <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+                                <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+                                <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+                                <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+                                <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+                                <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+                                <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+                                <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+                                <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+                                <&audio_clk_a>, <&audio_clk_b>,
+                                <&audio_clk_c>,
+                                <&cpg CPG_CORE R8A7795_CLK_S0D4>;
+                       clock-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0",
+                                     "src.9", "src.8", "src.7", "src.6",
+                                     "src.5", "src.4", "src.3", "src.2",
+                                     "src.1", "src.0",
+                                     "dvc.0", "dvc.1",
+                                     "clk_a", "clk_b", "clk_c", "clk_i";
+                       power-domains = <&cpg>;
+                       status = "disabled";
+
+                       rcar_sound,dvc {
+                               dvc0: dvc@0 {
+                                       dmas = <&audma0 0xbc>;
+                                       dma-names = "tx";
+                               };
+                               dvc1: dvc@1 {
+                                       dmas = <&audma0 0xbe>;
+                                       dma-names = "tx";
+                               };
+                       };
+
+                       rcar_sound,src {
+                               src0: src@0 {
+                                       interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x85>, <&audma1 0x9a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src1: src@1 {
+                                       interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x87>, <&audma1 0x9c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src2: src@2 {
+                                       interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x89>, <&audma1 0x9e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src3: src@3 {
+                                       interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src4: src@4 {
+                                       interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src5: src@5 {
+                                       interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src6: src@6 {
+                                       interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x91>, <&audma1 0xb4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src7: src@7 {
+                                       interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x93>, <&audma1 0xb6>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src8: src@8 {
+                                       interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x95>, <&audma1 0xb8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src9: src@9 {
+                                       interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x97>, <&audma1 0xba>;
+                                       dma-names = "rx", "tx";
+                               };
+                       };
+
+                       rcar_sound,ssi {
+                               ssi0: ssi@0 {
+                                       interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi1: ssi@1 {
+                                        interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi2: ssi@2 {
+                                       interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi3: ssi@3 {
+                                       interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi4: ssi@4 {
+                                       interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi5: ssi@5 {
+                                       interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi6: ssi@6 {
+                                       interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi7: ssi@7 {
+                                       interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi8: ssi@8 {
+                                       interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                               ssi9: ssi@9 {
+                                       interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
+                                       dma-names = "rx", "tx", "rxu", "txu";
+                               };
+                       };
+               };
+
+               sata: sata@ee300000 {
+                       compatible = "renesas,sata-r8a7795";
+                       reg = <0 0xee300000 0 0x1fff>;
+                       interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 815>;
+                       status = "disabled";
+               };
+       };
+};
index 601e6a2..e3f0b5f 100644 (file)
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
 
 always         := $(dtb-y)
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts b/arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts
new file mode 100644 (file)
index 0000000..8a5275f
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015 Caesar Wang <wxt@rock-chips.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3368-evb.dtsi"
+
+/ {
+       model = "Rockchip RK3368 EVB with ACT8846 pmic";
+       compatible = "rockchip,rk3368-evb-act8846", "rockchip,rk3368";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+
+       vdd_cpu: syr827@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu";
+               regulator-min-microvolt = <850000>;
+               regulator-max-microvolt = <1350000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vdd_gpu: syr828@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <850000>;
+               regulator-max-microvolt = <1350000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       act8846: act8846@5a {
+               compatible = "active-semi,act8846";
+               reg = <0x5a>;
+               status = "okay";
+
+               vp1-supply = <&vcc_sys>;
+               vp2-supply = <&vcc_sys>;
+               vp3-supply = <&vcc_sys>;
+               vp4-supply = <&vcc_sys>;
+               inl1-supply = <&vcc_io>;
+               inl2-supply = <&vcc_sys>;
+               inl3-supply = <&vcc_20>;
+
+               regulators {
+                       vcc_ddr: REG1 {
+                               regulator-name = "VCC_DDR";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_io: REG2 {
+                               regulator-name = "VCC_IO";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_log: REG3 {
+                               regulator-name = "VDD_LOG";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_20: REG4 {
+                               regulator-name = "VCC_20";
+                               regulator-min-microvolt = <2000000>;
+                               regulator-max-microvolt = <2000000>;
+                               regulator-always-on;
+                       };
+
+                       vccio_sd: REG5 {
+                               regulator-name = "VCCIO_SD";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd10_lcd: REG6 {
+                               regulator-name = "VDD10_LCD";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                       };
+
+                       vcca_codec: REG7 {
+                               regulator-name = "VCCA_CODEC";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vcca_tp: REG8 {
+                               regulator-name = "VCCA_TP";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vccio_pmu: REG9 {
+                               regulator-name = "VCCIO_PMU";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_10: REG10 {
+                               regulator-name = "VDD_10";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_18: REG11 {
+                               regulator-name = "VCC_18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+
+                       vcc18_lcd: REG12 {
+                               regulator-name = "VCC18_LCD";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
new file mode 100644 (file)
index 0000000..8c219cc
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2015 Caesar Wang <wxt@rock-chips.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3368.dtsi"
+
+/ {
+       chosen {
+               stdout-path = "serial2:115200n8";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <
+                         0   1   2   3   4   5   6   7
+                         8   9  10  11  12  13  14  15
+                        16  17  18  19  20  21  22  23
+                        24  25  26  27  28  29  30  31
+                        32  33  34  35  36  37  38  39
+                        40  41  42  43  44  45  46  47
+                        48  49  50  51  52  53  54  55
+                        56  57  58  59  60  61  62  63
+                        64  65  66  67  68  69  70  71
+                        72  73  74  75  76  77  78  79
+                        80  81  82  83  84  85  86  87
+                        88  89  90  91  92  93  94  95
+                        96  97  98  99 100 101 102 103
+                       104 105 106 107 108 109 110 111
+                       112 113 114 115 116 117 118 119
+                       120 121 122 123 124 125 126 127
+                       128 129 130 131 132 133 134 135
+                       136 137 138 139 140 141 142 143
+                       144 145 146 147 148 149 150 151
+                       152 153 154 155 156 157 158 159
+                       160 161 162 163 164 165 166 167
+                       168 169 170 171 172 173 174 175
+                       176 177 178 179 180 181 182 183
+                       184 185 186 187 188 189 190 191
+                       192 193 194 195 196 197 198 199
+                       200 201 202 203 204 205 206 207
+                       208 209 210 211 212 213 214 215
+                       216 217 218 219 220 221 222 223
+                       224 225 226 227 228 229 230 231
+                       232 233 234 235 236 237 238 239
+                       240 241 242 243 244 245 246 247
+                       248 249 250 251 252 253 254 255>;
+               default-brightness-level = <128>;
+               enable-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_en>;
+               pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>;
+               pwm-delay-us = <10000>;
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               pinctrl-0 = <&emmc_reset>;
+               pinctrl-names = "default";
+               reset-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+       };
+
+       keys: gpio-keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwr_key>;
+
+               button@0 {
+                       gpio-key,wakeup = <1>;
+                       gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+                       label = "GPIO Power";
+                       linux,code = <116>;
+               };
+       };
+
+       /* supplies both host and otg */
+       vcc_host: vcc-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&host_vbus_drv>;
+               regulator-name = "vcc_host";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_lan: vcc-lan-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_lan";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_io>;
+       };
+
+       vcc_sys: vcc-sys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&emmc {
+       broken-cd;
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       disable-wp;
+       mmc-pwrseq = <&emmc_pwrseq>;
+       non-removable;
+       num-slots = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+       status = "okay";
+};
+
+&gmac {
+       phy-supply = <&vcc_lan>;
+       phy-mode = "rmii";
+       clock_in_out = "output";
+       snps,reset-gpio = <&gpio3 12 0>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 10000 1000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&rmii_pins>;
+       tx_delay = <0x30>;
+       rx_delay = <0x10>;
+       status = "ok";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&pinctrl {
+       pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+               bias-disable;
+               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 = <0 20 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       emmc {
+               emmc_bus8: emmc-bus8 {
+                       rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 19 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 20 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 21 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 22 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 23 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 24 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+                                       <1 25 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+               };
+
+               emmc-clk {
+                       rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none_drv_8ma>;
+               };
+
+               emmc-cmd {
+                       rockchip,pins = <1 26 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+               };
+
+               emmc_reset: emmc-reset {
+                       rockchip,pins = <2 3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       keys {
+               pwr_key: pwr-key {
+                       rockchip,pins = <0 2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       pmic {
+               pmic_int: pmic-int {
+                       rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       sdio {
+               wifi_reg_on: wifi-reg-on {
+                       rockchip,pins = <3 4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_rst: bt-rst {
+                       rockchip,pins = <3 5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb {
+               host_vbus_drv: host-vbus-drv {
+                       rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&wdt {
+       status = "okay";
+};
index 401a812..104cbee 100644 (file)
        status = "okay";
 };
 
+&tsadc {
+       rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+       status = "okay";
+};
+
 &uart2 {
        status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi
new file mode 100644 (file)
index 0000000..a10010f
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Device Tree Source for RK3368 SoC thermal
+ *
+ * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
+ * Caesar Wang <wxt@rock-chips.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+cpu_thermal: cpu_thermal {
+       polling-delay-passive = <100>; /* milliseconds */
+       polling-delay = <5000>; /* milliseconds */
+
+       thermal-sensors = <&tsadc 0>;
+
+       trips {
+               cpu_alert0: cpu_alert0 {
+                       temperature = <75000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_alert1: cpu_alert1 {
+                       temperature = <80000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               cpu_crit: cpu_crit {
+                       temperature = <95000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "critical";
+               };
+       };
+
+       cooling-maps {
+               map0 {
+                       trip = <&cpu_alert0>;
+                       cooling-device =
+                               <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
+               map1 {
+                       trip = <&cpu_alert1>;
+                       cooling-device =
+                               <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
+       };
+};
+
+gpu_thermal: gpu_thermal {
+       polling-delay-passive = <100>; /* milliseconds */
+       polling-delay = <5000>; /* milliseconds */
+
+       thermal-sensors = <&tsadc 1>;
+
+       trips {
+               gpu_alert0: gpu_alert0 {
+                       temperature = <80000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "passive";
+               };
+               gpu_crit: gpu_crit {
+                       temperature = <1150000>; /* millicelsius */
+                       hysteresis = <2000>; /* millicelsius */
+                       type = "critical";
+               };
+       };
+
+       cooling-maps {
+               map0 {
+                       trip = <&gpu_alert0>;
+                       cooling-device =
+                               <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+               };
+       };
+};
index cc093a4..122777b 100644 (file)
@@ -45,6 +45,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        compatible = "rockchip,rk3368";
@@ -53,6 +54,7 @@
        #size-cells = <2>;
 
        aliases {
+               ethernet0 = &gmac;
                i2c0 = &i2c0;
                i2c1 = &i2c1;
                i2c2 = &i2c2;
                        reg = <0x0 0x0>;
                        cpu-idle-states = <&cpu_sleep>;
                        enable-method = "psci";
+
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_l1: cpu@1 {
                        reg = <0x0 0x100>;
                        cpu-idle-states = <&cpu_sleep>;
                        enable-method = "psci";
+
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_b1: cpu@101 {
                status = "disabled";
        };
 
+       thermal-zones {
+               #include "rk3368-thermal.dtsi"
+       };
+
+       tsadc: tsadc@ff280000 {
+               compatible = "rockchip,rk3368-tsadc";
+               reg = <0x0 0xff280000 0x0 0x100>;
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+               clock-names = "tsadc", "apb_pclk";
+               resets = <&cru SRST_TSADC>;
+               reset-names = "tsadc-apb";
+               pinctrl-names = "init", "default", "sleep";
+               pinctrl-0 = <&otp_gpio>;
+               pinctrl-1 = <&otp_out>;
+               pinctrl-2 = <&otp_gpio>;
+               #thermal-sensor-cells = <1>;
+               rockchip,hw-tshut-temp = <95000>;
+               status = "disabled";
+       };
+
        gmac: ethernet@ff290000 {
                compatible = "rockchip,rk3368-gmac";
                reg = <0x0 0xff290000 0x0 0x10000>;
                status = "disabled";
        };
 
+       pwm0: pwm@ff680000 {
+               compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff680000 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_pin>;
+               clocks = <&cru PCLK_PWM1>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pwm1: pwm@ff680010 {
+               compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff680010 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm1_pin>;
+               clocks = <&cru PCLK_PWM1>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pwm2: pwm@ff680020 {
+               compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff680020 0x0 0x10>;
+               #pwm-cells = <3>;
+               clocks = <&cru PCLK_PWM1>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pwm3: pwm@ff680030 {
+               compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff680030 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm3_pin>;
+               clocks = <&cru PCLK_PWM1>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
        uart2: serial@ff690000 {
                compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
                reg = <0x0 0xff690000 0x0 0x100>;
                status = "disabled";
        };
 
+       timer@ff810000 {
+               compatible = "rockchip,rk3368-timer", "rockchip,rk3288-timer";
+               reg = <0x0 0xff810000 0x0 0x20>;
+               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        gic: interrupt-controller@ffb71000 {
                compatible = "arm,gic-400";
                interrupt-controller;
                        };
                };
 
+               pwm0 {
+                       pwm0_pin: pwm0-pin {
+                               rockchip,pins = <3 8 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm1 {
+                       pwm1_pin: pwm1-pin {
+                               rockchip,pins = <0 8 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm3 {
+                       pwm3_pin: pwm3-pin {
+                               rockchip,pins = <3 29 RK_FUNC_3 &pcfg_pull_none>;
+                       };
+               };
+
                sdio0 {
                        sdio0_bus1: sdio0-bus1 {
                                rockchip,pins = <2 28 RK_FUNC_1 &pcfg_pull_up>;
                                rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_up>;
                        };
 
-                       sdmmc_cd: sdmcc-cd {
+                       sdmmc_cd: sdmmc-cd {
                                rockchip,pins = <2 11 RK_FUNC_1 &pcfg_pull_up>;
                        };
 
                        };
                };
 
+               tsadc {
+                       otp_gpio: otp-gpio {
+                               rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+
+                       otp_out: otp-out {
+                               rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
                uart0 {
                        uart0_xfer: uart0-xfer {
                                rockchip,pins = <2 24 RK_FUNC_1 &pcfg_pull_up>,
diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile
new file mode 100644 (file)
index 0000000..8d72771
--- /dev/null
@@ -0,0 +1,4 @@
+dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld10-ref.dtb
+
+always         := $(dtb-y)
+clean-files    := *.dtb
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts
new file mode 100644 (file)
index 0000000..3e53317
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD10 Reference Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+/include/ "uniphier-ph1-ld10.dtsi"
+/include/ "uniphier-support-card.dtsi"
+
+/ {
+       model = "UniPhier PH1-LD10 Reference Board";
+       compatible = "socionext,ph1-ld10-ref", "socionext,ph1-ld10";
+
+       memory {
+               device_type = "memory";
+               reg = <0 0x80000000 0 0xc0000000>;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       aliases {
+               serial0 = &serial0;
+               serial1 = &serial1;
+               serial2 = &serial2;
+               serial3 = &serial3;
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+       };
+};
+
+&extbus {
+       ranges = <1 0x00000000 0x42000000 0x02000000>;
+};
+
+&support_card {
+       ranges = <0x00000000 1 0x01f00000 0x00100000>;
+};
+
+&ethsc {
+       interrupts = <0 48 4>;
+};
+
+&serial0 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi
new file mode 100644 (file)
index 0000000..0296af9
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD10 SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+       compatible = "socionext,ph1-ld10";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&gic>;
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+                       };
+
+                       cluster1 {
+                               core0 {
+                                       cpu = <&cpu2>;
+                               };
+                               core1 {
+                                       cpu = <&cpu3>;
+                               };
+                       };
+               };
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0 0x000>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x80000100>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0 0x001>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x80000100>;
+               };
+
+               cpu2: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0 0x100>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x80000100>;
+               };
+
+               cpu3: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0 0x101>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x80000100>;
+               };
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <58820000>;
+               };
+
+               i2c_clk: i2c_clk {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <50000000>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <1 13 0xf01>,
+                            <1 14 0xf01>,
+                            <1 11 0xf01>,
+                            <1 10 0xf01>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0 0 0xffffffff>;
+
+               extbus: extbus {
+                       compatible = "simple-bus";
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+               };
+
+               serial0: serial@54006800 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006800 0x40>;
+                       interrupts = <0 33 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart0>;
+                       clocks = <&uart_clk>;
+               };
+
+               serial1: serial@54006900 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006900 0x40>;
+                       interrupts = <0 35 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart1>;
+                       clocks = <&uart_clk>;
+               };
+
+               serial2: serial@54006a00 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006a00 0x40>;
+                       interrupts = <0 37 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart2>;
+                       clocks = <&uart_clk>;
+               };
+
+               serial3: serial@54006b00 {
+                       compatible = "socionext,uniphier-uart";
+                       status = "disabled";
+                       reg = <0x54006b00 0x40>;
+                       interrupts = <0 177 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_uart3>;
+                       clocks = <&uart_clk>;
+               };
+
+               i2c0: i2c@58780000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       status = "disabled";
+                       reg = <0x58780000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 41 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_i2c0>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <100000>;
+               };
+
+               i2c1: i2c@58781000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       status = "disabled";
+                       reg = <0x58781000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 42 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_i2c1>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <100000>;
+               };
+
+               i2c2: i2c@58782000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       status = "disabled";
+                       reg = <0x58782000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 43 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_i2c2>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <100000>;
+               };
+
+               i2c3: i2c@58783000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       status = "disabled";
+                       reg = <0x58783000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 44 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_i2c3>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <100000>;
+               };
+
+               i2c4: i2c@58784000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       reg = <0x58784000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 45 4>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <400000>;
+               };
+
+               i2c5: i2c@58785000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       reg = <0x58785000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 25 4>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <400000>;
+               };
+
+               i2c6: i2c@58786000 {
+                       compatible = "socionext,uniphier-fi2c";
+                       reg = <0x58786000 0x80>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <0 26 4>;
+                       clocks = <&i2c_clk>;
+                       clock-frequency = <400000>;
+               };
+
+               pinctrl: pinctrl@5f801000 {
+                       compatible = "socionext,ph1-ld10-pinctrl", "syscon";
+                       reg = <0x5f801000 0xe00>;
+               };
+
+               gic: interrupt-controller@5fe00000 {
+                       compatible = "arm,gic-v3";
+                       reg = <0x5fe00000 0x10000>,     /* GICD */
+                             <0x5fe80000 0x80000>;     /* GICR */
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       interrupts = <1 9 4>;
+               };
+       };
+};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi
new file mode 120000 (symlink)
index 0000000..f42fb6f
--- /dev/null
@@ -0,0 +1 @@
+../../../../arm/boot/dts/uniphier-pinctrl.dtsi
\ No newline at end of file
diff --git a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi
new file mode 120000 (symlink)
index 0000000..1246db9
--- /dev/null
@@ -0,0 +1 @@
+../../../../arm/boot/dts/uniphier-support-card.dtsi
\ No newline at end of file
index 857eda5..200fb58 100644 (file)
                        clocks = <&misc_clk>;
                        interrupt-parent = <&gic>;
                        interrupts = <0 16 4>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
                        reg = <0x0 0xff0a0000 0x1000>;
                };
 
index bdd7aa3..18ca9fb 100644 (file)
@@ -39,12 +39,16 @@ CONFIG_ARCH_HISI=y
 CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_ARCH_SEATTLE=y
+CONFIG_ARCH_RENESAS=y
+CONFIG_ARCH_R8A7795=y
 CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_132_SOC=y
+CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_SPRD=y
 CONFIG_ARCH_THUNDER=y
+CONFIG_ARCH_UNIPHIER=y
 CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_XGENE=y
 CONFIG_ARCH_ZYNQMP=y
@@ -76,7 +80,6 @@ CONFIG_BPF_JIT=y
 # CONFIG_WIRELESS is not set
 CONFIG_NET_9P=y
 CONFIG_NET_9P_VIRTIO=y
-# CONFIG_TEGRA_AHB is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -91,6 +94,7 @@ CONFIG_SATA_AHCI=y
 CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_AHCI_CEVA=y
 CONFIG_AHCI_XGENE=y
+CONFIG_SATA_RCAR=y
 CONFIG_PATA_PLATFORM=y
 CONFIG_PATA_OF_PLATFORM=y
 CONFIG_NETDEVICES=y
@@ -98,8 +102,10 @@ CONFIG_TUN=y
 CONFIG_VIRTIO_NET=y
 CONFIG_NET_XGENE=y
 CONFIG_SKY2=y
+CONFIG_RAVB=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
+CONFIG_MICREL_PHY=y
 # CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
@@ -110,12 +116,17 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_UNIPHIER=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_SAMSUNG=y
 CONFIG_SERIAL_SAMSUNG_UARTS_4=y
 CONFIG_SERIAL_SAMSUNG_UARTS=4
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=11
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
@@ -125,11 +136,13 @@ CONFIG_VIRTIO_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_QUP=y
+CONFIG_I2C_RCAR=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_QUP=y
 CONFIG_PINCTRL_MSM8916=y
 CONFIG_GPIO_PL061=y
+CONFIG_GPIO_RCAR=y
 CONFIG_GPIO_XGENE=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
@@ -143,6 +156,11 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_RCAR=y
+CONFIG_SND_SOC_AK4613=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
@@ -155,6 +173,7 @@ CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_TEGRA=y
 CONFIG_MMC_SPI=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
@@ -170,10 +189,13 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_EFI=y
 CONFIG_RTC_DRV_XGENE=y
 CONFIG_DMADEVICES=y
+CONFIG_RCAR_DMAC=y
 CONFIG_QCOM_BAM_DMA=y
+CONFIG_TEGRA20_APB_DMA=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
+CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_MSM_GCC_8916=y
 CONFIG_HWSPINLOCK_QCOM=y
@@ -197,7 +219,7 @@ CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_EFIVAR_FS=y
-# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_SQUASHFS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
@@ -206,6 +228,7 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=y
+CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
index 61e08f3..ba437f0 100644 (file)
@@ -64,8 +64,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
        return dev->archdata.dma_coherent;
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
        return (dma_addr_t)paddr;
index ae7ac92..1115f2a 100644 (file)
 #ifndef __ASM_AVR32_DMA_MAPPING_H
 #define __ASM_AVR32_DMA_MAPPING_H
 
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/scatterlist.h>
-#include <asm/processor.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
-
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
        int direction);
 
-/*
- * Return whether the given device DMA address mask can be supported
- * properly.  For example, if your device can only drive the low 24-bits
- * during bus mastering, then you would pass 0x00ffffff as the mask
- * to this function.
- */
-static inline int dma_supported(struct device *dev, u64 mask)
-{
-       /* Fix when needed. I really don't know of any limitations */
-       return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-               return -EIO;
-
-       *dev->dma_mask = dma_mask;
-       return 0;
-}
+extern struct dma_map_ops avr32_dma_ops;
 
-/*
- * dma_map_single can't fail as it is implemented now.
- */
-static inline int dma_mapping_error(struct device *dev, dma_addr_t addr)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       return 0;
+       return &avr32_dma_ops;
 }
 
-/**
- * dma_alloc_coherent - allocate consistent memory for DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: required memory size
- * @handle: bus-specific DMA address
- *
- * Allocate some uncached, unbuffered memory for a device for
- * performing DMA.  This function allocates pages, and will
- * return the CPU-viewed address, and sets @handle to be the
- * device-viewed address.
- */
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
-                               dma_addr_t *handle, gfp_t gfp);
-
-/**
- * dma_free_coherent - free memory allocated by dma_alloc_coherent
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: size of memory originally requested in dma_alloc_coherent
- * @cpu_addr: CPU-view address returned from dma_alloc_coherent
- * @handle: device-view address returned from dma_alloc_coherent
- *
- * Free (and unmap) a DMA buffer previously allocated by
- * dma_alloc_coherent().
- *
- * References to memory and mappings associated with cpu_addr/handle
- * during and after this call executing are illegal.
- */
-extern void dma_free_coherent(struct device *dev, size_t size,
-                             void *cpu_addr, dma_addr_t handle);
-
-/**
- * dma_alloc_writecombine - allocate write-combining memory for DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: required memory size
- * @handle: bus-specific DMA address
- *
- * Allocate some uncached, buffered memory for a device for
- * performing DMA.  This function allocates pages, and will
- * return the CPU-viewed address, and sets @handle to be the
- * device-viewed address.
- */
-extern void *dma_alloc_writecombine(struct device *dev, size_t size,
-                                   dma_addr_t *handle, gfp_t gfp);
-
-/**
- * dma_free_coherent - free memory allocated by dma_alloc_writecombine
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: size of memory originally requested in dma_alloc_writecombine
- * @cpu_addr: CPU-view address returned from dma_alloc_writecombine
- * @handle: device-view address returned from dma_alloc_writecombine
- *
- * Free (and unmap) a DMA buffer previously allocated by
- * dma_alloc_writecombine().
- *
- * References to memory and mappings associated with cpu_addr/handle
- * during and after this call executing are illegal.
- */
-extern void dma_free_writecombine(struct device *dev, size_t size,
-                                 void *cpu_addr, dma_addr_t handle);
-
-/**
- * dma_map_single - map a single buffer for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @cpu_addr: CPU direct mapped address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed.  The CPU
- * can regain ownership by calling dma_unmap_single() or dma_sync_single().
- */
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-              enum dma_data_direction direction)
-{
-       dma_cache_sync(dev, cpu_addr, size, direction);
-       return virt_to_bus(cpu_addr);
-}
-
-/**
- * dma_unmap_single - unmap a single buffer previously mapped
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Unmap a single streaming mode DMA translation.  The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction)
-{
-
-}
-
-/**
- * dma_map_page - map a portion of a page for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @page: page that buffer resides in
- * @offset: offset into page for start of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed.  The CPU
- * can regain ownership by calling dma_unmap_page() or dma_sync_single().
- */
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-            unsigned long offset, size_t size,
-            enum dma_data_direction direction)
-{
-       return dma_map_single(dev, page_address(page) + offset,
-                             size, direction);
-}
-
-/**
- * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Unmap a single streaming mode DMA translation.  The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction)
-{
-       dma_unmap_single(dev, dma_address, size, direction);
-}
-
-/**
- * dma_map_sg - map a set of SG buffers for streaming mode DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scatter-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-          enum dma_data_direction direction)
-{
-       int i;
-       struct scatterlist *sg;
-
-       for_each_sg(sglist, sg, nents, i) {
-               char *virt;
-
-               sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
-               virt = sg_virt(sg);
-               dma_cache_sync(dev, virt, sg->length, direction);
-       }
-
-       return nents;
-}
-
-/**
- * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Unmap a set of streaming mode DMA translations.
- * Again, CPU read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction)
-{
-
-}
-
-/**
- * dma_sync_single_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Make physical memory consistent for a single streaming mode DMA
- * translation after a transfer.
- *
- * If you perform a dma_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the DMA mapping,
- * you must call this function before doing so.  At the next point you
- * give the DMA address back to the card, you must first perform a
- * dma_sync_single_for_device, and then the device again owns the
- * buffer.
- */
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                       size_t size, enum dma_data_direction direction)
-{
-       /*
-        * No need to do anything since the CPU isn't supposed to
-        * touch this memory after we flushed it at mapping- or
-        * sync-for-device time.
-        */
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-                          size_t size, enum dma_data_direction direction)
-{
-       dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction)
-{
-       /* just sync everything, that's all the pci API can do */
-       dma_sync_single_for_cpu(dev, dma_handle, offset+size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
-{
-       /* just sync everything, that's all the pci API can do */
-       dma_sync_single_for_device(dev, dma_handle, offset+size, direction);
-}
-
-/**
- * dma_sync_sg_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as dma_sync_single_for_* but for a scatter-gather list,
- * same rules and usage.
- */
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-                   int nents, enum dma_data_direction direction)
-{
-       /*
-        * No need to do anything since the CPU isn't supposed to
-        * touch this memory after we flushed it at mapping- or
-        * sync-for-device time.
-        */
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
-                      int nents, enum dma_data_direction direction)
-{
-       int i;
-       struct scatterlist *sg;
-
-       for_each_sg(sglist, sg, nents, i)
-               dma_cache_sync(dev, sg_virt(sg), sg->length, direction);
-}
-
-/* Now for the API extensions over the pci_ one */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
 #endif /* __ASM_AVR32_DMA_MAPPING_H */
index 50cdb5b..92cf1fb 100644 (file)
@@ -9,9 +9,14 @@
 #include <linux/dma-mapping.h>
 #include <linux/gfp.h>
 #include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/scatterlist.h>
 
-#include <asm/addrspace.h>
+#include <asm/processor.h>
 #include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
 
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction)
 {
@@ -93,60 +98,100 @@ static void __dma_free(struct device *dev, size_t size,
                __free_page(page++);
 }
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *handle, gfp_t gfp)
+static void *avr32_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
 {
        struct page *page;
-       void *ret = NULL;
+       dma_addr_t phys;
 
        page = __dma_alloc(dev, size, handle, gfp);
-       if (page)
-               ret = phys_to_uncached(page_to_phys(page));
+       if (!page)
+               return NULL;
+       phys = page_to_phys(page);
 
-       return ret;
+       if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) {
+               /* Now, map the page into P3 with write-combining turned on */
+               *handle = phys;
+               return __ioremap(phys, size, _PAGE_BUFFER);
+       } else {
+               return phys_to_uncached(phys);
+       }
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void dma_free_coherent(struct device *dev, size_t size,
-                      void *cpu_addr, dma_addr_t handle)
+static void avr32_dma_free(struct device *dev, size_t size,
+               void *cpu_addr, dma_addr_t handle, struct dma_attrs *attrs)
 {
-       void *addr = phys_to_cached(uncached_to_phys(cpu_addr));
        struct page *page;
 
-       pr_debug("dma_free_coherent addr %p (phys %08lx) size %u\n",
-                cpu_addr, (unsigned long)handle, (unsigned)size);
-       BUG_ON(!virt_addr_valid(addr));
-       page = virt_to_page(addr);
+       if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) {
+               iounmap(cpu_addr);
+
+               page = phys_to_page(handle);
+       } else {
+               void *addr = phys_to_cached(uncached_to_phys(cpu_addr));
+
+               pr_debug("avr32_dma_free addr %p (phys %08lx) size %u\n",
+                        cpu_addr, (unsigned long)handle, (unsigned)size);
+
+               BUG_ON(!virt_addr_valid(addr));
+               page = virt_to_page(addr);
+       }
+
        __dma_free(dev, size, page, handle);
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
-void *dma_alloc_writecombine(struct device *dev, size_t size,
-                            dma_addr_t *handle, gfp_t gfp)
+static dma_addr_t avr32_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
 {
-       struct page *page;
-       dma_addr_t phys;
+       void *cpu_addr = page_address(page) + offset;
 
-       page = __dma_alloc(dev, size, handle, gfp);
-       if (!page)
-               return NULL;
+       dma_cache_sync(dev, cpu_addr, size, direction);
+       return virt_to_bus(cpu_addr);
+}
 
-       phys = page_to_phys(page);
-       *handle = phys;
+static int avr32_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nents, i) {
+               char *virt;
 
-       /* Now, map the page into P3 with write-combining turned on */
-       return __ioremap(phys, size, _PAGE_BUFFER);
+               sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
+               virt = sg_virt(sg);
+               dma_cache_sync(dev, virt, sg->length, direction);
+       }
+
+       return nents;
 }
-EXPORT_SYMBOL(dma_alloc_writecombine);
 
-void dma_free_writecombine(struct device *dev, size_t size,
-                          void *cpu_addr, dma_addr_t handle)
+static void avr32_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
 {
-       struct page *page;
+       dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
+}
 
-       iounmap(cpu_addr);
+static void avr32_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sglist, int nents,
+               enum dma_data_direction direction)
+{
+       int i;
+       struct scatterlist *sg;
 
-       page = phys_to_page(handle);
-       __dma_free(dev, size, page, handle);
+       for_each_sg(sglist, sg, nents, i)
+               dma_cache_sync(dev, sg_virt(sg), sg->length, direction);
 }
-EXPORT_SYMBOL(dma_free_writecombine);
+
+struct dma_map_ops avr32_dma_ops = {
+       .alloc                  = avr32_dma_alloc,
+       .free                   = avr32_dma_free,
+       .map_page               = avr32_dma_map_page,
+       .map_sg                 = avr32_dma_map_sg,
+       .sync_single_for_device = avr32_dma_sync_single_for_device,
+       .sync_sg_for_device     = avr32_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(avr32_dma_ops);
index 054d9ec..3490570 100644 (file)
@@ -8,36 +8,6 @@
 #define _BLACKFIN_DMA_MAPPING_H
 
 #include <asm/cacheflush.h>
-struct scatterlist;
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *dma_handle, gfp_t gfp);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-                      dma_addr_t dma_handle);
-
-/*
- * Now for the API extensions over the pci_ one
- */
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_supported(d, m)         (1)
-
-static inline int
-dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-               return -EIO;
-
-       *dev->dma_mask = dma_mask;
-
-       return 0;
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
-}
 
 extern void
 __dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir);
@@ -66,102 +36,11 @@ _dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
                __dma_sync(addr, size, dir);
 }
 
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-              enum dma_data_direction dir)
-{
-       _dma_sync((dma_addr_t)ptr, size, dir);
-       return (dma_addr_t) ptr;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-            unsigned long offset, size_t size,
-            enum dma_data_direction dir)
-{
-       return dma_map_single(dev, page_address(page) + offset, size, dir);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction dir)
-{
-       BUG_ON(!valid_dma_direction(dir));
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
-              enum dma_data_direction dir)
-{
-       dma_unmap_single(dev, dma_addr, size, dir);
-}
+extern struct dma_map_ops bfin_dma_ops;
 
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-                     enum dma_data_direction dir);
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-            int nhwentries, enum dma_data_direction dir)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       BUG_ON(!valid_dma_direction(dir));
+       return &bfin_dma_ops;
 }
 
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction dir)
-{
-       BUG_ON(!valid_dma_direction(dir));
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction dir)
-{
-       _dma_sync(handle + offset, size, dir);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
-                       enum dma_data_direction dir)
-{
-       dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
-                          enum dma_data_direction dir)
-{
-       dma_sync_single_range_for_device(dev, handle, 0, size, dir);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
-                   enum dma_data_direction dir)
-{
-       BUG_ON(!valid_dma_direction(dir));
-}
-
-extern void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-                      int nents, enum dma_data_direction dir);
-
-static inline void
-dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-              enum dma_data_direction dir)
-{
-       _dma_sync((dma_addr_t)vaddr, size, dir);
-}
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
 #endif                         /* _BLACKFIN_DMA_MAPPING_H */
index df437e5..771afe6 100644 (file)
@@ -78,8 +78,8 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages)
        spin_unlock_irqrestore(&dma_page_lock, flags);
 }
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *dma_handle, gfp_t gfp)
+static void *bfin_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
        void *ret;
 
@@ -92,15 +92,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 
        return ret;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void
-dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-                 dma_addr_t dma_handle)
+static void bfin_dma_free(struct device *dev, size_t size, void *vaddr,
+                 dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        __free_dma_pages((unsigned long)vaddr, get_pages(size));
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
 /*
  * Streaming DMA mappings
@@ -112,9 +109,9 @@ void __dma_sync(dma_addr_t addr, size_t size,
 }
 EXPORT_SYMBOL(__dma_sync);
 
-int
-dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents,
-          enum dma_data_direction direction)
+static int bfin_dma_map_sg(struct device *dev, struct scatterlist *sg_list,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        struct scatterlist *sg;
        int i;
@@ -126,10 +123,10 @@ dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents,
 
        return nents;
 }
-EXPORT_SYMBOL(dma_map_sg);
 
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg_list,
-                           int nelems, enum dma_data_direction direction)
+static void bfin_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sg_list, int nelems,
+               enum dma_data_direction direction)
 {
        struct scatterlist *sg;
        int i;
@@ -139,4 +136,31 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg_list,
                __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
        }
 }
-EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+static dma_addr_t bfin_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size, enum dma_data_direction dir,
+               struct dma_attrs *attrs)
+{
+       dma_addr_t handle = (dma_addr_t)(page_address(page) + offset);
+
+       _dma_sync(handle, size, dir);
+       return handle;
+}
+
+static inline void bfin_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+       _dma_sync(handle, size, dir);
+}
+
+struct dma_map_ops bfin_dma_ops = {
+       .alloc                  = bfin_dma_alloc,
+       .free                   = bfin_dma_free,
+
+       .map_page               = bfin_dma_map_page,
+       .map_sg                 = bfin_dma_map_sg,
+
+       .sync_single_for_device = bfin_dma_sync_single_for_device,
+       .sync_sg_for_device     = bfin_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(bfin_dma_ops);
index 77ea09b..79049d4 100644 (file)
@@ -17,6 +17,7 @@ config C6X
        select OF_EARLY_FLATTREE
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
+       select ARCH_NO_COHERENT_DMA_MMAP
 
 config MMU
        def_bool n
index bbd7774..6b5cd7b 100644 (file)
 #ifndef _ASM_C6X_DMA_MAPPING_H
 #define _ASM_C6X_DMA_MAPPING_H
 
-#include <linux/dma-debug.h>
-#include <asm-generic/dma-coherent.h>
-
-#define dma_supported(d, m)    1
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
-                                                   dma_addr_t addr,
-                                                   unsigned long offset,
-                                                   size_t size,
-                                                   enum dma_data_direction dir)
-{
-}
-
-static inline int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-               return -EIO;
-
-       *dev->dma_mask = dma_mask;
-
-       return 0;
-}
-
 /*
  * DMA errors are defined by all-bits-set in the DMA address.
  */
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       debug_dma_mapping_error(dev, dma_addr);
-       return dma_addr == ~0;
-}
-
-extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
-                                size_t size, enum dma_data_direction dir);
+#define DMA_ERROR_CODE ~0
 
-extern void dma_unmap_single(struct device *dev, dma_addr_t handle,
-                            size_t size, enum dma_data_direction dir);
+extern struct dma_map_ops c6x_dma_ops;
 
-extern int dma_map_sg(struct device *dev, struct scatterlist *sglist,
-                     int nents, enum dma_data_direction direction);
-
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
-                        int nents, enum dma_data_direction direction);
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-                                     unsigned long offset, size_t size,
-                                     enum dma_data_direction dir)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       dma_addr_t handle;
-
-       handle = dma_map_single(dev, page_address(page) + offset, size, dir);
-
-       debug_dma_map_page(dev, page, offset, size, dir, handle, false);
-
-       return handle;
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
-               size_t size, enum dma_data_direction dir)
-{
-       dma_unmap_single(dev, handle, size, dir);
-
-       debug_dma_unmap_page(dev, handle, size, dir, false);
+       return &c6x_dma_ops;
 }
 
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
-                                   size_t size, enum dma_data_direction dir);
-
-extern void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
-                                      size_t size,
-                                      enum dma_data_direction dir);
-
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-                               int nents, enum dma_data_direction dir);
-
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-                                  int nents, enum dma_data_direction dir);
-
 extern void coherent_mem_init(u32 start, u32 size);
-extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
-#define dma_free_noncoherent(d, s, v, h)  dma_free_coherent((d), (s), (v), (h))
-
-/* Not supported for now */
-static inline int dma_mmap_coherent(struct device *dev,
-                                   struct vm_area_struct *vma, void *cpu_addr,
-                                   dma_addr_t dma_addr, size_t size)
-{
-       return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size)
-{
-       return -EINVAL;
-}
+void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+               gfp_t gfp, struct dma_attrs *attrs);
+void c6x_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs);
 
 #endif /* _ASM_C6X_DMA_MAPPING_H */
index ab7b12d..8a80f3a 100644 (file)
@@ -36,110 +36,101 @@ static void c6x_dma_sync(dma_addr_t handle, size_t size,
        }
 }
 
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-                         enum dma_data_direction dir)
+static dma_addr_t c6x_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size, enum dma_data_direction dir,
+               struct dma_attrs *attrs)
 {
-       dma_addr_t addr = virt_to_phys(ptr);
+       dma_addr_t handle = virt_to_phys(page_address(page) + offset);
 
-       c6x_dma_sync(addr, size, dir);
-
-       debug_dma_map_page(dev, virt_to_page(ptr),
-                          (unsigned long)ptr & ~PAGE_MASK, size,
-                          dir, addr, true);
-       return addr;
+       c6x_dma_sync(handle, size, dir);
+       return handle;
 }
-EXPORT_SYMBOL(dma_map_single);
-
 
-void dma_unmap_single(struct device *dev, dma_addr_t handle,
-                     size_t size, enum dma_data_direction dir)
+static void c6x_dma_unmap_page(struct device *dev, dma_addr_t handle,
+               size_t size, enum dma_data_direction dir, struct dma_attrs *attrs)
 {
        c6x_dma_sync(handle, size, dir);
-
-       debug_dma_unmap_page(dev, handle, size, dir, true);
 }
-EXPORT_SYMBOL(dma_unmap_single);
-
 
-int dma_map_sg(struct device *dev, struct scatterlist *sglist,
-              int nents, enum dma_data_direction dir)
+static int c6x_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
 {
        struct scatterlist *sg;
        int i;
 
-       for_each_sg(sglist, sg, nents, i)
-               sg->dma_address = dma_map_single(dev, sg_virt(sg), sg->length,
-                                                dir);
-
-       debug_dma_map_sg(dev, sglist, nents, nents, dir);
+       for_each_sg(sglist, sg, nents, i) {
+               sg->dma_address = sg_phys(sg);
+               c6x_dma_sync(sg->dma_address, sg->length, dir);
+       }
 
        return nents;
 }
-EXPORT_SYMBOL(dma_map_sg);
-
 
-void dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
-                 int nents, enum dma_data_direction dir)
+static void c6x_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
+                 int nents, enum dma_data_direction dir,
+                 struct dma_attrs *attrs)
 {
        struct scatterlist *sg;
        int i;
 
        for_each_sg(sglist, sg, nents, i)
-               dma_unmap_single(dev, sg_dma_address(sg), sg->length, dir);
+               c6x_dma_sync(sg_dma_address(sg), sg->length, dir);
 
-       debug_dma_unmap_sg(dev, sglist, nents, dir);
 }
-EXPORT_SYMBOL(dma_unmap_sg);
 
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
-                            size_t size, enum dma_data_direction dir)
+static void c6x_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+               size_t size, enum dma_data_direction dir)
 {
        c6x_dma_sync(handle, size, dir);
 
-       debug_dma_sync_single_for_cpu(dev, handle, size, dir);
 }
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
 
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
-                               size_t size, enum dma_data_direction dir)
+static void c6x_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
        c6x_dma_sync(handle, size, dir);
 
-       debug_dma_sync_single_for_device(dev, handle, size, dir);
 }
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
 
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
-                        int nents, enum dma_data_direction dir)
+static void c6x_dma_sync_sg_for_cpu(struct device *dev,
+               struct scatterlist *sglist, int nents,
+               enum dma_data_direction dir)
 {
        struct scatterlist *sg;
        int i;
 
        for_each_sg(sglist, sg, nents, i)
-               dma_sync_single_for_cpu(dev, sg_dma_address(sg),
+               c6x_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
                                        sg->length, dir);
 
-       debug_dma_sync_sg_for_cpu(dev, sglist, nents, dir);
 }
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
 
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
-                           int nents, enum dma_data_direction dir)
+static void c6x_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sglist, int nents,
+               enum dma_data_direction dir)
 {
        struct scatterlist *sg;
        int i;
 
        for_each_sg(sglist, sg, nents, i)
-               dma_sync_single_for_device(dev, sg_dma_address(sg),
+               c6x_dma_sync_single_for_device(dev, sg_dma_address(sg),
                                           sg->length, dir);
 
-       debug_dma_sync_sg_for_device(dev, sglist, nents, dir);
 }
-EXPORT_SYMBOL(dma_sync_sg_for_device);
 
+struct dma_map_ops c6x_dma_ops = {
+       .alloc                  = c6x_dma_alloc,
+       .free                   = c6x_dma_free,
+       .map_page               = c6x_dma_map_page,
+       .unmap_page             = c6x_dma_unmap_page,
+       .map_sg                 = c6x_dma_map_sg,
+       .unmap_sg               = c6x_dma_unmap_sg,
+       .sync_single_for_device = c6x_dma_sync_single_for_device,
+       .sync_single_for_cpu    = c6x_dma_sync_single_for_cpu,
+       .sync_sg_for_device     = c6x_dma_sync_sg_for_device,
+       .sync_sg_for_cpu        = c6x_dma_sync_sg_for_cpu,
+};
+EXPORT_SYMBOL(c6x_dma_ops);
 
 /* Number of entries preallocated for DMA-API debugging */
 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
index 4187e51..f7ee63a 100644 (file)
@@ -73,8 +73,8 @@ static void __free_dma_pages(u32 addr, int order)
  * Allocate DMA coherent memory space and return both the kernel
  * virtual and DMA address for that space.
  */
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *handle, gfp_t gfp)
+void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+               gfp_t gfp, struct dma_attrs *attrs)
 {
        u32 paddr;
        int order;
@@ -94,13 +94,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 
        return phys_to_virt(paddr);
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
 /*
  * Free DMA coherent memory as defined by the above mapping.
  */
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-                      dma_addr_t dma_handle)
+void c6x_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        int order;
 
@@ -111,7 +110,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
 
        __free_dma_pages(virt_to_phys(vaddr), order);
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
 /*
  * Initialise the coherent DMA memory allocator using the given uncached region.
index 7d307cc..b6549e5 100644 (file)
@@ -468,7 +468,7 @@ etrax_console_device(struct console* co, int *index)
 #endif
 }
 
-static struct console sercons = {
+static struct console ser_console = {
        name : "ttyS",
        write: console_write,
        read : NULL,
@@ -480,7 +480,7 @@ static struct console sercons = {
        cflag : 0,
        next : NULL
 };
-static struct console sercons0 = {
+static struct console ser0_console = {
        name : "ttyS",
        write: console_write,
        read : NULL,
@@ -493,7 +493,7 @@ static struct console sercons0 = {
        next : NULL
 };
 
-static struct console sercons1 = {
+static struct console ser1_console = {
        name : "ttyS",
        write: console_write,
        read : NULL,
@@ -505,7 +505,7 @@ static struct console sercons1 = {
        cflag : 0,
        next : NULL
 };
-static struct console sercons2 = {
+static struct console ser2_console = {
        name : "ttyS",
        write: console_write,
        read : NULL,
@@ -517,7 +517,7 @@ static struct console sercons2 = {
        cflag : 0,
        next : NULL
 };
-static struct console sercons3 = {
+static struct console ser3_console = {
        name : "ttyS",
        write: console_write,
        read : NULL,
@@ -539,17 +539,17 @@ init_etrax_debug(void)
        static int first = 1;
 
        if (!first) {
-               unregister_console(&sercons);
-               register_console(&sercons0);
-               register_console(&sercons1);
-               register_console(&sercons2);
-               register_console(&sercons3);
+               unregister_console(&ser_console);
+               register_console(&ser0_console);
+               register_console(&ser1_console);
+               register_console(&ser2_console);
+               register_console(&ser3_console);
                 init_dummy_console();
                return 0;
        }
 
        first = 0;
-       register_console(&sercons);
+       register_console(&ser_console);
        start_port(port);
 #ifdef CONFIG_ETRAX_KGDB
        start_port(kgdb_port);
index a4877a4..a74aa23 100644 (file)
@@ -5,6 +5,8 @@
  *
  */
 
+#include <linux/init.h>
+
 #define ASSEMBLER_MACROS_ONLY
 /* The IO_* macros use the ## token concatenation operator, so
    -traditional must not be used when assembling this file.  */
@@ -25,7 +27,7 @@
        .globl  romfs_in_flash
        .globl  swapper_pg_dir
 
-       .text
+       __HEAD
 
        ;; This is the entry point of the kernel. We are in supervisor mode.
        ;; 0x00000000 if Flash, 0x40004000 if DRAM
@@ -159,7 +161,7 @@ _inflash0:
 
        ;; Put this in a suitable section where we can reclaim storage
        ;; after init.
-       .section ".init.text", "ax"
+       __INIT
 _inflash:
 #ifdef CONFIG_ETRAX_ETHERNET
        ;; Start MII clock to make sure it is running when tranceiver is reset
index ee55578..8d5efa5 100644 (file)
 #include <linux/gfp.h>
 #include <asm/io.h>
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t gfp)
+static void *v32_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp,  struct dma_attrs *attrs)
 {
        void *ret;
-       int order = get_order(size);
+
        /* ignore region specifiers */
        gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
-       if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
-               return ret;
-
        if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
                gfp |= GFP_DMA;
 
-       ret = (void *)__get_free_pages(gfp, order);
+       ret = (void *)__get_free_pages(gfp,  get_order(size));
 
        if (ret != NULL) {
                memset(ret, 0, size);
@@ -39,12 +36,45 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        return ret;
 }
 
-void dma_free_coherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle)
+static void v32_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
+{
+       free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static inline dma_addr_t v32_dma_map_page(struct device *dev,
+               struct page *page, unsigned long offset, size_t size,
+               enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
-       int order = get_order(size);
+       return page_to_phys(page) + offset;
+}
 
-       if (!dma_release_from_coherent(dev, order, vaddr))
-               free_pages((unsigned long)vaddr, order);
+static inline int v32_dma_map_sg(struct device *dev, struct scatterlist *sg,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       printk("Map sg\n");
+       return nents;
+}
+
+static inline int v32_dma_supported(struct device *dev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if (mask < 0x00ffffff)
+                return 0;
+       return 1;
 }
 
+struct dma_map_ops v32_dma_ops = {
+       .alloc                  = v32_dma_alloc,
+       .free                   = v32_dma_free,
+       .map_page               = v32_dma_map_page,
+       .map_sg                 = v32_dma_map_sg,
+       .dma_supported          = v32_dma_supported,
+};
+EXPORT_SYMBOL(v32_dma_ops);
index ea63668..5ce83eb 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright (C) 2003, Axis Communications AB
  */
 
+#include <linux/init.h>
+
 #define ASSEMBLER_MACROS_ONLY
 
 /*
@@ -36,7 +38,7 @@
        .global nand_boot
        .global swapper_pg_dir
 
-       .text
+       __HEAD
 tstart:
        ;; This is the entry point of the kernel. The CPU is currently in
        ;; supervisor mode.
@@ -177,7 +179,7 @@ _inflash0:
 
        ;; Put the following in a section so that storage for it can be
        ;; reclaimed after init is finished.
-       .section ".init.text", "ax"
+       __INIT
 
 _inflash:
 
index 57f794e..5a37017 100644 (file)
-/* DMA mapping. Nothing tricky here, just virt_to_phys */
-
 #ifndef _ASM_CRIS_DMA_MAPPING_H
 #define _ASM_CRIS_DMA_MAPPING_H
 
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/scatterlist.h>
-
-#include <asm/cache.h>
-#include <asm/io.h>
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
 #ifdef CONFIG_PCI
-#include <asm-generic/dma-coherent.h>
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag);
+extern struct dma_map_ops v32_dma_ops;
 
-void dma_free_coherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle);
-#else
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-                   gfp_t flag)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-        BUG();
-        return NULL;
+       return &v32_dma_ops;
 }
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-                    dma_addr_t dma_handle)
+#else
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-        BUG();
+       BUG();
+       return NULL;
 }
 #endif
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       return virt_to_phys(ptr);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-          enum dma_data_direction direction)
-{
-       printk("Map sg\n");
-       return nents;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-            size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       return page_to_phys(page) + offset;
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-                       enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-                       enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                   enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-                   enum dma_data_direction direction)
-{
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
-        /*
-         * we fall back to GFP_DMA when the mask isn't all 1s,
-         * so we can't guarantee allocations that must be
-         * within a tighter range than GFP_DMA..
-         */
-        if(mask < 0x00ffffff)
-                return 0;
-
-       return 1;
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
-       if(!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-
-       return 0;
-}
 
 static inline void
 dma_cache_sync(struct device *dev, void *vaddr, size_t size,
@@ -158,15 +22,4 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 {
 }
 
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
-
 #endif
index a68b983..7552c25 100644 (file)
@@ -40,6 +40,7 @@ SECTIONS
        _stext = .;
        __stext = .;
        .text : {
+               HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
                LOCK_TEXT
index 03bfd6b..eefd9a4 100644 (file)
@@ -15,6 +15,7 @@ config FRV
        select OLD_SIGSUSPEND3
        select OLD_SIGACTION
        select HAVE_DEBUG_STACKOVERFLOW
+       select ARCH_NO_COHERENT_DMA_MMAP
 
 config ZONE_DMA
        bool
index 2840adc..9a82bfa 100644 (file)
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
 
-#include <linux/device.h>
-#include <linux/scatterlist.h>
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
-
-/*
- * See Documentation/DMA-API.txt for the description of how the
- * following DMA API should work.
- */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 
 extern unsigned long __nongprelbss dma_coherent_mem_start;
 extern unsigned long __nongprelbss dma_coherent_mem_end;
 
-void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
-
-extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-                                enum dma_data_direction direction);
-
-static inline
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                     enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-                     enum dma_data_direction direction);
-
-static inline
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-extern
-dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-                       size_t size, enum dma_data_direction direction);
-
-static inline
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-                   enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-
-static inline
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-                            enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-                               enum dma_data_direction direction)
-{
-       flush_write_buffers();
-}
-
-static inline
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                                  unsigned long offset, size_t size,
-                                  enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                     unsigned long offset, size_t size,
-                                     enum dma_data_direction direction)
-{
-       flush_write_buffers();
-}
-
-static inline
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                        enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-                           enum dma_data_direction direction)
-{
-       flush_write_buffers();
-}
-
-static inline
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-static inline
-int dma_supported(struct device *dev, u64 mask)
-{
-        /*
-         * we fall back to GFP_DMA when the mask isn't all 1s,
-         * so we can't guarantee allocations that must be
-         * within a tighter range than GFP_DMA..
-         */
-        if (mask < 0x00ffffff)
-                return 0;
-
-       return 1;
-}
+extern struct dma_map_ops frv_dma_ops;
 
-static inline
-int dma_set_mask(struct device *dev, u64 mask)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-
-       return 0;
+       return &frv_dma_ops;
 }
 
 static inline
@@ -132,19 +21,4 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
        flush_write_buffers();
 }
 
-/* Not supported for now */
-static inline int dma_mmap_coherent(struct device *dev,
-                                   struct vm_area_struct *vma, void *cpu_addr,
-                                   dma_addr_t dma_addr, size_t size)
-{
-       return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size)
-{
-       return -EINVAL;
-}
-
 #endif  /* _ASM_DMA_MAPPING_H */
index 70dfbea..8062fc7 100644 (file)
@@ -43,9 +43,20 @@ static inline unsigned long _swapl(unsigned long v)
 //#define __iormb() asm volatile("membar")
 //#define __iowmb() asm volatile("membar")
 
-#define __raw_readb __builtin_read8
-#define __raw_readw __builtin_read16
-#define __raw_readl __builtin_read32
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+       return __builtin_read8((volatile void __iomem *)addr);
+}
+
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+       return __builtin_read16((volatile void __iomem *)addr);
+}
+
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+       return __builtin_read32((volatile void __iomem *)addr);
+}
 
 #define __raw_writeb(datum, addr) __builtin_write8(addr, datum)
 #define __raw_writew(datum, addr) __builtin_write16(addr, datum)
index 8eeea0d..082be49 100644 (file)
@@ -34,7 +34,8 @@ struct dma_alloc_record {
 static DEFINE_SPINLOCK(dma_alloc_lock);
 static LIST_HEAD(dma_alloc_list);
 
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
+static void *frv_dma_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle,
+               gfp_t gfp, struct dma_attrs *attrs)
 {
        struct dma_alloc_record *new;
        struct list_head *this = &dma_alloc_list;
@@ -84,9 +85,8 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
        return NULL;
 }
 
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void frv_dma_free(struct device *hwdev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        struct dma_alloc_record *rec;
        unsigned long flags;
@@ -105,22 +105,9 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
        BUG();
 }
 
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-                         enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
-
-       return virt_to_bus(ptr);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-              enum dma_data_direction direction)
+static int frv_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        int i;
        struct scatterlist *sg;
@@ -135,14 +122,49 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
        return nents;
 }
 
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-                       size_t size, enum dma_data_direction direction)
+static dma_addr_t frv_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        BUG_ON(direction == DMA_NONE);
        flush_dcache_page(page);
        return (dma_addr_t) page_to_phys(page) + offset;
 }
 
-EXPORT_SYMBOL(dma_map_page);
+static void frv_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+static void frv_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sg, int nelems,
+               enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+
+static int frv_dma_supported(struct device *dev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if (mask < 0x00ffffff)
+                return 0;
+       return 1;
+}
+
+struct dma_map_ops frv_dma_ops = {
+       .alloc                  = frv_dma_alloc,
+       .free                   = frv_dma_free,
+       .map_page               = frv_dma_map_page,
+       .map_sg                 = frv_dma_map_sg,
+       .sync_single_for_device = frv_dma_sync_single_for_device,
+       .sync_sg_for_device     = frv_dma_sync_sg_for_device,
+       .dma_supported          = frv_dma_supported,
+};
+EXPORT_SYMBOL(frv_dma_ops);
index 4d1f01d..316b7b6 100644 (file)
@@ -18,7 +18,9 @@
 #include <linux/scatterlist.h>
 #include <asm/io.h>
 
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
+static void *frv_dma_alloc(struct device *hwdev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp,
+               struct dma_attrs *attrs)
 {
        void *ret;
 
@@ -29,29 +31,15 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
        return ret;
 }
 
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void frv_dma_free(struct device *hwdev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        consistent_free(vaddr);
 }
 
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-                         enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
-
-       return virt_to_bus(ptr);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-              enum dma_data_direction direction)
+static int frv_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        unsigned long dampr2;
        void *vaddr;
@@ -79,14 +67,48 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
        return nents;
 }
 
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-                       size_t size, enum dma_data_direction direction)
+static dma_addr_t frv_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
 {
-       BUG_ON(direction == DMA_NONE);
        flush_dcache_page(page);
        return (dma_addr_t) page_to_phys(page) + offset;
 }
 
-EXPORT_SYMBOL(dma_map_page);
+static void frv_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+static void frv_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sg, int nelems,
+               enum dma_data_direction direction)
+{
+       flush_write_buffers();
+}
+
+
+static int frv_dma_supported(struct device *dev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if (mask < 0x00ffffff)
+                return 0;
+       return 1;
+}
+
+struct dma_map_ops frv_dma_ops = {
+       .alloc                  = frv_dma_alloc,
+       .free                   = frv_dma_free,
+       .map_page               = frv_dma_map_page,
+       .map_sg                 = frv_dma_map_sg,
+       .sync_single_for_device = frv_dma_sync_single_for_device,
+       .sync_sg_for_device     = frv_dma_sync_sg_for_device,
+       .dma_supported          = frv_dma_supported,
+};
+EXPORT_SYMBOL(frv_dma_ops);
index 2e20333..986ea84 100644 (file)
@@ -15,9 +15,11 @@ config H8300
        select OF_IRQ
        select OF_EARLY_FLATTREE
        select HAVE_MEMBLOCK
-       select HAVE_DMA_ATTRS
        select CLKSRC_OF
        select H8300_TMR8
+       select HAVE_KERNEL_GZIP
+       select HAVE_KERNEL_LZO
+       select HAVE_ARCH_KGDB
 
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
index d7bc3fa..7643633 100644 (file)
@@ -28,11 +28,16 @@ $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
 $(obj)/vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
 
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
-       $(call if_changed,gzip)
+suffix-$(CONFIG_KERNEL_GZIP)    := gzip
+suffix-$(CONFIG_KERNEL_LZO)     := lzo
+
+$(obj)/vmlinux.bin.$(suffix-y): $(obj)/vmlinux.bin FORCE
+       $(call if_changed,$(suffix-y))
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300-linux -T
 OBJCOPYFLAGS := -O binary
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
        $(call if_changed,ld)
+
+CFLAGS_misc.o = -O0
index 6029c53..9f64fe8 100644 (file)
@@ -32,7 +32,13 @@ extern char output[];
 
 #define HEAP_SIZE             0x10000
 
+#ifdef CONFIG_KERNEL_GZIP
 #include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
 
 void *memset(void *s, int c, size_t n)
 {
index 44fd209..ad848a7 100644 (file)
@@ -13,16 +13,18 @@ SECTIONS
        {
                *(.rodata)
        }
+        . = ALIGN(0x4) ;
         .data :
 
         {
+        . = ALIGN(0x4) ;
         __sdata = . ;
         ___data_start = . ;
                 *(.data.*)
        }
+        . = ALIGN(0x4) ;
         .bss :
         {
-        . = ALIGN(0x4) ;
         __sbss = . ;
                 *(.bss*)
         . = ALIGN(0x4) ;
index d9b5b80..7ac7fad 100644 (file)
@@ -8,6 +8,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
        return &h8300_dma_map_ops;
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 #endif
index f0e14f3..2e221c5 100644 (file)
@@ -44,17 +44,17 @@ static inline void __raw_writel(u32 b, const volatile void __iomem *addr)
 static inline void ctrl_bclr(int b, void __iomem *addr)
 {
        if (__builtin_constant_p(b))
-               __asm__("bclr %1,%0" : "+WU"(*addr): "i"(b));
+               __asm__("bclr %1,%0" : "+WU"(*(u8 *)addr): "i"(b));
        else
-               __asm__("bclr %w1,%0" : "+WU"(*addr): "r"(b));
+               __asm__("bclr %w1,%0" : "+WU"(*(u8 *)addr): "r"(b));
 }
 
 static inline void ctrl_bset(int b, void __iomem *addr)
 {
        if (__builtin_constant_p(b))
-               __asm__("bset %1,%0" : "+WU"(*addr): "i"(b));
+               __asm__("bset %1,%0" : "+WU"(*(u8 *)addr): "i"(b));
        else
-               __asm__("bset %w1,%0" : "+WU"(*addr): "r"(b));
+               __asm__("bset %w1,%0" : "+WU"(*(u8 *)addr): "r"(b));
 }
 
 #include <asm-generic/io.h>
diff --git a/arch/h8300/include/asm/kgdb.h b/arch/h8300/include/asm/kgdb.h
new file mode 100644 (file)
index 0000000..726ff8f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_H8300_KGDB_H
+#define _ASM_H8300_KGDB_H
+
+#define CACHE_FLUSH_IS_SAFE    1
+#define BUFMAX                 2048
+
+enum regnames {
+       GDB_ER0, GDB_ER1, GDB_ER2, GDB_ER3,
+       GDB_ER4, GDB_ER5, GDB_ER6, GDB_SP,
+       GDB_CCR, GDB_PC,
+       GDB_CYCLLE,
+#if defined(CONFIG_CPU_H8S)
+       GDB_EXR,
+#endif
+       GDB_TICK, GDB_INST,
+#if defined(CONFIG_CPU_H8S)
+       GDB_MACH, GDB_MACL,
+#endif
+       /* do not change the last entry or anything below! */
+       GDB_NUMREGBYTES,                /* number of registers */
+};
+
+#define GDB_SIZEOF_REG         sizeof(u32)
+#if defined(CONFIG_CPU_H8300H)
+#define DBG_MAX_REG_NUM                (13)
+#elif defined(CONFIG_CPU_H8S)
+#define DBG_MAX_REG_NUM                (14)
+#endif
+#define NUMREGBYTES            (DBG_MAX_REG_NUM * GDB_SIZEOF_REG)
+
+#define BREAK_INSTR_SIZE       2
+static inline void arch_kgdb_breakpoint(void)
+{
+       __asm__ __volatile__("trapa #2");
+}
+
+#endif /* _ASM_H8300_KGDB_H */
index aa34e75..15e7011 100644 (file)
@@ -36,6 +36,6 @@ extern unsigned long *_interrupt_redirect_table;
 extern char _start, _etext;
 #define check_kernel_text(addr) \
        ((addr >= (unsigned long)(&_start)) && \
-        (addr <  (unsigned long)(&_etext)))
+        (addr <  (unsigned long)(&_etext)) && !(addr & 1))
 
 #endif /* _H8300_TRAPS_H */
index 5bc33f2..253f8e3 100644 (file)
@@ -17,3 +17,5 @@ obj-$(CONFIG_H8S_SIM) += sim-console.o
 
 obj-$(CONFIG_CPU_H8300H) += ptrace_h.o
 obj-$(CONFIG_CPU_H8S) += ptrace_s.o
+
+obj-$(CONFIG_KGDB) += kgdb.o
index 797dfa8..4f67d4b 100644 (file)
@@ -188,7 +188,11 @@ _interrupt_redirect_table:
        jsr     @_interrupt_entry               /* NMI */
        jmp     @_system_call                   /* TRAPA #0 (System call) */
        .long   0
+#if defined(CONFIG_KGDB)
+       jmp     @_kgdb_trap
+#else
        .long   0
+#endif
        jmp     @_trace_break                   /* TRAPA #3 (breakpoint) */
        .rept   INTERRUPTS-12
        jsr     @_interrupt_entry
@@ -242,6 +246,7 @@ _system_call:
        /* save top of frame */
        mov.l   sp,er0
        jsr     @set_esp0
+       andc    #0x3f,ccr
        mov.l   sp,er2
        and.w   #0xe000,r2
        mov.l   @(TI_FLAGS:16,er2),er2
@@ -405,6 +410,20 @@ _nmi:
        mov.l   @sp+, er0
        jmp     @_interrupt_entry
 
+#if defined(CONFIG_KGDB)
+_kgdb_trap:
+       subs    #4,sp
+       SAVE_ALL
+       mov.l   sp,er0
+       add.l   #LRET,er0
+       mov.l   er0,@(LSP,sp)
+       jsr     @set_esp0
+       mov.l   sp,er0
+       subs    #4,er0
+       jsr     @h8300_kgdb_trap
+       jmp     @ret_from_exception
+#endif
+
        .section        .bss
 _sw_ksp:
        .space  4
diff --git a/arch/h8300/kernel/kgdb.c b/arch/h8300/kernel/kgdb.c
new file mode 100644 (file)
index 0000000..602e478
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * H8/300 KGDB support
+ *
+ * Copyright (C) 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/ptrace.h>
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/io.h>
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
+       { "er0", GDB_SIZEOF_REG, offsetof(struct pt_regs, er0) },
+       { "er1", GDB_SIZEOF_REG, offsetof(struct pt_regs, er1) },
+       { "er2", GDB_SIZEOF_REG, offsetof(struct pt_regs, er2) },
+       { "er3", GDB_SIZEOF_REG, offsetof(struct pt_regs, er3) },
+       { "er4", GDB_SIZEOF_REG, offsetof(struct pt_regs, er4) },
+       { "er5", GDB_SIZEOF_REG, offsetof(struct pt_regs, er5) },
+       { "er6", GDB_SIZEOF_REG, offsetof(struct pt_regs, er6) },
+       { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
+       { "ccr", GDB_SIZEOF_REG, offsetof(struct pt_regs, ccr) },
+       { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, pc) },
+       { "cycles", GDB_SIZEOF_REG, -1 },
+#if defined(CONFIG_CPU_H8S)
+       { "exr", GDB_SIZEOF_REG, offsetof(struct pt_regs, exr) },
+#endif
+       { "tick", GDB_SIZEOF_REG, -1 },
+       { "inst", GDB_SIZEOF_REG, -1 },
+};
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return NULL;
+
+       switch (regno) {
+       case GDB_CCR:
+#if defined(CONFIG_CPU_H8S)
+       case GDB_EXR:
+#endif
+               *(u32 *)mem = *(u16 *)((void *)regs +
+                                      dbg_reg_def[regno].offset);
+               break;
+       default:
+               if (dbg_reg_def[regno].offset >= 0)
+                       memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+                              dbg_reg_def[regno].size);
+               else
+                       memset(mem, 0, dbg_reg_def[regno].size);
+               break;
+       }
+       return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return -EINVAL;
+
+       switch (regno) {
+       case GDB_CCR:
+#if defined(CONFIG_CPU_H8S)
+       case GDB_EXR:
+#endif
+               *(u16 *)((void *)regs +
+                        dbg_reg_def[regno].offset) = *(u32 *)mem;
+               break;
+       default:
+               memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+                      dbg_reg_def[regno].size);
+       }
+       return 0;
+}
+
+asmlinkage void h8300_kgdb_trap(struct pt_regs *regs)
+{
+       regs->pc &= 0x00ffffff;
+       if (kgdb_handle_exception(10, SIGTRAP, 0, regs))
+               return;
+       if (*(u16 *)(regs->pc) == *(u16 *)&arch_kgdb_ops.gdb_bpt_instr)
+               regs->pc += BREAK_INSTR_SIZE;
+       regs->pc |= regs->ccr << 24;
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+       memset((char *)gdb_regs, 0, NUMREGBYTES);
+       gdb_regs[GDB_SP] = p->thread.ksp;
+       gdb_regs[GDB_PC] = KSTK_EIP(p);
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+       regs->pc = pc;
+}
+
+int kgdb_arch_handle_exception(int vector, int signo, int err_code,
+                               char *remcom_in_buffer, char *remcom_out_buffer,
+                               struct pt_regs *regs)
+{
+       char *ptr;
+       unsigned long addr;
+
+       switch (remcom_in_buffer[0]) {
+       case 's':
+       case 'c':
+               /* handle the optional parameters */
+               ptr = &remcom_in_buffer[1];
+               if (kgdb_hex2long(&ptr, &addr))
+                       regs->pc = addr;
+
+               return 0;
+       }
+
+       return -1; /* this means that we do not want to exit from the handler */
+}
+
+int kgdb_arch_init(void)
+{
+       return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+       /* Nothing to do */
+}
+
+const struct kgdb_arch arch_kgdb_ops = {
+       /* Breakpoint instruction: trapa #2 */
+       .gdb_bpt_instr = { 0x57, 0x20 },
+};
index 380fffd..ad1f81f 100644 (file)
@@ -95,7 +95,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
        regs->ccr |= ccr;
        regs->orig_er0 = -1;            /* disable syscall checks */
        err |= __get_user(usp, &usc->sc_usp);
-       wrusp(usp);
+       regs->sp = usp;
 
        err |= __get_user(er0, &usc->sc_er0);
        *pd0 = er0;
@@ -180,7 +180,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
                return -EFAULT;
 
        /* Set up to return from userspace.  */
-       ret = frame->retcode;
+       ret = (unsigned char *)&frame->retcode;
        if (ksig->ka.sa.sa_flags & SA_RESTORER)
                ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
        else {
@@ -196,8 +196,8 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
                return -EFAULT;
 
        /* Set up registers for signal handler */
-       wrusp((unsigned long) frame);
-       regs->pc  = (unsigned long) ksig->ka.sa.sa_handler;
+       regs->sp  = (unsigned long)frame;
+       regs->pc  = (unsigned long)ksig->ka.sa.sa_handler;
        regs->er0 = ksig->sig;
        regs->er1 = (unsigned long)&(frame->info);
        regs->er2 = (unsigned long)&frame->uc;
index 1b2d7cd..044a361 100644 (file)
@@ -125,17 +125,18 @@ void show_stack(struct task_struct *task, unsigned long *esp)
 
        pr_info("Stack from %08lx:", (unsigned long)stack);
        for (i = 0; i < kstack_depth_to_print; i++) {
-               if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0)
+               if (((unsigned long)stack & (THREAD_SIZE - 1)) >=
+                   THREAD_SIZE-4)
                        break;
                if (i % 8 == 0)
-                       pr_info("\n       ");
-               pr_info(" %08lx", *stack++);
+                       pr_info(" ");
+               pr_cont(" %08lx", *stack++);
        }
 
-       pr_info("\nCall Trace:");
+       pr_info("\nCall Trace:\n");
        i = 0;
        stack = esp;
-       while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) {
+       while (((unsigned long)stack & (THREAD_SIZE - 1)) < THREAD_SIZE-4) {
                addr = *stack++;
                /*
                 * If the address is either in the text segment of the
@@ -147,15 +148,10 @@ void show_stack(struct task_struct *task, unsigned long *esp)
                 */
                if (check_kernel_text(addr)) {
                        if (i % 4 == 0)
-                               pr_info("\n       ");
-                       pr_info(" [<%08lx>]", addr);
+                               pr_info("       ");
+                       pr_cont(" [<%08lx>]", addr);
                        i++;
                }
        }
        pr_info("\n");
 }
-
-void show_trace_task(struct task_struct *tsk)
-{
-       show_stack(tsk, (unsigned long *)tsk->thread.esp0);
-}
index 4dc89d1..57298e7 100644 (file)
@@ -27,7 +27,6 @@ config HEXAGON
        select GENERIC_CLOCKEVENTS_BROADCAST
        select MODULES_USE_ELF_RELA
        select GENERIC_CPU_DEVICES
-       select HAVE_DMA_ATTRS
        ---help---
          Qualcomm Hexagon is a processor architecture designed for high
          performance and low power across a wide variety of applications.
index 268fde8..aa62034 100644 (file)
@@ -49,8 +49,6 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_handle);
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                           enum dma_data_direction direction);
 
-#include <asm-generic/dma-mapping-common.h>
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
        if (!dev->dma_mask)
index eb0249e..fb0515e 100644 (file)
@@ -25,7 +25,6 @@ config IA64
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
        select HAVE_FUNCTION_TRACER
-       select HAVE_DMA_ATTRS
        select TTY
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DMA_API_DEBUG
index 9beccf8..d472805 100644 (file)
@@ -25,8 +25,6 @@ extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
 
 #define get_dma_ops(dev) platform_dma_get_ops(dev)
 
-#include <asm-generic/dma-mapping-common.h>
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
        if (!dev->dma_mask)
index 74c132d..6a86850 100644 (file)
@@ -11,7 +11,7 @@
 
 
 
-#define NR_syscalls                    323 /* length of syscall table */
+#define NR_syscalls                    324 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
index 762edce..41369a1 100644 (file)
 #define __NR_membarrier                        1344
 #define __NR_kcmp                      1345
 #define __NR_mlock2                    1346
+#define __NR_copy_file_range           1347
 
 #endif /* _UAPI_ASM_IA64_UNISTD_H */
index 534a74a..477c55e 100644 (file)
@@ -1772,5 +1772,6 @@ sys_call_table:
        data8 sys_membarrier
        data8 sys_kcmp                          // 1345
        data8 sys_mlock2
+       data8 sys_copy_file_range
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
index 05aa535..96c5361 100644 (file)
 #ifndef _M68K_DMA_MAPPING_H
 #define _M68K_DMA_MAPPING_H
 
-#include <asm/cache.h>
+extern struct dma_map_ops m68k_dma_ops;
 
-struct scatterlist;
-
-static inline int dma_supported(struct device *dev, u64 mask)
-{
-       return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-       return 0;
-}
-
-extern void *dma_alloc_coherent(struct device *, size_t,
-                               dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t,
-                             void *, dma_addr_t);
-
-static inline void *dma_alloc_attrs(struct device *dev, size_t size,
-                                   dma_addr_t *dma_handle, gfp_t flag,
-                                   struct dma_attrs *attrs)
-{
-       /* attrs is not supported and ignored */
-       return dma_alloc_coherent(dev, size, dma_handle, flag);
-}
-
-static inline void dma_free_attrs(struct device *dev, size_t size,
-                                 void *cpu_addr, dma_addr_t dma_handle,
-                                 struct dma_attrs *attrs)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       /* attrs is not supported and ignored */
-       dma_free_coherent(dev, size, cpu_addr, dma_handle);
+        return &m68k_dma_ops;
 }
 
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
-                                         dma_addr_t *handle, gfp_t flag)
-{
-       return dma_alloc_coherent(dev, size, handle, flag);
-}
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
-                                       void *addr, dma_addr_t handle)
-{
-       dma_free_coherent(dev, size, addr, handle);
-}
 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                                  enum dma_data_direction dir)
 {
        /* we use coherent allocation, so not much to do here. */
 }
 
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
-                                enum dma_data_direction);
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
-                                   size_t size, enum dma_data_direction dir)
-{
-}
-
-extern dma_addr_t dma_map_page(struct device *, struct page *,
-                              unsigned long, size_t size,
-                              enum dma_data_direction);
-static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
-                                 size_t size, enum dma_data_direction dir)
-{
-}
-
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
-                     enum dma_data_direction);
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-                               int nhwentries, enum dma_data_direction dir)
-{
-}
-
-extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
-                                      enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
-                                  enum dma_data_direction);
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
-               dma_addr_t dma_handle, unsigned long offset, size_t size,
-               enum dma_data_direction direction)
-{
-       /* just sync everything for now */
-       dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
-                                          size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-                                      int nents, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
-               dma_addr_t dma_handle, unsigned long offset, size_t size,
-               enum dma_data_direction direction)
-{
-       /* just sync everything for now */
-       dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
-{
-       return 0;
-}
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
 #endif  /* _M68K_DMA_MAPPING_H */
index 564665f..cbc78b4 100644 (file)
@@ -18,8 +18,8 @@
 
 #if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *handle, gfp_t flag)
+static void *m68k_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+               gfp_t flag, struct dma_attrs *attrs)
 {
        struct page *page, **map;
        pgprot_t pgprot;
@@ -61,8 +61,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        return addr;
 }
 
-void dma_free_coherent(struct device *dev, size_t size,
-                      void *addr, dma_addr_t handle)
+static void m68k_dma_free(struct device *dev, size_t size, void *addr,
+               dma_addr_t handle, struct dma_attrs *attrs)
 {
        pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
        vfree(addr);
@@ -72,8 +72,8 @@ void dma_free_coherent(struct device *dev, size_t size,
 
 #include <asm/cacheflush.h>
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t gfp)
+static void *m68k_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
        void *ret;
        /* ignore region specifiers */
@@ -90,19 +90,16 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        return ret;
 }
 
-void dma_free_coherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle)
+static void m68k_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        free_pages((unsigned long)vaddr, get_order(size));
 }
 
 #endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
 
-EXPORT_SYMBOL(dma_alloc_coherent);
-EXPORT_SYMBOL(dma_free_coherent);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
-                               size_t size, enum dma_data_direction dir)
+static void m68k_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
        switch (dir) {
        case DMA_BIDIRECTIONAL:
@@ -118,10 +115,9 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
                break;
        }
 }
-EXPORT_SYMBOL(dma_sync_single_for_device);
 
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
-                           int nents, enum dma_data_direction dir)
+static void m68k_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sglist, int nents, enum dma_data_direction dir)
 {
        int i;
        struct scatterlist *sg;
@@ -131,31 +127,19 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
                                           dir);
        }
 }
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
-                         enum dma_data_direction dir)
-{
-       dma_addr_t handle = virt_to_bus(addr);
-
-       dma_sync_single_for_device(dev, handle, size, dir);
-       return handle;
-}
-EXPORT_SYMBOL(dma_map_single);
 
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-                       unsigned long offset, size_t size,
-                       enum dma_data_direction dir)
+static dma_addr_t m68k_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size, enum dma_data_direction dir,
+               struct dma_attrs *attrs)
 {
        dma_addr_t handle = page_to_phys(page) + offset;
 
        dma_sync_single_for_device(dev, handle, size, dir);
        return handle;
 }
-EXPORT_SYMBOL(dma_map_page);
 
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-              enum dma_data_direction dir)
+static int m68k_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
 {
        int i;
        struct scatterlist *sg;
@@ -167,4 +151,13 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
        }
        return nents;
 }
-EXPORT_SYMBOL(dma_map_sg);
+
+struct dma_map_ops m68k_dma_ops = {
+       .alloc                  = m68k_dma_alloc,
+       .free                   = m68k_dma_free,
+       .map_page               = m68k_dma_map_page,
+       .map_sg                 = m68k_dma_map_sg,
+       .sync_single_for_device = m68k_dma_sync_single_for_device,
+       .sync_sg_for_device     = m68k_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(m68k_dma_ops);
index eb5cdec..27af5d4 100644 (file)
 #ifndef _ASM_METAG_DMA_MAPPING_H
 #define _ASM_METAG_DMA_MAPPING_H
 
-#include <linux/mm.h>
+extern struct dma_map_ops metag_dma_ops;
 
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <linux/scatterlist.h>
-#include <asm/bug.h>
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
-                      void *vaddr, dma_addr_t dma_handle);
-
-void dma_sync_for_device(void *vaddr, size_t size, int dma_direction);
-void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction);
-
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-                     void *cpu_addr, dma_addr_t dma_addr, size_t size);
-
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
-                         void *cpu_addr, dma_addr_t dma_addr, size_t size);
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-       WARN_ON(size == 0);
-       dma_sync_for_device(ptr, size, direction);
-       return virt_to_phys(ptr);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-       dma_sync_for_cpu(phys_to_virt(dma_addr), size, direction);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-          enum dma_data_direction direction)
-{
-       struct scatterlist *sg;
-       int i;
-
-       BUG_ON(!valid_dma_direction(direction));
-       WARN_ON(nents == 0 || sglist[0].length == 0);
-
-       for_each_sg(sglist, sg, nents, i) {
-               BUG_ON(!sg_page(sg));
-
-               sg->dma_address = sg_phys(sg);
-               dma_sync_for_device(sg_virt(sg), sg->length, direction);
-       }
-
-       return nents;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-            size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-       dma_sync_for_device((void *)(page_to_phys(page) + offset), size,
-                           direction);
-       return page_to_phys(page) + offset;
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-       dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
-}
-
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nhwentries,
-            enum dma_data_direction direction)
-{
-       struct scatterlist *sg;
-       int i;
-
-       BUG_ON(!valid_dma_direction(direction));
-       WARN_ON(nhwentries == 0 || sglist[0].length == 0);
-
-       for_each_sg(sglist, sg, nhwentries, i) {
-               BUG_ON(!sg_page(sg));
-
-               sg->dma_address = sg_phys(sg);
-               dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
-       }
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-                       enum dma_data_direction direction)
-{
-       dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-                          size_t size, enum dma_data_direction direction)
-{
-       dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction)
-{
-       dma_sync_for_cpu(phys_to_virt(dma_handle)+offset, size,
-                        direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
-{
-       dma_sync_for_device(phys_to_virt(dma_handle)+offset, size,
-                           direction);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nelems,
-                   enum dma_data_direction direction)
-{
-       int i;
-       struct scatterlist *sg;
-
-       for_each_sg(sglist, sg, nelems, i)
-               dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
-                      int nelems, enum dma_data_direction direction)
-{
-       int i;
-       struct scatterlist *sg;
-
-       for_each_sg(sglist, sg, nelems, i)
-               dma_sync_for_device(sg_virt(sg), sg->length, direction);
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       return 0;
-}
-
-#define dma_supported(dev, mask)        (1)
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-
-       return 0;
+       return &metag_dma_ops;
 }
 
 /*
@@ -184,11 +18,4 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 {
 }
 
-/* drivers/base/dma-mapping.c */
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size);
-
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
 #endif
index c700d62..e12368d 100644 (file)
@@ -171,8 +171,8 @@ out:
  * Allocate DMA-coherent memory space and return both the kernel remapped
  * virtual and bus address for that space.
  */
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *handle, gfp_t gfp)
+static void *metag_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
 {
        struct page *page;
        struct metag_vm_region *c;
@@ -263,13 +263,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 no_page:
        return NULL;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
 /*
  * free a page as defined by the above mapping.
  */
-void dma_free_coherent(struct device *dev, size_t size,
-                      void *vaddr, dma_addr_t dma_handle)
+static void metag_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        struct metag_vm_region *c;
        unsigned long flags, addr;
@@ -329,16 +328,19 @@ no_area:
               __func__, vaddr);
        dump_stack();
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
-
-static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
-                   void *cpu_addr, dma_addr_t dma_addr, size_t size)
+static int metag_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+               void *cpu_addr, dma_addr_t dma_addr, size_t size,
+               struct dma_attrs *attrs)
 {
-       int ret = -ENXIO;
-
        unsigned long flags, user_size, kern_size;
        struct metag_vm_region *c;
+       int ret = -ENXIO;
+
+       if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
+               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+       else
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
        user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 
@@ -364,25 +366,6 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
        return ret;
 }
 
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-                     void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-       return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-EXPORT_SYMBOL(dma_mmap_coherent);
-
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
-                         void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
-       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-       return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-EXPORT_SYMBOL(dma_mmap_writecombine);
-
-
-
-
 /*
  * Initialise the consistent memory allocation.
  */
@@ -423,7 +406,7 @@ early_initcall(dma_alloc_init);
 /*
  * make an area consistent to devices.
  */
-void dma_sync_for_device(void *vaddr, size_t size, int dma_direction)
+static void dma_sync_for_device(void *vaddr, size_t size, int dma_direction)
 {
        /*
         * Ensure any writes get through the write combiner. This is necessary
@@ -465,12 +448,11 @@ void dma_sync_for_device(void *vaddr, size_t size, int dma_direction)
 
        wmb();
 }
-EXPORT_SYMBOL(dma_sync_for_device);
 
 /*
  * make an area consistent to the core.
  */
-void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction)
+static void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction)
 {
        /*
         * Hardware L2 cache prefetch doesn't occur across 4K physical
@@ -497,4 +479,100 @@ void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction)
 
        rmb();
 }
-EXPORT_SYMBOL(dma_sync_for_cpu);
+
+static dma_addr_t metag_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+       dma_sync_for_device((void *)(page_to_phys(page) + offset), size,
+                           direction);
+       return page_to_phys(page) + offset;
+}
+
+static void metag_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+               size_t size, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
+}
+
+static int metag_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sglist, sg, nents, i) {
+               BUG_ON(!sg_page(sg));
+
+               sg->dma_address = sg_phys(sg);
+               dma_sync_for_device(sg_virt(sg), sg->length, direction);
+       }
+
+       return nents;
+}
+
+
+static void metag_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
+               int nhwentries, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sglist, sg, nhwentries, i) {
+               BUG_ON(!sg_page(sg));
+
+               sg->dma_address = sg_phys(sg);
+               dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+       }
+}
+
+static void metag_dma_sync_single_for_cpu(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
+{
+       dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
+}
+
+static void metag_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
+{
+       dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
+}
+
+static void metag_dma_sync_sg_for_cpu(struct device *dev,
+               struct scatterlist *sglist, int nelems,
+               enum dma_data_direction direction)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nelems, i)
+               dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+}
+
+static void metag_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sglist, int nelems,
+               enum dma_data_direction direction)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nelems, i)
+               dma_sync_for_device(sg_virt(sg), sg->length, direction);
+}
+
+struct dma_map_ops metag_dma_ops = {
+       .alloc                  = metag_dma_alloc,
+       .free                   = metag_dma_free,
+       .map_page               = metag_dma_map_page,
+       .map_sg                 = metag_dma_map_sg,
+       .sync_single_for_device = metag_dma_sync_single_for_device,
+       .sync_single_for_cpu    = metag_dma_sync_single_for_cpu,
+       .sync_sg_for_cpu        = metag_dma_sync_sg_for_cpu,
+       .mmap                   = metag_dma_mmap,
+};
+EXPORT_SYMBOL(metag_dma_ops);
index 5ecd028..53b69de 100644 (file)
@@ -19,7 +19,6 @@ config MICROBLAZE
        select HAVE_ARCH_KGDB
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_API_DEBUG
-       select HAVE_DMA_ATTRS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
index 24b1297..1884783 100644 (file)
@@ -44,8 +44,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
        return &dma_direct_ops;
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 static inline void __dma_sync(unsigned long paddr,
                              size_t size, enum dma_data_direction direction)
 {
index a96c81d..c5cd63a 100644 (file)
@@ -21,6 +21,7 @@ platforms += mti-malta
 platforms += mti-sead3
 platforms += netlogic
 platforms += paravirt
+platforms += pic32
 platforms += pistachio
 platforms += pmcs-msp71xx
 platforms += pnx833x
index 71683a8..57a945e 100644 (file)
@@ -31,7 +31,6 @@ config MIPS
        select RTC_LIB if !MACH_LOONGSON64
        select GENERIC_ATOMIC64 if !64BIT
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_CONTIGUOUS
        select HAVE_DMA_API_DEBUG
        select GENERIC_IRQ_PROBE
@@ -170,6 +169,7 @@ config BMIPS_GENERIC
        select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
        select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
        select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+       select ARCH_WANT_OPTIONAL_GPIOLIB
        help
          Build a generic DT-based kernel image that boots on select
          BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top
@@ -481,6 +481,14 @@ config MIPS_MALTA
          This enables support for the MIPS Technologies Malta evaluation
          board.
 
+config MACH_PIC32
+       bool "Microchip PIC32 Family"
+       help
+         This enables support for the Microchip PIC32 family of platforms.
+
+         Microchip PIC32 is a family of general-purpose 32 bit MIPS core
+         microcontrollers.
+
 config MIPS_SEAD3
        bool "MIPS SEAD3 board"
        select BOOT_ELF32
@@ -980,6 +988,7 @@ source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
 source "arch/mips/lantiq/Kconfig"
 source "arch/mips/lasat/Kconfig"
+source "arch/mips/pic32/Kconfig"
 source "arch/mips/pistachio/Kconfig"
 source "arch/mips/pmcs-msp71xx/Kconfig"
 source "arch/mips/ralink/Kconfig"
@@ -1756,6 +1765,10 @@ config SYS_SUPPORTS_ZBOOT_UART16550
        bool
        select SYS_SUPPORTS_ZBOOT
 
+config SYS_SUPPORTS_ZBOOT_UART_PROM
+       bool
+       select SYS_SUPPORTS_ZBOOT
+
 config CPU_LOONGSON2
        bool
        select CPU_SUPPORTS_32BIT_KERNEL
@@ -2018,7 +2031,8 @@ config KVM_GUEST
        bool "KVM Guest Kernel"
        depends on BROKEN_ON_SMP
        help
-         Select this option if building a guest kernel for KVM (Trap & Emulate) mode
+         Select this option if building a guest kernel for KVM (Trap & Emulate)
+         mode.
 
 config KVM_GUEST_TIMER_FREQ
        int "Count/Compare Timer Frequency (MHz)"
index 3f70ba5..e78d60d 100644 (file)
@@ -166,16 +166,6 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
 endif
 cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
 cflags-$(CONFIG_CPU_BMIPS)     += -march=mips32 -Wa,-mips32 -Wa,--trap
-#
-# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
-# as MIPS64 R1; older versions as just R1.  This leaves the possibility open
-# that GCC might generate R2 code for -march=loongson3a which then is rejected
-# by GAS.  The cc-option can't probe for this behaviour so -march=loongson3a
-# can't easily be used safely within the kbuild framework.
-#
-cflags-$(CONFIG_CPU_LOONGSON3)  +=                                     \
-       $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
-       -Wa,-mips64r2 -Wa,--trap
 
 cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
 cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
index f9bc4f5..84548f7 100644 (file)
@@ -40,7 +40,7 @@
 
 static int gpio2_get(struct gpio_chip *chip, unsigned offset)
 {
-       return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
+       return !!alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
 }
 
 static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -68,7 +68,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
 
 static int gpio1_get(struct gpio_chip *chip, unsigned offset)
 {
-       return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
+       return !!alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
 }
 
 static void gpio1_set(struct gpio_chip *chip,
@@ -119,7 +119,7 @@ struct gpio_chip alchemy_gpio_chip[] = {
 
 static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
 {
-       return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
+       return !!au1300_gpio_get_value(off + AU1300_GPIO_BASE);
 }
 
 static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
index f493045..f969f58 100644 (file)
@@ -37,7 +37,7 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
                                container_of(chip, struct ar7_gpio_chip, chip);
        void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
 
-       return readl(gpio_in) & (1 << gpio);
+       return !!(readl(gpio_in) & (1 << gpio));
 }
 
 static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
index ca7cc19..870c6b2 100644 (file)
@@ -23,7 +23,6 @@ void ath79_clocks_init(void);
 unsigned long ath79_get_sys_clk_rate(const char *id);
 
 void ath79_ddr_ctrl_init(void);
-void ath79_ddr_wb_flush(unsigned int reg);
 
 void ath79_gpio_init(void);
 
index eeb3953..511c065 100644 (file)
 #include "common.h"
 #include "machtypes.h"
 
+static void __init ath79_misc_intc_domain_init(
+       struct device_node *node, int irq);
+
 static void ath79_misc_irq_handler(struct irq_desc *desc)
 {
-       void __iomem *base = ath79_reset_base;
+       struct irq_domain *domain = irq_desc_get_handler_data(desc);
+       void __iomem *base = domain->host_data;
        u32 pending;
 
        pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
@@ -42,15 +46,15 @@ static void ath79_misc_irq_handler(struct irq_desc *desc)
        while (pending) {
                int bit = __ffs(pending);
 
-               generic_handle_irq(ATH79_MISC_IRQ(bit));
+               generic_handle_irq(irq_linear_revmap(domain, bit));
                pending &= ~BIT(bit);
        }
 }
 
 static void ar71xx_misc_irq_unmask(struct irq_data *d)
 {
-       unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-       void __iomem *base = ath79_reset_base;
+       void __iomem *base = irq_data_get_irq_chip_data(d);
+       unsigned int irq = d->hwirq;
        u32 t;
 
        t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
@@ -62,8 +66,8 @@ static void ar71xx_misc_irq_unmask(struct irq_data *d)
 
 static void ar71xx_misc_irq_mask(struct irq_data *d)
 {
-       unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-       void __iomem *base = ath79_reset_base;
+       void __iomem *base = irq_data_get_irq_chip_data(d);
+       unsigned int irq = d->hwirq;
        u32 t;
 
        t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
@@ -75,8 +79,8 @@ static void ar71xx_misc_irq_mask(struct irq_data *d)
 
 static void ar724x_misc_irq_ack(struct irq_data *d)
 {
-       unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-       void __iomem *base = ath79_reset_base;
+       void __iomem *base = irq_data_get_irq_chip_data(d);
+       unsigned int irq = d->hwirq;
        u32 t;
 
        t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
@@ -94,12 +98,6 @@ static struct irq_chip ath79_misc_irq_chip = {
 
 static void __init ath79_misc_irq_init(void)
 {
-       void __iomem *base = ath79_reset_base;
-       int i;
-
-       __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-       __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
        if (soc_is_ar71xx() || soc_is_ar913x())
                ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
        else if (soc_is_ar724x() ||
@@ -110,13 +108,7 @@ static void __init ath79_misc_irq_init(void)
        else
                BUG();
 
-       for (i = ATH79_MISC_IRQ_BASE;
-            i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
-               irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
-                                        handle_level_irq);
-       }
-
-       irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler);
+       ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6));
 }
 
 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
@@ -256,10 +248,10 @@ asmlinkage void plat_irq_dispatch(void)
        }
 }
 
-#ifdef CONFIG_IRQCHIP
 static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
        irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
+       irq_set_chip_data(irq, d->host_data);
        return 0;
 }
 
@@ -268,19 +260,14 @@ static const struct irq_domain_ops misc_irq_domain_ops = {
        .map = misc_map,
 };
 
-static int __init ath79_misc_intc_of_init(
-       struct device_node *node, struct device_node *parent)
+static void __init ath79_misc_intc_domain_init(
+       struct device_node *node, int irq)
 {
        void __iomem *base = ath79_reset_base;
        struct irq_domain *domain;
-       int irq;
-
-       irq = irq_of_parse_and_map(node, 0);
-       if (!irq)
-               panic("Failed to get MISC IRQ");
 
        domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
-                       ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
+                       ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base);
        if (!domain)
                panic("Failed to add MISC irqdomain");
 
@@ -288,9 +275,19 @@ static int __init ath79_misc_intc_of_init(
        __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
        __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
 
+       irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
+}
 
-       irq_set_chained_handler(irq, ath79_misc_irq_handler);
+static int __init ath79_misc_intc_of_init(
+       struct device_node *node, struct device_node *parent)
+{
+       int irq;
 
+       irq = irq_of_parse_and_map(node, 0);
+       if (!irq)
+               panic("Failed to get MISC IRQ");
+
+       ath79_misc_intc_domain_init(node, irq);
        return 0;
 }
 
@@ -349,8 +346,6 @@ static int __init ar79_cpu_intc_of_init(
 IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
                ar79_cpu_intc_of_init);
 
-#endif
-
 void __init arch_init_irq(void)
 {
        if (mips_machtype == ATH79_MACH_GENERIC_OF) {
index 8755d61..be451ee 100644 (file)
 
 #define ATH79_SYS_TYPE_LEN     64
 
-#define AR71XX_BASE_FREQ       40000000
-#define AR724X_BASE_FREQ       5000000
-#define AR913X_BASE_FREQ       5000000
-
 static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
 
 static void ath79_restart(char *command)
@@ -272,15 +268,10 @@ void __init device_tree_init(void)
        unflatten_and_copy_device_tree();
 }
 
-static void __init ath79_generic_init(void)
-{
-       /* Nothing to do */
-}
-
 MIPS_MACHINE(ATH79_MACH_GENERIC,
             "Generic",
             "Generic AR71XX/AR724X/AR913X based board",
-            ath79_generic_init);
+            NULL);
 
 MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
             "DTB",
index a7e569c..959c145 100644 (file)
@@ -666,9 +666,15 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
        switch (bus->hosttype) {
        case BCMA_HOSTTYPE_PCI:
                memset(out, 0, sizeof(struct ssb_sprom));
-               snprintf(buf, sizeof(buf), "pci/%u/%u/",
-                        bus->host_pci->bus->number + 1,
-                        PCI_SLOT(bus->host_pci->devfn));
+               /* On BCM47XX all PCI buses share the same domain */
+               if (config_enabled(CONFIG_BCM47XX))
+                       snprintf(buf, sizeof(buf), "pci/%u/%u/",
+                                bus->host_pci->bus->number + 1,
+                                PCI_SLOT(bus->host_pci->devfn));
+               else
+                       snprintf(buf, sizeof(buf), "pci/%u/%u/",
+                                pci_domain_nr(bus->host_pci->bus) + 1,
+                                bus->host_pci->bus->number);
                bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
                prefix = buf;
                break;
index 4b50d40..5f2bc1e 100644 (file)
@@ -10,6 +10,7 @@
 
 #define pr_fmt(fmt) "bcm63xx_nvram: " fmt
 
+#include <linux/bcm963xx_nvram.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 #include <linux/export.h>
 
 #include <bcm63xx_nvram.h>
 
-/*
- * nvram structure
- */
-struct bcm963xx_nvram {
-       u32     version;
-       u8      reserved1[256];
-       u8      name[16];
-       u32     main_tp_number;
-       u32     psi_size;
-       u32     mac_addr_count;
-       u8      mac_addr_base[ETH_ALEN];
-       u8      reserved2[2];
-       u32     checksum_old;
-       u8      reserved3[720];
-       u32     checksum_high;
-};
-
-#define BCM63XX_DEFAULT_PSI_SIZE       64
-
 static struct bcm963xx_nvram nvram;
 static int mac_addr_used;
 
 void __init bcm63xx_nvram_init(void *addr)
 {
-       unsigned int check_len;
        u32 crc, expected_crc;
        u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
 
        /* extract nvram data */
-       memcpy(&nvram, addr, sizeof(nvram));
+       memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE);
 
        /* check checksum before using data */
-       if (nvram.version <= 4) {
-               check_len = offsetof(struct bcm963xx_nvram, reserved3);
-               expected_crc = nvram.checksum_old;
-               nvram.checksum_old = 0;
-       } else {
-               check_len = sizeof(nvram);
-               expected_crc = nvram.checksum_high;
-               nvram.checksum_high = 0;
-       }
-
-       crc = crc32_le(~0, (u8 *)&nvram, check_len);
-
-       if (crc != expected_crc)
+       if (bcm963xx_nvram_checksum(&nvram, &expected_crc, &crc))
                pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
                        expected_crc, crc);
 
@@ -116,12 +85,3 @@ int bcm63xx_nvram_get_mac_address(u8 *mac)
        return 0;
 }
 EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
-
-int bcm63xx_nvram_get_psi_size(void)
-{
-       if (nvram.psi_size > 0)
-               return nvram.psi_size;
-
-       return BCM63XX_DEFAULT_PSI_SIZE;
-}
-EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size);
index 5b16d29..3553528 100644 (file)
@@ -105,6 +105,7 @@ static const struct bmips_quirk bmips_quirk_list[] = {
        { "brcm,bcm33843-viper",        &bcm3384_viper_quirks           },
        { "brcm,bcm6328",               &bcm6328_quirks                 },
        { "brcm,bcm6368",               &bcm6368_quirks                 },
+       { "brcm,bcm63168",              &bcm6368_quirks                 },
        { },
 };
 
index d5bdee1..4eff1ef 100644 (file)
@@ -29,20 +29,23 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
        -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
        -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
 
-targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o
-
 # decompressor objects (linked with vmlinuz)
 vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o
 
 ifdef CONFIG_DEBUG_ZBOOT
 vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT)                 += $(obj)/dbg.o
 vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o
 vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY)                += $(obj)/uart-alchemy.o
 endif
 
-ifdef CONFIG_KERNEL_XZ
-vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o
-endif
+vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o
+
+$(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib
+$(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c
+       $(call cmd,shipped)
+
+targets := $(notdir $(vmlinuzobjs-y))
 
 targets += vmlinux.bin
 OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
@@ -60,7 +63,7 @@ targets += vmlinux.bin.z
 $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
        $(call if_changed,$(tool_y))
 
-targets += piggy.o
+targets += piggy.o dummy.o
 OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
                        --set-section-flags=.image=contents,alloc,load,readonly,data
 $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
diff --git a/arch/mips/boot/compressed/uart-prom.c b/arch/mips/boot/compressed/uart-prom.c
new file mode 100644 (file)
index 0000000..1c3d51b
--- /dev/null
@@ -0,0 +1,7 @@
+
+extern void prom_putchar(unsigned char ch);
+
+void putc(char c)
+{
+       prom_putchar(c);
+}
index a0bf516..fc7a0a9 100644 (file)
@@ -4,6 +4,7 @@ dts-dirs        += ingenic
 dts-dirs       += lantiq
 dts-dirs       += mti
 dts-dirs       += netlogic
+dts-dirs       += pic32
 dts-dirs       += qca
 dts-dirs       += ralink
 dts-dirs       += xilfpga
index d52ce3d..459b9b2 100644 (file)
@@ -31,6 +31,7 @@
        };
 
        aliases {
+               leds0 = &leds0;
                uart0 = &uart0;
        };
 
                        offset = <0x28>;
                        mask = <0x1>;
                };
+
+               leds0: led-controller@10000800 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "brcm,bcm6328-leds";
+                       reg = <0x10000800 0x24>;
+                       status = "disabled";
+               };
        };
 };
index 45152bc..9c8d3fe 100644 (file)
@@ -32,6 +32,7 @@
        };
 
        aliases {
+               leds0 = &leds0;
                uart0 = &uart0;
        };
 
                compatible = "simple-bus";
                ranges;
 
+               periph_cntl: syscon@10000000 {
+                       compatible = "syscon";
+                       reg = <0x10000000 0x14>;
+                       little-endian;
+               };
+
+               reboot: syscon-reboot@10000008 {
+                       compatible = "syscon-reboot";
+                       regmap = <&periph_cntl>;
+                       offset = <0x8>;
+                       mask = <0x1>;
+               };
+
                periph_intc: periph_intc@10000020 {
                        compatible = "brcm,bcm3380-l2-intc";
                        reg = <0x10000024 0x4 0x1000002c 0x4>,
                        interrupts = <2>;
                };
 
+               leds0: led-controller@100000d0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "brcm,bcm6358-leds";
+                       reg = <0x100000d0 0x8>;
+                       status = "disabled";
+               };
+
                uart0: serial@10000100 {
                        compatible = "brcm,bcm6345-uart";
                        reg = <0x10000100 0x18>;
index 9fcb9e7..1652d8d 100644 (file)
 &uart4 {
        status = "okay";
 };
+
+&nemc {
+       status = "okay";
+
+       nandc: nand-controller@1 {
+               compatible = "ingenic,jz4780-nand";
+               reg = <1 0 0x1000000>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ingenic,bch-controller = <&bch>;
+
+               ingenic,nemc-tAS = <10>;
+               ingenic,nemc-tAH = <5>;
+               ingenic,nemc-tBP = <10>;
+               ingenic,nemc-tAW = <15>;
+               ingenic,nemc-tSTRV = <100>;
+
+               nand@1 {
+                       reg = <1>;
+
+                       nand-ecc-step-size = <1024>;
+                       nand-ecc-strength = <24>;
+                       nand-ecc-mode = "hw";
+                       nand-on-flash-bbt;
+
+                       partitions {
+                               compatible = "fixed-partitions";
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+
+                               partition@0 {
+                                       label = "u-boot-spl";
+                                       reg = <0x0 0x0 0x0 0x800000>;
+                               };
+
+                               partition@0x800000 {
+                                       label = "u-boot";
+                                       reg = <0x0 0x800000 0x0 0x200000>;
+                               };
+
+                               partition@0xa00000 {
+                                       label = "u-boot-env";
+                                       reg = <0x0 0xa00000 0x0 0x200000>;
+                               };
+
+                               partition@0xc00000 {
+                                       label = "boot";
+                                       reg = <0x0 0xc00000 0x0 0x4000000>;
+                               };
+
+                               partition@0x8c00000 {
+                                       label = "system";
+                                       reg = <0x0 0x4c00000 0x1 0xfb400000>;
+                               };
+                       };
+               };
+       };
+};
+
+&bch {
+       status = "okay";
+};
index 65389f6..b868b42 100644 (file)
 
                status = "disabled";
        };
+
+       nemc: nemc@13410000 {
+               compatible = "ingenic,jz4780-nemc";
+               reg = <0x13410000 0x10000>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <1 0 0x1b000000 0x1000000
+                         2 0 0x1a000000 0x1000000
+                         3 0 0x19000000 0x1000000
+                         4 0 0x18000000 0x1000000
+                         5 0 0x17000000 0x1000000
+                         6 0 0x16000000 0x1000000>;
+
+               clocks = <&cgu JZ4780_CLK_NEMC>;
+
+               status = "disabled";
+       };
+
+       bch: bch@134d0000 {
+               compatible = "ingenic,jz4780-bch";
+               reg = <0x134d0000 0x10000>;
+
+               clocks = <&cgu JZ4780_CLK_BCH>;
+
+               status = "disabled";
+       };
 };
diff --git a/arch/mips/boot/dts/pic32/Makefile b/arch/mips/boot/dts/pic32/Makefile
new file mode 100644 (file)
index 0000000..7ac7905
--- /dev/null
@@ -0,0 +1,12 @@
+dtb-$(CONFIG_DTB_PIC32_MZDA_SK)                += pic32mzda_sk.dtb
+
+dtb-$(CONFIG_DTB_PIC32_NONE)           += \
+                                       pic32mzda_sk.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
new file mode 100644 (file)
index 0000000..ef13350
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Device Tree Source for PIC32MZDA clock data
+ *
+ * Purna Chandra Mandal <purna.mandal@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/* all fixed rate clocks */
+
+/ {
+       POSC:posc_clk { /* On-chip primary oscillator */
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+       };
+
+       FRC:frc_clk { /* internal FRC oscillator */
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <8000000>;
+       };
+
+       BFRC:bfrc_clk { /* internal backup FRC oscillator */
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <8000000>;
+       };
+
+       LPRC:lprc_clk { /* internal low-power FRC oscillator */
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <32000>;
+       };
+
+       /* UPLL provides clock to USBCORE */
+       UPLL:usb_phy_clk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "usbphy_clk";
+       };
+
+       TxCKI:txcki_clk { /* external clock input on TxCLKI pin */
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <4000000>;
+               status = "disabled";
+       };
+
+       /* external clock input on REFCLKIx pin */
+       REFIx:refix_clk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               status = "disabled";
+       };
+
+       /* PIC32 specific clks */
+       pic32_clktree {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x1f801200 0x200>;
+               compatible = "microchip,pic32mzda-clk";
+               ranges = <0 0x1f801200 0x200>;
+
+               /* secondary oscillator; external input on SOSCI pin */
+               SOSC:sosc_clk@0 {
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-sosc";
+                       clock-frequency = <32768>;
+                       reg = <0x000 0x10>,   /* enable reg */
+                             <0x1d0 0x10>; /* status reg */
+                       microchip,bit-mask = <0x02>; /* enable mask */
+                       microchip,status-bit-mask = <0x10>; /* status-mask*/
+               };
+
+               FRCDIV:frcdiv_clk {
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-frcdivclk";
+                       clocks = <&FRC>;
+                       clock-output-names = "frcdiv_clk";
+               };
+
+               /* System PLL clock */
+               SYSPLL:spll_clk@020 {
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-syspll";
+                       reg = <0x020 0x10>, /* SPLL register */
+                             <0x1d0 0x10>; /* CLKSTAT register */
+                       clocks = <&POSC>, <&FRC>;
+                       clock-output-names = "sys_pll";
+                       microchip,status-bit-mask = <0x80>; /* SPLLRDY */
+               };
+
+               /* system clock; mux with postdiv & slew */
+               SYSCLK:sys_clk@1c0 {
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-sysclk-v2";
+                       reg = <0x1c0 0x04>; /* SLEWCON */
+                       clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
+                                <&LPRC>, <&FRCDIV>;
+                       microchip,clock-indices = <0>, <1>, <2>, <4>,
+                                                 <5>, <7>;
+                       clock-output-names = "sys_clk";
+               };
+
+               /* Peripheral bus1 clock */
+               PBCLK1:pb1_clk@140 {
+                       reg = <0x140 0x10>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       clocks = <&SYSCLK>;
+                       clock-output-names = "pb1_clk";
+                       /* used by system modules, not gateable */
+                       microchip,ignore-unused;
+               };
+
+               /* Peripheral bus2 clock */
+               PBCLK2:pb2_clk@150 {
+                       reg = <0x150 0x10>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       clocks = <&SYSCLK>;
+                       clock-output-names = "pb2_clk";
+                       /* avoid gating even if unused */
+                       microchip,ignore-unused;
+               };
+
+               /* Peripheral bus3 clock */
+               PBCLK3:pb3_clk@160 {
+                       reg = <0x160 0x10>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       clocks = <&SYSCLK>;
+                       clock-output-names = "pb3_clk";
+               };
+
+               /* Peripheral bus4 clock(I/O ports, GPIO) */
+               PBCLK4:pb4_clk@170 {
+                       reg = <0x170 0x10>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       clocks = <&SYSCLK>;
+                       clock-output-names = "pb4_clk";
+               };
+
+               /* Peripheral bus clock */
+               PBCLK5:pb5_clk@180 {
+                       reg = <0x180 0x10>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       clocks = <&SYSCLK>;
+                       clock-output-names = "pb5_clk";
+               };
+
+               /* Peripheral Bus6 clock; */
+               PBCLK6:pb6_clk@190 {
+                       reg = <0x190 0x10>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       clocks = <&SYSCLK>;
+                       #clock-cells = <0>;
+               };
+
+               /* Peripheral bus7 clock */
+               PBCLK7:pb7_clk@1a0 {
+                       reg = <0x1a0 0x10>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-pbclk";
+                       /* CPU is driven by this clock; so named */
+                       clock-output-names = "cpu_clk";
+                       clocks = <&SYSCLK>;
+               };
+
+               /* Reference Oscillator clock for SPI/I2S */
+               REFCLKO1:refo1_clk@80 {
+                       reg = <0x080 0x20>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-refoclk";
+                       clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+                                <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+                       microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+                                                 <5>, <7>, <8>, <9>;
+                       clock-output-names = "refo1_clk";
+               };
+
+               /* Reference Oscillator clock for SQI */
+               REFCLKO2:refo2_clk@a0 {
+                       reg = <0x0a0 0x20>;
+                       #clock-cells = <0>;
+                       compatible = "microchip,pic32mzda-refoclk";
+                       clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+                                <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+                       microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+                                                 <5>, <7>, <8>, <9>;
+                       clock-output-names = "refo2_clk";
+               };
+
+               /* Reference Oscillator clock, ADC */
+               REFCLKO3:refo3_clk@c0 {
+                       reg = <0x0c0 0x20>;
+                       compatible = "microchip,pic32mzda-refoclk";
+                       clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+                                <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+                       microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+                                                 <5>, <7>, <8>, <9>;
+                       #clock-cells = <0>;
+                       clock-output-names = "refo3_clk";
+               };
+
+               /* Reference Oscillator clock */
+               REFCLKO4:refo4_clk@e0 {
+                       reg = <0x0e0 0x20>;
+                       compatible = "microchip,pic32mzda-refoclk";
+                       clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+                                <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+                       microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+                                                 <5>, <7>, <8>, <9>;
+                       #clock-cells = <0>;
+                       clock-output-names = "refo4_clk";
+               };
+
+               /* Reference Oscillator clock, LCD */
+               REFCLKO5:refo5_clk@100 {
+                       reg = <0x100 0x20>;
+                       compatible = "microchip,pic32mzda-refoclk";
+                       clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
+                                <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
+                       microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+                                                 <5>, <7>, <8>, <9>;
+                       #clock-cells = <0>;
+                       clock-output-names = "refo5_clk";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/pic32/pic32mzda.dtsi b/arch/mips/boot/dts/pic32/pic32mzda.dtsi
new file mode 100644 (file)
index 0000000..ad9e331
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "pic32mzda-clk.dtsi"
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&evic>;
+
+       aliases {
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+               gpio3 = &gpio3;
+               gpio4 = &gpio4;
+               gpio5 = &gpio5;
+               gpio6 = &gpio6;
+               gpio7 = &gpio7;
+               gpio8 = &gpio8;
+               gpio9 = &gpio9;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               serial5 = &uart6;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "mti,mips14KEc";
+                       device_type = "cpu";
+               };
+       };
+
+       soc {
+               compatible = "microchip,pic32mzda-infra";
+               interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+       };
+
+       evic: interrupt-controller@1f810000 {
+               compatible = "microchip,pic32mzda-evic";
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               reg = <0x1f810000 0x1000>;
+               microchip,external-irqs = <3 8 13 18 23>;
+       };
+
+       pic32_pinctrl: pinctrl@1f801400{
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "microchip,pic32mzda-pinctrl";
+               reg = <0x1f801400 0x400>;
+               clocks = <&PBCLK1>;
+       };
+
+       /* PORTA */
+       gpio0: gpio0@1f860000 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860000 0x100>;
+               interrupts = <118 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <0>;
+               gpio-ranges = <&pic32_pinctrl 0 0 16>;
+       };
+
+       /* PORTB */
+       gpio1: gpio1@1f860100 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860100 0x100>;
+               interrupts = <119 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <1>;
+               gpio-ranges = <&pic32_pinctrl 0 16 16>;
+       };
+
+       /* PORTC */
+       gpio2: gpio2@1f860200 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860200 0x100>;
+               interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <2>;
+               gpio-ranges = <&pic32_pinctrl 0 32 16>;
+       };
+
+       /* PORTD */
+       gpio3: gpio3@1f860300 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860300 0x100>;
+               interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <3>;
+               gpio-ranges = <&pic32_pinctrl 0 48 16>;
+       };
+
+       /* PORTE */
+       gpio4: gpio4@1f860400 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860400 0x100>;
+               interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <4>;
+               gpio-ranges = <&pic32_pinctrl 0 64 16>;
+       };
+
+       /* PORTF */
+       gpio5: gpio5@1f860500 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860500 0x100>;
+               interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <5>;
+               gpio-ranges = <&pic32_pinctrl 0 80 16>;
+       };
+
+       /* PORTG */
+       gpio6: gpio6@1f860600 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860600 0x100>;
+               interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <6>;
+               gpio-ranges = <&pic32_pinctrl 0 96 16>;
+       };
+
+       /* PORTH */
+       gpio7: gpio7@1f860700 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860700 0x100>;
+               interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <7>;
+               gpio-ranges = <&pic32_pinctrl 0 112 16>;
+       };
+
+       /* PORTI does not exist */
+
+       /* PORTJ */
+       gpio8: gpio8@1f860800 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860800 0x100>;
+               interrupts = <126 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <8>;
+               gpio-ranges = <&pic32_pinctrl 0 128 16>;
+       };
+
+       /* PORTK */
+       gpio9: gpio9@1f860900 {
+               compatible = "microchip,pic32mzda-gpio";
+               reg = <0x1f860900 0x100>;
+               interrupts = <127 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&PBCLK4>;
+               microchip,gpio-bank = <9>;
+               gpio-ranges = <&pic32_pinctrl 0 144 16>;
+       };
+
+       sdhci: sdhci@1f8ec000 {
+               compatible = "microchip,pic32mzda-sdhci";
+               reg = <0x1f8ec000 0x100>;
+               interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&REFCLKO4>, <&PBCLK5>;
+               clock-names = "base_clk", "sys_clk";
+               bus-width = <4>;
+               cap-sd-highspeed;
+               status = "disabled";
+       };
+
+       uart1: serial@1f822000 {
+               compatible = "microchip,pic32mzda-uart";
+               reg = <0x1f822000 0x50>;
+               interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
+                       <113 IRQ_TYPE_LEVEL_HIGH>,
+                       <114 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&PBCLK2>;
+               status = "disabled";
+       };
+
+       uart2: serial@1f822200 {
+               compatible = "microchip,pic32mzda-uart";
+               reg = <0x1f822200 0x50>;
+               interrupts = <145 IRQ_TYPE_LEVEL_HIGH>,
+                       <146 IRQ_TYPE_LEVEL_HIGH>,
+                       <147 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&PBCLK2>;
+               status = "disabled";
+       };
+
+       uart3: serial@1f822400 {
+               compatible = "microchip,pic32mzda-uart";
+               reg = <0x1f822400 0x50>;
+               interrupts = <157 IRQ_TYPE_LEVEL_HIGH>,
+                       <158 IRQ_TYPE_LEVEL_HIGH>,
+                       <159 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&PBCLK2>;
+               status = "disabled";
+       };
+
+       uart4: serial@1f822600 {
+               compatible = "microchip,pic32mzda-uart";
+               reg = <0x1f822600 0x50>;
+               interrupts = <170 IRQ_TYPE_LEVEL_HIGH>,
+                       <171 IRQ_TYPE_LEVEL_HIGH>,
+                       <172 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&PBCLK2>;
+               status = "disabled";
+       };
+
+       uart5: serial@1f822800 {
+               compatible = "microchip,pic32mzda-uart";
+               reg = <0x1f822800 0x50>;
+               interrupts = <179 IRQ_TYPE_LEVEL_HIGH>,
+                       <180 IRQ_TYPE_LEVEL_HIGH>,
+                       <181 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&PBCLK2>;
+               status = "disabled";
+       };
+
+       uart6: serial@1f822A00 {
+               compatible = "microchip,pic32mzda-uart";
+               reg = <0x1f822A00 0x50>;
+               interrupts = <188 IRQ_TYPE_LEVEL_HIGH>,
+                       <189 IRQ_TYPE_LEVEL_HIGH>,
+                       <190 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&PBCLK2>;
+               status = "disabled";
+       };
+};
diff --git a/arch/mips/boot/dts/pic32/pic32mzda_sk.dts b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts
new file mode 100644 (file)
index 0000000..5d434a5
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "pic32mzda.dtsi"
+
+/ {
+       compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda";
+       model = "Microchip PIC32MZDA Starter Kit";
+
+       memory {
+               device_type = "memory";
+               reg = <0x08000000 0x08000000>;
+       };
+
+       chosen {
+               bootargs = "earlyprintk=ttyPIC1,115200n8r console=ttyPIC1,115200n8";
+       };
+
+       leds0 {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&user_leds_s0>;
+
+               led@1 {
+                       label = "pic32mzda_sk:red:led1";
+                       gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led@2 {
+                       label = "pic32mzda_sk:yellow:led2";
+                       gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc0";
+               };
+
+               led@3 {
+                       label = "pic32mzda_sk:green:led3";
+                       gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+               };
+       };
+
+       keys0 {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&user_buttons_s0>;
+               pinctrl-names = "default";
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               button@sw1 {
+                       label = "ESC";
+                       linux,code = <1>;
+                       gpios = <&gpio1 12 0>;
+               };
+
+               button@sw2 {
+                       label = "Home";
+                       linux,code = <102>;
+                       gpios = <&gpio1 13 0>;
+               };
+
+               button@sw3 {
+                       label = "Menu";
+                       linux,code = <139>;
+                       gpios = <&gpio1 14 0>;
+               };
+       };
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&sdhci {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdhc1>;
+       status = "okay";
+       assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>;
+       assigned-clock-rates = <50000000>,<25000000>,<40000000>;
+};
+
+&pic32_pinctrl {
+
+       pinctrl_sdhc1: sdhc1_pins0 {
+               pins = "A6", "D4", "G13", "G12", "G14", "A7", "A0";
+               microchip,digital;
+       };
+
+       user_leds_s0: user_leds_s0 {
+               pins = "H0", "H1", "H2";
+               output-low;
+               microchip,digital;
+       };
+
+       user_buttons_s0: user_buttons_s0 {
+               pins = "B12", "B13", "B14";
+               microchip,digital;
+               input-enable;
+               bias-pull-up;
+       };
+
+       pinctrl_uart2: pinctrl_uart2 {
+               uart2-tx {
+                       pins = "G9";
+                       function = "U2TX";
+                       microchip,digital;
+                       output-high;
+               };
+               uart2-rx {
+                       pins = "B0";
+                       function = "U2RX";
+                       microchip,digital;
+                       input-enable;
+               };
+       };
+
+       pinctrl_uart4: uart4-0 {
+               uart4-tx {
+                       pins = "C3";
+                       function = "U4TX";
+                       microchip,digital;
+                       output-high;
+               };
+               uart4-rx {
+                       pins = "E8";
+                       function = "U4RX";
+                       microchip,digital;
+                       input-enable;
+               };
+       };
+};
index 13d0439..3ad4ba9 100644 (file)
                        };
                };
 
+               usb@1b000100 {
+                       compatible = "qca,ar7100-ehci", "generic-ehci";
+                       reg = <0x1b000100 0x100>;
+
+                       interrupts = <3>;
+                       resets = <&rst 5>;
+
+                       has-transaction-translator;
+
+                       phy-names = "usb";
+                       phys = <&usb_phy>;
+
+                       status = "disabled";
+               };
+
                spi@1f000000 {
                        compatible = "qca,ar9132-spi", "qca,ar7100-spi";
                        reg = <0x1f000000 0x10>;
                        #size-cells = <0>;
                };
        };
+
+       usb_phy: usb-phy {
+               compatible = "qca,ar7100-usb-phy";
+
+               reset-names = "usb-phy", "usb-suspend-override";
+               resets = <&rst 4>, <&rst 3>;
+
+               #phy-cells = <0>;
+
+               status = "disabled";
+       };
 };
index 003015a..e535ee3 100644 (file)
                        };
                };
 
+               usb@1b000100 {
+                       status = "okay";
+               };
+
                spi@1f000000 {
                        status = "okay";
                        num-cs = <1>;
                };
        };
 
+       usb-phy {
+               status = "okay";
+       };
+
        gpio-keys {
                compatible = "gpio-keys-polled";
                #address-cells = <1>;
diff --git a/arch/mips/configs/pic32mzda_defconfig b/arch/mips/configs/pic32mzda_defconfig
new file mode 100644 (file)
index 0000000..52192c6
--- /dev/null
@@ -0,0 +1,89 @@
+CONFIG_MACH_PIC32=y
+CONFIG_DTB_PIC32_MZDA_SK=y
+CONFIG_HZ_100=y
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_SECCOMP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_SGI_PARTITION=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_SUSPEND is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_INPUT_LEDS=m
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_GPIO_POLLED=m
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PIC32=y
+CONFIG_SERIAL_PIC32_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_RAW_DRIVER=m
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_HIDRAW=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MICROCHIP_PIC32=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# CONFIG_MIPS_PLATFORM_DEVICES is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_FSCACHE=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
index 06b9bc7..c3212ff 100644 (file)
 #ifndef __ASM_CACHEOPS_H
 #define __ASM_CACHEOPS_H
 
+/*
+ * Most cache ops are split into a 2 bit field identifying the cache, and a 3
+ * bit field identifying the cache operation.
+ */
+#define CacheOp_Cache                  0x03
+#define CacheOp_Op                     0x1c
+
+#define Cache_I                                0x00
+#define Cache_D                                0x01
+#define Cache_T                                0x02
+#define Cache_S                                0x03
+
+#define Index_Writeback_Inv            0x00
+#define Index_Load_Tag                 0x04
+#define Index_Store_Tag                        0x08
+#define Hit_Invalidate                 0x10
+#define Hit_Writeback_Inv              0x14    /* not with Cache_I though */
+#define Hit_Writeback                  0x18
+
 /*
  * Cache Operations available on all MIPS processors with R4000-style caches
  */
-#define Index_Invalidate_I             0x00
-#define Index_Writeback_Inv_D          0x01
-#define Index_Load_Tag_I               0x04
-#define Index_Load_Tag_D               0x05
-#define Index_Store_Tag_I              0x08
-#define Index_Store_Tag_D              0x09
-#define Hit_Invalidate_I               0x10
-#define Hit_Invalidate_D               0x11
-#define Hit_Writeback_Inv_D            0x15
+#define Index_Invalidate_I             (Cache_I | Index_Writeback_Inv)
+#define Index_Writeback_Inv_D          (Cache_D | Index_Writeback_Inv)
+#define Index_Load_Tag_I               (Cache_I | Index_Load_Tag)
+#define Index_Load_Tag_D               (Cache_D | Index_Load_Tag)
+#define Index_Store_Tag_I              (Cache_I | Index_Store_Tag)
+#define Index_Store_Tag_D              (Cache_D | Index_Store_Tag)
+#define Hit_Invalidate_I               (Cache_I | Hit_Invalidate)
+#define Hit_Invalidate_D               (Cache_D | Hit_Invalidate)
+#define Hit_Writeback_Inv_D            (Cache_D | Hit_Writeback_Inv)
 
 /*
  * R4000-specific cacheops
  */
-#define Create_Dirty_Excl_D            0x0d
-#define Fill                           0x14
-#define Hit_Writeback_I                        0x18
-#define Hit_Writeback_D                        0x19
+#define Create_Dirty_Excl_D            (Cache_D | 0x0c)
+#define Fill                           (Cache_I | 0x14)
+#define Hit_Writeback_I                        (Cache_I | Hit_Writeback)
+#define Hit_Writeback_D                        (Cache_D | Hit_Writeback)
 
 /*
  * R4000SC and R4400SC-specific cacheops
  */
-#define Index_Invalidate_SI            0x02
-#define Index_Writeback_Inv_SD         0x03
-#define Index_Load_Tag_SI              0x06
-#define Index_Load_Tag_SD              0x07
-#define Index_Store_Tag_SI             0x0A
-#define Index_Store_Tag_SD             0x0B
-#define Create_Dirty_Excl_SD           0x0f
-#define Hit_Invalidate_SI              0x12
-#define Hit_Invalidate_SD              0x13
-#define Hit_Writeback_Inv_SD           0x17
-#define Hit_Writeback_SD               0x1b
-#define Hit_Set_Virtual_SI             0x1e
-#define Hit_Set_Virtual_SD             0x1f
+#define Cache_SI                       0x02
+#define Cache_SD                       0x03
+
+#define Index_Invalidate_SI            (Cache_SI | Index_Writeback_Inv)
+#define Index_Writeback_Inv_SD         (Cache_SD | Index_Writeback_Inv)
+#define Index_Load_Tag_SI              (Cache_SI | Index_Load_Tag)
+#define Index_Load_Tag_SD              (Cache_SD | Index_Load_Tag)
+#define Index_Store_Tag_SI             (Cache_SI | Index_Store_Tag)
+#define Index_Store_Tag_SD             (Cache_SD | Index_Store_Tag)
+#define Create_Dirty_Excl_SD           (Cache_SD | 0x0c)
+#define Hit_Invalidate_SI              (Cache_SI | Hit_Invalidate)
+#define Hit_Invalidate_SD              (Cache_SD | Hit_Invalidate)
+#define Hit_Writeback_Inv_SD           (Cache_SD | Hit_Writeback_Inv)
+#define Hit_Writeback_SD               (Cache_SD | Hit_Writeback)
+#define Hit_Set_Virtual_SI             (Cache_SI | 0x1c)
+#define Hit_Set_Virtual_SD             (Cache_SD | 0x1c)
 
 /*
  * R5000-specific cacheops
  */
-#define R5K_Page_Invalidate_S          0x17
+#define R5K_Page_Invalidate_S          (Cache_S | 0x14)
 
 /*
  * RM7000-specific cacheops
  */
-#define Page_Invalidate_T              0x16
-#define Index_Store_Tag_T              0x0a
-#define Index_Load_Tag_T               0x06
+#define Page_Invalidate_T              (Cache_T | 0x14)
+#define Index_Store_Tag_T              (Cache_T | Index_Store_Tag)
+#define Index_Load_Tag_T               (Cache_T | Index_Load_Tag)
 
 /*
  * R10000-specific cacheops
  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
  * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
  */
-#define Index_Writeback_Inv_S          0x03
-#define Index_Load_Tag_S               0x07
-#define Index_Store_Tag_S              0x0B
-#define Hit_Invalidate_S               0x13
+#define Index_Writeback_Inv_S          (Cache_S | Index_Writeback_Inv)
+#define Index_Load_Tag_S               (Cache_S | Index_Load_Tag)
+#define Index_Store_Tag_S              (Cache_S | Index_Store_Tag)
+#define Hit_Invalidate_S               (Cache_S | Hit_Invalidate)
 #define Cache_Barrier                  0x14
-#define Hit_Writeback_Inv_S            0x17
-#define Index_Load_Data_I              0x18
-#define Index_Load_Data_D              0x19
-#define Index_Load_Data_S              0x1b
-#define Index_Store_Data_I             0x1c
-#define Index_Store_Data_D             0x1d
-#define Index_Store_Data_S             0x1f
+#define Hit_Writeback_Inv_S            (Cache_S | Hit_Writeback_Inv)
+#define Index_Load_Data_I              (Cache_I | 0x18)
+#define Index_Load_Data_D              (Cache_D | 0x18)
+#define Index_Load_Data_S              (Cache_S | 0x18)
+#define Index_Store_Data_I             (Cache_I | 0x1c)
+#define Index_Store_Data_D             (Cache_D | 0x1c)
+#define Index_Store_Data_S             (Cache_S | 0x1c)
 
 /*
  * Loongson2-specific cacheops
  */
-#define Hit_Invalidate_I_Loongson2     0x00
+#define Hit_Invalidate_I_Loongson2     (Cache_I | 0x00)
 
 #endif /* __ASM_CACHEOPS_H */
index d1e04c9..eeec8c8 100644 (file)
 # define cpu_has_small_pages   (cpu_data[0].options & MIPS_CPU_SP)
 #endif
 
+#ifndef cpu_has_nan_legacy
+#define cpu_has_nan_legacy     (cpu_data[0].options & MIPS_CPU_NAN_LEGACY)
+#endif
+#ifndef cpu_has_nan_2008
+#define cpu_has_nan_2008       (cpu_data[0].options & MIPS_CPU_NAN_2008)
+#endif
+
 #endif /* __ASM_CPU_FEATURES_H */
index 82ad15f..a97ca97 100644 (file)
@@ -386,6 +386,8 @@ enum cpu_type_enum {
 #define MIPS_CPU_BP_GHIST      0x8000000000ull /* R12K+ Branch Prediction Global History */
 #define MIPS_CPU_SP            0x10000000000ull /* Small (1KB) page support */
 #define MIPS_CPU_FTLB          0x20000000000ull /* CPU has Fixed-page-size TLB */
+#define MIPS_CPU_NAN_LEGACY    0x40000000000ull /* Legacy NaN implemented */
+#define MIPS_CPU_NAN_2008      0x80000000000ull /* 2008 NaN implemented */
 
 /*
  * CPU ASE encodings
index e604f76..12fa79e 100644 (file)
@@ -29,8 +29,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-#include <asm-generic/dma-mapping-common.h>
-
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
               enum dma_data_direction direction);
 
index b01a6ff..cefb7a5 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/fs.h>
 #include <uapi/linux/elf.h>
 
-#include <asm/cpu-info.h>
 #include <asm/current.h>
 
 /* ELF header e_flags defines. */
@@ -44,6 +43,7 @@
 #define EF_MIPS_OPTIONS_FIRST  0x00000080
 #define EF_MIPS_32BITMODE      0x00000100
 #define EF_MIPS_FP64           0x00000200
+#define EF_MIPS_NAN2008                0x00000400
 #define EF_MIPS_ABI            0x0000f000
 #define EF_MIPS_ARCH           0xf0000000
 
@@ -305,7 +305,7 @@ do {                                                                        \
                                                                        \
        current->thread.abi = &mips_abi;                                \
                                                                        \
-       current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31;            \
+       mips_set_personality_nan(state);                                \
 } while (0)
 
 #endif /* CONFIG_32BIT */
@@ -367,7 +367,7 @@ do {                                                                        \
        else                                                            \
                current->thread.abi = &mips_abi;                        \
                                                                        \
-       current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31;            \
+       mips_set_personality_nan(state);                                \
                                                                        \
        p = personality(current->personality);                          \
        if (p != PER_LINUX32 && p != PER_LINUX)                         \
@@ -432,6 +432,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
                                       int uses_interp);
 
 struct arch_elf_state {
+       int nan_2008;
        int fp_abi;
        int interp_fp_abi;
        int overall_fp_mode;
@@ -440,17 +441,23 @@ struct arch_elf_state {
 #define MIPS_ABI_FP_UNKNOWN    (-1)    /* Unknown FP ABI (kernel internal) */
 
 #define INIT_ARCH_ELF_STATE {                  \
+       .nan_2008 = -1,                         \
        .fp_abi = MIPS_ABI_FP_UNKNOWN,          \
        .interp_fp_abi = MIPS_ABI_FP_UNKNOWN,   \
        .overall_fp_mode = -1,                  \
 }
 
+/* Whether to accept legacy-NaN and 2008-NaN user binaries.  */
+extern bool mips_use_nan_legacy;
+extern bool mips_use_nan_2008;
+
 extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
                            bool is_interp, struct arch_elf_state *state);
 
-extern int arch_check_elf(void *ehdr, bool has_interpreter,
+extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
                          struct arch_elf_state *state);
 
+extern void mips_set_personality_nan(struct arch_elf_state *state);
 extern void mips_set_personality_fp(struct arch_elf_state *state);
 
 #endif /* _ASM_ELF_H */
index 2f021cd..3225c3c 100644 (file)
@@ -79,7 +79,7 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 /*
  * Break instruction with special math emu break code set
  */
-#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
+#define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
 
 #define SIGNALLING_NAN 0x7ff800007ff80000LL
 
index d10fd80..2b4dc7a 100644 (file)
@@ -275,6 +275,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  */
 #define ioremap_cachable(offset, size)                                 \
        __ioremap_mode((offset), (size), _page_cachable_default)
+#define ioremap_cache ioremap_cachable
 
 /*
  * These two are MIPS specific ioremap variant.         ioremap_cacheable_cow
index e7b138b..65c351e 100644 (file)
@@ -84,41 +84,11 @@ static inline void arch_local_irq_restore(unsigned long flags)
        : "memory");
 }
 
-static inline void __arch_local_irq_restore(unsigned long flags)
-{
-       __asm__ __volatile__(
-       "       .set    push                                            \n"
-       "       .set    noreorder                                       \n"
-       "       .set    noat                                            \n"
-#if defined(CONFIG_IRQ_MIPS_CPU)
-       /*
-        * Slow, but doesn't suffer from a relatively unlikely race
-        * condition we're having since days 1.
-        */
-       "       beqz    %[flags], 1f                                    \n"
-       "       di                                                      \n"
-       "       ei                                                      \n"
-       "1:                                                             \n"
-#else
-       /*
-        * Fast, dangerous.  Life is fun, life is good.
-        */
-       "       mfc0    $1, $12                                         \n"
-       "       ins     $1, %[flags], 0, 1                              \n"
-       "       mtc0    $1, $12                                         \n"
-#endif
-       "       " __stringify(__irq_disable_hazard) "                   \n"
-       "       .set    pop                                             \n"
-       : [flags] "=r" (flags)
-       : "0" (flags)
-       : "memory");
-}
 #else
 /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
 void arch_local_irq_disable(void);
 unsigned long arch_local_irq_save(void);
 void arch_local_irq_restore(unsigned long flags);
-void __arch_local_irq_restore(unsigned long flags);
 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
 
 static inline void arch_local_irq_enable(void)
index 7c19144..f6b1279 100644 (file)
@@ -58,7 +58,7 @@
 #define KVM_MAX_VCPUS          1
 #define KVM_USER_MEM_SLOTS     8
 /* memory slots that does not exposed to userspace */
-#define KVM_PRIVATE_MEM_SLOTS  0
+#define KVM_PRIVATE_MEM_SLOTS  0
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 #define KVM_HALT_POLL_NS_DEFAULT 500000
 #define KVM_INVALID_INST               0xdeadbeef
 #define KVM_INVALID_ADDR               0xdeadbeef
 
-#define KVM_MALTA_GUEST_RTC_ADDR       0xb8000070UL
-
-#define GUEST_TICKS_PER_JIFFY          (40000000/HZ)
-#define MS_TO_NS(x)                    (x * 1E6L)
-
-#define CAUSEB_DC                      27
-#define CAUSEF_DC                      (_ULCAST_(1) << 27)
-
 extern atomic_t kvm_mips_instance;
 extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
 extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
@@ -289,34 +281,6 @@ enum mips_mmu_types {
        MMU_TYPE_R8000
 };
 
-/*
- * Trap codes
- */
-#define T_INT                  0       /* Interrupt pending */
-#define T_TLB_MOD              1       /* TLB modified fault */
-#define T_TLB_LD_MISS          2       /* TLB miss on load or ifetch */
-#define T_TLB_ST_MISS          3       /* TLB miss on a store */
-#define T_ADDR_ERR_LD          4       /* Address error on a load or ifetch */
-#define T_ADDR_ERR_ST          5       /* Address error on a store */
-#define T_BUS_ERR_IFETCH       6       /* Bus error on an ifetch */
-#define T_BUS_ERR_LD_ST                7       /* Bus error on a load or store */
-#define T_SYSCALL              8       /* System call */
-#define T_BREAK                        9       /* Breakpoint */
-#define T_RES_INST             10      /* Reserved instruction exception */
-#define T_COP_UNUSABLE         11      /* Coprocessor unusable */
-#define T_OVFLOW               12      /* Arithmetic overflow */
-
-/*
- * Trap definitions added for r4000 port.
- */
-#define T_TRAP                 13      /* Trap instruction */
-#define T_VCEI                 14      /* Virtual coherency exception */
-#define T_MSAFPE               14      /* MSA floating point exception */
-#define T_FPE                  15      /* Floating point exception */
-#define T_MSADIS               21      /* MSA disabled exception */
-#define T_WATCH                        23      /* Watch address reference */
-#define T_VCED                 31      /* Virtual coherency data */
-
 /* Resume Flags */
 #define RESUME_FLAG_DR         (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST       (1<<1)  /* Resume host? */
@@ -686,7 +650,6 @@ extern void kvm_mips_dump_host_tlbs(void);
 extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
 extern void kvm_mips_flush_host_tlb(int skip_kseg0);
 extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
-extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index);
 
 extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
                                     unsigned long entryhi);
index 4eee221..2b34872 100644 (file)
@@ -115,6 +115,7 @@ static inline int soc_is_qca955x(void)
        return soc_is_qca9556() || soc_is_qca9558();
 }
 
+void ath79_ddr_wb_flush(unsigned int reg);
 void ath79_ddr_set_pci_windows(void);
 
 extern void __iomem *ath79_pll_base;
index 348df49..4e0b6bc 100644 (file)
@@ -30,6 +30,4 @@ u8 *bcm63xx_nvram_get_name(void);
  */
 int bcm63xx_nvram_get_mac_address(u8 *mac);
 
-int bcm63xx_nvram_get_psi_size(void);
-
 #endif /* BCM63XX_NVRAM_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
deleted file mode 100644 (file)
index 1e6b587..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef __BCM963XX_TAG_H
-#define __BCM963XX_TAG_H
-
-#define TAGVER_LEN             4       /* Length of Tag Version */
-#define TAGLAYOUT_LEN          4       /* Length of FlashLayoutVer */
-#define SIG1_LEN               20      /* Company Signature 1 Length */
-#define SIG2_LEN               14      /* Company Signature 2 Length */
-#define BOARDID_LEN            16      /* Length of BoardId */
-#define ENDIANFLAG_LEN         2       /* Endian Flag Length */
-#define CHIPID_LEN             6       /* Chip Id Length */
-#define IMAGE_LEN              10      /* Length of Length Field */
-#define ADDRESS_LEN            12      /* Length of Address field */
-#define DUALFLAG_LEN           2       /* Dual Image flag Length */
-#define INACTIVEFLAG_LEN       2       /* Inactie Flag Length */
-#define RSASIG_LEN             20      /* Length of RSA Signature in tag */
-#define TAGINFO1_LEN           30      /* Length of vendor information field1 in tag */
-#define FLASHLAYOUTVER_LEN     4       /* Length of Flash Layout Version String tag */
-#define TAGINFO2_LEN           16      /* Length of vendor information field2 in tag */
-#define ALTTAGINFO_LEN         54      /* Alternate length for vendor information; Pirelli */
-
-#define NUM_PIRELLI            2
-#define IMAGETAG_CRC_START     0xFFFFFFFF
-
-#define PIRELLI_BOARDS { \
-       "AGPF-S0", \
-       "DWV-S0", \
-}
-
-/*
- * The broadcom firmware assumes the rootfs starts the image,
- * therefore uses the rootfs start (flash_image_address)
- * to determine where to flash the image.  Since we have the kernel first
- * we have to give it the kernel address, but the crc uses the length
- * associated with this address (root_length), which is added to the kernel
- * length (kernel_length) to determine the length of image to flash and thus
- * needs to be rootfs + deadcode (jffs2 EOF marker)
-*/
-
-struct bcm_tag {
-       /* 0-3: Version of the image tag */
-       char tag_version[TAGVER_LEN];
-       /* 4-23: Company Line 1 */
-       char sig_1[SIG1_LEN];
-       /*  24-37: Company Line 2 */
-       char sig_2[SIG2_LEN];
-       /* 38-43: Chip this image is for */
-       char chip_id[CHIPID_LEN];
-       /* 44-59: Board name */
-       char board_id[BOARDID_LEN];
-       /* 60-61: Map endianness -- 1 BE 0 LE */
-       char big_endian[ENDIANFLAG_LEN];
-       /* 62-71: Total length of image */
-       char total_length[IMAGE_LEN];
-       /* 72-83: Address in memory of CFE */
-       char cfe__address[ADDRESS_LEN];
-       /* 84-93: Size of CFE */
-       char cfe_length[IMAGE_LEN];
-       /* 94-105: Address in memory of image start
-        * (kernel for OpenWRT, rootfs for stock firmware)
-        */
-       char flash_image_start[ADDRESS_LEN];
-       /* 106-115: Size of rootfs */
-       char root_length[IMAGE_LEN];
-       /* 116-127: Address in memory of kernel */
-       char kernel_address[ADDRESS_LEN];
-       /* 128-137: Size of kernel */
-       char kernel_length[IMAGE_LEN];
-       /* 138-139: Unused at the moment */
-       char dual_image[DUALFLAG_LEN];
-       /* 140-141: Unused at the moment */
-       char inactive_flag[INACTIVEFLAG_LEN];
-       /* 142-161: RSA Signature (not used; some vendors may use this) */
-       char rsa_signature[RSASIG_LEN];
-       /* 162-191: Compilation and related information (not used in OpenWrt) */
-       char information1[TAGINFO1_LEN];
-       /* 192-195: Version flash layout */
-       char flash_layout_ver[FLASHLAYOUTVER_LEN];
-       /* 196-199: kernel+rootfs CRC32 */
-       __u32 fskernel_crc;
-       /* 200-215: Unused except on Alice Gate where is is information */
-       char information2[TAGINFO2_LEN];
-       /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
-       __u32 image_crc;
-       /* 220-223: CRC32 of rootfs partition */
-       __u32 rootfs_crc;
-       /* 224-227: CRC32 of kernel partition */
-       __u32 kernel_crc;
-       /* 228-235: Unused at present */
-       char reserved1[8];
-       /* 236-239: CRC32 of header excluding last 20 bytes */
-       __u32 header_crc;
-       /* 240-255: Unused at present */
-       char reserved2[16];
-};
-
-#endif /* __BCM63XX_TAG_H */
diff --git a/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h b/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..4682308
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * CPU feature overrides for PIC32 boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_vint           1
+#define cpu_has_veic           0
+#define cpu_has_tlb            1
+#define cpu_has_4kex           1
+#define cpu_has_4k_cache       1
+#define cpu_has_fpu            0
+#define cpu_has_counter                1
+#define cpu_has_llsc           1
+#define cpu_has_nofpuex                0
+#define cpu_icache_snoops_remote_store 1
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#error This platform does not support 64bit.
+#endif
+
+#endif /* __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-pic32/irq.h b/arch/mips/include/asm/mach-pic32/irq.h
new file mode 100644 (file)
index 0000000..864330c
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+#ifndef __ASM_MACH_PIC32_IRQ_H
+#define __ASM_MACH_PIC32_IRQ_H
+
+#define NR_IRQS        256
+#define MIPS_CPU_IRQ_BASE 0
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_PIC32_IRQ_H */
diff --git a/arch/mips/include/asm/mach-pic32/pic32.h b/arch/mips/include/asm/mach-pic32/pic32.h
new file mode 100644 (file)
index 0000000..ce52e91
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+#ifndef _ASM_MACH_PIC32_H
+#define _ASM_MACH_PIC32_H
+
+#include <linux/io.h>
+
+/*
+ * PIC32 register offsets for SET/CLR/INV where supported.
+ */
+#define PIC32_CLR(_reg)                ((_reg) + 0x04)
+#define PIC32_SET(_reg)                ((_reg) + 0x08)
+#define PIC32_INV(_reg)                ((_reg) + 0x0C)
+
+/*
+ * PIC32 Base Register Offsets
+ */
+#define PIC32_BASE_CONFIG      0x1f800000
+#define PIC32_BASE_OSC         0x1f801200
+#define PIC32_BASE_RESET       0x1f801240
+#define PIC32_BASE_PPS         0x1f801400
+#define PIC32_BASE_UART                0x1f822000
+#define PIC32_BASE_PORT                0x1f860000
+#define PIC32_BASE_DEVCFG2     0x1fc4ff44
+
+/*
+ * Register unlock sequence required for some register access.
+ */
+void pic32_syskey_unlock_debug(const char *fn, const ulong ln);
+#define pic32_syskey_unlock()  \
+       pic32_syskey_unlock_debug(__func__, __LINE__)
+
+#endif /* _ASM_MACH_PIC32_H */
diff --git a/arch/mips/include/asm/mach-pic32/spaces.h b/arch/mips/include/asm/mach-pic32/spaces.h
new file mode 100644 (file)
index 0000000..046a0a9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+#ifndef _ASM_MACH_PIC32_SPACES_H
+#define _ASM_MACH_PIC32_SPACES_H
+
+#ifdef CONFIG_PIC32MZDA
+#define PHYS_OFFSET    _AC(0x08000000, UL)
+#define UNCAC_BASE     _AC(0xa8000000, UL)
+#endif
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_MACH_PIC32_SPACES_H */
diff --git a/arch/mips/include/asm/mach-ralink/irq.h b/arch/mips/include/asm/mach-ralink/irq.h
new file mode 100644 (file)
index 0000000..4321865
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_RALINK_IRQ_H
+#define __ASM_MACH_RALINK_IRQ_H
+
+#define GIC_NUM_INTRS  64
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif
diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
new file mode 100644 (file)
index 0000000..610b61e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _MT7621_REGS_H_
+#define _MT7621_REGS_H_
+
+#define MT7621_PALMBUS_BASE            0x1C000000
+#define MT7621_PALMBUS_SIZE            0x03FFFFFF
+
+#define MT7621_SYSC_BASE               0x1E000000
+
+#define SYSC_REG_CHIP_NAME0            0x00
+#define SYSC_REG_CHIP_NAME1            0x04
+#define SYSC_REG_CHIP_REV              0x0c
+#define SYSC_REG_SYSTEM_CONFIG0                0x10
+#define SYSC_REG_SYSTEM_CONFIG1                0x14
+
+#define CHIP_REV_PKG_MASK              0x1
+#define CHIP_REV_PKG_SHIFT             16
+#define CHIP_REV_VER_MASK              0xf
+#define CHIP_REV_VER_SHIFT             8
+#define CHIP_REV_ECO_MASK              0xf
+
+#define MT7621_DRAM_BASE                0x0
+#define MT7621_DDR2_SIZE_MIN           32
+#define MT7621_DDR2_SIZE_MAX           256
+
+#define MT7621_CHIP_NAME0              0x3637544D
+#define MT7621_CHIP_NAME1              0x20203132
+
+#define MIPS_GIC_IRQ_BASE           (MIPS_CPU_IRQ_BASE + 8)
+
+#endif
diff --git a/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..15db1b3
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Ralink MT7621 specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ *     Copyright (C) 2003, 2004 Ralf Baechle
+ *     Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef _MT7621_CPU_FEATURE_OVERRIDES_H
+#define _MT7621_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb            1
+#define cpu_has_4kex           1
+#define cpu_has_3k_cache       0
+#define cpu_has_4k_cache       1
+#define cpu_has_tx39_cache     0
+#define cpu_has_sb1_cache      0
+#define cpu_has_fpu            0
+#define cpu_has_32fpr          0
+#define cpu_has_counter                1
+#define cpu_has_watch          1
+#define cpu_has_divec          1
+
+#define cpu_has_prefetch       1
+#define cpu_has_ejtag          1
+#define cpu_has_llsc           1
+
+#define cpu_has_mips16         1
+#define cpu_has_mdmx           0
+#define cpu_has_mips3d         0
+#define cpu_has_smartmips      0
+
+#define cpu_has_mips32r1       1
+#define cpu_has_mips32r2       1
+#define cpu_has_mips64r1       0
+#define cpu_has_mips64r2       0
+
+#define cpu_has_dsp            1
+#define cpu_has_dsp2           0
+#define cpu_has_mipsmt         1
+
+#define cpu_has_64bits         0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs  0
+#define cpu_has_64bit_addresses        0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#define cpu_has_dc_aliases     0
+#define cpu_has_vtag_icache    0
+
+#define cpu_has_rixi           0
+#define cpu_has_tlbinv         0
+#define cpu_has_userlocal      1
+
+#endif /* _MT7621_CPU_FEATURE_OVERRIDES_H */
index 6516e9d..b196825 100644 (file)
@@ -243,6 +243,10 @@ BUILD_CM_Cx_R_(tcid_8_priority,    0x80)
 #define  CM_GCR_BASE_CMDEFTGT_IOCU0            2
 #define  CM_GCR_BASE_CMDEFTGT_IOCU1            3
 
+/* GCR_RESET_EXT_BASE register fields */
+#define CM_GCR_RESET_EXT_BASE_EVARESET         BIT(31)
+#define CM_GCR_RESET_EXT_BASE_UEB              BIT(30)
+
 /* GCR_ACCESS register fields */
 #define CM_GCR_ACCESS_ACCESSEN_SHF             0
 #define CM_GCR_ACCESS_ACCESSEN_MSK             (_ULCAST_(0xff) << 0)
index 4b89f28..1f6ea83 100644 (file)
@@ -52,7 +52,7 @@ do {                                                                  \
        __this_cpu_inc(mipsr2emustats.M);                               \
        err = __get_user(nir, (u32 __user *)regs->cp0_epc);             \
        if (!err) {                                                     \
-               if (nir == BREAK_MATH)                                  \
+               if (nir == BREAK_MATH(0))                               \
                        __this_cpu_inc(mipsr2bdemustats.M);             \
        }                                                               \
        preempt_enable();                                               \
index e43aca1..3ad19ad 100644 (file)
 #define CAUSEF_IV              (_ULCAST_(1)   << 23)
 #define CAUSEB_PCI             26
 #define CAUSEF_PCI             (_ULCAST_(1)   << 26)
+#define CAUSEB_DC              27
+#define CAUSEF_DC              (_ULCAST_(1)   << 27)
 #define CAUSEB_CE              28
 #define CAUSEF_CE              (_ULCAST_(3)   << 28)
 #define CAUSEB_TI              30
 #define CAUSEB_BD              31
 #define CAUSEF_BD              (_ULCAST_(1)   << 31)
 
+/*
+ * Cause.ExcCode trap codes.
+ */
+#define EXCCODE_INT            0       /* Interrupt pending */
+#define EXCCODE_MOD            1       /* TLB modified fault */
+#define EXCCODE_TLBL           2       /* TLB miss on load or ifetch */
+#define EXCCODE_TLBS           3       /* TLB miss on a store */
+#define EXCCODE_ADEL           4       /* Address error on a load or ifetch */
+#define EXCCODE_ADES           5       /* Address error on a store */
+#define EXCCODE_IBE            6       /* Bus error on an ifetch */
+#define EXCCODE_DBE            7       /* Bus error on a load or store */
+#define EXCCODE_SYS            8       /* System call */
+#define EXCCODE_BP             9       /* Breakpoint */
+#define EXCCODE_RI             10      /* Reserved instruction exception */
+#define EXCCODE_CPU            11      /* Coprocessor unusable */
+#define EXCCODE_OV             12      /* Arithmetic overflow */
+#define EXCCODE_TR             13      /* Trap instruction */
+#define EXCCODE_MSAFPE         14      /* MSA floating point exception */
+#define EXCCODE_FPE            15      /* Floating point exception */
+#define EXCCODE_TLBRI          19      /* TLB Read-Inhibit exception */
+#define EXCCODE_TLBXI          20      /* TLB Execution-Inhibit exception */
+#define EXCCODE_MSADIS         21      /* MSA disabled exception */
+#define EXCCODE_MDMX           22      /* MDMX unusable exception */
+#define EXCCODE_WATCH          23      /* Watch address reference */
+#define EXCCODE_MCHECK         24      /* Machine check */
+#define EXCCODE_THREAD         25      /* Thread exceptions (MT) */
+#define EXCCODE_DSPDIS         26      /* DSP disabled exception */
+#define EXCCODE_GE             27      /* Virtualized guest exception (VZ) */
+
+/* Implementation specific trap codes used by MIPS cores */
+#define MIPS_EXCCODE_TLBPAR    16      /* TLB parity error exception */
+
 /*
  * Bits in the coprocessor 0 config register.
  */
index 2046c02..21ed715 100644 (file)
@@ -33,7 +33,7 @@
 #define PAGE_SHIFT     16
 #endif
 #define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK      (~(PAGE_SIZE - 1))
+#define PAGE_MASK      (~((1 << PAGE_SHIFT) - 1))
 
 /*
  * This is used for calculating the real page sizes
index 6995b4a..9a4fe01 100644 (file)
@@ -353,7 +353,7 @@ static inline pte_t pte_mkdirty(pte_t pte)
 static inline pte_t pte_mkyoung(pte_t pte)
 {
        pte_val(pte) |= _PAGE_ACCESSED;
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
        if (!(pte_val(pte) & _PAGE_NO_READ))
                pte_val(pte) |= _PAGE_SILENT_READ;
        else
@@ -542,7 +542,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
 {
        pmd_val(pmd) |= _PAGE_ACCESSED;
 
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
        if (!(pmd_val(pmd) & _PAGE_NO_READ))
                pmd_val(pmd) |= _PAGE_SILENT_READ;
        else
index 9b44d5a..ddea53e 100644 (file)
@@ -116,7 +116,8 @@ enum cop_op {
        dmtc_op       = 0x05, ctc_op        = 0x06,
        mthc0_op      = 0x06, mthc_op       = 0x07,
        bc_op         = 0x08, bc1eqz_op     = 0x09,
-       bc1nez_op     = 0x0d, cop_op        = 0x10,
+       mfmc0_op      = 0x0b, bc1nez_op     = 0x0d,
+       wrpgpr_op     = 0x0e, cop_op        = 0x10,
        copm_op       = 0x18
 };
 
@@ -529,7 +530,7 @@ enum MIPS6e_i8_func {
 };
 
 /*
- * (microMIPS & MIPS16e) NOP instruction.
+ * (microMIPS) NOP instruction.
  */
 #define MM_NOP16       0x0c00
 
@@ -679,7 +680,7 @@ struct fp0_format {         /* FPU multiply and add format (MIPS32) */
        ;))))))
 };
 
-struct mm_fp0_format {         /* FPU multipy and add format (microMIPS) */
+struct mm_fp0_format {         /* FPU multiply and add format (microMIPS) */
        __BITFIELD_FIELD(unsigned int opcode : 6,
        __BITFIELD_FIELD(unsigned int ft : 5,
        __BITFIELD_FIELD(unsigned int fs : 5,
@@ -799,6 +800,13 @@ struct mm_x_format {               /* Scaled indexed load format (microMIPS) */
        ;)))))
 };
 
+struct mm_a_format {           /* ADDIUPC format (microMIPS) */
+       __BITFIELD_FIELD(unsigned int opcode : 6,
+       __BITFIELD_FIELD(unsigned int rs : 3,
+       __BITFIELD_FIELD(signed int simmediate : 23,
+       ;)))
+};
+
 /*
  * microMIPS instruction formats (16-bit length)
  */
@@ -940,6 +948,7 @@ union mips_instruction {
        struct mm_i_format mm_i_format;
        struct mm_m_format mm_m_format;
        struct mm_x_format mm_x_format;
+       struct mm_a_format mm_a_format;
        struct mm_b0_format mm_b0_format;
        struct mm_b1_format mm_b1_format;
        struct mm16_m_format mm16_m_format ;
index b0ebe59..ccdcfcb 100644 (file)
@@ -73,7 +73,6 @@
 #define MADV_SEQUENTIAL 2              /* expect sequential page references */
 #define MADV_WILLNEED  3               /* will need these pages */
 #define MADV_DONTNEED  4               /* don't need these pages */
-#define MADV_FREE      5               /* free pages only if memory pressure */
 
 /* common parameters: try to keep these consistent across architectures */
 #define MADV_FREE      8               /* free pages only if memory pressure */
index 09f4034..6392dbe 100644 (file)
@@ -190,7 +190,7 @@ static inline void check_daddi(void)
        printk("Checking for the daddi bug... ");
 
        local_irq_save(flags);
-       handler = set_except_vector(12, handle_daddi_ov);
+       handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
        /*
         * The following code fails to trigger an overflow exception
         * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
@@ -214,7 +214,7 @@ static inline void check_daddi(void)
                ".set   pop"
                : "=r" (v), "=&r" (tmp)
                : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
-       set_except_vector(12, handler);
+       set_except_vector(EXCCODE_OV, handler);
        local_irq_restore(flags);
 
        if (daddi_ov) {
@@ -225,14 +225,14 @@ static inline void check_daddi(void)
        printk("yes, workaround... ");
 
        local_irq_save(flags);
-       handler = set_except_vector(12, handle_daddi_ov);
+       handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
        asm volatile(
                "addiu  %1, $0, %2\n\t"
                "dsrl   %1, %1, 1\n\t"
                "daddi  %0, %1, %3"
                : "=r" (v), "=&r" (tmp)
                : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
-       set_except_vector(12, handler);
+       set_except_vector(EXCCODE_OV, handler);
        local_irq_restore(flags);
 
        if (daddi_ov) {
index 6b90644..b725b71 100644 (file)
@@ -98,6 +98,161 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
        c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
 }
 
+/*
+ * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
+ * supported by FPU hardware.
+ */
+static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
+{
+       if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+                           MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                           MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+               unsigned long sr, fir, fcsr, fcsr0, fcsr1;
+
+               sr = read_c0_status();
+               __enable_fpu(FPU_AS_IS);
+
+               fir = read_32bit_cp1_register(CP1_REVISION);
+               if (fir & MIPS_FPIR_HAS2008) {
+                       fcsr = read_32bit_cp1_register(CP1_STATUS);
+
+                       fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+                       write_32bit_cp1_register(CP1_STATUS, fcsr0);
+                       fcsr0 = read_32bit_cp1_register(CP1_STATUS);
+
+                       fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+                       write_32bit_cp1_register(CP1_STATUS, fcsr1);
+                       fcsr1 = read_32bit_cp1_register(CP1_STATUS);
+
+                       write_32bit_cp1_register(CP1_STATUS, fcsr);
+
+                       if (!(fcsr0 & FPU_CSR_NAN2008))
+                               c->options |= MIPS_CPU_NAN_LEGACY;
+                       if (fcsr1 & FPU_CSR_NAN2008)
+                               c->options |= MIPS_CPU_NAN_2008;
+
+                       if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008)
+                               c->fpu_msk31 &= ~FPU_CSR_ABS2008;
+                       else
+                               c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008;
+
+                       if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008)
+                               c->fpu_msk31 &= ~FPU_CSR_NAN2008;
+                       else
+                               c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008;
+               } else {
+                       c->options |= MIPS_CPU_NAN_LEGACY;
+               }
+
+               write_c0_status(sr);
+       } else {
+               c->options |= MIPS_CPU_NAN_LEGACY;
+       }
+}
+
+/*
+ * IEEE 754 conformance mode to use.  Affects the NaN encoding and the
+ * ABS.fmt/NEG.fmt execution mode.
+ */
+static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
+
+/*
+ * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
+ * to support by the FPU emulator according to the IEEE 754 conformance
+ * mode selected.  Note that "relaxed" straps the emulator so that it
+ * allows 2008-NaN binaries even for legacy processors.
+ */
+static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
+{
+       c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
+       c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+       c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+
+       switch (ieee754) {
+       case STRICT:
+               if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+                                   MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                                   MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+                       c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
+               } else {
+                       c->options |= MIPS_CPU_NAN_LEGACY;
+                       c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+               }
+               break;
+       case LEGACY:
+               c->options |= MIPS_CPU_NAN_LEGACY;
+               c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+               break;
+       case STD2008:
+               c->options |= MIPS_CPU_NAN_2008;
+               c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+               c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+               break;
+       case RELAXED:
+               c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
+               break;
+       }
+}
+
+/*
+ * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
+ * according to the "ieee754=" parameter.
+ */
+static void cpu_set_nan_2008(struct cpuinfo_mips *c)
+{
+       switch (ieee754) {
+       case STRICT:
+               mips_use_nan_legacy = !!cpu_has_nan_legacy;
+               mips_use_nan_2008 = !!cpu_has_nan_2008;
+               break;
+       case LEGACY:
+               mips_use_nan_legacy = !!cpu_has_nan_legacy;
+               mips_use_nan_2008 = !cpu_has_nan_legacy;
+               break;
+       case STD2008:
+               mips_use_nan_legacy = !cpu_has_nan_2008;
+               mips_use_nan_2008 = !!cpu_has_nan_2008;
+               break;
+       case RELAXED:
+               mips_use_nan_legacy = true;
+               mips_use_nan_2008 = true;
+               break;
+       }
+}
+
+/*
+ * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
+ * settings:
+ *
+ * strict:  accept binaries that request a NaN encoding supported by the FPU
+ * legacy:  only accept legacy-NaN binaries
+ * 2008:    only accept 2008-NaN binaries
+ * relaxed: accept any binaries regardless of whether supported by the FPU
+ */
+static int __init ieee754_setup(char *s)
+{
+       if (!s)
+               return -1;
+       else if (!strcmp(s, "strict"))
+               ieee754 = STRICT;
+       else if (!strcmp(s, "legacy"))
+               ieee754 = LEGACY;
+       else if (!strcmp(s, "2008"))
+               ieee754 = STD2008;
+       else if (!strcmp(s, "relaxed"))
+               ieee754 = RELAXED;
+       else
+               return -1;
+
+       if (!(boot_cpu_data.options & MIPS_CPU_FPU))
+               cpu_set_nofpu_2008(&boot_cpu_data);
+       cpu_set_nan_2008(&boot_cpu_data);
+
+       return 0;
+}
+
+early_param("ieee754", ieee754_setup);
+
 /*
  * Set the FIR feature flags for the FPU emulator.
  */
@@ -113,6 +268,8 @@ static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
        if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
                            MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
                value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
+       if (c->options & MIPS_CPU_NAN_2008)
+               value |= MIPS_FPIR_HAS2008;
        c->fpu_id = value;
 }
 
@@ -137,6 +294,8 @@ static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
        }
 
        cpu_set_fpu_fcsr_mask(c);
+       cpu_set_fpu_2008(c);
+       cpu_set_nan_2008(c);
 }
 
 /*
@@ -147,6 +306,8 @@ static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
        c->options &= ~MIPS_CPU_FPU;
        c->fpu_msk31 = mips_nofpu_msk31;
 
+       cpu_set_nofpu_2008(c);
+       cpu_set_nan_2008(c);
        cpu_set_nofpu_id(c);
 }
 
index 4a4d9e0..c3c234d 100644 (file)
 #include <linux/elf.h>
 #include <linux/sched.h>
 
+#include <asm/cpu-info.h>
+
+/* Whether to accept legacy-NaN and 2008-NaN user binaries.  */
+bool mips_use_nan_legacy;
+bool mips_use_nan_2008;
+
 /* FPU modes */
 enum {
        FP_FRE,
@@ -68,15 +74,23 @@ static struct mode_req none_req = { true, true, false, true, true };
 int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
                     bool is_interp, struct arch_elf_state *state)
 {
-       struct elf32_hdr *ehdr32 = _ehdr;
+       union {
+               struct elf32_hdr e32;
+               struct elf64_hdr e64;
+       } *ehdr = _ehdr;
        struct elf32_phdr *phdr32 = _phdr;
        struct elf64_phdr *phdr64 = _phdr;
        struct mips_elf_abiflags_v0 abiflags;
+       bool elf32;
+       u32 flags;
        int ret;
 
+       elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+       flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
+
        /* Lets see if this is an O32 ELF */
-       if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
-               if (ehdr32->e_flags & EF_MIPS_FP64) {
+       if (elf32) {
+               if (flags & EF_MIPS_FP64) {
                        /*
                         * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
                         * later if needed
@@ -120,13 +134,50 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
        return 0;
 }
 
-int arch_check_elf(void *_ehdr, bool has_interpreter,
+int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
                   struct arch_elf_state *state)
 {
-       struct elf32_hdr *ehdr = _ehdr;
+       union {
+               struct elf32_hdr e32;
+               struct elf64_hdr e64;
+       } *ehdr = _ehdr;
+       union {
+               struct elf32_hdr e32;
+               struct elf64_hdr e64;
+       } *iehdr = _interp_ehdr;
        struct mode_req prog_req, interp_req;
        int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
-       bool is_mips64;
+       bool elf32;
+       u32 flags;
+
+       elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+       flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
+
+       /*
+        * Determine the NaN personality, reject the binary if not allowed.
+        * Also ensure that any interpreter matches the executable.
+        */
+       if (flags & EF_MIPS_NAN2008) {
+               if (mips_use_nan_2008)
+                       state->nan_2008 = 1;
+               else
+                       return -ENOEXEC;
+       } else {
+               if (mips_use_nan_legacy)
+                       state->nan_2008 = 0;
+               else
+                       return -ENOEXEC;
+       }
+       if (has_interpreter) {
+               bool ielf32;
+               u32 iflags;
+
+               ielf32 = iehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+               iflags = ielf32 ? iehdr->e32.e_flags : iehdr->e64.e_flags;
+
+               if ((flags ^ iflags) & EF_MIPS_NAN2008)
+                       return -ELIBBAD;
+       }
 
        if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
                return 0;
@@ -142,21 +193,18 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
                abi0 = abi1 = fp_abi;
        }
 
-       is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ||
-                   (ehdr->e_flags & EF_MIPS_ABI2);
+       if (elf32 && !(flags & EF_MIPS_ABI2)) {
+               /* Default to a mode capable of running code expecting FR=0 */
+               state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
 
-       if (is_mips64) {
+               /* Allow all ABIs we know about */
+               max_abi = MIPS_ABI_FP_64A;
+       } else {
                /* MIPS64 code always uses FR=1, thus the default is easy */
                state->overall_fp_mode = FP_FR1;
 
                /* Disallow access to the various FPXX & FP64 ABIs */
                max_abi = MIPS_ABI_FP_SOFT;
-       } else {
-               /* Default to a mode capable of running code expecting FR=0 */
-               state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
-
-               /* Allow all ABIs we know about */
-               max_abi = MIPS_ABI_FP_64A;
        }
 
        if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
@@ -254,3 +302,27 @@ void mips_set_personality_fp(struct arch_elf_state *state)
                BUG();
        }
 }
+
+/*
+ * Select the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
+ * in FCSR according to the ELF NaN personality.
+ */
+void mips_set_personality_nan(struct arch_elf_state *state)
+{
+       struct cpuinfo_mips *c = &boot_cpu_data;
+       struct task_struct *t = current;
+
+       t->thread.fpu.fcr31 = c->fpu_csr31;
+       switch (state->nan_2008) {
+       case 0:
+               break;
+       case 1:
+               if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
+                       t->thread.fpu.fcr31 |= FPU_CSR_NAN2008;
+               if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
+                       t->thread.fpu.fcr31 |= FPU_CSR_ABS2008;
+               break;
+       default:
+               BUG();
+       }
+}
index c6854d9..705be43 100644 (file)
@@ -21,7 +21,7 @@ static struct txx9_pio_reg __iomem *txx9_pioptr;
 
 static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
-       return __raw_readl(&txx9_pioptr->din) & (1 << offset);
+       return !!(__raw_readl(&txx9_pioptr->din) & (1 << offset));
 }
 
 static void txx9_gpio_set_raw(unsigned int offset, int value)
index 4f0ac78..a5279b2 100644 (file)
@@ -548,9 +548,6 @@ static const struct pt_regs_offset regoffset_table[] = {
        REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
        REG_OFFSET_NAME(c0_cause, cp0_cause),
        REG_OFFSET_NAME(c0_epc, cp0_epc),
-#ifdef CONFIG_MIPS_MT_SMTC
-       REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus),
-#endif
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
        REG_OFFSET_NAME(mpl0, mpl[0]),
        REG_OFFSET_NAME(mpl1, mpl[1]),
index 66aac55..569a7d5 100644 (file)
@@ -623,7 +623,7 @@ static void __init request_crashkernel(struct resource *res)
 
 #define USE_PROM_CMDLINE       IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
 #define USE_DTB_CMDLINE                IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
-#define EXTEND_WITH_PROM       IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND)
+#define EXTEND_WITH_PROM       IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
 
 static void __init arch_mem_init(char **cmdline_p)
 {
index e04c805..2ad4e4c 100644 (file)
@@ -202,6 +202,9 @@ static void boot_core(unsigned core)
        /* Ensure its coherency is disabled */
        write_gcr_co_coherence(0);
 
+       /* Start it with the legacy memory map and exception base */
+       write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB);
+
        /* Ensure the core can access the GCRs */
        access = read_gcr_access();
        access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
index 2242bdd..4472a7f 100644 (file)
 #include <asm/barrier.h>
 #include <asm/mipsregs.h>
 
-static atomic_t count_start_flag = ATOMIC_INIT(0);
+static unsigned int initcount = 0;
 static atomic_t count_count_start = ATOMIC_INIT(0);
 static atomic_t count_count_stop = ATOMIC_INIT(0);
-static atomic_t count_reference = ATOMIC_INIT(0);
 
 #define COUNTON 100
-#define NR_LOOPS 5
+#define NR_LOOPS 3
 
 void synchronise_count_master(int cpu)
 {
        int i;
        unsigned long flags;
-       unsigned int initcount;
 
        printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
 
        local_irq_save(flags);
 
-       /*
-        * Notify the slaves that it's time to start
-        */
-       atomic_set(&count_reference, read_c0_count());
-       atomic_set(&count_start_flag, cpu);
-       smp_wmb();
-
-       /* Count will be initialised to current timer for all CPU's */
-       initcount = read_c0_count();
-
        /*
         * We loop a few times to get a primed instruction cache,
         * then the last pass is more or less synchronised and
@@ -63,9 +51,13 @@ void synchronise_count_master(int cpu)
                atomic_set(&count_count_stop, 0);
                smp_wmb();
 
-               /* this lets the slaves write their count register */
+               /* Let the slave writes its count register */
                atomic_inc(&count_count_start);
 
+               /* Count will be initialised to current timer */
+               if (i == 1)
+                       initcount = read_c0_count();
+
                /*
                 * Everyone initialises count in the last loop:
                 */
@@ -73,7 +65,7 @@ void synchronise_count_master(int cpu)
                        write_c0_count(initcount);
 
                /*
-                * Wait for all slaves to leave the synchronization point:
+                * Wait for slave to leave the synchronization point:
                 */
                while (atomic_read(&count_count_stop) != 1)
                        mb();
@@ -83,7 +75,6 @@ void synchronise_count_master(int cpu)
        }
        /* Arrange for an interrupt in a short while */
        write_c0_compare(read_c0_count() + COUNTON);
-       atomic_set(&count_start_flag, 0);
 
        local_irq_restore(flags);
 
@@ -98,19 +89,12 @@ void synchronise_count_master(int cpu)
 void synchronise_count_slave(int cpu)
 {
        int i;
-       unsigned int initcount;
 
        /*
         * Not every cpu is online at the time this gets called,
         * so we first wait for the master to say everyone is ready
         */
 
-       while (atomic_read(&count_start_flag) != cpu)
-               mb();
-
-       /* Count will be initialised to next expire for all CPU's */
-       initcount = atomic_read(&count_reference);
-
        for (i = 0; i < NR_LOOPS; i++) {
                atomic_inc(&count_count_start);
                while (atomic_read(&count_count_start) != 2)
index 886cb19..bafcb7a 100644 (file)
@@ -2250,7 +2250,7 @@ void __init trap_init(void)
         * Only some CPUs have the watch exceptions.
         */
        if (cpu_has_watch)
-               set_except_vector(23, handle_watch);
+               set_except_vector(EXCCODE_WATCH, handle_watch);
 
        /*
         * Initialise interrupt handlers
@@ -2277,27 +2277,27 @@ void __init trap_init(void)
        if (board_be_init)
                board_be_init();
 
-       set_except_vector(0, using_rollback_handler() ? rollback_handle_int
-                                                     : handle_int);
-       set_except_vector(1, handle_tlbm);
-       set_except_vector(2, handle_tlbl);
-       set_except_vector(3, handle_tlbs);
+       set_except_vector(EXCCODE_INT, using_rollback_handler() ?
+                                       rollback_handle_int : handle_int);
+       set_except_vector(EXCCODE_MOD, handle_tlbm);
+       set_except_vector(EXCCODE_TLBL, handle_tlbl);
+       set_except_vector(EXCCODE_TLBS, handle_tlbs);
 
-       set_except_vector(4, handle_adel);
-       set_except_vector(5, handle_ades);
+       set_except_vector(EXCCODE_ADEL, handle_adel);
+       set_except_vector(EXCCODE_ADES, handle_ades);
 
-       set_except_vector(6, handle_ibe);
-       set_except_vector(7, handle_dbe);
+       set_except_vector(EXCCODE_IBE, handle_ibe);
+       set_except_vector(EXCCODE_DBE, handle_dbe);
 
-       set_except_vector(8, handle_sys);
-       set_except_vector(9, handle_bp);
-       set_except_vector(10, rdhwr_noopt ? handle_ri :
+       set_except_vector(EXCCODE_SYS, handle_sys);
+       set_except_vector(EXCCODE_BP, handle_bp);
+       set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri :
                          (cpu_has_vtag_icache ?
                           handle_ri_rdhwr_vivt : handle_ri_rdhwr));
-       set_except_vector(11, handle_cpu);
-       set_except_vector(12, handle_ov);
-       set_except_vector(13, handle_tr);
-       set_except_vector(14, handle_msa_fpe);
+       set_except_vector(EXCCODE_CPU, handle_cpu);
+       set_except_vector(EXCCODE_OV, handle_ov);
+       set_except_vector(EXCCODE_TR, handle_tr);
+       set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
 
        if (current_cpu_type() == CPU_R6000 ||
            current_cpu_type() == CPU_R6000A) {
@@ -2318,25 +2318,25 @@ void __init trap_init(void)
                board_nmi_handler_setup();
 
        if (cpu_has_fpu && !cpu_has_nofpuex)
-               set_except_vector(15, handle_fpe);
+               set_except_vector(EXCCODE_FPE, handle_fpe);
 
-       set_except_vector(16, handle_ftlb);
+       set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb);
 
        if (cpu_has_rixiex) {
-               set_except_vector(19, tlb_do_page_fault_0);
-               set_except_vector(20, tlb_do_page_fault_0);
+               set_except_vector(EXCCODE_TLBRI, tlb_do_page_fault_0);
+               set_except_vector(EXCCODE_TLBXI, tlb_do_page_fault_0);
        }
 
-       set_except_vector(21, handle_msa);
-       set_except_vector(22, handle_mdmx);
+       set_except_vector(EXCCODE_MSADIS, handle_msa);
+       set_except_vector(EXCCODE_MDMX, handle_mdmx);
 
        if (cpu_has_mcheck)
-               set_except_vector(24, handle_mcheck);
+               set_except_vector(EXCCODE_MCHECK, handle_mcheck);
 
        if (cpu_has_mipsmt)
-               set_except_vector(25, handle_mt);
+               set_except_vector(EXCCODE_THREAD, handle_mt);
 
-       set_except_vector(26, handle_dsp);
+       set_except_vector(EXCCODE_DSPDIS, handle_dsp);
 
        if (board_cache_error_setup)
                board_cache_error_setup();
index 313c2e3..d88aa21 100644 (file)
@@ -11,4 +11,4 @@
 #include <linux/kvm_host.h>
 
 struct kvm_mips_callbacks *kvm_mips_callbacks;
-EXPORT_SYMBOL(kvm_mips_callbacks);
+EXPORT_SYMBOL_GPL(kvm_mips_callbacks);
index 521121b..f1527a4 100644 (file)
@@ -86,10 +86,8 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
        } else {
                mfc0_inst = LW_TEMPLATE;
                mfc0_inst |= ((rt & 0x1f) << 16);
-               mfc0_inst |=
-                   offsetof(struct mips_coproc,
-                            reg[rd][sel]) + offsetof(struct kvm_mips_commpage,
-                                                     cop0);
+               mfc0_inst |= offsetof(struct kvm_mips_commpage,
+                                     cop0.reg[rd][sel]);
        }
 
        if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
@@ -123,9 +121,7 @@ int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
        sel = inst & 0x7;
 
        mtc0_inst |= ((rt & 0x1f) << 16);
-       mtc0_inst |=
-           offsetof(struct mips_coproc,
-                    reg[rd][sel]) + offsetof(struct kvm_mips_commpage, cop0);
+       mtc0_inst |= offsetof(struct kvm_mips_commpage, cop0.reg[rd][sel]);
 
        if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
                kseg0_opc =
index 1b675c7..b37954c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/random.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
+#include <asm/cacheops.h>
 #include <asm/cpu-info.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
@@ -29,7 +30,6 @@
 #include <asm/r4kcache.h>
 #define CONFIG_MIPS_MT
 
-#include "opcode.h"
 #include "interrupt.h"
 #include "commpage.h"
 
@@ -1239,21 +1239,20 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
                        er = EMULATE_FAIL;
                        break;
 
-               case mfmcz_op:
+               case mfmc0_op:
 #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
                        cop0->stat[MIPS_CP0_STATUS][0]++;
 #endif
-                       if (rt != 0) {
+                       if (rt != 0)
                                vcpu->arch.gprs[rt] =
                                    kvm_read_c0_guest_status(cop0);
-                       }
                        /* EI */
                        if (inst & 0x20) {
-                               kvm_debug("[%#lx] mfmcz_op: EI\n",
+                               kvm_debug("[%#lx] mfmc0_op: EI\n",
                                          vcpu->arch.pc);
                                kvm_set_c0_guest_status(cop0, ST0_IE);
                        } else {
-                               kvm_debug("[%#lx] mfmcz_op: DI\n",
+                               kvm_debug("[%#lx] mfmc0_op: DI\n",
                                          vcpu->arch.pc);
                                kvm_clear_c0_guest_status(cop0, ST0_IE);
                        }
@@ -1545,19 +1544,6 @@ int kvm_mips_sync_icache(unsigned long va, struct kvm_vcpu *vcpu)
        return 0;
 }
 
-#define MIPS_CACHE_OP_INDEX_INV         0x0
-#define MIPS_CACHE_OP_INDEX_LD_TAG      0x1
-#define MIPS_CACHE_OP_INDEX_ST_TAG      0x2
-#define MIPS_CACHE_OP_IMP               0x3
-#define MIPS_CACHE_OP_HIT_INV           0x4
-#define MIPS_CACHE_OP_FILL_WB_INV       0x5
-#define MIPS_CACHE_OP_HIT_HB            0x6
-#define MIPS_CACHE_OP_FETCH_LOCK        0x7
-
-#define MIPS_CACHE_ICACHE               0x0
-#define MIPS_CACHE_DCACHE               0x1
-#define MIPS_CACHE_SEC                  0x3
-
 enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
                                             uint32_t cause,
                                             struct kvm_run *run,
@@ -1582,8 +1568,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
        base = (inst >> 21) & 0x1f;
        op_inst = (inst >> 16) & 0x1f;
        offset = (int16_t)inst;
-       cache = (inst >> 16) & 0x3;
-       op = (inst >> 18) & 0x7;
+       cache = op_inst & CacheOp_Cache;
+       op = op_inst & CacheOp_Op;
 
        va = arch->gprs[base] + offset;
 
@@ -1595,14 +1581,14 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
         * invalidate the caches entirely by stepping through all the
         * ways/indexes
         */
-       if (op == MIPS_CACHE_OP_INDEX_INV) {
+       if (op == Index_Writeback_Inv) {
                kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
                          vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
                          arch->gprs[base], offset);
 
-               if (cache == MIPS_CACHE_DCACHE)
+               if (cache == Cache_D)
                        r4k_blast_dcache();
-               else if (cache == MIPS_CACHE_ICACHE)
+               else if (cache == Cache_I)
                        r4k_blast_icache();
                else {
                        kvm_err("%s: unsupported CACHE INDEX operation\n",
@@ -1675,9 +1661,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 
 skip_fault:
        /* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
-       if (cache == MIPS_CACHE_DCACHE
-           && (op == MIPS_CACHE_OP_FILL_WB_INV
-               || op == MIPS_CACHE_OP_HIT_INV)) {
+       if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) {
                flush_dcache_line(va);
 
 #ifdef CONFIG_KVM_MIPS_DYN_TRANS
@@ -1687,7 +1671,7 @@ skip_fault:
                 */
                kvm_mips_trans_cache_va(inst, opc, vcpu);
 #endif
-       } else if (op == MIPS_CACHE_OP_HIT_INV && cache == MIPS_CACHE_ICACHE) {
+       } else if (op_inst == Hit_Invalidate_I) {
                flush_dcache_line(va);
                flush_icache_line(va);
 
@@ -1781,7 +1765,7 @@ enum emulation_result kvm_mips_emulate_syscall(unsigned long cause,
                kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_SYSCALL << CAUSEB_EXCCODE));
+                                         (EXCCODE_SYS << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -1828,7 +1812,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause,
        }
 
        kvm_change_c0_guest_cause(cop0, (0xff),
-                                 (T_TLB_LD_MISS << CAUSEB_EXCCODE));
+                                 (EXCCODE_TLBL << CAUSEB_EXCCODE));
 
        /* setup badvaddr, context and entryhi registers for the guest */
        kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1874,7 +1858,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause,
        }
 
        kvm_change_c0_guest_cause(cop0, (0xff),
-                                 (T_TLB_LD_MISS << CAUSEB_EXCCODE));
+                                 (EXCCODE_TLBL << CAUSEB_EXCCODE));
 
        /* setup badvaddr, context and entryhi registers for the guest */
        kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1918,7 +1902,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause,
        }
 
        kvm_change_c0_guest_cause(cop0, (0xff),
-                                 (T_TLB_ST_MISS << CAUSEB_EXCCODE));
+                                 (EXCCODE_TLBS << CAUSEB_EXCCODE));
 
        /* setup badvaddr, context and entryhi registers for the guest */
        kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1962,7 +1946,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause,
        }
 
        kvm_change_c0_guest_cause(cop0, (0xff),
-                                 (T_TLB_ST_MISS << CAUSEB_EXCCODE));
+                                 (EXCCODE_TLBS << CAUSEB_EXCCODE));
 
        /* setup badvaddr, context and entryhi registers for the guest */
        kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -2033,7 +2017,8 @@ enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause,
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
        }
 
-       kvm_change_c0_guest_cause(cop0, (0xff), (T_TLB_MOD << CAUSEB_EXCCODE));
+       kvm_change_c0_guest_cause(cop0, (0xff),
+                                 (EXCCODE_MOD << CAUSEB_EXCCODE));
 
        /* setup badvaddr, context and entryhi registers for the guest */
        kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -2068,7 +2053,7 @@ enum emulation_result kvm_mips_emulate_fpu_exc(unsigned long cause,
        arch->pc = KVM_GUEST_KSEG0 + 0x180;
 
        kvm_change_c0_guest_cause(cop0, (0xff),
-                                 (T_COP_UNUSABLE << CAUSEB_EXCCODE));
+                                 (EXCCODE_CPU << CAUSEB_EXCCODE));
        kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE));
 
        return EMULATE_DONE;
@@ -2096,7 +2081,7 @@ enum emulation_result kvm_mips_emulate_ri_exc(unsigned long cause,
                kvm_debug("Delivering RI @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_RES_INST << CAUSEB_EXCCODE));
+                                         (EXCCODE_RI << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2131,7 +2116,7 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause,
                kvm_debug("Delivering BP @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_BREAK << CAUSEB_EXCCODE));
+                                         (EXCCODE_BP << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2166,7 +2151,7 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause,
                kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_TRAP << CAUSEB_EXCCODE));
+                                         (EXCCODE_TR << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2201,7 +2186,7 @@ enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause,
                kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_MSAFPE << CAUSEB_EXCCODE));
+                                         (EXCCODE_MSAFPE << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2236,7 +2221,7 @@ enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
                kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_FPE << CAUSEB_EXCCODE));
+                                         (EXCCODE_FPE << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2271,7 +2256,7 @@ enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause,
                kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc);
 
                kvm_change_c0_guest_cause(cop0, (0xff),
-                                         (T_MSADIS << CAUSEB_EXCCODE));
+                                         (EXCCODE_MSADIS << CAUSEB_EXCCODE));
 
                /* Set PC to the exception entry point */
                arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2480,25 +2465,25 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
 
        if (usermode) {
                switch (exccode) {
-               case T_INT:
-               case T_SYSCALL:
-               case T_BREAK:
-               case T_RES_INST:
-               case T_TRAP:
-               case T_MSAFPE:
-               case T_FPE:
-               case T_MSADIS:
+               case EXCCODE_INT:
+               case EXCCODE_SYS:
+               case EXCCODE_BP:
+               case EXCCODE_RI:
+               case EXCCODE_TR:
+               case EXCCODE_MSAFPE:
+               case EXCCODE_FPE:
+               case EXCCODE_MSADIS:
                        break;
 
-               case T_COP_UNUSABLE:
+               case EXCCODE_CPU:
                        if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0)
                                er = EMULATE_PRIV_FAIL;
                        break;
 
-               case T_TLB_MOD:
+               case EXCCODE_MOD:
                        break;
 
-               case T_TLB_LD_MISS:
+               case EXCCODE_TLBL:
                        /*
                         * We we are accessing Guest kernel space, then send an
                         * address error exception to the guest
@@ -2507,12 +2492,12 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
                                kvm_debug("%s: LD MISS @ %#lx\n", __func__,
                                          badvaddr);
                                cause &= ~0xff;
-                               cause |= (T_ADDR_ERR_LD << CAUSEB_EXCCODE);
+                               cause |= (EXCCODE_ADEL << CAUSEB_EXCCODE);
                                er = EMULATE_PRIV_FAIL;
                        }
                        break;
 
-               case T_TLB_ST_MISS:
+               case EXCCODE_TLBS:
                        /*
                         * We we are accessing Guest kernel space, then send an
                         * address error exception to the guest
@@ -2521,26 +2506,26 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
                                kvm_debug("%s: ST MISS @ %#lx\n", __func__,
                                          badvaddr);
                                cause &= ~0xff;
-                               cause |= (T_ADDR_ERR_ST << CAUSEB_EXCCODE);
+                               cause |= (EXCCODE_ADES << CAUSEB_EXCCODE);
                                er = EMULATE_PRIV_FAIL;
                        }
                        break;
 
-               case T_ADDR_ERR_ST:
+               case EXCCODE_ADES:
                        kvm_debug("%s: address error ST @ %#lx\n", __func__,
                                  badvaddr);
                        if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
                                cause &= ~0xff;
-                               cause |= (T_TLB_ST_MISS << CAUSEB_EXCCODE);
+                               cause |= (EXCCODE_TLBS << CAUSEB_EXCCODE);
                        }
                        er = EMULATE_PRIV_FAIL;
                        break;
-               case T_ADDR_ERR_LD:
+               case EXCCODE_ADEL:
                        kvm_debug("%s: address error LD @ %#lx\n", __func__,
                                  badvaddr);
                        if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
                                cause &= ~0xff;
-                               cause |= (T_TLB_LD_MISS << CAUSEB_EXCCODE);
+                               cause |= (EXCCODE_TLBL << CAUSEB_EXCCODE);
                        }
                        er = EMULATE_PRIV_FAIL;
                        break;
@@ -2583,13 +2568,12 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
         * an entry into the guest TLB.
         */
        index = kvm_mips_guest_tlb_lookup(vcpu,
-                                         (va & VPN2_MASK) |
-                                         (kvm_read_c0_guest_entryhi
-                                          (vcpu->arch.cop0) & ASID_MASK));
+                     (va & VPN2_MASK) |
+                     (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK));
        if (index < 0) {
-               if (exccode == T_TLB_LD_MISS) {
+               if (exccode == EXCCODE_TLBL) {
                        er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
-               } else if (exccode == T_TLB_ST_MISS) {
+               } else if (exccode == EXCCODE_TLBS) {
                        er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu);
                } else {
                        kvm_err("%s: invalid exc code: %d\n", __func__,
@@ -2604,10 +2588,10 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
                 * exception to the guest
                 */
                if (!TLB_IS_VALID(*tlb, va)) {
-                       if (exccode == T_TLB_LD_MISS) {
+                       if (exccode == EXCCODE_TLBL) {
                                er = kvm_mips_emulate_tlbinv_ld(cause, opc, run,
                                                                vcpu);
-                       } else if (exccode == T_TLB_ST_MISS) {
+                       } else if (exccode == EXCCODE_TLBS) {
                                er = kvm_mips_emulate_tlbinv_st(cause, opc, run,
                                                                vcpu);
                        } else {
index 9b44459..95f7906 100644 (file)
@@ -128,7 +128,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
                    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
                    && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
                        allowed = 1;
-                       exccode = T_INT;
+                       exccode = EXCCODE_INT;
                }
                break;
 
@@ -137,7 +137,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
                    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
                    && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
                        allowed = 1;
-                       exccode = T_INT;
+                       exccode = EXCCODE_INT;
                }
                break;
 
@@ -146,7 +146,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
                    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
                    && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
                        allowed = 1;
-                       exccode = T_INT;
+                       exccode = EXCCODE_INT;
                }
                break;
 
@@ -155,7 +155,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
                    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
                    && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
                        allowed = 1;
-                       exccode = T_INT;
+                       exccode = EXCCODE_INT;
                }
                break;
 
index 7e22108..81687ab 100644 (file)
@@ -335,7 +335,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
 
        /* Now restore the host state just enough to run the handlers */
 
-       /* Swtich EBASE to the one used by Linux */
+       /* Switch EBASE to the one used by Linux */
        /* load up the host EBASE */
        mfc0    v0, CP0_STATUS
 
@@ -490,11 +490,11 @@ __kvm_mips_return_to_guest:
        REG_ADDU t3, t1, t2
        LONG_L  k0, (t3)
        andi    k0, k0, 0xff
-       mtc0    k0,CP0_ENTRYHI
+       mtc0    k0, CP0_ENTRYHI
        ehb
 
        /* Disable RDHWR access */
-       mtc0    zero,  CP0_HWRENA
+       mtc0    zero, CP0_HWRENA
 
        /* load the guest context from VCPU and return */
        LONG_L  $0, VCPU_R0(k1)
@@ -606,11 +606,11 @@ __kvm_mips_return_to_host:
 
        /* Restore RDHWR access */
        PTR_LI  k0, 0x2000000F
-       mtc0    k0,  CP0_HWRENA
+       mtc0    k0, CP0_HWRENA
 
        /* Restore RA, which is the address we will return to */
-       LONG_L  ra, PT_R31(k1)
-       j       ra
+       LONG_L  ra, PT_R31(k1)
+       j       ra
         nop
 
 VECTOR_END(MIPSX(GuestExceptionEnd))
index b9b803f..8bc3977 100644 (file)
@@ -229,7 +229,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
                            kzalloc(npages * sizeof(unsigned long), GFP_KERNEL);
 
                        if (!kvm->arch.guest_pmap) {
-                               kvm_err("Failed to allocate guest PMAP");
+                               kvm_err("Failed to allocate guest PMAP\n");
                                return;
                        }
 
@@ -1264,8 +1264,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
        }
 
        switch (exccode) {
-       case T_INT:
-               kvm_debug("[%d]T_INT @ %p\n", vcpu->vcpu_id, opc);
+       case EXCCODE_INT:
+               kvm_debug("[%d]EXCCODE_INT @ %p\n", vcpu->vcpu_id, opc);
 
                ++vcpu->stat.int_exits;
                trace_kvm_exit(vcpu, INT_EXITS);
@@ -1276,8 +1276,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
                ret = RESUME_GUEST;
                break;
 
-       case T_COP_UNUSABLE:
-               kvm_debug("T_COP_UNUSABLE: @ PC: %p\n", opc);
+       case EXCCODE_CPU:
+               kvm_debug("EXCCODE_CPU: @ PC: %p\n", opc);
 
                ++vcpu->stat.cop_unusable_exits;
                trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS);
@@ -1287,13 +1287,13 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
                        ret = RESUME_HOST;
                break;
 
-       case T_TLB_MOD:
+       case EXCCODE_MOD:
                ++vcpu->stat.tlbmod_exits;
                trace_kvm_exit(vcpu, TLBMOD_EXITS);
                ret = kvm_mips_callbacks->handle_tlb_mod(vcpu);
                break;
 
-       case T_TLB_ST_MISS:
+       case EXCCODE_TLBS:
                kvm_debug("TLB ST fault:  cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n",
                          cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc,
                          badvaddr);
@@ -1303,7 +1303,7 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
                ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu);
                break;
 
-       case T_TLB_LD_MISS:
+       case EXCCODE_TLBL:
                kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n",
                          cause, opc, badvaddr);
 
@@ -1312,55 +1312,55 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
                ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu);
                break;
 
-       case T_ADDR_ERR_ST:
+       case EXCCODE_ADES:
                ++vcpu->stat.addrerr_st_exits;
                trace_kvm_exit(vcpu, ADDRERR_ST_EXITS);
                ret = kvm_mips_callbacks->handle_addr_err_st(vcpu);
                break;
 
-       case T_ADDR_ERR_LD:
+       case EXCCODE_ADEL:
                ++vcpu->stat.addrerr_ld_exits;
                trace_kvm_exit(vcpu, ADDRERR_LD_EXITS);
                ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu);
                break;
 
-       case T_SYSCALL:
+       case EXCCODE_SYS:
                ++vcpu->stat.syscall_exits;
                trace_kvm_exit(vcpu, SYSCALL_EXITS);
                ret = kvm_mips_callbacks->handle_syscall(vcpu);
                break;
 
-       case T_RES_INST:
+       case EXCCODE_RI:
                ++vcpu->stat.resvd_inst_exits;
                trace_kvm_exit(vcpu, RESVD_INST_EXITS);
                ret = kvm_mips_callbacks->handle_res_inst(vcpu);
                break;
 
-       case T_BREAK:
+       case EXCCODE_BP:
                ++vcpu->stat.break_inst_exits;
                trace_kvm_exit(vcpu, BREAK_INST_EXITS);
                ret = kvm_mips_callbacks->handle_break(vcpu);
                break;
 
-       case T_TRAP:
+       case EXCCODE_TR:
                ++vcpu->stat.trap_inst_exits;
                trace_kvm_exit(vcpu, TRAP_INST_EXITS);
                ret = kvm_mips_callbacks->handle_trap(vcpu);
                break;
 
-       case T_MSAFPE:
+       case EXCCODE_MSAFPE:
                ++vcpu->stat.msa_fpe_exits;
                trace_kvm_exit(vcpu, MSA_FPE_EXITS);
                ret = kvm_mips_callbacks->handle_msa_fpe(vcpu);
                break;
 
-       case T_FPE:
+       case EXCCODE_FPE:
                ++vcpu->stat.fpe_exits;
                trace_kvm_exit(vcpu, FPE_EXITS);
                ret = kvm_mips_callbacks->handle_fpe(vcpu);
                break;
 
-       case T_MSADIS:
+       case EXCCODE_MSADIS:
                ++vcpu->stat.msa_disabled_exits;
                trace_kvm_exit(vcpu, MSA_DISABLED_EXITS);
                ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
@@ -1620,7 +1620,7 @@ static struct notifier_block kvm_mips_csr_die_notifier = {
        .notifier_call = kvm_mips_csr_die_notify,
 };
 
-int __init kvm_mips_init(void)
+static int __init kvm_mips_init(void)
 {
        int ret;
 
@@ -1646,7 +1646,7 @@ int __init kvm_mips_init(void)
        return 0;
 }
 
-void __exit kvm_mips_exit(void)
+static void __exit kvm_mips_exit(void)
 {
        kvm_exit();
 
diff --git a/arch/mips/kvm/opcode.h b/arch/mips/kvm/opcode.h
deleted file mode 100644 (file)
index 03a6ae8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
- * Authors: Sanjay Lal <sanjayl@kymasys.com>
- */
-
-/* Define opcode values not defined in <asm/isnt.h> */
-
-#ifndef __KVM_MIPS_OPCODE_H__
-#define __KVM_MIPS_OPCODE_H__
-
-/* COP0 Ops */
-#define mfmcz_op       0x0b    /* 01011 */
-#define wrpgpr_op      0x0e    /* 01110 */
-
-/* COP0 opcodes (only if COP0 and CO=1): */
-#define wait_op                0x20    /* 100000 */
-
-#endif /* __KVM_MIPS_OPCODE_H__ */
index 570479c..a08c439 100644 (file)
 #define PRIx64 "llx"
 
 atomic_t kvm_mips_instance;
-EXPORT_SYMBOL(kvm_mips_instance);
+EXPORT_SYMBOL_GPL(kvm_mips_instance);
 
 /* These function pointers are initialized once the KVM module is loaded */
 kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
-EXPORT_SYMBOL(kvm_mips_gfn_to_pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_gfn_to_pfn);
 
 void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_release_pfn_clean);
+EXPORT_SYMBOL_GPL(kvm_mips_release_pfn_clean);
 
 bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_is_error_pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn);
 
 uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
 {
@@ -111,7 +111,7 @@ void kvm_mips_dump_host_tlbs(void)
        mtc0_tlbw_hazard();
        local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_mips_dump_host_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_host_tlbs);
 
 void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
 {
@@ -139,7 +139,7 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
                         (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
        }
 }
-EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs);
 
 static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 {
@@ -191,7 +191,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu,
 
        return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
 }
-EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa);
+EXPORT_SYMBOL_GPL(kvm_mips_translate_guest_kseg0_to_hpa);
 
 /* XXXKYMA: Must be called with interrupts disabled */
 /* set flush_dcache_mask == 0 if no dcache flush required */
@@ -308,7 +308,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
        return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
                                       flush_dcache_mask);
 }
-EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_kseg0_tlb_fault);
 
 int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
        struct kvm_vcpu *vcpu)
@@ -351,7 +351,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
 
        return 0;
 }
-EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_commpage_tlb_fault);
 
 int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
                                         struct kvm_mips_tlb *tlb,
@@ -401,7 +401,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
        return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
                                       tlb->tlb_mask);
 }
-EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_mapped_seg_tlb_fault);
 
 int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 {
@@ -422,7 +422,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 
        return index;
 }
-EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_guest_tlb_lookup);
 
 int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
 {
@@ -458,7 +458,7 @@ int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
 
        return idx;
 }
-EXPORT_SYMBOL(kvm_mips_host_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_lookup);
 
 int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
 {
@@ -505,44 +505,7 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
 
        return 0;
 }
-EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
-
-/* XXXKYMA: Fix Guest USER/KERNEL no longer share the same ASID */
-int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index)
-{
-       unsigned long flags, old_entryhi;
-
-       if (index >= current_cpu_data.tlbsize)
-               BUG();
-
-       local_irq_save(flags);
-
-       old_entryhi = read_c0_entryhi();
-
-       write_c0_entryhi(UNIQUE_ENTRYHI(index));
-       mtc0_tlbw_hazard();
-
-       write_c0_index(index);
-       mtc0_tlbw_hazard();
-
-       write_c0_entrylo0(0);
-       mtc0_tlbw_hazard();
-
-       write_c0_entrylo1(0);
-       mtc0_tlbw_hazard();
-
-       tlb_write_indexed();
-       mtc0_tlbw_hazard();
-       tlbw_use_hazard();
-
-       write_c0_entryhi(old_entryhi);
-       mtc0_tlbw_hazard();
-       tlbw_use_hazard();
-
-       local_irq_restore(flags);
-
-       return 0;
-}
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_inv);
 
 void kvm_mips_flush_host_tlb(int skip_kseg0)
 {
@@ -594,7 +557,7 @@ void kvm_mips_flush_host_tlb(int skip_kseg0)
 
        local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_mips_flush_host_tlb);
+EXPORT_SYMBOL_GPL(kvm_mips_flush_host_tlb);
 
 void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
                             struct kvm_vcpu *vcpu)
@@ -642,7 +605,7 @@ void kvm_local_flush_tlb_all(void)
 
        local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_local_flush_tlb_all);
+EXPORT_SYMBOL_GPL(kvm_local_flush_tlb_all);
 
 /**
  * kvm_mips_migrate_count() - Migrate timer.
@@ -673,8 +636,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
        local_irq_save(flags);
 
-       if (((vcpu->arch.
-             guest_kernel_asid[cpu] ^ asid_cache(cpu)) & ASID_VERSION_MASK)) {
+       if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) &
+                                                       ASID_VERSION_MASK) {
                kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
                vcpu->arch.guest_kernel_asid[cpu] =
                    vcpu->arch.guest_kernel_mm.context.asid[cpu];
@@ -739,7 +702,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        local_irq_restore(flags);
 
 }
-EXPORT_SYMBOL(kvm_arch_vcpu_load);
+EXPORT_SYMBOL_GPL(kvm_arch_vcpu_load);
 
 /* ASID can change if another task is scheduled during preemption */
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -768,7 +731,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
        local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_arch_vcpu_put);
+EXPORT_SYMBOL_GPL(kvm_arch_vcpu_put);
 
 uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
 {
@@ -813,4 +776,4 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
 
        return inst;
 }
-EXPORT_SYMBOL(kvm_get_inst);
+EXPORT_SYMBOL_GPL(kvm_get_inst);
index d836ed5..ad98800 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <linux/kvm_host.h>
 
-#include "opcode.h"
 #include "interrupt.h"
 
 static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
index 272af8a..5530070 100644 (file)
@@ -57,7 +57,6 @@ notrace void arch_local_irq_disable(void)
 }
 EXPORT_SYMBOL(arch_local_irq_disable);
 
-
 notrace unsigned long arch_local_irq_save(void)
 {
        unsigned long flags;
@@ -111,31 +110,4 @@ notrace void arch_local_irq_restore(unsigned long flags)
 }
 EXPORT_SYMBOL(arch_local_irq_restore);
 
-
-notrace void __arch_local_irq_restore(unsigned long flags)
-{
-       unsigned long __tmp1;
-
-       preempt_disable();
-
-       __asm__ __volatile__(
-       "       .set    push                                            \n"
-       "       .set    noreorder                                       \n"
-       "       .set    noat                                            \n"
-       "       mfc0    $1, $12                                         \n"
-       "       andi    %[flags], 1                                     \n"
-       "       ori     $1, 0x1f                                        \n"
-       "       xori    $1, 0x1f                                        \n"
-       "       or      %[flags], $1                                    \n"
-       "       mtc0    %[flags], $12                                   \n"
-       "       " __stringify(__irq_disable_hazard) "                   \n"
-       "       .set    pop                                             \n"
-       : [flags] "=r" (__tmp1)
-       : "0" (flags)
-       : "memory");
-
-       preempt_enable();
-}
-EXPORT_SYMBOL(__arch_local_irq_restore);
-
-#endif /* !CONFIG_CPU_MIPSR2 */
+#endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */
index 2e48e83..85d8089 100644 (file)
@@ -22,6 +22,27 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
   endif
 endif
 
+cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap
+#
+# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
+# as MIPS64 R2; older versions as just R1.  This leaves the possibility open
+# that GCC might generate R2 code for -march=loongson3a which then is rejected
+# by GAS.  The cc-option can't probe for this behaviour so -march=loongson3a
+# can't easily be used safely within the kbuild framework.
+#
+ifeq ($(call cc-ifversion, -ge, 0409, y), y)
+  ifeq ($(call ld-ifversion, -ge, 22500000, y), y)
+    cflags-$(CONFIG_CPU_LOONGSON3)  += \
+      $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+  else
+    cflags-$(CONFIG_CPU_LOONGSON3)  += \
+      $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+  endif
+else
+    cflags-$(CONFIG_CPU_LOONGSON3)  += \
+      $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+endif
+
 #
 # Loongson Machines' Support
 #
index bf9f1a7..a2631a5 100644 (file)
@@ -13,6 +13,9 @@
 #define SMBUS_PCI_REG64                0x64
 #define SMBUS_PCI_REGB4                0xb4
 
+#define HPET_MIN_CYCLES                64
+#define HPET_MIN_PROG_DELTA    (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
+
 static DEFINE_SPINLOCK(hpet_lock);
 DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
 
@@ -161,8 +164,9 @@ static int hpet_next_event(unsigned long delta,
        cnt += delta;
        hpet_write(HPET_T0_CMP, cnt);
 
-       res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
-       return res;
+       res = (int)(cnt - hpet_read(HPET_COUNTER));
+
+       return res < HPET_MIN_CYCLES ? -ETIME : 0;
 }
 
 static irqreturn_t hpet_irq_handler(int irq, void *data)
@@ -237,7 +241,7 @@ void __init setup_hpet_timer(void)
        cd->cpumask = cpumask_of(cpu);
        clockevent_set_clock(cd, HPET_FREQ);
        cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
-       cd->min_delta_ns = 5000;
+       cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd);
 
        clockevents_register_device(cd);
        setup_irq(HPET_T0_IRQ, &hpet_irq);
index 1a4738a..509832a 100644 (file)
 #include "smp.h"
 
 DEFINE_PER_CPU(int, cpu_state);
-DEFINE_PER_CPU(uint32_t, core0_c0count);
 
 static void *ipi_set0_regs[16];
 static void *ipi_clear0_regs[16];
 static void *ipi_status0_regs[16];
 static void *ipi_en0_regs[16];
 static void *ipi_mailbox_buf[16];
+static uint32_t core0_c0count[NR_CPUS];
 
 /* read a 32bit value from ipi register */
 #define loongson3_ipi_read32(addr) readl(addr)
@@ -275,12 +275,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
        if (action & SMP_ASK_C0COUNT) {
                BUG_ON(cpu != 0);
                c0count = read_c0_count();
-               for (i = 1; i < num_possible_cpus(); i++)
-                       per_cpu(core0_c0count, i) = c0count;
+               c0count = c0count ? c0count : 1;
+               for (i = 1; i < nr_cpu_ids; i++)
+                       core0_c0count[i] = c0count;
+               __wbflush(); /* Let others see the result ASAP */
        }
 }
 
-#define MAX_LOOPS 1111
+#define MAX_LOOPS 800
 /*
  * SMP init and finish on secondary CPUs
  */
@@ -305,16 +307,20 @@ static void loongson3_init_secondary(void)
                cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
 
        i = 0;
-       __this_cpu_write(core0_c0count, 0);
+       core0_c0count[cpu] = 0;
        loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
-       while (!__this_cpu_read(core0_c0count)) {
+       while (!core0_c0count[cpu]) {
                i++;
                cpu_relax();
        }
 
        if (i > MAX_LOOPS)
                i = MAX_LOOPS;
-       initcount = __this_cpu_read(core0_c0count) + i;
+       if (cpu_data[cpu].package)
+               initcount = core0_c0count[cpu] + i;
+       else /* Local access is faster for loops */
+               initcount = core0_c0count[cpu] + i/2;
+
        write_c0_count(initcount);
 }
 
index 32f0e19..cdfd44f 100644 (file)
@@ -1266,6 +1266,8 @@ branch_common:
                                                 */
                                                sig = mips_dsemul(xcp, ir,
                                                                  contpc);
+                                               if (sig < 0)
+                                                       break;
                                                if (sig)
                                                        xcp->cp0_epc = bcpc;
                                                /*
@@ -1319,6 +1321,8 @@ branch_common:
                                 * instruction in the dslot
                                 */
                                sig = mips_dsemul(xcp, ir, contpc);
+                               if (sig < 0)
+                                       break;
                                if (sig)
                                        xcp->cp0_epc = bcpc;
                                /* SIGILL forces out of the emulation loop.  */
index 926d56b..eb96485 100644 (file)
 
 union ieee754dp ieee754dp_neg(union ieee754dp x)
 {
-       unsigned int oldrm;
        union ieee754dp y;
 
-       oldrm = ieee754_csr.rm;
-       ieee754_csr.rm = FPU_CSR_RD;
-       y = ieee754dp_sub(ieee754dp_zero(0), x);
-       ieee754_csr.rm = oldrm;
+       if (ieee754_csr.abs2008) {
+               y = x;
+               DPSIGN(y) = !DPSIGN(x);
+       } else {
+               unsigned int oldrm;
+
+               oldrm = ieee754_csr.rm;
+               ieee754_csr.rm = FPU_CSR_RD;
+               y = ieee754dp_sub(ieee754dp_zero(0), x);
+               ieee754_csr.rm = oldrm;
+       }
        return y;
 }
 
 union ieee754dp ieee754dp_abs(union ieee754dp x)
 {
-       unsigned int oldrm;
        union ieee754dp y;
 
-       oldrm = ieee754_csr.rm;
-       ieee754_csr.rm = FPU_CSR_RD;
-       if (DPSIGN(x))
-               y = ieee754dp_sub(ieee754dp_zero(0), x);
-       else
-               y = ieee754dp_add(ieee754dp_zero(0), x);
-       ieee754_csr.rm = oldrm;
+       if (ieee754_csr.abs2008) {
+               y = x;
+               DPSIGN(y) = 0;
+       } else {
+               unsigned int oldrm;
+
+               oldrm = ieee754_csr.rm;
+               ieee754_csr.rm = FPU_CSR_RD;
+               if (DPSIGN(x))
+                       y = ieee754dp_sub(ieee754dp_zero(0), x);
+               else
+                       y = ieee754dp_add(ieee754dp_zero(0), x);
+               ieee754_csr.rm = oldrm;
+       }
        return y;
 }
index 6ffc336..f398561 100644 (file)
@@ -38,10 +38,13 @@ int ieee754dp_tint(union ieee754dp x)
        switch (xc) {
        case IEEE754_CLASS_SNAN:
        case IEEE754_CLASS_QNAN:
-       case IEEE754_CLASS_INF:
                ieee754_setcx(IEEE754_INVALID_OPERATION);
                return ieee754si_indef();
 
+       case IEEE754_CLASS_INF:
+               ieee754_setcx(IEEE754_INVALID_OPERATION);
+               return ieee754si_overflow(xs);
+
        case IEEE754_CLASS_ZERO:
                return 0;
 
@@ -53,7 +56,7 @@ int ieee754dp_tint(union ieee754dp x)
                /* Set invalid. We will only use overflow for floating
                   point overflow */
                ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754si_indef();
+               return ieee754si_overflow(xs);
        }
        /* oh gawd */
        if (xe > DP_FBITS) {
@@ -93,7 +96,7 @@ int ieee754dp_tint(union ieee754dp x)
                if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
                        /* This can happen after rounding */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754si_indef();
+                       return ieee754si_overflow(xs);
                }
                if (round || sticky)
                        ieee754_setcx(IEEE754_INEXACT);
index 9cdc145..748fa10 100644 (file)
@@ -38,10 +38,13 @@ s64 ieee754dp_tlong(union ieee754dp x)
        switch (xc) {
        case IEEE754_CLASS_SNAN:
        case IEEE754_CLASS_QNAN:
-       case IEEE754_CLASS_INF:
                ieee754_setcx(IEEE754_INVALID_OPERATION);
                return ieee754di_indef();
 
+       case IEEE754_CLASS_INF:
+               ieee754_setcx(IEEE754_INVALID_OPERATION);
+               return ieee754di_overflow(xs);
+
        case IEEE754_CLASS_ZERO:
                return 0;
 
@@ -56,7 +59,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
                /* Set invalid. We will only use overflow for floating
                   point overflow */
                ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754di_indef();
+               return ieee754di_overflow(xs);
        }
        /* oh gawd */
        if (xe > DP_FBITS) {
@@ -97,7 +100,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
                if ((xm >> 63) != 0) {
                        /* This can happen after rounding */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754di_indef();
+                       return ieee754di_overflow(xs);
                }
                if (round || sticky)
                        ieee754_setcx(IEEE754_INEXACT);
index cbb36c1..46b964d 100644 (file)
@@ -31,17 +31,41 @@ struct emuframe {
        unsigned long           epc;
 };
 
+/*
+ * Set up an emulation frame for instruction IR, from a delay slot of
+ * a branch jumping to CPC.  Return 0 if successful, -1 if no emulation
+ * required, otherwise a signal number causing a frame setup failure.
+ */
 int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 {
+       int isa16 = get_isa16_mode(regs->cp0_epc);
+       mips_instruction break_math;
        struct emuframe __user *fr;
        int err;
 
-       if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) ||
-               (ir == 0)) {
-               /* NOP is easy */
-               regs->cp0_epc = cpc;
-               clear_delay_slot(regs);
-               return 0;
+       /* NOP is easy */
+       if (ir == 0)
+               return -1;
+
+       /* microMIPS instructions */
+       if (isa16) {
+               union mips_instruction insn = { .word = ir };
+
+               /* NOP16 aka MOVE16 $0, $0 */
+               if ((ir >> 16) == MM_NOP16)
+                       return -1;
+
+               /* ADDIUPC */
+               if (insn.mm_a_format.opcode == mm_addiupc_op) {
+                       unsigned int rs;
+                       s32 v;
+
+                       rs = (((insn.mm_a_format.rs + 0x1e) & 0xf) + 2);
+                       v = regs->cp0_epc & ~3;
+                       v += insn.mm_a_format.simmediate << 2;
+                       regs->regs[rs] = (long)v;
+                       return -1;
+               }
        }
 
        pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
@@ -55,14 +79,10 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
         * Algorithmics used a system call instruction, and
         * borrowed that vector.  MIPS/Linux version is a bit
         * more heavyweight in the interests of portability and
-        * multiprocessor support.  For Linux we generate a
-        * an unaligned access and force an address error exception.
-        *
-        * For embedded systems (stand-alone) we prefer to use a
-        * non-existing CP1 instruction. This prevents us from emulating
-        * branches, but gives us a cleaner interface to the exception
-        * handler (single entry point).
+        * multiprocessor support.  For Linux we use a BREAK 514
+        * instruction causing a breakpoint exception.
         */
+       break_math = BREAK_MATH(isa16);
 
        /* Ensure that the two instructions are in the same cache line */
        fr = (struct emuframe __user *)
@@ -72,14 +92,18 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
        if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
                return SIGBUS;
 
-       if (get_isa16_mode(regs->cp0_epc)) {
-               err = __put_user(ir >> 16, (u16 __user *)(&fr->emul));
-               err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2));
-               err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst));
-               err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2));
+       if (isa16) {
+               err = __put_user(ir >> 16,
+                                (u16 __user *)(&fr->emul));
+               err |= __put_user(ir & 0xffff,
+                                 (u16 __user *)((long)(&fr->emul) + 2));
+               err |= __put_user(break_math >> 16,
+                                 (u16 __user *)(&fr->badinst));
+               err |= __put_user(break_math & 0xffff,
+                                 (u16 __user *)((long)(&fr->badinst) + 2));
        } else {
                err = __put_user(ir, &fr->emul);
-               err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst);
+               err |= __put_user(break_math, &fr->badinst);
        }
 
        err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
@@ -90,8 +114,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
                return SIGBUS;
        }
 
-       regs->cp0_epc = ((unsigned long) &fr->emul) |
-               get_isa16_mode(regs->cp0_epc);
+       regs->cp0_epc = (unsigned long)&fr->emul | isa16;
 
        flush_cache_sigtramp((unsigned long)&fr->emul);
 
@@ -100,6 +123,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 
 int do_dsemulret(struct pt_regs *xcp)
 {
+       int isa16 = get_isa16_mode(xcp->cp0_epc);
        struct emuframe __user *fr;
        unsigned long epc;
        u32 insn, cookie;
@@ -122,16 +146,19 @@ int do_dsemulret(struct pt_regs *xcp)
         *  - Is the instruction pointed to by the EPC an BREAK_MATH?
         *  - Is the following memory word the BD_COOKIE?
         */
-       if (get_isa16_mode(xcp->cp0_epc)) {
-               err = __get_user(instr[0], (u16 __user *)(&fr->badinst));
-               err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2));
+       if (isa16) {
+               err = __get_user(instr[0],
+                                (u16 __user *)(&fr->badinst));
+               err |= __get_user(instr[1],
+                                 (u16 __user *)((long)(&fr->badinst) + 2));
                insn = (instr[0] << 16) | instr[1];
        } else {
                err = __get_user(insn, &fr->badinst);
        }
        err |= __get_user(cookie, &fr->cookie);
 
-       if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
+       if (unlikely(err ||
+                    insn != BREAK_MATH(isa16) || cookie != BD_COOKIE)) {
                MIPS_FPU_EMU_INC_STATS(errors);
                return 0;
        }
index 8e97acb..e16ae7b 100644 (file)
@@ -59,7 +59,8 @@ const union ieee754dp __ieee754dp_spcvals[] = {
        DPCNST(1, 3,           0x4000000000000ULL),     /* - 10.0   */
        DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL),     /* + infinity */
        DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL),     /* - infinity */
-       DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL),     /* + indef quiet Nan */
+       DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL),     /* + ind legacy qNaN */
+       DPCNST(0, DP_EMAX + 1, 0x8000000000000ULL),     /* + indef 2008 qNaN */
        DPCNST(0, DP_EMAX,     0xFFFFFFFFFFFFFULL),     /* + max */
        DPCNST(1, DP_EMAX,     0xFFFFFFFFFFFFFULL),     /* - max */
        DPCNST(0, DP_EMIN,     0x0000000000000ULL),     /* + min normal */
@@ -82,7 +83,8 @@ const union ieee754sp __ieee754sp_spcvals[] = {
        SPCNST(1, 3,           0x200000),       /* - 10.0   */
        SPCNST(0, SP_EMAX + 1, 0x000000),       /* + infinity */
        SPCNST(1, SP_EMAX + 1, 0x000000),       /* - infinity */
-       SPCNST(0, SP_EMAX + 1, 0x3FFFFF),       /* + indef quiet Nan  */
+       SPCNST(0, SP_EMAX + 1, 0x3FFFFF),       /* + indef legacy quiet NaN */
+       SPCNST(0, SP_EMAX + 1, 0x400000),       /* + indef 2008 quiet NaN */
        SPCNST(0, SP_EMAX,     0x7FFFFF),       /* + max normal */
        SPCNST(1, SP_EMAX,     0x7FFFFF),       /* - max normal */
        SPCNST(0, SP_EMIN,     0x000000),       /* + min normal */
index df94720..d3be351 100644 (file)
@@ -221,15 +221,16 @@ union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
 #define IEEE754_SPCVAL_NTEN            5       /* -10.0 */
 #define IEEE754_SPCVAL_PINFINITY       6       /* +inf */
 #define IEEE754_SPCVAL_NINFINITY       7       /* -inf */
-#define IEEE754_SPCVAL_INDEF           8       /* quiet NaN */
-#define IEEE754_SPCVAL_PMAX            9       /* +max norm */
-#define IEEE754_SPCVAL_NMAX            10      /* -max norm */
-#define IEEE754_SPCVAL_PMIN            11      /* +min norm */
-#define IEEE754_SPCVAL_NMIN            12      /* -min norm */
-#define IEEE754_SPCVAL_PMIND           13      /* +min denorm */
-#define IEEE754_SPCVAL_NMIND           14      /* -min denorm */
-#define IEEE754_SPCVAL_P1E31           15      /* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63           16      /* + 1.0e63 */
+#define IEEE754_SPCVAL_INDEF_LEG       8       /* legacy quiet NaN */
+#define IEEE754_SPCVAL_INDEF_2008      9       /* IEEE 754-2008 quiet NaN */
+#define IEEE754_SPCVAL_PMAX            10      /* +max norm */
+#define IEEE754_SPCVAL_NMAX            11      /* -max norm */
+#define IEEE754_SPCVAL_PMIN            12      /* +min norm */
+#define IEEE754_SPCVAL_NMIN            13      /* -min norm */
+#define IEEE754_SPCVAL_PMIND           14      /* +min denorm */
+#define IEEE754_SPCVAL_NMIND           15      /* -min denorm */
+#define IEEE754_SPCVAL_P1E31           16      /* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63           17      /* + 1.0e63 */
 
 extern const union ieee754dp __ieee754dp_spcvals[];
 extern const union ieee754sp __ieee754sp_spcvals[];
@@ -243,7 +244,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
 #define ieee754dp_zero(sn)     (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 #define ieee754dp_one(sn)      (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 #define ieee754dp_ten(sn)      (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef()      (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_indef()      (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
+                                                  ieee754_csr.nan2008])
 #define ieee754dp_max(sn)      (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 #define ieee754dp_min(sn)      (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 #define ieee754dp_mind(sn)     (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
@@ -254,7 +256,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
 #define ieee754sp_zero(sn)     (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 #define ieee754sp_one(sn)      (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 #define ieee754sp_ten(sn)      (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef()      (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_indef()      (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
+                                                  ieee754_csr.nan2008])
 #define ieee754sp_max(sn)      (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 #define ieee754sp_min(sn)      (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 #define ieee754sp_mind(sn)     (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
@@ -266,12 +269,25 @@ extern const union ieee754sp __ieee754sp_spcvals[];
  */
 static inline int ieee754si_indef(void)
 {
-       return INT_MAX;
+       return ieee754_csr.nan2008 ? 0 : INT_MAX;
 }
 
 static inline s64 ieee754di_indef(void)
 {
-       return S64_MAX;
+       return ieee754_csr.nan2008 ? 0 : S64_MAX;
+}
+
+/*
+ * Overflow integer value
+ */
+static inline int ieee754si_overflow(int xs)
+{
+       return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX;
+}
+
+static inline s64 ieee754di_overflow(int xs)
+{
+       return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX;
 }
 
 /* result types for xctx.rt */
index 522d843..ad3c734 100644 (file)
@@ -37,8 +37,11 @@ static inline int ieee754dp_isnan(union ieee754dp x)
 
 static inline int ieee754dp_issnan(union ieee754dp x)
 {
+       int qbit;
+
        assert(ieee754dp_isnan(x));
-       return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
+       qbit = (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
+       return ieee754_csr.nan2008 ^ qbit;
 }
 
 
@@ -51,7 +54,12 @@ union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
        assert(ieee754dp_issnan(r));
 
        ieee754_setcx(IEEE754_INVALID_OPERATION);
-       return ieee754dp_indef();
+       if (ieee754_csr.nan2008)
+               DPMANT(r) |= DP_MBIT(DP_FBITS - 1);
+       else
+               r = ieee754dp_indef();
+
+       return r;
 }
 
 static u64 ieee754dp_get_rounding(int sn, u64 xm)
index 6383e2c..ed7bb27 100644 (file)
@@ -63,10 +63,10 @@ static inline int ieee754_class_nan(int xc)
        if (ve == SP_EMAX+1+SP_EBIAS) {                                 \
                if (vm == 0)                                            \
                        vc = IEEE754_CLASS_INF;                         \
-               else if (vm & SP_MBIT(SP_FBITS-1))                      \
-                       vc = IEEE754_CLASS_SNAN;                        \
-               else                                                    \
+               else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
                        vc = IEEE754_CLASS_QNAN;                        \
+               else                                                    \
+                       vc = IEEE754_CLASS_SNAN;                        \
        } else if (ve == SP_EMIN-1+SP_EBIAS) {                          \
                if (vm) {                                               \
                        ve = SP_EMIN;                                   \
@@ -97,10 +97,10 @@ static inline int ieee754_class_nan(int xc)
        if (ve == DP_EMAX+1+DP_EBIAS) {                                 \
                if (vm == 0)                                            \
                        vc = IEEE754_CLASS_INF;                         \
-               else if (vm & DP_MBIT(DP_FBITS-1))                      \
-                       vc = IEEE754_CLASS_SNAN;                        \
-               else                                                    \
+               else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
                        vc = IEEE754_CLASS_QNAN;                        \
+               else                                                    \
+                       vc = IEEE754_CLASS_SNAN;                        \
        } else if (ve == DP_EMIN-1+DP_EBIAS) {                          \
                if (vm) {                                               \
                        ve = DP_EMIN;                                   \
index ca8e35e..def00ff 100644 (file)
@@ -37,8 +37,11 @@ static inline int ieee754sp_isnan(union ieee754sp x)
 
 static inline int ieee754sp_issnan(union ieee754sp x)
 {
+       int qbit;
+
        assert(ieee754sp_isnan(x));
-       return SPMANT(x) & SP_MBIT(SP_FBITS - 1);
+       qbit = (SPMANT(x) & SP_MBIT(SP_FBITS - 1)) == SP_MBIT(SP_FBITS - 1);
+       return ieee754_csr.nan2008 ^ qbit;
 }
 
 
@@ -51,7 +54,12 @@ union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
        assert(ieee754sp_issnan(r));
 
        ieee754_setcx(IEEE754_INVALID_OPERATION);
-       return ieee754sp_indef();
+       if (ieee754_csr.nan2008)
+               SPMANT(r) |= SP_MBIT(SP_FBITS - 1);
+       else
+               r = ieee754sp_indef();
+
+       return r;
 }
 
 static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
index 3797148..5060e8f 100644 (file)
@@ -44,13 +44,16 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
 
        switch (xc) {
        case IEEE754_CLASS_SNAN:
-               return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm));
-
+               x = ieee754dp_nanxcpt(x);
+               EXPLODEXDP;
+               /* Fall through.  */
        case IEEE754_CLASS_QNAN:
                y = ieee754sp_nan_fdp(xs, xm);
-               EXPLODEYSP;
-               if (!ieee754_class_nan(yc))
-                       y = ieee754sp_indef();
+               if (!ieee754_csr.nan2008) {
+                       EXPLODEYSP;
+                       if (!ieee754_class_nan(yc))
+                               y = ieee754sp_indef();
+               }
                return y;
 
        case IEEE754_CLASS_INF:
index c50e945..756c9cf 100644 (file)
 
 union ieee754sp ieee754sp_neg(union ieee754sp x)
 {
-       unsigned int oldrm;
        union ieee754sp y;
 
-       oldrm = ieee754_csr.rm;
-       ieee754_csr.rm = FPU_CSR_RD;
-       y = ieee754sp_sub(ieee754sp_zero(0), x);
-       ieee754_csr.rm = oldrm;
+       if (ieee754_csr.abs2008) {
+               y = x;
+               SPSIGN(y) = !SPSIGN(x);
+       } else {
+               unsigned int oldrm;
+
+               oldrm = ieee754_csr.rm;
+               ieee754_csr.rm = FPU_CSR_RD;
+               y = ieee754sp_sub(ieee754sp_zero(0), x);
+               ieee754_csr.rm = oldrm;
+       }
        return y;
 }
 
 union ieee754sp ieee754sp_abs(union ieee754sp x)
 {
-       unsigned int oldrm;
        union ieee754sp y;
 
-       oldrm = ieee754_csr.rm;
-       ieee754_csr.rm = FPU_CSR_RD;
-       if (SPSIGN(x))
-               y = ieee754sp_sub(ieee754sp_zero(0), x);
-       else
-               y = ieee754sp_add(ieee754sp_zero(0), x);
-       ieee754_csr.rm = oldrm;
+       if (ieee754_csr.abs2008) {
+               y = x;
+               SPSIGN(y) = 0;
+       } else {
+               unsigned int oldrm;
+
+               oldrm = ieee754_csr.rm;
+               ieee754_csr.rm = FPU_CSR_RD;
+               if (SPSIGN(x))
+                       y = ieee754sp_sub(ieee754sp_zero(0), x);
+               else
+                       y = ieee754sp_add(ieee754sp_zero(0), x);
+               ieee754_csr.rm = oldrm;
+       }
        return y;
 }
index 091299a..f4b4cab 100644 (file)
@@ -38,10 +38,13 @@ int ieee754sp_tint(union ieee754sp x)
        switch (xc) {
        case IEEE754_CLASS_SNAN:
        case IEEE754_CLASS_QNAN:
-       case IEEE754_CLASS_INF:
                ieee754_setcx(IEEE754_INVALID_OPERATION);
                return ieee754si_indef();
 
+       case IEEE754_CLASS_INF:
+               ieee754_setcx(IEEE754_INVALID_OPERATION);
+               return ieee754si_overflow(xs);
+
        case IEEE754_CLASS_ZERO:
                return 0;
 
@@ -56,7 +59,7 @@ int ieee754sp_tint(union ieee754sp x)
                /* Set invalid. We will only use overflow for floating
                   point overflow */
                ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754si_indef();
+               return ieee754si_overflow(xs);
        }
        /* oh gawd */
        if (xe > SP_FBITS) {
@@ -97,7 +100,7 @@ int ieee754sp_tint(union ieee754sp x)
                if ((xm >> 31) != 0) {
                        /* This can happen after rounding */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754si_indef();
+                       return ieee754si_overflow(xs);
                }
                if (round || sticky)
                        ieee754_setcx(IEEE754_INEXACT);
index 9f3c742..a2450c7 100644 (file)
@@ -39,10 +39,13 @@ s64 ieee754sp_tlong(union ieee754sp x)
        switch (xc) {
        case IEEE754_CLASS_SNAN:
        case IEEE754_CLASS_QNAN:
-       case IEEE754_CLASS_INF:
                ieee754_setcx(IEEE754_INVALID_OPERATION);
                return ieee754di_indef();
 
+       case IEEE754_CLASS_INF:
+               ieee754_setcx(IEEE754_INVALID_OPERATION);
+               return ieee754di_overflow(xs);
+
        case IEEE754_CLASS_ZERO:
                return 0;
 
@@ -57,7 +60,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
                /* Set invalid. We will only use overflow for floating
                   point overflow */
                ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754di_indef();
+               return ieee754di_overflow(xs);
        }
        /* oh gawd */
        if (xe > SP_FBITS) {
@@ -94,7 +97,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
                if ((xm >> 63) != 0) {
                        /* This can happen after rounding */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754di_indef();
+                       return ieee754di_overflow(xs);
                }
                if (round || sticky)
                        ieee754_setcx(IEEE754_INEXACT);
index 482192c..5a04b6f 100644 (file)
@@ -241,7 +241,7 @@ static void output_pgtable_bits_defines(void)
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
        pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
 #endif
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
        if (cpu_has_rixi) {
 #ifdef _PAGE_NO_EXEC_SHIFT
                pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
index 2eda01e..139ad1d 100644 (file)
@@ -43,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80)  += pci-bcm1480.o pci-bcm1480ht.o
 obj-$(CONFIG_SNI_RM)           += fixup-sni.o ops-sni.o
 obj-$(CONFIG_LANTIQ)           += fixup-lantiq.o
 obj-$(CONFIG_PCI_LANTIQ)       += pci-lantiq.o ops-lantiq.o
+obj-$(CONFIG_SOC_MT7620)       += pci-mt7620.o
 obj-$(CONFIG_SOC_RT288X)       += pci-rt2880.o
 obj-$(CONFIG_SOC_RT3883)       += pci-rt3883.o
 obj-$(CONFIG_TANBAC_TB0219)    += fixup-tb0219.o
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
new file mode 100644 (file)
index 0000000..a009ee4
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ *  Ralink MT7620A SoC PCI support
+ *
+ *  Copyright (C) 2007-2013 Bruce Chang (Mediatek)
+ *  Copyright (C) 2013-2016 John Crispin <blogic@openwrt.org>
+ *
+ *  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/types.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/reset.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/mt7620.h>
+
+#define RALINK_PCI_IO_MAP_BASE         0x10160000
+#define RALINK_PCI_MEMORY_BASE         0x0
+
+#define RALINK_INT_PCIE0               4
+
+#define RALINK_CLKCFG1                 0x30
+#define RALINK_GPIOMODE                        0x60
+
+#define PPLL_CFG1                      0x9c
+#define PDRV_SW_SET                    BIT(23)
+
+#define PPLL_DRV                       0xa0
+#define PDRV_SW_SET                    (1<<31)
+#define LC_CKDRVPD                     (1<<19)
+#define LC_CKDRVOHZ                    (1<<18)
+#define LC_CKDRVHZ                     (1<<17)
+#define LC_CKTEST                      (1<<16)
+
+/* PCI Bridge registers */
+#define RALINK_PCI_PCICFG_ADDR         0x00
+#define PCIRST                         BIT(1)
+
+#define RALINK_PCI_PCIENA              0x0C
+#define PCIINT2                                BIT(20)
+
+#define RALINK_PCI_CONFIG_ADDR         0x20
+#define RALINK_PCI_CONFIG_DATA_VIRT_REG        0x24
+#define RALINK_PCI_MEMBASE             0x28
+#define RALINK_PCI_IOBASE              0x2C
+
+/* PCI RC registers */
+#define RALINK_PCI0_BAR0SETUP_ADDR     0x10
+#define RALINK_PCI0_IMBASEBAR0_ADDR    0x18
+#define RALINK_PCI0_ID                 0x30
+#define RALINK_PCI0_CLASS              0x34
+#define RALINK_PCI0_SUBID              0x38
+#define RALINK_PCI0_STATUS             0x50
+#define PCIE_LINK_UP_ST                        BIT(0)
+
+#define PCIEPHY0_CFG                   0x90
+
+#define RALINK_PCIEPHY_P0_CTL_OFFSET   0x7498
+#define RALINK_PCIE0_CLK_EN            (1 << 26)
+
+#define BUSY                           0x80000000
+#define WAITRETRY_MAX                  10
+#define WRITE_MODE                     (1UL << 23)
+#define DATA_SHIFT                     0
+#define ADDR_SHIFT                     8
+
+
+static void __iomem *bridge_base;
+static void __iomem *pcie_base;
+
+static struct reset_control *rstpcie0;
+
+static inline void bridge_w32(u32 val, unsigned reg)
+{
+       iowrite32(val, bridge_base + reg);
+}
+
+static inline u32 bridge_r32(unsigned reg)
+{
+       return ioread32(bridge_base + reg);
+}
+
+static inline void pcie_w32(u32 val, unsigned reg)
+{
+       iowrite32(val, pcie_base + reg);
+}
+
+static inline u32 pcie_r32(unsigned reg)
+{
+       return ioread32(pcie_base + reg);
+}
+
+static inline void pcie_m32(u32 clr, u32 set, unsigned reg)
+{
+       u32 val = pcie_r32(reg);
+
+       val &= ~clr;
+       val |= set;
+       pcie_w32(val, reg);
+}
+
+static int wait_pciephy_busy(void)
+{
+       unsigned long reg_value = 0x0, retry = 0;
+
+       while (1) {
+               reg_value = pcie_r32(PCIEPHY0_CFG);
+
+               if (reg_value & BUSY)
+                       mdelay(100);
+               else
+                       break;
+               if (retry++ > WAITRETRY_MAX) {
+                       printk(KERN_WARN "PCIE-PHY retry failed.\n");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static void pcie_phy(unsigned long addr, unsigned long val)
+{
+       wait_pciephy_busy();
+       pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT),
+                PCIEPHY0_CFG);
+       mdelay(1);
+       wait_pciephy_busy();
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+                          int size, u32 *val)
+{
+       unsigned int slot = PCI_SLOT(devfn);
+       u8 func = PCI_FUNC(devfn);
+       u32 address;
+       u32 data;
+       u32 num = 0;
+
+       if (bus)
+               num = bus->number;
+
+       address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
+                 (func << 8) | (where & 0xfc) | 0x80000000;
+       bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
+       data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+       switch (size) {
+       case 1:
+               *val = (data >> ((where & 3) << 3)) & 0xff;
+               break;
+       case 2:
+               *val = (data >> ((where & 3) << 3)) & 0xffff;
+               break;
+       case 4:
+               *val = data;
+               break;
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+                           int size, u32 val)
+{
+       unsigned int slot = PCI_SLOT(devfn);
+       u8 func = PCI_FUNC(devfn);
+       u32 address;
+       u32 data;
+       u32 num = 0;
+
+       if (bus)
+               num = bus->number;
+
+       address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
+                 (func << 8) | (where & 0xfc) | 0x80000000;
+       bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
+       data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+       switch (size) {
+       case 1:
+               data = (data & ~(0xff << ((where & 3) << 3))) |
+                       (val << ((where & 3) << 3));
+               break;
+       case 2:
+               data = (data & ~(0xffff << ((where & 3) << 3))) |
+                       (val << ((where & 3) << 3));
+               break;
+       case 4:
+               data = val;
+               break;
+       }
+
+       bridge_w32(data, RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mt7620_pci_ops = {
+       .read   = pci_config_read,
+       .write  = pci_config_write,
+};
+
+static struct resource mt7620_res_pci_mem1;
+static struct resource mt7620_res_pci_io1;
+struct pci_controller mt7620_controller = {
+       .pci_ops        = &mt7620_pci_ops,
+       .mem_resource   = &mt7620_res_pci_mem1,
+       .mem_offset     = 0x00000000UL,
+       .io_resource    = &mt7620_res_pci_io1,
+       .io_offset      = 0x00000000UL,
+       .io_map_base    = 0xa0000000,
+};
+
+static int mt7620_pci_hw_init(struct platform_device *pdev)
+{
+       /* bypass PCIe DLL */
+       pcie_phy(0x0, 0x80);
+       pcie_phy(0x1, 0x04);
+
+       /* Elastic buffer control */
+       pcie_phy(0x68, 0xB4);
+
+       /* put core into reset */
+       pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
+       reset_control_assert(rstpcie0);
+
+       /* disable power and all clocks */
+       rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+       rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+
+       /* bring core out of reset */
+       reset_control_deassert(rstpcie0);
+       rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+       mdelay(100);
+
+       if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
+               dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
+               reset_control_assert(rstpcie0);
+               rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+               return -1;
+       }
+
+       /* power up the bus */
+       rt_sysc_m32(LC_CKDRVHZ | LC_CKDRVOHZ, LC_CKDRVPD | PDRV_SW_SET,
+                   PPLL_DRV);
+
+       return 0;
+}
+
+static int mt7628_pci_hw_init(struct platform_device *pdev)
+{
+       u32 val = 0;
+
+       /* bring the core out of reset */
+       rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+       reset_control_deassert(rstpcie0);
+
+       /* enable the pci clk */
+       rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+       mdelay(100);
+
+       /* voodoo from the SDK driver */
+       pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
+
+       pci_config_read(NULL, 0, 0x70c, 4, &val);
+       val &= ~(0xff) << 8;
+       val |= 0x50 << 8;
+       pci_config_write(NULL, 0, 0x70c, 4, val);
+
+       pci_config_read(NULL, 0, 0x70c, 4, &val);
+       dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
+
+       return 0;
+}
+
+static int mt7620_pci_probe(struct platform_device *pdev)
+{
+       struct resource *bridge_res = platform_get_resource(pdev,
+                                                           IORESOURCE_MEM, 0);
+       struct resource *pcie_res = platform_get_resource(pdev,
+                                                         IORESOURCE_MEM, 1);
+       u32 val = 0;
+
+       rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0");
+       if (IS_ERR(rstpcie0))
+               return PTR_ERR(rstpcie0);
+
+       bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res);
+       if (!bridge_base)
+               return -ENOMEM;
+
+       pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res);
+       if (!pcie_base)
+               return -ENOMEM;
+
+       iomem_resource.start = 0;
+       iomem_resource.end = ~0;
+       ioport_resource.start = 0;
+       ioport_resource.end = ~0;
+
+       /* bring up the pci core */
+       switch (ralink_soc) {
+       case MT762X_SOC_MT7620A:
+               if (mt7620_pci_hw_init(pdev))
+                       return -1;
+               break;
+
+       case MT762X_SOC_MT7628AN:
+               if (mt7628_pci_hw_init(pdev))
+                       return -1;
+               break;
+
+       default:
+               dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
+               return -1;
+       }
+       mdelay(50);
+
+       /* enable write access */
+       pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+       mdelay(100);
+
+       /* check if there is a card present */
+       if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
+               reset_control_assert(rstpcie0);
+               rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+               if (ralink_soc == MT762X_SOC_MT7620A)
+                       rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+               dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
+               return -1;
+       }
+
+       /* setup ranges */
+       bridge_w32(0xffffffff, RALINK_PCI_MEMBASE);
+       bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
+
+       pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+       pcie_w32(RALINK_PCI_MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR);
+       pcie_w32(0x06040001, RALINK_PCI0_CLASS);
+
+       /* enable interrupts */
+       pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
+
+       /* voodoo from the SDK driver */
+       pci_config_read(NULL, 0, 4, 4, &val);
+       pci_config_write(NULL, 0, 4, 4, val | 0x7);
+
+       pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
+       register_pci_controller(&mt7620_controller);
+
+       return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       u16 cmd;
+       u32 val;
+       int irq = 0;
+
+       if ((dev->bus->number == 0) && (slot == 0)) {
+               pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+               pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4,
+                                RALINK_PCI_MEMORY_BASE);
+               pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val);
+       } else if ((dev->bus->number == 1) && (slot == 0x0)) {
+               irq = RALINK_INT_PCIE0;
+       } else {
+               dev_err(&dev->dev, "no irq found - bus=0x%x, slot = 0x%x\n",
+                       dev->bus->number, slot);
+               return 0;
+       }
+       dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
+               dev->bus->number, slot, irq);
+
+       /* configure the cache line size to 0x14 */
+       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);
+
+       /* configure latency timer to 0xff */
+       pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xff);
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+       /* setup the slot */
+       cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+       pci_write_config_word(dev, PCI_COMMAND, cmd);
+       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+       return irq;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       return 0;
+}
+
+static const struct of_device_id mt7620_pci_ids[] = {
+       { .compatible = "mediatek,mt7620-pci" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mt7620_pci_ids);
+
+static struct platform_driver mt7620_pci_driver = {
+       .probe = mt7620_pci_probe,
+       .driver = {
+               .name = "mt7620-pci",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(mt7620_pci_ids),
+       },
+};
+
+static int __init mt7620_pci_init(void)
+{
+       return platform_driver_register(&mt7620_pci_driver);
+}
+
+arch_initcall(mt7620_pci_init);
diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig
new file mode 100644 (file)
index 0000000..fde56a8
--- /dev/null
@@ -0,0 +1,51 @@
+if MACH_PIC32
+
+choice
+       prompt "Machine Type"
+
+config PIC32MZDA
+       bool "Microchip PIC32MZDA Platform"
+       select BOOT_ELF32
+       select BOOT_RAW
+       select CEVT_R4K
+       select CSRC_R4K
+       select DMA_NONCOHERENT
+       select SYS_HAS_CPU_MIPS32_R2
+       select SYS_HAS_EARLY_PRINTK
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select ARCH_REQUIRE_GPIOLIB
+       select HAVE_MACH_CLKDEV
+       select COMMON_CLK
+       select CLKDEV_LOOKUP
+       select LIBFDT
+       select USE_OF
+       select PINCTRL
+       select PIC32_EVIC
+       help
+         Support for the Microchip PIC32MZDA microcontroller.
+
+         This is a 32-bit microcontroller with support for external or
+         internally packaged DDR2 memory up to 128MB.
+
+         For more information, see <http://www.microchip.com/>.
+
+endchoice
+
+choice
+       prompt "Devicetree selection"
+       default DTB_PIC32_NONE
+       help
+         Select the devicetree.
+
+config DTB_PIC32_NONE
+       bool "None"
+
+config DTB_PIC32_MZDA_SK
+       bool "PIC32MZDA Starter Kit"
+       depends on PIC32MZDA
+       select BUILTIN_DTB
+
+endchoice
+
+endif # MACH_PIC32
diff --git a/arch/mips/pic32/Makefile b/arch/mips/pic32/Makefile
new file mode 100644 (file)
index 0000000..fd357f4
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc.  All rights reserved.
+#
+obj-$(CONFIG_MACH_PIC32) += common/
+obj-$(CONFIG_PIC32MZDA) += pic32mzda/
diff --git a/arch/mips/pic32/Platform b/arch/mips/pic32/Platform
new file mode 100644 (file)
index 0000000..cd2084f
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# PIC32MZDA
+#
+platform-$(CONFIG_PIC32MZDA)   += pic32/
+cflags-$(CONFIG_PIC32MZDA)     += -I$(srctree)/arch/mips/include/asm/mach-pic32
+load-$(CONFIG_PIC32MZDA)       += 0xffffffff88000000
+all-$(CONFIG_PIC32MZDA)                := $(COMPRESSION_FNAME).bin
diff --git a/arch/mips/pic32/common/Makefile b/arch/mips/pic32/common/Makefile
new file mode 100644 (file)
index 0000000..be1909c
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc.  All rights reserved.
+#
+obj-y = reset.o irq.o
diff --git a/arch/mips/pic32/common/irq.c b/arch/mips/pic32/common/irq.c
new file mode 100644 (file)
index 0000000..6df347e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <linux/init.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+
+void __init arch_init_irq(void)
+{
+       irqchip_init();
+}
diff --git a/arch/mips/pic32/common/reset.c b/arch/mips/pic32/common/reset.c
new file mode 100644 (file)
index 0000000..8334575
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <asm/reboot.h>
+#include <asm/mach-pic32/pic32.h>
+
+#define PIC32_RSWRST           0x10
+
+static void pic32_halt(void)
+{
+       while (1) {
+               __asm__(".set push;\n"
+                       ".set arch=r4000;\n"
+                       "wait;\n"
+                       ".set pop;\n"
+               );
+       }
+}
+
+static void pic32_machine_restart(char *command)
+{
+       void __iomem *reg =
+               ioremap(PIC32_BASE_RESET + PIC32_RSWRST, sizeof(u32));
+
+       pic32_syskey_unlock();
+
+       /* magic write/read */
+       __raw_writel(1, reg);
+       (void)__raw_readl(reg);
+
+       pic32_halt();
+}
+
+static void pic32_machine_halt(void)
+{
+       local_irq_disable();
+
+       pic32_halt();
+}
+
+static int __init mips_reboot_setup(void)
+{
+       _machine_restart = pic32_machine_restart;
+       _machine_halt = pic32_machine_halt;
+       pm_power_off = pic32_machine_halt;
+
+       return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/pic32/pic32mzda/Makefile b/arch/mips/pic32/pic32mzda/Makefile
new file mode 100644 (file)
index 0000000..4a4c272
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc.  All rights reserved.
+#
+obj-y                  := init.o time.o config.o
+
+obj-$(CONFIG_EARLY_PRINTK)     += early_console.o      \
+                                  early_pin.o          \
+                                  early_clk.o
diff --git a/arch/mips/pic32/pic32mzda/config.c b/arch/mips/pic32/pic32mzda/config.c
new file mode 100644 (file)
index 0000000..fe293a0
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Purna Chandra Mandal, purna.mandal@microchip.com
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach-pic32/pic32.h>
+
+#include "pic32mzda.h"
+
+#define PIC32_CFGCON   0x0000
+#define PIC32_DEVID    0x0020
+#define PIC32_SYSKEY   0x0030
+#define PIC32_CFGEBIA  0x00c0
+#define PIC32_CFGEBIC  0x00d0
+#define PIC32_CFGCON2  0x00f0
+#define PIC32_RCON     0x1240
+
+static void __iomem *pic32_conf_base;
+static DEFINE_SPINLOCK(config_lock);
+static u32 pic32_reset_status;
+
+static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask)
+{
+       u32 v;
+
+       v = readl(pic32_conf_base + offset);
+       v >>= rshift;
+       v &= mask;
+
+       return v;
+}
+
+static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set)
+{
+       u32 v;
+       unsigned long flags;
+
+       spin_lock_irqsave(&config_lock, flags);
+       v = readl(pic32_conf_base + offset);
+       v &= ~mask;
+       v |= (set & mask);
+       writel(v, pic32_conf_base + offset);
+       spin_unlock_irqrestore(&config_lock, flags);
+
+       return 0;
+}
+
+int pic32_enable_lcd(void)
+{
+       return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31));
+}
+
+int pic32_disable_lcd(void)
+{
+       return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0);
+}
+
+int pic32_set_lcd_mode(int mode)
+{
+       u32 mask = mode ? BIT(30) : 0;
+
+       return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask);
+}
+
+int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh)
+{
+       u32 clr, set;
+
+       clr = (0x3ff << 4) | (0x3ff << 16);
+       set = (rthrsh << 4) | (wthrsh << 16);
+       return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set);
+}
+
+void pic32_syskey_unlock_debug(const char *func, const ulong line)
+{
+       void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY;
+
+       pr_debug("%s: called from %s:%lu\n", __func__, func, line);
+       writel(0x00000000, syskey);
+       writel(0xAA996655, syskey);
+       writel(0x556699AA, syskey);
+}
+
+static u32 pic32_get_device_id(void)
+{
+       return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff);
+}
+
+static u32 pic32_get_device_version(void)
+{
+       return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf);
+}
+
+u32 pic32_get_boot_status(void)
+{
+       return pic32_reset_status;
+}
+EXPORT_SYMBOL(pic32_get_boot_status);
+
+void __init pic32_config_init(void)
+{
+       pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110);
+       if (!pic32_conf_base)
+               panic("pic32: config base not mapped");
+
+       /* Boot Status */
+       pic32_reset_status = readl(pic32_conf_base + PIC32_RCON);
+       writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON));
+
+       /* Device Inforation */
+       pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n",
+               pic32_get_device_id(),
+               pic32_get_device_version());
+}
diff --git a/arch/mips/pic32/pic32mzda/early_clk.c b/arch/mips/pic32/pic32mzda/early_clk.c
new file mode 100644 (file)
index 0000000..96c090e
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <asm/mach-pic32/pic32.h>
+
+#include "pic32mzda.h"
+
+/* Oscillators, PLL & clocks */
+#define ICLK_MASK      0x00000080
+#define PLLDIV_MASK    0x00000007
+#define CUROSC_MASK    0x00000007
+#define PLLMUL_MASK    0x0000007F
+#define PB_MASK                0x00000007
+#define FRC1           0
+#define FRC2           7
+#define SPLL           1
+#define POSC           2
+#define FRC_CLK                8000000
+
+#define PIC32_POSC_FREQ        24000000
+
+#define OSCCON         0x0000
+#define SPLLCON                0x0020
+#define PB1DIV         0x0140
+
+u32 pic32_get_sysclk(void)
+{
+       u32 osc_freq = 0;
+       u32 pllclk;
+       u32 frcdivn;
+       u32 osccon;
+       u32 spllcon;
+       int curr_osc;
+
+       u32 plliclk;
+       u32 pllidiv;
+       u32 pllodiv;
+       u32 pllmult;
+       u32 frcdiv;
+
+       void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
+
+       osccon = __raw_readl(osc_base + OSCCON);
+       spllcon = __raw_readl(osc_base + SPLLCON);
+
+       plliclk = (spllcon & ICLK_MASK);
+       pllidiv = ((spllcon >> 8) & PLLDIV_MASK) + 1;
+       pllodiv = ((spllcon >> 24) & PLLDIV_MASK);
+       pllmult = ((spllcon >> 16) & PLLMUL_MASK) + 1;
+       frcdiv = ((osccon >> 24) & PLLDIV_MASK);
+
+       pllclk = plliclk ? FRC_CLK : PIC32_POSC_FREQ;
+       frcdivn = ((1 << frcdiv) + 1) + (128 * (frcdiv == 7));
+
+       if (pllodiv < 2)
+               pllodiv = 2;
+       else if (pllodiv < 5)
+               pllodiv = (1 << pllodiv);
+       else
+               pllodiv = 32;
+
+       curr_osc = (int)((osccon >> 12) & CUROSC_MASK);
+
+       switch (curr_osc) {
+       case FRC1:
+       case FRC2:
+               osc_freq = FRC_CLK / frcdivn;
+               break;
+       case SPLL:
+               osc_freq = ((pllclk / pllidiv) * pllmult) / pllodiv;
+               break;
+       case POSC:
+               osc_freq = PIC32_POSC_FREQ;
+               break;
+       default:
+               break;
+       }
+
+       iounmap(osc_base);
+
+       return osc_freq;
+}
+
+u32 pic32_get_pbclk(int bus)
+{
+       u32 clk_freq;
+       void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
+       u32 pbxdiv = PB1DIV + ((bus - 1) * 0x10);
+       u32 pbdiv = (__raw_readl(osc_base + pbxdiv) & PB_MASK) + 1;
+
+       iounmap(osc_base);
+
+       clk_freq = pic32_get_sysclk();
+
+       return clk_freq / pbdiv;
+}
diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c
new file mode 100644 (file)
index 0000000..d7b7834
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <asm/mach-pic32/pic32.h>
+#include <asm/fw/fw.h>
+
+#include "pic32mzda.h"
+#include "early_pin.h"
+
+/* Default early console parameters */
+#define EARLY_CONSOLE_PORT     1
+#define EARLY_CONSOLE_BAUDRATE 115200
+
+#define UART_ENABLE            BIT(15)
+#define UART_ENABLE_RX         BIT(12)
+#define UART_ENABLE_TX         BIT(10)
+#define UART_TX_FULL           BIT(9)
+
+/* UART1(x == 0) - UART6(x == 5) */
+#define UART_BASE(x)   ((x) * 0x0200)
+#define U_MODE(x)      UART_BASE(x)
+#define U_STA(x)       (UART_BASE(x) + 0x10)
+#define U_TXR(x)       (UART_BASE(x) + 0x20)
+#define U_BRG(x)       (UART_BASE(x) + 0x40)
+
+static void __iomem *uart_base;
+static char console_port = -1;
+
+static int __init configure_uart_pins(int port)
+{
+       switch (port) {
+       case 1:
+               pic32_pps_input(IN_FUNC_U2RX, IN_RPB0);
+               pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9);
+               break;
+       case 5:
+               pic32_pps_input(IN_FUNC_U6RX, IN_RPD0);
+               pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8);
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
+static void __init configure_uart(char port, int baud)
+{
+       u32 pbclk;
+
+       pbclk = pic32_get_pbclk(2);
+
+       __raw_writel(0, uart_base + U_MODE(port));
+       __raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port));
+       __raw_writel(UART_ENABLE, uart_base + U_MODE(port));
+       __raw_writel(UART_ENABLE_TX | UART_ENABLE_RX,
+                    uart_base + PIC32_SET(U_STA(port)));
+}
+
+static void __init setup_early_console(char port, int baud)
+{
+       if (configure_uart_pins(port))
+               return;
+
+       console_port = port;
+       configure_uart(console_port, baud);
+}
+
+static char * __init pic32_getcmdline(void)
+{
+       /*
+        * arch_mem_init() has not been called yet, so we don't have a real
+        * command line setup if using CONFIG_CMDLINE_BOOL.
+        */
+#ifdef CONFIG_CMDLINE_OVERRIDE
+       return CONFIG_CMDLINE;
+#else
+       return fw_getcmdline();
+#endif
+}
+
+static int __init get_port_from_cmdline(char *arch_cmdline)
+{
+       char *s;
+       int port = -1;
+
+       if (!arch_cmdline || *arch_cmdline == '\0')
+               goto _out;
+
+       s = strstr(arch_cmdline, "earlyprintk=");
+       if (s) {
+               s = strstr(s, "ttyS");
+               if (s)
+                       s += 4;
+               else
+                       goto _out;
+
+               port = (*s) - '0';
+       }
+
+_out:
+       return port;
+}
+
+static int __init get_baud_from_cmdline(char *arch_cmdline)
+{
+       char *s;
+       int baud = -1;
+
+       if (!arch_cmdline || *arch_cmdline == '\0')
+               goto _out;
+
+       s = strstr(arch_cmdline, "earlyprintk=");
+       if (s) {
+               s = strstr(s, "ttyS");
+               if (s)
+                       s += 6;
+               else
+                       goto _out;
+
+               baud = 0;
+               while (*s >= '0' && *s <= '9')
+                       baud = baud * 10 + *s++ - '0';
+       }
+
+_out:
+       return baud;
+}
+
+void __init fw_init_early_console(char port)
+{
+       char *arch_cmdline = pic32_getcmdline();
+       int baud = -1;
+
+       uart_base = ioremap_nocache(PIC32_BASE_UART, 0xc00);
+
+       baud = get_baud_from_cmdline(arch_cmdline);
+       if (port == -1)
+               port = get_port_from_cmdline(arch_cmdline);
+
+       if (port == -1)
+               port = EARLY_CONSOLE_PORT;
+
+       if (baud == -1)
+               baud = EARLY_CONSOLE_BAUDRATE;
+
+       setup_early_console(port, baud);
+}
+
+int prom_putchar(char c)
+{
+       if (console_port >= 0) {
+               while (__raw_readl(
+                               uart_base + U_STA(console_port)) & UART_TX_FULL)
+                       ;
+
+               __raw_writel(c, uart_base + U_TXR(console_port));
+       }
+
+       return 1;
+}
diff --git a/arch/mips/pic32/pic32mzda/early_pin.c b/arch/mips/pic32/pic32mzda/early_pin.c
new file mode 100644 (file)
index 0000000..aa673f8
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <asm/io.h>
+
+#include "early_pin.h"
+
+#define PPS_BASE 0x1f800000
+
+/* Input PPS Registers */
+#define INT1R 0x1404
+#define INT2R 0x1408
+#define INT3R 0x140C
+#define INT4R 0x1410
+#define T2CKR 0x1418
+#define T3CKR 0x141C
+#define T4CKR 0x1420
+#define T5CKR 0x1424
+#define T6CKR 0x1428
+#define T7CKR 0x142C
+#define T8CKR 0x1430
+#define T9CKR 0x1434
+#define IC1R 0x1438
+#define IC2R 0x143C
+#define IC3R 0x1440
+#define IC4R 0x1444
+#define IC5R 0x1448
+#define IC6R 0x144C
+#define IC7R 0x1450
+#define IC8R 0x1454
+#define IC9R 0x1458
+#define OCFAR 0x1460
+#define U1RXR 0x1468
+#define U1CTSR 0x146C
+#define U2RXR 0x1470
+#define U2CTSR 0x1474
+#define U3RXR 0x1478
+#define U3CTSR 0x147C
+#define U4RXR 0x1480
+#define U4CTSR 0x1484
+#define U5RXR 0x1488
+#define U5CTSR 0x148C
+#define U6RXR 0x1490
+#define U6CTSR 0x1494
+#define SDI1R 0x149C
+#define SS1R 0x14A0
+#define SDI2R 0x14A8
+#define SS2R 0x14AC
+#define SDI3R 0x14B4
+#define SS3R 0x14B8
+#define SDI4R 0x14C0
+#define SS4R 0x14C4
+#define SDI5R 0x14CC
+#define SS5R 0x14D0
+#define SDI6R 0x14D8
+#define SS6R 0x14DC
+#define C1RXR 0x14E0
+#define C2RXR 0x14E4
+#define REFCLKI1R 0x14E8
+#define REFCLKI3R 0x14F0
+#define REFCLKI4R 0x14F4
+
+static const struct
+{
+       int function;
+       int reg;
+} input_pin_reg[] = {
+       { IN_FUNC_INT3, INT3R },
+       { IN_FUNC_T2CK, T2CKR },
+       { IN_FUNC_T6CK, T6CKR },
+       { IN_FUNC_IC3, IC3R  },
+       { IN_FUNC_IC7, IC7R },
+       { IN_FUNC_U1RX, U1RXR },
+       { IN_FUNC_U2CTS, U2CTSR },
+       { IN_FUNC_U5RX, U5RXR },
+       { IN_FUNC_U6CTS, U6CTSR },
+       { IN_FUNC_SDI1, SDI1R },
+       { IN_FUNC_SDI3, SDI3R },
+       { IN_FUNC_SDI5, SDI5R },
+       { IN_FUNC_SS6, SS6R },
+       { IN_FUNC_REFCLKI1, REFCLKI1R },
+       { IN_FUNC_INT4, INT4R },
+       { IN_FUNC_T5CK, T5CKR },
+       { IN_FUNC_T7CK, T7CKR },
+       { IN_FUNC_IC4, IC4R },
+       { IN_FUNC_IC8, IC8R },
+       { IN_FUNC_U3RX, U3RXR },
+       { IN_FUNC_U4CTS, U4CTSR },
+       { IN_FUNC_SDI2, SDI2R },
+       { IN_FUNC_SDI4, SDI4R },
+       { IN_FUNC_C1RX, C1RXR },
+       { IN_FUNC_REFCLKI4, REFCLKI4R },
+       { IN_FUNC_INT2, INT2R },
+       { IN_FUNC_T3CK, T3CKR },
+       { IN_FUNC_T8CK, T8CKR },
+       { IN_FUNC_IC2, IC2R },
+       { IN_FUNC_IC5, IC5R },
+       { IN_FUNC_IC9, IC9R },
+       { IN_FUNC_U1CTS, U1CTSR },
+       { IN_FUNC_U2RX, U2RXR },
+       { IN_FUNC_U5CTS, U5CTSR },
+       { IN_FUNC_SS1, SS1R },
+       { IN_FUNC_SS3, SS3R },
+       { IN_FUNC_SS4, SS4R },
+       { IN_FUNC_SS5, SS5R },
+       { IN_FUNC_C2RX, C2RXR },
+       { IN_FUNC_INT1, INT1R },
+       { IN_FUNC_T4CK, T4CKR },
+       { IN_FUNC_T9CK, T9CKR },
+       { IN_FUNC_IC1, IC1R },
+       { IN_FUNC_IC6, IC6R },
+       { IN_FUNC_U3CTS, U3CTSR },
+       { IN_FUNC_U4RX, U4RXR },
+       { IN_FUNC_U6RX, U6RXR },
+       { IN_FUNC_SS2, SS2R },
+       { IN_FUNC_SDI6, SDI6R },
+       { IN_FUNC_OCFA, OCFAR },
+       { IN_FUNC_REFCLKI3, REFCLKI3R },
+};
+
+void pic32_pps_input(int function, int pin)
+{
+       void __iomem *pps_base = ioremap_nocache(PPS_BASE, 0xF4);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(input_pin_reg); i++) {
+               if (input_pin_reg[i].function == function) {
+                       __raw_writel(pin, pps_base + input_pin_reg[i].reg);
+                       return;
+               }
+       }
+
+       iounmap(pps_base);
+}
+
+/* Output PPS Registers */
+#define RPA14R 0x1538
+#define RPA15R 0x153C
+#define RPB0R 0x1540
+#define RPB1R 0x1544
+#define RPB2R 0x1548
+#define RPB3R 0x154C
+#define RPB5R 0x1554
+#define RPB6R 0x1558
+#define RPB7R 0x155C
+#define RPB8R 0x1560
+#define RPB9R 0x1564
+#define RPB10R 0x1568
+#define RPB14R 0x1578
+#define RPB15R 0x157C
+#define RPC1R 0x1584
+#define RPC2R 0x1588
+#define RPC3R 0x158C
+#define RPC4R 0x1590
+#define RPC13R 0x15B4
+#define RPC14R 0x15B8
+#define RPD0R 0x15C0
+#define RPD1R 0x15C4
+#define RPD2R 0x15C8
+#define RPD3R 0x15CC
+#define RPD4R 0x15D0
+#define RPD5R 0x15D4
+#define RPD6R 0x15D8
+#define RPD7R 0x15DC
+#define RPD9R 0x15E4
+#define RPD10R 0x15E8
+#define RPD11R 0x15EC
+#define RPD12R 0x15F0
+#define RPD14R 0x15F8
+#define RPD15R 0x15FC
+#define RPE3R 0x160C
+#define RPE5R 0x1614
+#define RPE8R 0x1620
+#define RPE9R 0x1624
+#define RPF0R 0x1640
+#define RPF1R 0x1644
+#define RPF2R 0x1648
+#define RPF3R 0x164C
+#define RPF4R 0x1650
+#define RPF5R 0x1654
+#define RPF8R 0x1660
+#define RPF12R 0x1670
+#define RPF13R 0x1674
+#define RPG0R 0x1680
+#define RPG1R 0x1684
+#define RPG6R 0x1698
+#define RPG7R 0x169C
+#define RPG8R 0x16A0
+#define RPG9R 0x16A4
+
+static const struct
+{
+       int pin;
+       int reg;
+} output_pin_reg[] = {
+       { OUT_RPD2, RPD2R },
+       { OUT_RPG8, RPG8R },
+       { OUT_RPF4, RPF4R },
+       { OUT_RPD10, RPD10R },
+       { OUT_RPF1, RPF1R },
+       { OUT_RPB9, RPB9R },
+       { OUT_RPB10, RPB10R },
+       { OUT_RPC14, RPC14R },
+       { OUT_RPB5, RPB5R },
+       { OUT_RPC1, RPC1R },
+       { OUT_RPD14, RPD14R },
+       { OUT_RPG1, RPG1R },
+       { OUT_RPA14, RPA14R },
+       { OUT_RPD6, RPD6R },
+       { OUT_RPD3, RPD3R },
+       { OUT_RPG7, RPG7R },
+       { OUT_RPF5, RPF5R },
+       { OUT_RPD11, RPD11R },
+       { OUT_RPF0, RPF0R },
+       { OUT_RPB1, RPB1R },
+       { OUT_RPE5, RPE5R },
+       { OUT_RPC13, RPC13R },
+       { OUT_RPB3, RPB3R },
+       { OUT_RPC4, RPC4R },
+       { OUT_RPD15, RPD15R },
+       { OUT_RPG0, RPG0R },
+       { OUT_RPA15, RPA15R },
+       { OUT_RPD7, RPD7R },
+       { OUT_RPD9, RPD9R },
+       { OUT_RPG6, RPG6R },
+       { OUT_RPB8, RPB8R },
+       { OUT_RPB15, RPB15R },
+       { OUT_RPD4, RPD4R },
+       { OUT_RPB0, RPB0R },
+       { OUT_RPE3, RPE3R },
+       { OUT_RPB7, RPB7R },
+       { OUT_RPF12, RPF12R },
+       { OUT_RPD12, RPD12R },
+       { OUT_RPF8, RPF8R },
+       { OUT_RPC3, RPC3R },
+       { OUT_RPE9, RPE9R },
+       { OUT_RPD1, RPD1R },
+       { OUT_RPG9, RPG9R },
+       { OUT_RPB14, RPB14R },
+       { OUT_RPD0, RPD0R },
+       { OUT_RPB6, RPB6R },
+       { OUT_RPD5, RPD5R },
+       { OUT_RPB2, RPB2R },
+       { OUT_RPF3, RPF3R },
+       { OUT_RPF13, RPF13R },
+       { OUT_RPC2, RPC2R },
+       { OUT_RPE8, RPE8R },
+       { OUT_RPF2, RPF2R },
+};
+
+void pic32_pps_output(int function, int pin)
+{
+       void __iomem *pps_base = ioremap_nocache(PPS_BASE, 0x170);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(output_pin_reg); i++) {
+               if (output_pin_reg[i].pin == pin) {
+                       __raw_writel(function,
+                               pps_base + output_pin_reg[i].reg);
+                       return;
+               }
+       }
+
+       iounmap(pps_base);
+}
diff --git a/arch/mips/pic32/pic32mzda/early_pin.h b/arch/mips/pic32/pic32mzda/early_pin.h
new file mode 100644 (file)
index 0000000..417fae9
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#ifndef _PIC32MZDA_EARLY_PIN_H
+#define _PIC32MZDA_EARLY_PIN_H
+
+/*
+ * This is a complete, yet overly simplistic and unoptimized, PIC32MZDA PPS
+ * configuration only useful before we have full pinctrl initialized.
+ */
+
+/* Input PPS Functions */
+enum {
+       IN_FUNC_INT3,
+       IN_FUNC_T2CK,
+       IN_FUNC_T6CK,
+       IN_FUNC_IC3,
+       IN_FUNC_IC7,
+       IN_FUNC_U1RX,
+       IN_FUNC_U2CTS,
+       IN_FUNC_U5RX,
+       IN_FUNC_U6CTS,
+       IN_FUNC_SDI1,
+       IN_FUNC_SDI3,
+       IN_FUNC_SDI5,
+       IN_FUNC_SS6,
+       IN_FUNC_REFCLKI1,
+       IN_FUNC_INT4,
+       IN_FUNC_T5CK,
+       IN_FUNC_T7CK,
+       IN_FUNC_IC4,
+       IN_FUNC_IC8,
+       IN_FUNC_U3RX,
+       IN_FUNC_U4CTS,
+       IN_FUNC_SDI2,
+       IN_FUNC_SDI4,
+       IN_FUNC_C1RX,
+       IN_FUNC_REFCLKI4,
+       IN_FUNC_INT2,
+       IN_FUNC_T3CK,
+       IN_FUNC_T8CK,
+       IN_FUNC_IC2,
+       IN_FUNC_IC5,
+       IN_FUNC_IC9,
+       IN_FUNC_U1CTS,
+       IN_FUNC_U2RX,
+       IN_FUNC_U5CTS,
+       IN_FUNC_SS1,
+       IN_FUNC_SS3,
+       IN_FUNC_SS4,
+       IN_FUNC_SS5,
+       IN_FUNC_C2RX,
+       IN_FUNC_INT1,
+       IN_FUNC_T4CK,
+       IN_FUNC_T9CK,
+       IN_FUNC_IC1,
+       IN_FUNC_IC6,
+       IN_FUNC_U3CTS,
+       IN_FUNC_U4RX,
+       IN_FUNC_U6RX,
+       IN_FUNC_SS2,
+       IN_FUNC_SDI6,
+       IN_FUNC_OCFA,
+       IN_FUNC_REFCLKI3,
+};
+
+/* Input PPS Pins */
+#define IN_RPD2 0x00
+#define IN_RPG8 0x01
+#define IN_RPF4 0x02
+#define IN_RPD10 0x03
+#define IN_RPF1 0x04
+#define IN_RPB9 0x05
+#define IN_RPB10 0x06
+#define IN_RPC14 0x07
+#define IN_RPB5 0x08
+#define IN_RPC1 0x0A
+#define IN_RPD14 0x0B
+#define IN_RPG1 0x0C
+#define IN_RPA14 0x0D
+#define IN_RPD6 0x0E
+#define IN_RPD3 0x00
+#define IN_RPG7 0x01
+#define IN_RPF5 0x02
+#define IN_RPD11 0x03
+#define IN_RPF0 0x04
+#define IN_RPB1 0x05
+#define IN_RPE5 0x06
+#define IN_RPC13 0x07
+#define IN_RPB3 0x08
+#define IN_RPC4 0x0A
+#define IN_RPD15 0x0B
+#define IN_RPG0 0x0C
+#define IN_RPA15 0x0D
+#define IN_RPD7 0x0E
+#define IN_RPD9 0x00
+#define IN_RPG6 0x01
+#define IN_RPB8 0x02
+#define IN_RPB15 0x03
+#define IN_RPD4 0x04
+#define IN_RPB0 0x05
+#define IN_RPE3 0x06
+#define IN_RPB7 0x07
+#define IN_RPF12 0x09
+#define IN_RPD12 0x0A
+#define IN_RPF8 0x0B
+#define IN_RPC3 0x0C
+#define IN_RPE9 0x0D
+#define IN_RPD1 0x00
+#define IN_RPG9 0x01
+#define IN_RPB14 0x02
+#define IN_RPD0 0x03
+#define IN_RPB6 0x05
+#define IN_RPD5 0x06
+#define IN_RPB2 0x07
+#define IN_RPF3 0x08
+#define IN_RPF13 0x09
+#define IN_RPF2 0x0B
+#define IN_RPC2 0x0C
+#define IN_RPE8 0x0D
+
+/* Output PPS Pins */
+enum {
+       OUT_RPD2,
+       OUT_RPG8,
+       OUT_RPF4,
+       OUT_RPD10,
+       OUT_RPF1,
+       OUT_RPB9,
+       OUT_RPB10,
+       OUT_RPC14,
+       OUT_RPB5,
+       OUT_RPC1,
+       OUT_RPD14,
+       OUT_RPG1,
+       OUT_RPA14,
+       OUT_RPD6,
+       OUT_RPD3,
+       OUT_RPG7,
+       OUT_RPF5,
+       OUT_RPD11,
+       OUT_RPF0,
+       OUT_RPB1,
+       OUT_RPE5,
+       OUT_RPC13,
+       OUT_RPB3,
+       OUT_RPC4,
+       OUT_RPD15,
+       OUT_RPG0,
+       OUT_RPA15,
+       OUT_RPD7,
+       OUT_RPD9,
+       OUT_RPG6,
+       OUT_RPB8,
+       OUT_RPB15,
+       OUT_RPD4,
+       OUT_RPB0,
+       OUT_RPE3,
+       OUT_RPB7,
+       OUT_RPF12,
+       OUT_RPD12,
+       OUT_RPF8,
+       OUT_RPC3,
+       OUT_RPE9,
+       OUT_RPD1,
+       OUT_RPG9,
+       OUT_RPB14,
+       OUT_RPD0,
+       OUT_RPB6,
+       OUT_RPD5,
+       OUT_RPB2,
+       OUT_RPF3,
+       OUT_RPF13,
+       OUT_RPC2,
+       OUT_RPE8,
+       OUT_RPF2,
+};
+
+/* Output PPS Functions */
+#define OUT_FUNC_U3TX 0x01
+#define OUT_FUNC_U4RTS 0x02
+#define OUT_FUNC_SDO1 0x05
+#define OUT_FUNC_SDO2 0x06
+#define OUT_FUNC_SDO3 0x07
+#define OUT_FUNC_SDO5 0x09
+#define OUT_FUNC_SS6 0x0A
+#define OUT_FUNC_OC3 0x0B
+#define OUT_FUNC_OC6 0x0C
+#define OUT_FUNC_REFCLKO4 0x0D
+#define OUT_FUNC_C2OUT 0x0E
+#define OUT_FUNC_C1TX 0x0F
+#define OUT_FUNC_U1TX 0x01
+#define OUT_FUNC_U2RTS 0x02
+#define OUT_FUNC_U5TX 0x03
+#define OUT_FUNC_U6RTS 0x04
+#define OUT_FUNC_SDO1 0x05
+#define OUT_FUNC_SDO2 0x06
+#define OUT_FUNC_SDO3 0x07
+#define OUT_FUNC_SDO4 0x08
+#define OUT_FUNC_SDO5 0x09
+#define OUT_FUNC_OC4 0x0B
+#define OUT_FUNC_OC7 0x0C
+#define OUT_FUNC_REFCLKO1 0x0F
+#define OUT_FUNC_U3RTS 0x01
+#define OUT_FUNC_U4TX 0x02
+#define OUT_FUNC_U6TX 0x04
+#define OUT_FUNC_SS1 0x05
+#define OUT_FUNC_SS3 0x07
+#define OUT_FUNC_SS4 0x08
+#define OUT_FUNC_SS5 0x09
+#define OUT_FUNC_SDO6 0x0A
+#define OUT_FUNC_OC5 0x0B
+#define OUT_FUNC_OC8 0x0C
+#define OUT_FUNC_C1OUT 0x0E
+#define OUT_FUNC_REFCLKO3 0x0F
+#define OUT_FUNC_U1RTS 0x01
+#define OUT_FUNC_U2TX 0x02
+#define OUT_FUNC_U5RTS 0x03
+#define OUT_FUNC_U6TX 0x04
+#define OUT_FUNC_SS2 0x06
+#define OUT_FUNC_SDO4 0x08
+#define OUT_FUNC_SDO6 0x0A
+#define OUT_FUNC_OC2 0x0B
+#define OUT_FUNC_OC1 0x0C
+#define OUT_FUNC_OC9 0x0D
+#define OUT_FUNC_C2TX 0x0F
+
+void pic32_pps_input(int function, int pin);
+void pic32_pps_output(int function, int pin);
+
+#endif
diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c
new file mode 100644 (file)
index 0000000..775ff90
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Joshua Henderson, joshua.henderson@microchip.com
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/sdhci-pic32.h>
+
+#include <asm/fw/fw.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/prom.h>
+
+#include "pic32mzda.h"
+
+const char *get_system_type(void)
+{
+       return "PIC32MZDA";
+}
+
+static ulong get_fdtaddr(void)
+{
+       ulong ftaddr = 0;
+
+       if ((fw_arg0 == -2) && fw_arg1 && !fw_arg2 && !fw_arg3)
+               return (ulong)fw_arg1;
+
+       if (__dtb_start < __dtb_end)
+               ftaddr = (ulong)__dtb_start;
+
+       return ftaddr;
+}
+
+void __init plat_mem_setup(void)
+{
+       void *dtb;
+
+       dtb = (void *)get_fdtaddr();
+       if (!dtb) {
+               pr_err("pic32: no DTB found.\n");
+               return;
+       }
+
+       /*
+        * Load the builtin device tree. This causes the chosen node to be
+        * parsed resulting in our memory appearing.
+        */
+       __dt_setup_arch(dtb);
+
+       pr_info("Found following command lines\n");
+       pr_info(" boot_command_line: %s\n", boot_command_line);
+       pr_info(" arcs_cmdline     : %s\n", arcs_cmdline);
+#ifdef CONFIG_CMDLINE_BOOL
+       pr_info(" builtin_cmdline  : %s\n", CONFIG_CMDLINE);
+#endif
+       if (dtb != __dtb_start)
+               strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+
+#ifdef CONFIG_EARLY_PRINTK
+       fw_init_early_console(-1);
+#endif
+       pic32_config_init();
+}
+
+static __init void pic32_init_cmdline(int argc, char *argv[])
+{
+       unsigned int count = COMMAND_LINE_SIZE - 1;
+       int i;
+       char *dst = &(arcs_cmdline[0]);
+       char *src;
+
+       for (i = 1; i < argc && count; ++i) {
+               src = argv[i];
+               while (*src && count) {
+                       *dst++ = *src++;
+                       --count;
+               }
+               *dst++ = ' ';
+       }
+       if (i > 1)
+               --dst;
+
+       *dst = 0;
+}
+
+void __init prom_init(void)
+{
+       pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init device_tree_init(void)
+{
+       if (!initial_boot_params)
+               return;
+
+       unflatten_and_copy_device_tree();
+}
+
+static struct pic32_sdhci_platform_data sdhci_data = {
+       .setup_dma = pic32_set_sdhci_adma_fifo_threshold,
+};
+
+static struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data),
+       { /* sentinel */}
+};
+
+static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup)
+{
+       struct device_node *root, *np;
+       struct resource res;
+
+       root = of_find_node_by_path("/");
+
+       for (; lookup->compatible; lookup++) {
+               np = of_find_compatible_node(NULL, NULL, lookup->compatible);
+               if (np) {
+                       lookup->name = (char *)np->name;
+                       if (lookup->phys_addr)
+                               continue;
+                       if (!of_address_to_resource(np, 0, &res))
+                               lookup->phys_addr = res.start;
+               }
+       }
+
+       return 0;
+}
+
+static int __init plat_of_setup(void)
+{
+       if (!of_have_populated_dt())
+               panic("Device tree not present");
+
+       pic32_of_prepare_platform_data(pic32_auxdata_lookup);
+       if (of_platform_populate(NULL, of_default_bus_match_table,
+                                pic32_auxdata_lookup, NULL))
+               panic("Failed to populate DT");
+
+       return 0;
+}
+arch_initcall(plat_of_setup);
diff --git a/arch/mips/pic32/pic32mzda/pic32mzda.h b/arch/mips/pic32/pic32mzda/pic32mzda.h
new file mode 100644 (file)
index 0000000..96d10e2
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#ifndef PIC32MZDA_COMMON_H
+#define PIC32MZDA_COMMON_H
+
+/* early clock */
+u32 pic32_get_pbclk(int bus);
+u32 pic32_get_sysclk(void);
+
+/* Device configuration */
+void __init pic32_config_init(void);
+int pic32_set_lcd_mode(int mode);
+int pic32_set_sdhci_adma_fifo_threshold(u32 rthrs, u32 wthrs);
+u32 pic32_get_boot_status(void);
+int pic32_disable_lcd(void);
+int pic32_enable_lcd(void);
+
+#endif
diff --git a/arch/mips/pic32/pic32mzda/time.c b/arch/mips/pic32/pic32mzda/time.c
new file mode 100644 (file)
index 0000000..ca6a62b
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/time.h>
+
+#include "pic32mzda.h"
+
+static const struct of_device_id pic32_infra_match[] = {
+       { .compatible = "microchip,pic32mzda-infra", },
+       { },
+};
+
+#define DEFAULT_CORE_TIMER_INTERRUPT 0
+
+static unsigned int pic32_xlate_core_timer_irq(void)
+{
+       static struct device_node *node;
+       unsigned int irq;
+
+       node = of_find_matching_node(NULL, pic32_infra_match);
+
+       if (WARN_ON(!node))
+               goto default_map;
+
+       irq = irq_of_parse_and_map(node, 0);
+       if (!irq)
+               goto default_map;
+
+       return irq;
+
+default_map:
+
+       return irq_create_mapping(NULL, DEFAULT_CORE_TIMER_INTERRUPT);
+}
+
+unsigned int get_c0_compare_int(void)
+{
+       return pic32_xlate_core_timer_irq();
+}
+
+void __init plat_time_init(void)
+{
+       struct clk *clk;
+
+       of_clk_init(NULL);
+       clk = clk_get_sys("cpu_clk", NULL);
+       if (IS_ERR(clk))
+               panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
+
+       clk_prepare_enable(clk);
+       pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
+       mips_hpt_frequency = clk_get_rate(clk) / 2;
+
+       clocksource_probe();
+}
index e9bc8c9..813826a 100644 (file)
@@ -12,6 +12,11 @@ config RALINK_ILL_ACC
        depends on SOC_RT305X
        default y
 
+config IRQ_INTC
+       bool
+       default y
+       depends on !SOC_MT7621
+
 choice
        prompt "Ralink SoC selection"
        default SOC_RT305X
@@ -33,7 +38,18 @@ choice
 
        config SOC_MT7620
                bool "MT7620/8"
+               select HW_HAS_PCI
 
+       config SOC_MT7621
+               bool "MT7621"
+               select MIPS_CPU_SCACHE
+               select SYS_SUPPORTS_MULTITHREADING
+               select SYS_SUPPORTS_SMP
+               select SYS_SUPPORTS_MIPS_CPS
+               select MIPS_GIC
+               select COMMON_CLK
+               select CLKSRC_MIPS_GIC
+               select HW_HAS_PCI
 endchoice
 
 choice
index a6c9d00..0d1795a 100644 (file)
@@ -6,16 +6,24 @@
 # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
 # Copyright (C) 2013 John Crispin <blogic@openwrt.org>
 
-obj-y := prom.o of.o reset.o clk.o irq.o timer.o
+obj-y := prom.o of.o reset.o
+
+ifndef CONFIG_MIPS_GIC
+       obj-y += clk.o timer.o
+endif
 
 obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
 
 obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
 
+obj-$(CONFIG_IRQ_INTC) += irq.o
+obj-$(CONFIG_MIPS_GIC) += irq-gic.o timer-gic.o
+
 obj-$(CONFIG_SOC_RT288X) += rt288x.o
 obj-$(CONFIG_SOC_RT305X) += rt305x.o
 obj-$(CONFIG_SOC_RT3883) += rt3883.o
 obj-$(CONFIG_SOC_MT7620) += mt7620.o
+obj-$(CONFIG_SOC_MT7621) += mt7621.o
 
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 
index 6d9c8c4..6095fcc 100644 (file)
@@ -27,3 +27,8 @@ cflags-$(CONFIG_SOC_RT3883)   += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt
 #
 load-$(CONFIG_SOC_MT7620)      += 0xffffffff80000000
 cflags-$(CONFIG_SOC_MT7620)    += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7620
+
+# Ralink MT7621
+#
+load-$(CONFIG_SOC_MT7621)      += 0xffffffff80001000
+cflags-$(CONFIG_SOC_MT7621)    += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7621
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c
new file mode 100644 (file)
index 0000000..50d6c55
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+
+#include <linux/of.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/mips-gic.h>
+
+int get_c0_perfcount_int(void)
+{
+       return gic_get_c0_perfcount_int();
+}
+EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+
+void __init arch_init_irq(void)
+{
+       irqchip_init();
+}
index dfb04fc..0d3d1a9 100644 (file)
@@ -107,31 +107,31 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
 };
 
 static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
-       FUNC("sdcx", 3, 19, 1),
+       FUNC("sdxc d6", 3, 19, 1),
        FUNC("utif", 2, 19, 1),
        FUNC("gpio", 1, 19, 1),
-       FUNC("pwm", 0, 19, 1),
+       FUNC("pwm1", 0, 19, 1),
 };
 
 static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
-       FUNC("sdcx", 3, 18, 1),
+       FUNC("sdxc d7", 3, 18, 1),
        FUNC("utif", 2, 18, 1),
        FUNC("gpio", 1, 18, 1),
-       FUNC("pwm", 0, 18, 1),
+       FUNC("pwm0", 0, 18, 1),
 };
 
 static struct rt2880_pmx_func uart2_grp_mt7628[] = {
-       FUNC("sdcx", 3, 20, 2),
+       FUNC("sdxc d5 d4", 3, 20, 2),
        FUNC("pwm", 2, 20, 2),
        FUNC("gpio", 1, 20, 2),
-       FUNC("uart", 0, 20, 2),
+       FUNC("uart2", 0, 20, 2),
 };
 
 static struct rt2880_pmx_func uart1_grp_mt7628[] = {
-       FUNC("sdcx", 3, 45, 2),
+       FUNC("sw_r", 3, 45, 2),
        FUNC("pwm", 2, 45, 2),
        FUNC("gpio", 1, 45, 2),
-       FUNC("uart", 0, 45, 2),
+       FUNC("uart1", 0, 45, 2),
 };
 
 static struct rt2880_pmx_func i2c_grp_mt7628[] = {
@@ -143,21 +143,21 @@ static struct rt2880_pmx_func i2c_grp_mt7628[] = {
 
 static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
 static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
-static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) };
+static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };
 static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
 
 static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
        FUNC("jtag", 3, 22, 8),
        FUNC("utif", 2, 22, 8),
        FUNC("gpio", 1, 22, 8),
-       FUNC("sdcx", 0, 22, 8),
+       FUNC("sdxc", 0, 22, 8),
 };
 
 static struct rt2880_pmx_func uart0_grp_mt7628[] = {
        FUNC("-", 3, 12, 2),
        FUNC("-", 2, 12, 2),
        FUNC("gpio", 1, 12, 2),
-       FUNC("uart", 0, 12, 2),
+       FUNC("uart0", 0, 12, 2),
 };
 
 static struct rt2880_pmx_func i2s_grp_mt7628[] = {
@@ -171,7 +171,7 @@ static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
        FUNC("-", 3, 6, 1),
        FUNC("refclk", 2, 6, 1),
        FUNC("gpio", 1, 6, 1),
-       FUNC("spi", 0, 6, 1),
+       FUNC("spi cs1", 0, 6, 1),
 };
 
 static struct rt2880_pmx_func spis_grp_mt7628[] = {
@@ -188,28 +188,44 @@ static struct rt2880_pmx_func gpio_grp_mt7628[] = {
        FUNC("gpio", 0, 11, 1),
 };
 
-#define MT7628_GPIO_MODE_MASK  0x3
-
-#define MT7628_GPIO_MODE_PWM1  30
-#define MT7628_GPIO_MODE_PWM0  28
-#define MT7628_GPIO_MODE_UART2 26
-#define MT7628_GPIO_MODE_UART1 24
-#define MT7628_GPIO_MODE_I2C   20
-#define MT7628_GPIO_MODE_REFCLK        18
-#define MT7628_GPIO_MODE_PERST 16
-#define MT7628_GPIO_MODE_WDT   14
-#define MT7628_GPIO_MODE_SPI   12
-#define MT7628_GPIO_MODE_SDMODE        10
-#define MT7628_GPIO_MODE_UART0 8
-#define MT7628_GPIO_MODE_I2S   6
-#define MT7628_GPIO_MODE_CS1   4
-#define MT7628_GPIO_MODE_SPIS  2
-#define MT7628_GPIO_MODE_GPIO  0
+static struct rt2880_pmx_func wled_kn_grp_mt7628[] = {
+       FUNC("rsvd", 3, 35, 1),
+       FUNC("rsvd", 2, 35, 1),
+       FUNC("gpio", 1, 35, 1),
+       FUNC("wled_kn", 0, 35, 1),
+};
+
+static struct rt2880_pmx_func wled_an_grp_mt7628[] = {
+       FUNC("rsvd", 3, 35, 1),
+       FUNC("rsvd", 2, 35, 1),
+       FUNC("gpio", 1, 35, 1),
+       FUNC("wled_an", 0, 35, 1),
+};
+
+#define MT7628_GPIO_MODE_MASK          0x3
+
+#define MT7628_GPIO_MODE_WLED_KN       48
+#define MT7628_GPIO_MODE_WLED_AN       32
+#define MT7628_GPIO_MODE_PWM1          30
+#define MT7628_GPIO_MODE_PWM0          28
+#define MT7628_GPIO_MODE_UART2         26
+#define MT7628_GPIO_MODE_UART1         24
+#define MT7628_GPIO_MODE_I2C           20
+#define MT7628_GPIO_MODE_REFCLK                18
+#define MT7628_GPIO_MODE_PERST         16
+#define MT7628_GPIO_MODE_WDT           14
+#define MT7628_GPIO_MODE_SPI           12
+#define MT7628_GPIO_MODE_SDMODE                10
+#define MT7628_GPIO_MODE_UART0         8
+#define MT7628_GPIO_MODE_I2S           6
+#define MT7628_GPIO_MODE_CS1           4
+#define MT7628_GPIO_MODE_SPIS          2
+#define MT7628_GPIO_MODE_GPIO          0
 
 static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
        GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,
                                1, MT7628_GPIO_MODE_PWM1),
-       GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
+       GRP_G("pmw0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
                                1, MT7628_GPIO_MODE_PWM0),
        GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,
                                1, MT7628_GPIO_MODE_UART2),
@@ -233,6 +249,10 @@ static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
                                1, MT7628_GPIO_MODE_SPIS),
        GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,
                                1, MT7628_GPIO_MODE_GPIO),
+       GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+                               1, MT7628_GPIO_MODE_WLED_AN),
+       GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+                               1, MT7628_GPIO_MODE_WLED_KN),
        { 0 }
 };
 
@@ -436,10 +456,13 @@ void __init ralink_clk_init(void)
        ralink_clk_add("10000100.timer", periph_rate);
        ralink_clk_add("10000120.watchdog", periph_rate);
        ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000b40.spi", sys_rate);
        ralink_clk_add("10000c00.uartlite", periph_rate);
+       ralink_clk_add("10000d00.uart1", periph_rate);
+       ralink_clk_add("10000e00.uart2", periph_rate);
        ralink_clk_add("10180000.wmac", xtal_rate);
 
-       if (IS_ENABLED(CONFIG_USB) && is_mt76x8()) {
+       if (IS_ENABLED(CONFIG_USB) && !is_mt76x8()) {
                /*
                 * When the CPU goes into sleep mode, the BUS clock will be
                 * too low for USB to function properly. Adjust the busses
@@ -552,7 +575,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
        }
 
        snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
-               "Ralink %s ver:%u eco:%u",
+               "MediaTek %s ver:%u eco:%u",
                name,
                (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
                (rev & CHIP_REV_ECO_MASK));
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
new file mode 100644 (file)
index 0000000..e9b9fa3
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/smp-ops.h>
+#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/mt7621.h>
+
+#include <pinmux.h>
+
+#include "common.h"
+
+#define SYSC_REG_SYSCFG                0x10
+#define SYSC_REG_CPLL_CLKCFG0  0x2c
+#define SYSC_REG_CUR_CLK_STS   0x44
+#define CPU_CLK_SEL            (BIT(30) | BIT(31))
+
+#define MT7621_GPIO_MODE_UART1         1
+#define MT7621_GPIO_MODE_I2C           2
+#define MT7621_GPIO_MODE_UART3_MASK    0x3
+#define MT7621_GPIO_MODE_UART3_SHIFT   3
+#define MT7621_GPIO_MODE_UART3_GPIO    1
+#define MT7621_GPIO_MODE_UART2_MASK    0x3
+#define MT7621_GPIO_MODE_UART2_SHIFT   5
+#define MT7621_GPIO_MODE_UART2_GPIO    1
+#define MT7621_GPIO_MODE_JTAG          7
+#define MT7621_GPIO_MODE_WDT_MASK      0x3
+#define MT7621_GPIO_MODE_WDT_SHIFT     8
+#define MT7621_GPIO_MODE_WDT_GPIO      1
+#define MT7621_GPIO_MODE_PCIE_RST      0
+#define MT7621_GPIO_MODE_PCIE_REF      2
+#define MT7621_GPIO_MODE_PCIE_MASK     0x3
+#define MT7621_GPIO_MODE_PCIE_SHIFT    10
+#define MT7621_GPIO_MODE_PCIE_GPIO     1
+#define MT7621_GPIO_MODE_MDIO_MASK     0x3
+#define MT7621_GPIO_MODE_MDIO_SHIFT    12
+#define MT7621_GPIO_MODE_MDIO_GPIO     1
+#define MT7621_GPIO_MODE_RGMII1                14
+#define MT7621_GPIO_MODE_RGMII2                15
+#define MT7621_GPIO_MODE_SPI_MASK      0x3
+#define MT7621_GPIO_MODE_SPI_SHIFT     16
+#define MT7621_GPIO_MODE_SPI_GPIO      1
+#define MT7621_GPIO_MODE_SDHCI_MASK    0x3
+#define MT7621_GPIO_MODE_SDHCI_SHIFT   18
+#define MT7621_GPIO_MODE_SDHCI_GPIO    1
+
+static struct rt2880_pmx_func uart1_grp[] =  { FUNC("uart1", 0, 1, 2) };
+static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 3, 2) };
+static struct rt2880_pmx_func uart3_grp[] = {
+       FUNC("uart3", 0, 5, 4),
+       FUNC("i2s", 2, 5, 4),
+       FUNC("spdif3", 3, 5, 4),
+};
+static struct rt2880_pmx_func uart2_grp[] = {
+       FUNC("uart2", 0, 9, 4),
+       FUNC("pcm", 2, 9, 4),
+       FUNC("spdif2", 3, 9, 4),
+};
+static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
+static struct rt2880_pmx_func wdt_grp[] = {
+       FUNC("wdt rst", 0, 18, 1),
+       FUNC("wdt refclk", 2, 18, 1),
+};
+static struct rt2880_pmx_func pcie_rst_grp[] = {
+       FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1),
+       FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1)
+};
+static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
+static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
+static struct rt2880_pmx_func spi_grp[] = {
+       FUNC("spi", 0, 34, 7),
+       FUNC("nand1", 2, 34, 7),
+};
+static struct rt2880_pmx_func sdhci_grp[] = {
+       FUNC("sdhci", 0, 41, 8),
+       FUNC("nand2", 2, 41, 8),
+};
+static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
+
+static struct rt2880_pmx_group mt7621_pinmux_data[] = {
+       GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1),
+       GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C),
+       GRP_G("uart3", uart3_grp, MT7621_GPIO_MODE_UART3_MASK,
+               MT7621_GPIO_MODE_UART3_GPIO, MT7621_GPIO_MODE_UART3_SHIFT),
+       GRP_G("uart2", uart2_grp, MT7621_GPIO_MODE_UART2_MASK,
+               MT7621_GPIO_MODE_UART2_GPIO, MT7621_GPIO_MODE_UART2_SHIFT),
+       GRP("jtag", jtag_grp, 1, MT7621_GPIO_MODE_JTAG),
+       GRP_G("wdt", wdt_grp, MT7621_GPIO_MODE_WDT_MASK,
+               MT7621_GPIO_MODE_WDT_GPIO, MT7621_GPIO_MODE_WDT_SHIFT),
+       GRP_G("pcie", pcie_rst_grp, MT7621_GPIO_MODE_PCIE_MASK,
+               MT7621_GPIO_MODE_PCIE_GPIO, MT7621_GPIO_MODE_PCIE_SHIFT),
+       GRP_G("mdio", mdio_grp, MT7621_GPIO_MODE_MDIO_MASK,
+               MT7621_GPIO_MODE_MDIO_GPIO, MT7621_GPIO_MODE_MDIO_SHIFT),
+       GRP("rgmii2", rgmii2_grp, 1, MT7621_GPIO_MODE_RGMII2),
+       GRP_G("spi", spi_grp, MT7621_GPIO_MODE_SPI_MASK,
+               MT7621_GPIO_MODE_SPI_GPIO, MT7621_GPIO_MODE_SPI_SHIFT),
+       GRP_G("sdhci", sdhci_grp, MT7621_GPIO_MODE_SDHCI_MASK,
+               MT7621_GPIO_MODE_SDHCI_GPIO, MT7621_GPIO_MODE_SDHCI_SHIFT),
+       GRP("rgmii1", rgmii1_grp, 1, MT7621_GPIO_MODE_RGMII1),
+       { 0 }
+};
+
+phys_addr_t mips_cpc_default_phys_base(void)
+{
+       panic("Cannot detect cpc address");
+}
+
+void __init ralink_clk_init(void)
+{
+       int cpu_fdiv = 0;
+       int cpu_ffrac = 0;
+       int fbdiv = 0;
+       u32 clk_sts, syscfg;
+       u8 clk_sel = 0, xtal_mode;
+       u32 cpu_clk;
+
+       if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
+               clk_sel = 1;
+
+       switch (clk_sel) {
+       case 0:
+               clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+               cpu_fdiv = ((clk_sts >> 8) & 0x1F);
+               cpu_ffrac = (clk_sts & 0x1F);
+               cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
+               break;
+
+       case 1:
+               fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
+               syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
+               xtal_mode = (syscfg >> 6) & 0x7;
+               if (xtal_mode >= 6) {
+                       /* 25Mhz Xtal */
+                       cpu_clk = 25 * fbdiv * 1000 * 1000;
+               } else if (xtal_mode >= 3) {
+                       /* 40Mhz Xtal */
+                       cpu_clk = 40 * fbdiv * 1000 * 1000;
+               } else {
+                       /* 20Mhz Xtal */
+                       cpu_clk = 20 * fbdiv * 1000 * 1000;
+               }
+               break;
+       }
+}
+
+void __init ralink_of_remap(void)
+{
+       rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
+       rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc");
+
+       if (!rt_sysc_membase || !rt_memc_membase)
+               panic("Failed to remap core resources");
+}
+
+void prom_soc_init(struct ralink_soc_info *soc_info)
+{
+       void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+       unsigned char *name = NULL;
+       u32 n0;
+       u32 n1;
+       u32 rev;
+
+       n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+       n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+
+       if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
+               name = "MT7621";
+               soc_info->compatible = "mtk,mt7621-soc";
+       } else {
+               panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+       }
+
+       rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+
+       snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+               "MediaTek %s ver:%u eco:%u",
+               name,
+               (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
+               (rev & CHIP_REV_ECO_MASK));
+
+       soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
+       soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
+       soc_info->mem_base = MT7621_DRAM_BASE;
+
+       rt2880_pinmux_data = mt7621_pinmux_data;
+
+       /* Early detection of CMP support */
+       mips_cm_probe();
+       mips_cpc_probe();
+
+       if (mips_cm_numiocu()) {
+               /*
+                * mips_cm_probe() wipes out bootloader
+                * config for CM regions and we have to configure them
+                * again. This SoC cannot talk to pamlbus devices
+                * witout proper iocu region set up.
+                *
+                * FIXME: it would be better to do this with values
+                * from DT, but we need this very early because
+                * without this we cannot talk to pretty much anything
+                * including serial.
+                */
+               write_gcr_reg0_base(MT7621_PALMBUS_BASE);
+               write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
+                                   CM_GCR_REGn_MASK_CMTGT_IOCU0);
+       }
+
+       if (!register_cps_smp_ops())
+               return;
+       if (!register_cmp_smp_ops())
+               return;
+       if (!register_vsmp_smp_ops())
+               return;
+}
index 844f5cd..3c84166 100644 (file)
@@ -119,5 +119,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
        soc_info->mem_size_max = RT2880_MEM_SIZE_MAX;
 
        rt2880_pinmux_data = rt2880_pinmux_data_act;
-       ralink_soc == RT2880_SOC;
+       ralink_soc = RT2880_SOC;
 }
index 9e45725..d7c4ba4 100644 (file)
@@ -201,6 +201,7 @@ void __init ralink_clk_init(void)
        ralink_clk_add("cpu", cpu_rate);
        ralink_clk_add("sys", sys_rate);
        ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000b40.spi", sys_rate);
        ralink_clk_add("10000100.timer", wdt_rate);
        ralink_clk_add("10000120.watchdog", wdt_rate);
        ralink_clk_add("10000500.uart", uart_rate);
index 582995a..fafec94 100644 (file)
@@ -109,6 +109,7 @@ void __init ralink_clk_init(void)
        ralink_clk_add("10000120.watchdog", sys_rate);
        ralink_clk_add("10000500.uart", 40000000);
        ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000b40.spi", sys_rate);
        ralink_clk_add("10000c00.uartlite", 40000000);
        ralink_clk_add("10100000.ethernet", sys_rate);
        ralink_clk_add("10180000.wmac", 40000000);
diff --git a/arch/mips/ralink/timer-gic.c b/arch/mips/ralink/timer-gic.c
new file mode 100644 (file)
index 0000000..5b4f186
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+
+#include "common.h"
+
+void __init plat_time_init(void)
+{
+       ralink_of_remap();
+
+       of_clk_init(NULL);
+       clocksource_probe();
+}
index 650d5d3..fd11085 100644 (file)
@@ -89,7 +89,7 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset)
        struct rb532_gpio_chip  *gpch;
 
        gpch = container_of(chip, struct rb532_gpio_chip, chip);
-       return rb532_get_bit(offset, gpch->regbase + GPIOD);
+       return !!rb532_get_bit(offset, gpch->regbase + GPIOD);
 }
 
 /*
index 9d9962a..2fd350f 100644 (file)
@@ -689,7 +689,7 @@ static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
 {
        struct txx9_iocled_data *data =
                container_of(chip, struct txx9_iocled_data, chip);
-       return data->cur_val & (1 << offset);
+       return !!(data->cur_val & (1 << offset));
 }
 
 static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
index 78ae555..10607f0 100644 (file)
@@ -14,6 +14,7 @@ config MN10300
        select OLD_SIGSUSPEND3
        select OLD_SIGACTION
        select HAVE_DEBUG_STACKOVERFLOW
+       select ARCH_NO_COHERENT_DMA_MMAP
 
 config AM33_2
        def_bool n
index a18abfc..1dcd447 100644 (file)
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
 
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-
 #include <asm/cache.h>
 #include <asm/io.h>
 
-/*
- * See Documentation/DMA-API.txt for the description of how the
- * following DMA API should work.
- */
-
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
-                               dma_addr_t *dma_handle, int flag);
-
-extern void dma_free_coherent(struct device *dev, size_t size,
-                             void *vaddr, dma_addr_t dma_handle);
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
-#define dma_free_noncoherent(d, s, v, h)  dma_free_coherent((d), (s), (v), (h))
-
-static inline
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-                         enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       mn10300_dcache_flush_inv();
-       return virt_to_bus(ptr);
-}
-
-static inline
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                     enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-static inline
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-              enum dma_data_direction direction)
-{
-       struct scatterlist *sg;
-       int i;
-
-       BUG_ON(!valid_dma_direction(direction));
-       WARN_ON(nents == 0 || sglist[0].length == 0);
-
-       for_each_sg(sglist, sg, nents, i) {
-               BUG_ON(!sg_page(sg));
-
-               sg->dma_address = sg_phys(sg);
-       }
+extern struct dma_map_ops mn10300_dma_ops;
 
-       mn10300_dcache_flush_inv();
-       return nents;
-}
-
-static inline
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-                 enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-}
-
-static inline
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-                       unsigned long offset, size_t size,
-                       enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       return page_to_bus(page) + offset;
-}
-
-static inline
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-                   enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-static inline
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                            size_t size, enum dma_data_direction direction)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-}
-
-static inline
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-                               size_t size, enum dma_data_direction direction)
-{
-       mn10300_dcache_flush_inv();
-}
-
-static inline
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                                  unsigned long offset, size_t size,
-                                  enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
-{
-       mn10300_dcache_flush_inv();
-}
-
-
-static inline
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-                        int nelems, enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-                           int nelems, enum dma_data_direction direction)
-{
-       mn10300_dcache_flush_inv();
-}
-
-static inline
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-static inline
-int dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s, so we can't
-        * guarantee allocations that must be within a tighter range than
-        * GFP_DMA
-        */
-       if (mask < 0x00ffffff)
-               return 0;
-       return 1;
-}
-
-static inline
-int dma_set_mask(struct device *dev, u64 mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-       return 0;
+       return &mn10300_dma_ops;
 }
 
 static inline
@@ -168,19 +28,4 @@ void dma_cache_sync(void *vaddr, size_t size,
        mn10300_dcache_flush_inv();
 }
 
-/* Not supported for now */
-static inline int dma_mmap_coherent(struct device *dev,
-                                   struct vm_area_struct *vma, void *cpu_addr,
-                                   dma_addr_t dma_addr, size_t size)
-{
-       return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size)
-{
-       return -EINVAL;
-}
-
 #endif
index e244ebe..8842394 100644 (file)
@@ -20,8 +20,8 @@
 
 static unsigned long pci_sram_allocated = 0xbc000000;
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *dma_handle, int gfp)
+static void *mn10300_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
        unsigned long addr;
        void *ret;
@@ -61,10 +61,9 @@ done:
        printk("dma_alloc_coherent() = %p [%x]\n", ret, *dma_handle);
        return ret;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-                      dma_addr_t dma_handle)
+static void mn10300_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        unsigned long addr = (unsigned long) vaddr & ~0x20000000;
 
@@ -73,4 +72,60 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
 
        free_pages(addr, get_order(size));
 }
-EXPORT_SYMBOL(dma_free_coherent);
+
+static int mn10300_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sglist, sg, nents, i) {
+               BUG_ON(!sg_page(sg));
+
+               sg->dma_address = sg_phys(sg);
+       }
+
+       mn10300_dcache_flush_inv();
+       return nents;
+}
+
+static dma_addr_t mn10300_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+       return page_to_bus(page) + offset;
+}
+
+static void mn10300_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+                               size_t size, enum dma_data_direction direction)
+{
+       mn10300_dcache_flush_inv();
+}
+
+static void mn10300_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+                           int nelems, enum dma_data_direction direction)
+{
+       mn10300_dcache_flush_inv();
+}
+
+static int mn10300_dma_supported(struct device *dev, u64 mask)
+{
+       /*
+        * we fall back to GFP_DMA when the mask isn't all 1s, so we can't
+        * guarantee allocations that must be within a tighter range than
+        * GFP_DMA
+        */
+       if (mask < 0x00ffffff)
+               return 0;
+       return 1;
+}
+
+struct dma_map_ops mn10300_dma_ops = {
+       .alloc                  = mn10300_dma_alloc,
+       .free                   = mn10300_dma_free,
+       .map_page               = mn10300_dma_map_page,
+       .map_sg                 = mn10300_dma_map_sg,
+       .sync_single_for_device = mn10300_dma_sync_single_for_device,
+       .sync_sg_for_device     = mn10300_dma_sync_sg_for_device,
+};
index b556723..bec8ac8 100644 (file)
 #ifndef _ASM_NIOS2_DMA_MAPPING_H
 #define _ASM_NIOS2_DMA_MAPPING_H
 
-#include <linux/scatterlist.h>
-#include <linux/cache.h>
-#include <asm/cacheflush.h>
+extern struct dma_map_ops nios2_dma_ops;
 
-static inline void __dma_sync_for_device(void *vaddr, size_t size,
-                             enum dma_data_direction direction)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       switch (direction) {
-       case DMA_FROM_DEVICE:
-               invalidate_dcache_range((unsigned long)vaddr,
-                       (unsigned long)(vaddr + size));
-               break;
-       case DMA_TO_DEVICE:
-               /*
-                * We just need to flush the caches here , but Nios2 flush
-                * instruction will do both writeback and invalidate.
-                */
-       case DMA_BIDIRECTIONAL: /* flush and invalidate */
-               flush_dcache_range((unsigned long)vaddr,
-                       (unsigned long)(vaddr + size));
-               break;
-       default:
-               BUG();
-       }
-}
-
-static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
-                             enum dma_data_direction direction)
-{
-       switch (direction) {
-       case DMA_BIDIRECTIONAL:
-       case DMA_FROM_DEVICE:
-               invalidate_dcache_range((unsigned long)vaddr,
-                       (unsigned long)(vaddr + size));
-               break;
-       case DMA_TO_DEVICE:
-               break;
-       default:
-               BUG();
-       }
-}
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle);
-
-static inline dma_addr_t dma_map_single(struct device *dev, void *ptr,
-                                       size_t size,
-                                       enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-       __dma_sync_for_device(ptr, size, direction);
-       return virt_to_phys(ptr);
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-                               size_t size, enum dma_data_direction direction)
-{
-}
-
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction);
-extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-       size_t size, enum dma_data_direction direction);
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-       int nhwentries, enum dma_data_direction direction);
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_for_device(struct device *dev,
-       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_range_for_cpu(struct device *dev,
-       dma_addr_t dma_handle, unsigned long offset, size_t size,
-       enum dma_data_direction direction);
-extern void dma_sync_single_range_for_device(struct device *dev,
-       dma_addr_t dma_handle, unsigned long offset, size_t size,
-       enum dma_data_direction direction);
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-       int nelems, enum dma_data_direction direction);
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-       int nelems, enum dma_data_direction direction);
-
-static inline int dma_supported(struct device *dev, u64 mask)
-{
-       return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-
-       return 0;
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
+       return &nios2_dma_ops;
 }
 
 /*
-* dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to
-* do any flushing here.
-*/
+ * dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to
+ * do any flushing here.
+ */
 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                                  enum dma_data_direction direction)
 {
 }
 
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-               void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-               void *cpu_addr, dma_addr_t dma_addr,
-               size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
 #endif /* _ASM_NIOS2_DMA_MAPPING_H */
index ac5da75..90422c3 100644 (file)
 #include <linux/cache.h>
 #include <asm/cacheflush.h>
 
+static inline void __dma_sync_for_device(void *vaddr, size_t size,
+                             enum dma_data_direction direction)
+{
+       switch (direction) {
+       case DMA_FROM_DEVICE:
+               invalidate_dcache_range((unsigned long)vaddr,
+                       (unsigned long)(vaddr + size));
+               break;
+       case DMA_TO_DEVICE:
+               /*
+                * We just need to flush the caches here , but Nios2 flush
+                * instruction will do both writeback and invalidate.
+                */
+       case DMA_BIDIRECTIONAL: /* flush and invalidate */
+               flush_dcache_range((unsigned long)vaddr,
+                       (unsigned long)(vaddr + size));
+               break;
+       default:
+               BUG();
+       }
+}
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                           dma_addr_t *dma_handle, gfp_t gfp)
+static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
+                             enum dma_data_direction direction)
+{
+       switch (direction) {
+       case DMA_BIDIRECTIONAL:
+       case DMA_FROM_DEVICE:
+               invalidate_dcache_range((unsigned long)vaddr,
+                       (unsigned long)(vaddr + size));
+               break;
+       case DMA_TO_DEVICE:
+               break;
+       default:
+               BUG();
+       }
+}
+
+static void *nios2_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
        void *ret;
 
@@ -45,24 +82,21 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 
        return ret;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-                       dma_addr_t dma_handle)
+static void nios2_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        unsigned long addr = (unsigned long) CAC_ADDR((unsigned long) vaddr);
 
        free_pages(addr, get_order(size));
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-               enum dma_data_direction direction)
+static int nios2_dma_map_sg(struct device *dev, struct scatterlist *sg,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        int i;
 
-       BUG_ON(!valid_dma_direction(direction));
-
        for_each_sg(sg, sg, nents, i) {
                void *addr;
 
@@ -75,40 +109,32 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 
        return nents;
 }
-EXPORT_SYMBOL(dma_map_sg);
 
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
+static dma_addr_t nios2_dma_map_page(struct device *dev, struct page *page,
                        unsigned long offset, size_t size,
-                       enum dma_data_direction direction)
+                       enum dma_data_direction direction,
+                       struct dma_attrs *attrs)
 {
-       void *addr;
-
-       BUG_ON(!valid_dma_direction(direction));
+       void *addr = page_address(page) + offset;
 
-       addr = page_address(page) + offset;
        __dma_sync_for_device(addr, size, direction);
-
        return page_to_phys(page) + offset;
 }
-EXPORT_SYMBOL(dma_map_page);
 
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-                   enum dma_data_direction direction)
+static void nios2_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+               size_t size, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
-       BUG_ON(!valid_dma_direction(direction));
-
        __dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
 }
-EXPORT_SYMBOL(dma_unmap_page);
 
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-                 enum dma_data_direction direction)
+static void nios2_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+               int nhwentries, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        void *addr;
        int i;
 
-       BUG_ON(!valid_dma_direction(direction));
-
        if (direction == DMA_TO_DEVICE)
                return;
 
@@ -118,69 +144,54 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
                        __dma_sync_for_cpu(addr, sg->length, direction);
        }
 }
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                            size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
 
-       __dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
-}
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-                               size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(!valid_dma_direction(direction));
-
-       __dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
-}
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                                       unsigned long offset, size_t size,
-                                       enum dma_data_direction direction)
+static void nios2_dma_sync_single_for_cpu(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
 {
-       BUG_ON(!valid_dma_direction(direction));
-
        __dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
 }
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
 
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                       unsigned long offset, size_t size,
-                                       enum dma_data_direction direction)
+static void nios2_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
 {
-       BUG_ON(!valid_dma_direction(direction));
-
        __dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
 }
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
 
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                        enum dma_data_direction direction)
+static void nios2_dma_sync_sg_for_cpu(struct device *dev,
+               struct scatterlist *sg, int nelems,
+               enum dma_data_direction direction)
 {
        int i;
 
-       BUG_ON(!valid_dma_direction(direction));
-
        /* Make sure that gcc doesn't leave the empty loop body.  */
        for_each_sg(sg, sg, nelems, i)
                __dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
 }
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
 
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-                               int nelems, enum dma_data_direction direction)
+static void nios2_dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sg, int nelems,
+               enum dma_data_direction direction)
 {
        int i;
 
-       BUG_ON(!valid_dma_direction(direction));
-
        /* Make sure that gcc doesn't leave the empty loop body.  */
        for_each_sg(sg, sg, nelems, i)
                __dma_sync_for_device(sg_virt(sg), sg->length, direction);
 
 }
-EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+struct dma_map_ops nios2_dma_ops = {
+       .alloc                  = nios2_dma_alloc,
+       .free                   = nios2_dma_free,
+       .map_page               = nios2_dma_map_page,
+       .unmap_page             = nios2_dma_unmap_page,
+       .map_sg                 = nios2_dma_map_sg,
+       .unmap_sg               = nios2_dma_unmap_sg,
+       .sync_single_for_device = nios2_dma_sync_single_for_device,
+       .sync_single_for_cpu    = nios2_dma_sync_single_for_cpu,
+       .sync_sg_for_cpu        = nios2_dma_sync_sg_for_cpu,
+       .sync_sg_for_device     = nios2_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(nios2_dma_ops);
index 443f44d..e118c02 100644 (file)
@@ -29,9 +29,6 @@ config OPENRISC
 config MMU
        def_bool y
 
-config HAVE_DMA_ATTRS
-       def_bool y
-
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
index 413bfcf..1f260bc 100644 (file)
@@ -42,6 +42,4 @@ static inline int dma_supported(struct device *dev, u64 dma_mask)
        return dma_mask == DMA_BIT_MASK(32);
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 #endif /* __ASM_OPENRISC_DMA_MAPPING_H */
index 7c34caf..14f655c 100644 (file)
@@ -29,6 +29,7 @@ config PARISC
        select TTY # Needed for pdc_cons.c
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_ARCH_AUDITSYSCALL
+       select ARCH_NO_COHERENT_DMA_MMAP
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
index d8d60a5..16e0246 100644 (file)
@@ -1,30 +1,11 @@
 #ifndef _PARISC_DMA_MAPPING_H
 #define _PARISC_DMA_MAPPING_H
 
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
 #include <asm/cacheflush.h>
 
-/* See Documentation/DMA-API-HOWTO.txt */
-struct hppa_dma_ops {
-       int  (*dma_supported)(struct device *dev, u64 mask);
-       void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
-       void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
-       void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
-       dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
-       void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
-       int  (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction);
-       void (*unmap_sg)(struct device *dev, struct scatterlist *sg, int nhwents, enum dma_data_direction direction);
-       void (*dma_sync_single_for_cpu)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
-       void (*dma_sync_single_for_device)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
-       void (*dma_sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
-       void (*dma_sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
-};
-
 /*
-** We could live without the hppa_dma_ops indirection if we didn't want
-** to support 4 different coherent dma models with one binary (they will
-** someday be loadable modules):
+** We need to support 4 different coherent dma models with one binary:
+**
 **     I/O MMU        consistent method           dma_sync behavior
 **  =============   ======================       =======================
 **  a) PA-7x00LC    uncachable host memory          flush/purge
@@ -40,158 +21,22 @@ struct hppa_dma_ops {
 */
 
 #ifdef CONFIG_PA11
-extern struct hppa_dma_ops pcxl_dma_ops;
-extern struct hppa_dma_ops pcx_dma_ops;
+extern struct dma_map_ops pcxl_dma_ops;
+extern struct dma_map_ops pcx_dma_ops;
 #endif
 
-extern struct hppa_dma_ops *hppa_dma_ops;
-
-#define dma_alloc_attrs(d, s, h, f, a) dma_alloc_coherent(d, s, h, f)
-#define dma_free_attrs(d, s, h, f, a) dma_free_coherent(d, s, h, f)
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-                  gfp_t flag)
-{
-       return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
-}
-
-static inline void *
-dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-                     gfp_t flag)
-{
-       return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, 
-                   void *vaddr, dma_addr_t dma_handle)
-{
-       hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
-}
-
-static inline void
-dma_free_noncoherent(struct device *dev, size_t size, 
-                   void *vaddr, dma_addr_t dma_handle)
-{
-       hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
-}
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-              enum dma_data_direction direction)
-{
-       return hppa_dma_ops->map_single(dev, ptr, size, direction);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction)
-{
-       hppa_dma_ops->unmap_single(dev, dma_addr, size, direction);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-          enum dma_data_direction direction)
-{
-       return hppa_dma_ops->map_sg(dev, sg, nents, direction);
-}
+extern struct dma_map_ops *hppa_dma_ops;
 
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction)
-{
-       hppa_dma_ops->unmap_sg(dev, sg, nhwentries, direction);
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-            size_t size, enum dma_data_direction direction)
-{
-       return dma_map_single(dev, (page_address(page) + (offset)), size, direction);
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-       dma_unmap_single(dev, dma_address, size, direction);
-}
-
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-               enum dma_data_direction direction)
-{
-       if(hppa_dma_ops->dma_sync_single_for_cpu)
-               hppa_dma_ops->dma_sync_single_for_cpu(dev, dma_handle, 0, size, direction);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-               enum dma_data_direction direction)
-{
-       if(hppa_dma_ops->dma_sync_single_for_device)
-               hppa_dma_ops->dma_sync_single_for_device(dev, dma_handle, 0, size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                     unsigned long offset, size_t size,
-                     enum dma_data_direction direction)
-{
-       if(hppa_dma_ops->dma_sync_single_for_cpu)
-               hppa_dma_ops->dma_sync_single_for_cpu(dev, dma_handle, offset, size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                     unsigned long offset, size_t size,
-                     enum dma_data_direction direction)
-{
-       if(hppa_dma_ops->dma_sync_single_for_device)
-               hppa_dma_ops->dma_sync_single_for_device(dev, dma_handle, offset, size, direction);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                enum dma_data_direction direction)
-{
-       if(hppa_dma_ops->dma_sync_sg_for_cpu)
-               hppa_dma_ops->dma_sync_sg_for_cpu(dev, sg, nelems, direction);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-                enum dma_data_direction direction)
-{
-       if(hppa_dma_ops->dma_sync_sg_for_device)
-               hppa_dma_ops->dma_sync_sg_for_device(dev, sg, nelems, direction);
-}
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
-       return hppa_dma_ops->dma_supported(dev, mask);
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
-       if(!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-
-       return 0;
+       return hppa_dma_ops;
 }
 
 static inline void
 dma_cache_sync(struct device *dev, void *vaddr, size_t size,
               enum dma_data_direction direction)
 {
-       if(hppa_dma_ops->dma_sync_single_for_cpu)
+       if (hppa_dma_ops->sync_single_for_cpu)
                flush_kernel_dcache_range((unsigned long)vaddr, size);
 }
 
@@ -238,22 +83,4 @@ struct parisc_device;
 void * sba_get_iommu(struct parisc_device *dev);
 #endif
 
-/* At the moment, we panic on error for IOMMU resource exaustion */
-#define dma_mapping_error(dev, x)      0
-
-/* This API cannot be supported on PA-RISC */
-static inline int dma_mmap_coherent(struct device *dev,
-                                   struct vm_area_struct *vma, void *cpu_addr,
-                                   dma_addr_t dma_addr, size_t size)
-{
-       return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
-                                 void *cpu_addr, dma_addr_t dma_addr,
-                                 size_t size)
-{
-       return -EINVAL;
-}
-
 #endif
index cf830d4..f3db7d8 100644 (file)
@@ -43,7 +43,6 @@
 #define MADV_SPACEAVAIL 5               /* insure that resources are reserved */
 #define MADV_VPS_PURGE  6               /* Purge pages from VM page cache */
 #define MADV_VPS_INHERIT 7              /* Inherit parents page size */
-#define MADV_FREE      8               /* free pages only if memory pressure */
 
 /* common/generic parameters */
 #define MADV_FREE      8               /* free pages only if memory pressure */
index dba508f..f815066 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/parisc-device.h>
 
 /* See comments in include/asm-parisc/pci.h */
-struct hppa_dma_ops *hppa_dma_ops __read_mostly;
+struct dma_map_ops *hppa_dma_ops __read_mostly;
 EXPORT_SYMBOL(hppa_dma_ops);
 
 static struct device root = {
index b9402c9..a27e492 100644 (file)
@@ -413,7 +413,8 @@ pcxl_dma_init(void)
 
 __initcall(pcxl_dma_init);
 
-static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
+static void *pa11_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
 {
        unsigned long vaddr;
        unsigned long paddr;
@@ -439,7 +440,8 @@ static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_ad
        return (void *)vaddr;
 }
 
-static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void pa11_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        int order;
 
@@ -450,15 +452,20 @@ static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vad
        free_pages((unsigned long)__va(dma_handle), order);
 }
 
-static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
+static dma_addr_t pa11_dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
 {
+       void *addr = page_address(page) + offset;
        BUG_ON(direction == DMA_NONE);
 
        flush_kernel_dcache_range((unsigned long) addr, size);
        return virt_to_phys(addr);
 }
 
-static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+static void pa11_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
+               size_t size, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        BUG_ON(direction == DMA_NONE);
 
@@ -475,7 +482,9 @@ static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, siz
        return;
 }
 
-static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
+static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        int i;
        struct scatterlist *sg;
@@ -492,7 +501,9 @@ static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int n
        return nents;
 }
 
-static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
+static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
+               int nents, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        int i;
        struct scatterlist *sg;
@@ -509,18 +520,24 @@ static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, in
        return;
 }
 
-static void pa11_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
+static void pa11_dma_sync_single_for_cpu(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
 {
        BUG_ON(direction == DMA_NONE);
 
-       flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
+       flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle),
+                       size);
 }
 
-static void pa11_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
+static void pa11_dma_sync_single_for_device(struct device *dev,
+               dma_addr_t dma_handle, size_t size,
+               enum dma_data_direction direction)
 {
        BUG_ON(direction == DMA_NONE);
 
-       flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
+       flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle),
+                       size);
 }
 
 static void pa11_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
@@ -545,32 +562,28 @@ static void pa11_dma_sync_sg_for_device(struct device *dev, struct scatterlist *
                flush_kernel_vmap_range(sg_virt(sg), sg->length);
 }
 
-struct hppa_dma_ops pcxl_dma_ops = {
+struct dma_map_ops pcxl_dma_ops = {
        .dma_supported =        pa11_dma_supported,
-       .alloc_consistent =     pa11_dma_alloc_consistent,
-       .alloc_noncoherent =    pa11_dma_alloc_consistent,
-       .free_consistent =      pa11_dma_free_consistent,
-       .map_single =           pa11_dma_map_single,
-       .unmap_single =         pa11_dma_unmap_single,
+       .alloc =                pa11_dma_alloc,
+       .free =                 pa11_dma_free,
+       .map_page =             pa11_dma_map_page,
+       .unmap_page =           pa11_dma_unmap_page,
        .map_sg =               pa11_dma_map_sg,
        .unmap_sg =             pa11_dma_unmap_sg,
-       .dma_sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
-       .dma_sync_single_for_device = pa11_dma_sync_single_for_device,
-       .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
-       .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+       .sync_single_for_cpu =  pa11_dma_sync_single_for_cpu,
+       .sync_single_for_device = pa11_dma_sync_single_for_device,
+       .sync_sg_for_cpu =      pa11_dma_sync_sg_for_cpu,
+       .sync_sg_for_device =   pa11_dma_sync_sg_for_device,
 };
 
-static void *fail_alloc_consistent(struct device *dev, size_t size,
-                                  dma_addr_t *dma_handle, gfp_t flag)
-{
-       return NULL;
-}
-
-static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
-                                         dma_addr_t *dma_handle, gfp_t flag)
+static void *pcx_dma_alloc(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
 {
        void *addr;
 
+       if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
+               return NULL;
+
        addr = (void *)__get_free_pages(flag, get_order(size));
        if (addr)
                *dma_handle = (dma_addr_t)virt_to_phys(addr);
@@ -578,24 +591,23 @@ static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
        return addr;
 }
 
-static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
-                                       void *vaddr, dma_addr_t iova)
+static void pcx_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t iova, struct dma_attrs *attrs)
 {
        free_pages((unsigned long)vaddr, get_order(size));
        return;
 }
 
-struct hppa_dma_ops pcx_dma_ops = {
+struct dma_map_ops pcx_dma_ops = {
        .dma_supported =        pa11_dma_supported,
-       .alloc_consistent =     fail_alloc_consistent,
-       .alloc_noncoherent =    pa11_dma_alloc_noncoherent,
-       .free_consistent =      pa11_dma_free_noncoherent,
-       .map_single =           pa11_dma_map_single,
-       .unmap_single =         pa11_dma_unmap_single,
+       .alloc =                pcx_dma_alloc,
+       .free =                 pcx_dma_free,
+       .map_page =             pa11_dma_map_page,
+       .unmap_page =           pa11_dma_unmap_page,
        .map_sg =               pa11_dma_map_sg,
        .unmap_sg =             pa11_dma_unmap_sg,
-       .dma_sync_single_for_cpu =      pa11_dma_sync_single_for_cpu,
-       .dma_sync_single_for_device =   pa11_dma_sync_single_for_device,
-       .dma_sync_sg_for_cpu =          pa11_dma_sync_sg_for_cpu,
-       .dma_sync_sg_for_device =       pa11_dma_sync_sg_for_device,
+       .sync_single_for_cpu =  pa11_dma_sync_single_for_cpu,
+       .sync_single_for_device = pa11_dma_sync_single_for_device,
+       .sync_sg_for_cpu =      pa11_dma_sync_sg_for_cpu,
+       .sync_sg_for_device =   pa11_dma_sync_sg_for_device,
 };
index 94f6c50..e4824fd 100644 (file)
@@ -108,7 +108,6 @@ config PPC
        select HAVE_ARCH_TRACEHOOK
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select HAVE_OPROFILE
        select HAVE_DEBUG_KMEMLEAK
@@ -158,6 +157,7 @@ config PPC
        select ARCH_HAS_DMA_SET_COHERENT_MASK
        select ARCH_HAS_DEVMEM_IS_ALLOWED
        select HAVE_ARCH_SECCOMP_FILTER
+       select ARCH_HAS_UBSAN_SANITIZE_ALL
 
 config GENERIC_CSUM
        def_bool CPU_LITTLE_ENDIAN
index 7f522c0..77816ac 100644 (file)
@@ -125,8 +125,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 #define HAVE_ARCH_DMA_SET_MASK 1
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
-#include <asm-generic/dma-mapping-common.h>
-
 extern int __dma_set_mask(struct device *dev, u64 dma_mask);
 extern u64 __dma_get_required_mask(struct device *dev);
 
index 493e72f..b4407d0 100644 (file)
@@ -191,7 +191,7 @@ struct fadump_crash_info_header {
        u64             elfcorehdr_addr;
        u32             crashing_cpu;
        struct pt_regs  regs;
-       struct cpumask  cpu_online_mask;
+       struct cpumask  online_mask;
 };
 
 /* Crash memory ranges */
index ba33693..794f22a 100644 (file)
@@ -136,12 +136,18 @@ endif
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)                += kvm.o kvm_emul.o
 
-# Disable GCOV in odd or sensitive code
+# Disable GCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
+UBSAN_SANITIZE_prom_init.o := n
 GCOV_PROFILE_ftrace.o := n
+UBSAN_SANITIZE_ftrace.o := n
 GCOV_PROFILE_machine_kexec_64.o := n
+UBSAN_SANITIZE_machine_kexec_64.o := n
 GCOV_PROFILE_machine_kexec_32.o := n
+UBSAN_SANITIZE_machine_kexec_32.o := n
 GCOV_PROFILE_kprobes.o := n
+UBSAN_SANITIZE_kprobes.o := n
+UBSAN_SANITIZE_vdso.o := n
 
 extra-$(CONFIG_PPC_FPU)                += fpu.o
 extra-$(CONFIG_ALTIVEC)                += vector.o
index 8d14feb..9387421 100644 (file)
@@ -400,7 +400,7 @@ static void *eeh_rmv_device(void *data, void *userdata)
         * support EEH. So we just care about PCI devices for
         * simplicity here.
         */
-       if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
+       if (!dev || (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE))
                return NULL;
 
        /*
index 26d091a..3cb3b02 100644 (file)
@@ -415,7 +415,7 @@ void crash_fadump(struct pt_regs *regs, const char *str)
        else
                ppc_save_regs(&fdh->regs);
 
-       fdh->cpu_online_mask = *cpu_online_mask;
+       fdh->online_mask = *cpu_online_mask;
 
        /* Call ibm,os-term rtas call to trigger firmware assisted dump */
        rtas_os_term((char *)str);
@@ -646,7 +646,7 @@ static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm)
                }
                /* Lower 4 bytes of reg_value contains logical cpu id */
                cpu = be64_to_cpu(reg_entry->reg_value) & FADUMP_CPU_ID_MASK;
-               if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) {
+               if (fdh && !cpumask_test_cpu(cpu, &fdh->online_mask)) {
                        SKIP_TO_NEXT_CPU(reg_entry);
                        continue;
                }
index 2e710c1..526ac67 100644 (file)
@@ -187,9 +187,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
 
        pci_device_add(dev, bus);
 
-       /* Setup MSI caps & disable MSI/MSI-X interrupts */
-       pci_msi_setup_pci_dev(dev);
-
        return dev;
 }
 EXPORT_SYMBOL(of_create_pci_dev);
index 6abffb7..cbabd14 100644 (file)
@@ -15,6 +15,7 @@ targets := $(obj-vdso32) vdso32.so vdso32.so.dbg
 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
 
 GCOV_PROFILE := n
+UBSAN_SANITIZE := n
 
 ccflags-y := -shared -fno-common -fno-builtin
 ccflags-y += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
index 8c8f2ae..c710802 100644 (file)
@@ -8,6 +8,7 @@ targets := $(obj-vdso64) vdso64.so vdso64.so.dbg
 obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
 
 GCOV_PROFILE := n
+UBSAN_SANITIZE := n
 
 ccflags-y := -shared -fno-common -fno-builtin
 ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
index 5038fd5..2936a00 100644 (file)
@@ -1799,9 +1799,9 @@ static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int data
        struct inode *inode = file_inode(file);
        int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (!err) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                err = spufs_mfc_flush(file, NULL);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        return err;
 }
index ad4840f..dfa8638 100644 (file)
@@ -163,7 +163,7 @@ static void spufs_prune_dir(struct dentry *dir)
 {
        struct dentry *dentry, *tmp;
 
-       mutex_lock(&d_inode(dir)->i_mutex);
+       inode_lock(d_inode(dir));
        list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
                spin_lock(&dentry->d_lock);
                if (simple_positive(dentry)) {
@@ -180,7 +180,7 @@ static void spufs_prune_dir(struct dentry *dir)
                }
        }
        shrink_dcache_parent(dir);
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 }
 
 /* Caller must hold parent->i_mutex */
@@ -225,9 +225,9 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
        parent = d_inode(dir->d_parent);
        ctx = SPUFS_I(d_inode(dir))->i_ctx;
 
-       mutex_lock_nested(&parent->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(parent, I_MUTEX_PARENT);
        ret = spufs_rmdir(parent, dir);
-       mutex_unlock(&parent->i_mutex);
+       inode_unlock(parent);
        WARN_ON(ret);
 
        return dcache_dir_close(inode, file);
@@ -270,7 +270,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        dget(dentry);
        inc_nlink(dir);
@@ -291,7 +291,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
        if (ret)
                spufs_rmdir(dir, dentry);
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
index 1278788..436062d 100644 (file)
@@ -3,6 +3,7 @@
 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 GCOV_PROFILE := n
+UBSAN_SANITIZE := n
 
 ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
 
index dbeeb3a..3be9c83 100644 (file)
@@ -579,7 +579,6 @@ config QDIO
 
 menuconfig PCI
        bool "PCI support"
-       select HAVE_DMA_ATTRS
        select PCI_MSI
        select IOMMU_SUPPORT
        help
index b2e5902..0f3da2c 100644 (file)
@@ -67,7 +67,7 @@ static void hypfs_remove(struct dentry *dentry)
        struct dentry *parent;
 
        parent = dentry->d_parent;
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        if (simple_positive(dentry)) {
                if (d_is_dir(dentry))
                        simple_rmdir(d_inode(parent), dentry);
@@ -76,7 +76,7 @@ static void hypfs_remove(struct dentry *dentry)
        }
        d_delete(dentry);
        dput(dentry);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
 }
 
 static void hypfs_delete_tree(struct dentry *root)
@@ -331,7 +331,7 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
        struct dentry *dentry;
        struct inode *inode;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        dentry = lookup_one_len(name, parent, strlen(name));
        if (IS_ERR(dentry)) {
                dentry = ERR_PTR(-ENOMEM);
@@ -359,7 +359,7 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
        d_instantiate(dentry, inode);
        dget(dentry);
 fail:
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        return dentry;
 }
 
index b3fd54d..e64bfcb 100644 (file)
@@ -23,8 +23,6 @@ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 {
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
        if (!dev->dma_mask)
index 6c391a5..e13da05 100644 (file)
@@ -11,7 +11,6 @@ config SUPERH
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DMA_API_DEBUG
-       select HAVE_DMA_ATTRS
        select HAVE_PERF_EVENTS
        select HAVE_DEBUG_BUGVERBOSE
        select ARCH_HAVE_CUSTOM_GPIO_H
index a3745a3..e11cf0c 100644 (file)
@@ -11,8 +11,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 
 #define DMA_ERROR_CODE 0
 
-#include <asm-generic/dma-mapping-common.h>
-
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                    enum dma_data_direction dir);
 
index 3203e42..57ffaf2 100644 (file)
@@ -26,7 +26,6 @@ config SPARC
        select RTC_CLASS
        select RTC_DRV_M48T59
        select RTC_SYSTOHC
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select HAVE_ARCH_JUMP_LABEL if SPARC64
        select GENERIC_IRQ_SHOW
index a21da59..1180ae2 100644 (file)
@@ -37,21 +37,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
        return dma_ops;
 }
 
-#define HAVE_ARCH_DMA_SET_MASK 1
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-#ifdef CONFIG_PCI
-       if (dev->bus == &pci_bus_type) {
-               if (!dev->dma_mask || !dma_supported(dev, mask))
-                       return -EINVAL;
-               *dev->dma_mask = mask;
-               return 0;
-       }
-#endif
-       return -EINVAL;
-}
-
-#include <asm-generic/dma-mapping-common.h>
-
 #endif
index 6bfbe8b..de4a4ff 100644 (file)
@@ -5,7 +5,6 @@ config TILE
        def_bool y
        select HAVE_PERF_EVENTS
        select USE_PMC if PERF_EVENTS
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select HAVE_KVM if !TILEGX
        select GENERIC_FIND_FIRST_BIT
index 96ac6cc..01ceb4a 100644 (file)
@@ -73,37 +73,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 }
 
 #define HAVE_ARCH_DMA_SET_MASK 1
-
-#include <asm-generic/dma-mapping-common.h>
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
-       struct dma_map_ops *dma_ops = get_dma_ops(dev);
-
-       /*
-        * For PCI devices with 64-bit DMA addressing capability, promote
-        * the dma_ops to hybrid, with the consistent memory DMA space limited
-        * to 32-bit. For 32-bit capable devices, limit the streaming DMA
-        * address range to max_direct_dma_addr.
-        */
-       if (dma_ops == gx_pci_dma_map_ops ||
-           dma_ops == gx_hybrid_pci_dma_map_ops ||
-           dma_ops == gx_legacy_pci_dma_map_ops) {
-               if (mask == DMA_BIT_MASK(64) &&
-                   dma_ops == gx_legacy_pci_dma_map_ops)
-                       set_dma_ops(dev, gx_hybrid_pci_dma_map_ops);
-               else if (mask > dev->archdata.max_direct_dma_addr)
-                       mask = dev->archdata.max_direct_dma_addr;
-       }
-
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-
-       *dev->dma_mask = mask;
-
-       return 0;
-}
+int dma_set_mask(struct device *dev, u64 mask);
 
 /*
  * dma_alloc_noncoherent() is #defined to return coherent memory,
index 09b5870..b6bc054 100644 (file)
@@ -583,6 +583,35 @@ struct dma_map_ops *gx_hybrid_pci_dma_map_ops;
 EXPORT_SYMBOL(gx_legacy_pci_dma_map_ops);
 EXPORT_SYMBOL(gx_hybrid_pci_dma_map_ops);
 
+int dma_set_mask(struct device *dev, u64 mask)
+{
+       struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+       /*
+        * For PCI devices with 64-bit DMA addressing capability, promote
+        * the dma_ops to hybrid, with the consistent memory DMA space limited
+        * to 32-bit. For 32-bit capable devices, limit the streaming DMA
+        * address range to max_direct_dma_addr.
+        */
+       if (dma_ops == gx_pci_dma_map_ops ||
+           dma_ops == gx_hybrid_pci_dma_map_ops ||
+           dma_ops == gx_legacy_pci_dma_map_ops) {
+               if (mask == DMA_BIT_MASK(64) &&
+                   dma_ops == gx_legacy_pci_dma_map_ops)
+                       set_dma_ops(dev, gx_hybrid_pci_dma_map_ops);
+               else if (mask > dev->archdata.max_direct_dma_addr)
+                       mask = dev->archdata.max_direct_dma_addr;
+       }
+
+       if (!dev->dma_mask || !dma_supported(dev, mask))
+               return -EIO;
+
+       *dev->dma_mask = mask;
+
+       return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
 #ifdef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK
 int dma_set_coherent_mask(struct device *dev, u64 mask)
 {
index 8773426..e5602ee 100644 (file)
@@ -5,7 +5,6 @@ config UNICORE32
        select ARCH_MIGHT_HAVE_PC_SERIO
        select HAVE_MEMBLOCK
        select HAVE_GENERIC_DMA_COHERENT
-       select HAVE_DMA_ATTRS
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_BZIP2
        select GENERIC_ATOMIC64
index 8140e05..4749854 100644 (file)
@@ -28,8 +28,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
        return &swiotlb_dma_map_ops;
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
        if (dev && dev->dma_mask)
index 4a10ba9..330e738 100644 (file)
@@ -31,6 +31,7 @@ config X86
        select ARCH_HAS_PMEM_API                if X86_64
        select ARCH_HAS_MMIO_FLUSH
        select ARCH_HAS_SG_CHAIN
+       select ARCH_HAS_UBSAN_SANITIZE_ALL
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select ARCH_MIGHT_HAVE_ACPI_PDC         if ACPI
        select ARCH_MIGHT_HAVE_PC_PARPORT
@@ -99,7 +100,6 @@ config X86
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_DMA_API_DEBUG
-       select HAVE_DMA_ATTRS
        select HAVE_DMA_CONTIGUOUS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_DYNAMIC_FTRACE_WITH_REGS
@@ -2699,6 +2699,19 @@ config PMC_ATOM
        def_bool y
         depends on PCI
 
+config VMD
+       depends on PCI_MSI
+       tristate "Volume Management Device Driver"
+       default N
+       ---help---
+         Adds support for the Intel Volume Management Device (VMD). VMD is a
+         secondary PCI host bridge that allows PCI Express root ports,
+         and devices attached to them, to be removed from the default
+         PCI domain and placed within the VMD domain. This provides
+         more bus resources than are otherwise possible with a
+         single domain. If you know your system provides one of these and
+         has devices attached to it, say Y; if you are not sure, say N.
+
 source "net/Kconfig"
 
 source "drivers/Kconfig"
index 2ee62db..bbe1a62 100644 (file)
@@ -60,6 +60,7 @@ clean-files += cpustr.h
 KBUILD_CFLAGS  := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP
 KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
+UBSAN_SANITIZE := n
 
 $(obj)/bzImage: asflags-y  := $(SVGA_MODE)
 
index 0a291cd..f9ce75d 100644 (file)
@@ -33,6 +33,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
 
 KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
+UBSAN_SANITIZE :=n
 
 LDFLAGS := -m elf_$(UTS_MACHINE)
 LDFLAGS_vmlinux := -T
index 265c0ed..c854541 100644 (file)
@@ -4,6 +4,7 @@
 
 KBUILD_CFLAGS += $(DISABLE_LTO)
 KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
 
 VDSO64-$(CONFIG_X86_64)                := y
 VDSOX32-$(CONFIG_X86_X32_ABI)  := y
index 03dd729..684ed6c 100644 (file)
@@ -10,6 +10,16 @@ struct dev_archdata {
 #endif
 };
 
+#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
+struct dma_domain {
+       struct list_head node;
+       struct dma_map_ops *dma_ops;
+       int domain_nr;
+};
+void add_dma_domain(struct dma_domain *domain);
+void del_dma_domain(struct dma_domain *domain);
+#endif
+
 struct pdev_archdata {
 };
 
index 953b726..3a27b93 100644 (file)
@@ -46,8 +46,6 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
 #define HAVE_ARCH_DMA_SUPPORTED 1
 extern int dma_supported(struct device *hwdev, u64 mask);
 
-#include <asm-generic/dma-mapping-common.h>
-
 extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
                                        dma_addr_t *dma_addr, gfp_t flag,
                                        struct dma_attrs *attrs);
index 1e3408e..1815b73 100644 (file)
@@ -129,6 +129,11 @@ struct irq_alloc_info {
                        unsigned long   uv_offset;
                        char            *uv_name;
                };
+#endif
+#if IS_ENABLED(CONFIG_VMD)
+               struct {
+                       struct msi_desc *desc;
+               };
 #endif
        };
 };
index fa1195d..46873fb 100644 (file)
@@ -151,11 +151,11 @@ extern struct list_head pci_mmcfg_list;
 #define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
 /*
- * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
- * on their northbrige except through the * %eax register. As such, you MUST
- * NOT use normal IOMEM accesses, you need to only use the magic mmio-config
- * accessor functions.
- * In fact just use pci_config_*, nothing else please.
+ * On AMD Fam10h CPUs, all PCI MMIO configuration space accesses must use
+ * %eax.  No other source or target registers may be used.  The following
+ * mmio_config_* accessors enforce this.  See "BIOS and Kernel Developer's
+ * Guide (BKDG) For AMD Family 10h Processors", rev. 3.48, sec 2.11.1,
+ * "MMIO Configuration Coding Requirements".
  */
 static inline unsigned char mmio_config_readb(void __iomem *pos)
 {
index 1544fab..c57fd1e 100644 (file)
@@ -67,18 +67,19 @@ static inline void arch_wmb_pmem(void)
 }
 
 /**
- * __arch_wb_cache_pmem - write back a cache range with CLWB
+ * arch_wb_cache_pmem - write back a cache range with CLWB
  * @vaddr:     virtual start address
  * @size:      number of bytes to write back
  *
  * Write back a cache range using the CLWB (cache line write back)
  * instruction.  This function requires explicit ordering with an
- * arch_wmb_pmem() call.  This API is internal to the x86 PMEM implementation.
+ * arch_wmb_pmem() call.
  */
-static inline void __arch_wb_cache_pmem(void *vaddr, size_t size)
+static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size)
 {
        u16 x86_clflush_size = boot_cpu_data.x86_clflush_size;
        unsigned long clflush_mask = x86_clflush_size - 1;
+       void *vaddr = (void __force *)addr;
        void *vend = vaddr + size;
        void *p;
 
@@ -115,7 +116,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes,
        len = copy_from_iter_nocache(vaddr, bytes, i);
 
        if (__iter_needs_pmem_wb(i))
-               __arch_wb_cache_pmem(vaddr, bytes);
+               arch_wb_cache_pmem(addr, bytes);
 
        return len;
 }
@@ -133,7 +134,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size)
        void *vaddr = (void __force *)addr;
 
        memset(vaddr, 0, size);
-       __arch_wb_cache_pmem(vaddr, size);
+       arch_wb_cache_pmem(addr, size);
 }
 
 static inline bool __arch_has_wmb_pmem(void)
index 660458a..a4a30e4 100644 (file)
@@ -134,6 +134,9 @@ extern int __get_user_4(void);
 extern int __get_user_8(void);
 extern int __get_user_bad(void);
 
+#define __uaccess_begin() stac()
+#define __uaccess_end()   clac()
+
 /*
  * This is a type: either unsigned long, if the argument fits into
  * that type, or otherwise unsigned long long.
@@ -193,10 +196,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
 #ifdef CONFIG_X86_32
 #define __put_user_asm_u64(x, addr, err, errret)                       \
-       asm volatile(ASM_STAC "\n"                                      \
+       asm volatile("\n"                                               \
                     "1:        movl %%eax,0(%2)\n"                     \
                     "2:        movl %%edx,4(%2)\n"                     \
-                    "3: " ASM_CLAC "\n"                                \
+                    "3:"                                               \
                     ".section .fixup,\"ax\"\n"                         \
                     "4:        movl %3,%0\n"                           \
                     "  jmp 3b\n"                                       \
@@ -207,10 +210,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
                     : "A" (x), "r" (addr), "i" (errret), "0" (err))
 
 #define __put_user_asm_ex_u64(x, addr)                                 \
-       asm volatile(ASM_STAC "\n"                                      \
+       asm volatile("\n"                                               \
                     "1:        movl %%eax,0(%1)\n"                     \
                     "2:        movl %%edx,4(%1)\n"                     \
-                    "3: " ASM_CLAC "\n"                                \
+                    "3:"                                               \
                     _ASM_EXTABLE_EX(1b, 2b)                            \
                     _ASM_EXTABLE_EX(2b, 3b)                            \
                     : : "A" (x), "r" (addr))
@@ -304,6 +307,10 @@ do {                                                                       \
        }                                                               \
 } while (0)
 
+/*
+ * This doesn't do __uaccess_begin/end - the exception handling
+ * around it must do that.
+ */
 #define __put_user_size_ex(x, ptr, size)                               \
 do {                                                                   \
        __chk_user_ptr(ptr);                                            \
@@ -358,9 +365,9 @@ do {                                                                        \
 } while (0)
 
 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
-       asm volatile(ASM_STAC "\n"                                      \
+       asm volatile("\n"                                               \
                     "1:        mov"itype" %2,%"rtype"1\n"              \
-                    "2: " ASM_CLAC "\n"                                \
+                    "2:\n"                                             \
                     ".section .fixup,\"ax\"\n"                         \
                     "3:        mov %3,%0\n"                            \
                     "  xor"itype" %"rtype"1,%"rtype"1\n"               \
@@ -370,6 +377,10 @@ do {                                                                       \
                     : "=r" (err), ltype(x)                             \
                     : "m" (__m(addr)), "i" (errret), "0" (err))
 
+/*
+ * This doesn't do __uaccess_begin/end - the exception handling
+ * around it must do that.
+ */
 #define __get_user_size_ex(x, ptr, size)                               \
 do {                                                                   \
        __chk_user_ptr(ptr);                                            \
@@ -400,7 +411,9 @@ do {                                                                        \
 #define __put_user_nocheck(x, ptr, size)                       \
 ({                                                             \
        int __pu_err;                                           \
+       __uaccess_begin();                                      \
        __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
+       __uaccess_end();                                        \
        __builtin_expect(__pu_err, 0);                          \
 })
 
@@ -408,7 +421,9 @@ do {                                                                        \
 ({                                                                     \
        int __gu_err;                                                   \
        unsigned long __gu_val;                                         \
+       __uaccess_begin();                                              \
        __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);    \
+       __uaccess_end();                                                \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
        __builtin_expect(__gu_err, 0);                                  \
 })
@@ -423,9 +438,9 @@ struct __large_struct { unsigned long buf[100]; };
  * aliasing issues.
  */
 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
-       asm volatile(ASM_STAC "\n"                                      \
+       asm volatile("\n"                                               \
                     "1:        mov"itype" %"rtype"1,%2\n"              \
-                    "2: " ASM_CLAC "\n"                                \
+                    "2:\n"                                             \
                     ".section .fixup,\"ax\"\n"                         \
                     "3:        mov %3,%0\n"                            \
                     "  jmp 2b\n"                                       \
@@ -445,11 +460,11 @@ struct __large_struct { unsigned long buf[100]; };
  */
 #define uaccess_try    do {                                            \
        current_thread_info()->uaccess_err = 0;                         \
-       stac();                                                         \
+       __uaccess_begin();                                              \
        barrier();
 
 #define uaccess_catch(err)                                             \
-       clac();                                                         \
+       __uaccess_end();                                                \
        (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0);    \
 } while (0)
 
@@ -547,12 +562,13 @@ extern void __cmpxchg_wrong_size(void)
        __typeof__(ptr) __uval = (uval);                                \
        __typeof__(*(ptr)) __old = (old);                               \
        __typeof__(*(ptr)) __new = (new);                               \
+       __uaccess_begin();                                              \
        switch (size) {                                                 \
        case 1:                                                         \
        {                                                               \
-               asm volatile("\t" ASM_STAC "\n"                         \
+               asm volatile("\n"                                       \
                        "1:\t" LOCK_PREFIX "cmpxchgb %4, %2\n"          \
-                       "2:\t" ASM_CLAC "\n"                            \
+                       "2:\n"                                          \
                        "\t.section .fixup, \"ax\"\n"                   \
                        "3:\tmov     %3, %0\n"                          \
                        "\tjmp     2b\n"                                \
@@ -566,9 +582,9 @@ extern void __cmpxchg_wrong_size(void)
        }                                                               \
        case 2:                                                         \
        {                                                               \
-               asm volatile("\t" ASM_STAC "\n"                         \
+               asm volatile("\n"                                       \
                        "1:\t" LOCK_PREFIX "cmpxchgw %4, %2\n"          \
-                       "2:\t" ASM_CLAC "\n"                            \
+                       "2:\n"                                          \
                        "\t.section .fixup, \"ax\"\n"                   \
                        "3:\tmov     %3, %0\n"                          \
                        "\tjmp     2b\n"                                \
@@ -582,9 +598,9 @@ extern void __cmpxchg_wrong_size(void)
        }                                                               \
        case 4:                                                         \
        {                                                               \
-               asm volatile("\t" ASM_STAC "\n"                         \
+               asm volatile("\n"                                       \
                        "1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n"          \
-                       "2:\t" ASM_CLAC "\n"                            \
+                       "2:\n"                                          \
                        "\t.section .fixup, \"ax\"\n"                   \
                        "3:\tmov     %3, %0\n"                          \
                        "\tjmp     2b\n"                                \
@@ -601,9 +617,9 @@ extern void __cmpxchg_wrong_size(void)
                if (!IS_ENABLED(CONFIG_X86_64))                         \
                        __cmpxchg_wrong_size();                         \
                                                                        \
-               asm volatile("\t" ASM_STAC "\n"                         \
+               asm volatile("\n"                                       \
                        "1:\t" LOCK_PREFIX "cmpxchgq %4, %2\n"          \
-                       "2:\t" ASM_CLAC "\n"                            \
+                       "2:\n"                                          \
                        "\t.section .fixup, \"ax\"\n"                   \
                        "3:\tmov     %3, %0\n"                          \
                        "\tjmp     2b\n"                                \
@@ -618,6 +634,7 @@ extern void __cmpxchg_wrong_size(void)
        default:                                                        \
                __cmpxchg_wrong_size();                                 \
        }                                                               \
+       __uaccess_end();                                                \
        *__uval = __old;                                                \
        __ret;                                                          \
 })
@@ -754,5 +771,30 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
  */
 #define __copy_from_user_nmi __copy_from_user_inatomic
 
+/*
+ * The "unsafe" user accesses aren't really "unsafe", but the naming
+ * is a big fat warning: you have to not only do the access_ok()
+ * checking before using them, but you have to surround them with the
+ * user_access_begin/end() pair.
+ */
+#define user_access_begin()    __uaccess_begin()
+#define user_access_end()      __uaccess_end()
+
+#define unsafe_put_user(x, ptr)                                                \
+({                                                                             \
+       int __pu_err;                                                           \
+       __put_user_size((x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);         \
+       __builtin_expect(__pu_err, 0);                                          \
+})
+
+#define unsafe_get_user(x, ptr)                                                \
+({                                                                             \
+       int __gu_err;                                                           \
+       unsigned long __gu_val;                                                 \
+       __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT);    \
+       (x) = (__force __typeof__(*(ptr)))__gu_val;                             \
+       __builtin_expect(__gu_err, 0);                                          \
+})
+
 #endif /* _ASM_X86_UACCESS_H */
 
index f2f9b39..b89c34c 100644 (file)
@@ -56,35 +56,49 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size)
        if (!__builtin_constant_p(size))
                return copy_user_generic(dst, (__force void *)src, size);
        switch (size) {
-       case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
+       case 1:
+               __uaccess_begin();
+               __get_user_asm(*(u8 *)dst, (u8 __user *)src,
                              ret, "b", "b", "=q", 1);
+               __uaccess_end();
                return ret;
-       case 2:__get_user_asm(*(u16 *)dst, (u16 __user *)src,
+       case 2:
+               __uaccess_begin();
+               __get_user_asm(*(u16 *)dst, (u16 __user *)src,
                              ret, "w", "w", "=r", 2);
+               __uaccess_end();
                return ret;
-       case 4:__get_user_asm(*(u32 *)dst, (u32 __user *)src,
+       case 4:
+               __uaccess_begin();
+               __get_user_asm(*(u32 *)dst, (u32 __user *)src,
                              ret, "l", "k", "=r", 4);
+               __uaccess_end();
                return ret;
-       case 8:__get_user_asm(*(u64 *)dst, (u64 __user *)src,
+       case 8:
+               __uaccess_begin();
+               __get_user_asm(*(u64 *)dst, (u64 __user *)src,
                              ret, "q", "", "=r", 8);
+               __uaccess_end();
                return ret;
        case 10:
+               __uaccess_begin();
                __get_user_asm(*(u64 *)dst, (u64 __user *)src,
                               ret, "q", "", "=r", 10);
-               if (unlikely(ret))
-                       return ret;
-               __get_user_asm(*(u16 *)(8 + (char *)dst),
-                              (u16 __user *)(8 + (char __user *)src),
-                              ret, "w", "w", "=r", 2);
+               if (likely(!ret))
+                       __get_user_asm(*(u16 *)(8 + (char *)dst),
+                                      (u16 __user *)(8 + (char __user *)src),
+                                      ret, "w", "w", "=r", 2);
+               __uaccess_end();
                return ret;
        case 16:
+               __uaccess_begin();
                __get_user_asm(*(u64 *)dst, (u64 __user *)src,
                               ret, "q", "", "=r", 16);
-               if (unlikely(ret))
-                       return ret;
-               __get_user_asm(*(u64 *)(8 + (char *)dst),
-                              (u64 __user *)(8 + (char __user *)src),
-                              ret, "q", "", "=r", 8);
+               if (likely(!ret))
+                       __get_user_asm(*(u64 *)(8 + (char *)dst),
+                                      (u64 __user *)(8 + (char __user *)src),
+                                      ret, "q", "", "=r", 8);
+               __uaccess_end();
                return ret;
        default:
                return copy_user_generic(dst, (__force void *)src, size);
@@ -106,35 +120,51 @@ int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size)
        if (!__builtin_constant_p(size))
                return copy_user_generic((__force void *)dst, src, size);
        switch (size) {
-       case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
+       case 1:
+               __uaccess_begin();
+               __put_user_asm(*(u8 *)src, (u8 __user *)dst,
                              ret, "b", "b", "iq", 1);
+               __uaccess_end();
                return ret;
-       case 2:__put_user_asm(*(u16 *)src, (u16 __user *)dst,
+       case 2:
+               __uaccess_begin();
+               __put_user_asm(*(u16 *)src, (u16 __user *)dst,
                              ret, "w", "w", "ir", 2);
+               __uaccess_end();
                return ret;
-       case 4:__put_user_asm(*(u32 *)src, (u32 __user *)dst,
+       case 4:
+               __uaccess_begin();
+               __put_user_asm(*(u32 *)src, (u32 __user *)dst,
                              ret, "l", "k", "ir", 4);
+               __uaccess_end();
                return ret;
-       case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
+       case 8:
+               __uaccess_begin();
+               __put_user_asm(*(u64 *)src, (u64 __user *)dst,
                              ret, "q", "", "er", 8);
+               __uaccess_end();
                return ret;
        case 10:
+               __uaccess_begin();
                __put_user_asm(*(u64 *)src, (u64 __user *)dst,
                               ret, "q", "", "er", 10);
-               if (unlikely(ret))
-                       return ret;
-               asm("":::"memory");
-               __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
-                              ret, "w", "w", "ir", 2);
+               if (likely(!ret)) {
+                       asm("":::"memory");
+                       __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
+                                      ret, "w", "w", "ir", 2);
+               }
+               __uaccess_end();
                return ret;
        case 16:
+               __uaccess_begin();
                __put_user_asm(*(u64 *)src, (u64 __user *)dst,
                               ret, "q", "", "er", 16);
-               if (unlikely(ret))
-                       return ret;
-               asm("":::"memory");
-               __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
-                              ret, "q", "", "er", 8);
+               if (likely(!ret)) {
+                       asm("":::"memory");
+                       __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
+                                      ret, "q", "", "er", 8);
+               }
+               __uaccess_end();
                return ret;
        default:
                return copy_user_generic((__force void *)dst, src, size);
@@ -160,39 +190,47 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
        switch (size) {
        case 1: {
                u8 tmp;
+               __uaccess_begin();
                __get_user_asm(tmp, (u8 __user *)src,
                               ret, "b", "b", "=q", 1);
                if (likely(!ret))
                        __put_user_asm(tmp, (u8 __user *)dst,
                                       ret, "b", "b", "iq", 1);
+               __uaccess_end();
                return ret;
        }
        case 2: {
                u16 tmp;
+               __uaccess_begin();
                __get_user_asm(tmp, (u16 __user *)src,
                               ret, "w", "w", "=r", 2);
                if (likely(!ret))
                        __put_user_asm(tmp, (u16 __user *)dst,
                                       ret, "w", "w", "ir", 2);
+               __uaccess_end();
                return ret;
        }
 
        case 4: {
                u32 tmp;
+               __uaccess_begin();
                __get_user_asm(tmp, (u32 __user *)src,
                               ret, "l", "k", "=r", 4);
                if (likely(!ret))
                        __put_user_asm(tmp, (u32 __user *)dst,
                                       ret, "l", "k", "ir", 4);
+               __uaccess_end();
                return ret;
        }
        case 8: {
                u64 tmp;
+               __uaccess_begin();
                __get_user_asm(tmp, (u64 __user *)src,
                               ret, "q", "", "=r", 8);
                if (likely(!ret))
                        __put_user_asm(tmp, (u64 __user *)dst,
                                       ret, "q", "", "er", 8);
+               __uaccess_end();
                return ret;
        }
        default:
index 819ab3f..ba7fbba 100644 (file)
@@ -385,6 +385,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
        return image->fops->cleanup(image->image_loader_data);
 }
 
+#ifdef CONFIG_KEXEC_VERIFY_SIG
 int arch_kexec_kernel_verify_sig(struct kimage *image, void *kernel,
                                 unsigned long kernel_len)
 {
@@ -395,6 +396,7 @@ int arch_kexec_kernel_verify_sig(struct kimage *image, void *kernel,
 
        return image->fops->verify_sig(kernel, kernel_len);
 }
+#endif
 
 /*
  * Apply purgatory relocations.
index 5c6fc35..97062a6 100644 (file)
@@ -23,6 +23,8 @@ obj-y                         += bus_numa.o
 obj-$(CONFIG_AMD_NB)           += amd_bus.o
 obj-$(CONFIG_PCI_CNB20LE_QUIRK)        += broadcom_bus.o
 
+obj-$(CONFIG_VMD) += vmd.o
+
 ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
 endif
index eccd4d9..2879efc 100644 (file)
@@ -641,6 +641,43 @@ unsigned int pcibios_assign_all_busses(void)
        return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
+#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
+static LIST_HEAD(dma_domain_list);
+static DEFINE_SPINLOCK(dma_domain_list_lock);
+
+void add_dma_domain(struct dma_domain *domain)
+{
+       spin_lock(&dma_domain_list_lock);
+       list_add(&domain->node, &dma_domain_list);
+       spin_unlock(&dma_domain_list_lock);
+}
+EXPORT_SYMBOL_GPL(add_dma_domain);
+
+void del_dma_domain(struct dma_domain *domain)
+{
+       spin_lock(&dma_domain_list_lock);
+       list_del(&domain->node);
+       spin_unlock(&dma_domain_list_lock);
+}
+EXPORT_SYMBOL_GPL(del_dma_domain);
+
+static void set_dma_domain_ops(struct pci_dev *pdev)
+{
+       struct dma_domain *domain;
+
+       spin_lock(&dma_domain_list_lock);
+       list_for_each_entry(domain, &dma_domain_list, node) {
+               if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
+                       pdev->dev.archdata.dma_ops = domain->dma_ops;
+                       break;
+               }
+       }
+       spin_unlock(&dma_domain_list_lock);
+}
+#else
+static void set_dma_domain_ops(struct pci_dev *pdev) {}
+#endif
+
 int pcibios_add_device(struct pci_dev *dev)
 {
        struct setup_data *data;
@@ -670,6 +707,7 @@ int pcibios_add_device(struct pci_dev *dev)
                pa_data = data->next;
                iounmap(data);
        }
+       set_dma_domain_ops(dev);
        return 0;
 }
 
index 9b83b90..9770e55 100644 (file)
@@ -180,6 +180,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
        unsigned long result = 0;
        unsigned long flags;
        unsigned long bx = (bus << 8) | devfn;
+       u16 number = 0, mask = 0;
 
        WARN_ON(seg);
        if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
@@ -189,53 +190,35 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
 
        switch (len) {
        case 1:
-               __asm__("lcall *(%%esi); cld\n\t"
-                       "jc 1f\n\t"
-                       "xor %%ah, %%ah\n"
-                       "1:"
-                       : "=c" (*value),
-                         "=a" (result)
-                       : "1" (PCIBIOS_READ_CONFIG_BYTE),
-                         "b" (bx),
-                         "D" ((long)reg),
-                         "S" (&pci_indirect));
-               /*
-                * Zero-extend the result beyond 8 bits, do not trust the
-                * BIOS having done it:
-                */
-               *value &= 0xff;
+               number = PCIBIOS_READ_CONFIG_BYTE;
+               mask = 0xff;
                break;
        case 2:
-               __asm__("lcall *(%%esi); cld\n\t"
-                       "jc 1f\n\t"
-                       "xor %%ah, %%ah\n"
-                       "1:"
-                       : "=c" (*value),
-                         "=a" (result)
-                       : "1" (PCIBIOS_READ_CONFIG_WORD),
-                         "b" (bx),
-                         "D" ((long)reg),
-                         "S" (&pci_indirect));
-               /*
-                * Zero-extend the result beyond 16 bits, do not trust the
-                * BIOS having done it:
-                */
-               *value &= 0xffff;
+               number = PCIBIOS_READ_CONFIG_WORD;
+               mask = 0xffff;
                break;
        case 4:
-               __asm__("lcall *(%%esi); cld\n\t"
-                       "jc 1f\n\t"
-                       "xor %%ah, %%ah\n"
-                       "1:"
-                       : "=c" (*value),
-                         "=a" (result)
-                       : "1" (PCIBIOS_READ_CONFIG_DWORD),
-                         "b" (bx),
-                         "D" ((long)reg),
-                         "S" (&pci_indirect));
+               number = PCIBIOS_READ_CONFIG_DWORD;
                break;
        }
 
+       __asm__("lcall *(%%esi); cld\n\t"
+               "jc 1f\n\t"
+               "xor %%ah, %%ah\n"
+               "1:"
+               : "=c" (*value),
+                 "=a" (result)
+               : "1" (number),
+                 "b" (bx),
+                 "D" ((long)reg),
+                 "S" (&pci_indirect));
+       /*
+        * Zero-extend the result beyond 8 or 16 bits, do not trust the
+        * BIOS having done it:
+        */
+       if (mask)
+               *value &= mask;
+
        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
        return (int)((result & 0xff00) >> 8);
@@ -247,6 +230,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
        unsigned long result = 0;
        unsigned long flags;
        unsigned long bx = (bus << 8) | devfn;
+       u16 number = 0;
 
        WARN_ON(seg);
        if ((bus > 255) || (devfn > 255) || (reg > 255)) 
@@ -256,43 +240,27 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
 
        switch (len) {
        case 1:
-               __asm__("lcall *(%%esi); cld\n\t"
-                       "jc 1f\n\t"
-                       "xor %%ah, %%ah\n"
-                       "1:"
-                       : "=a" (result)
-                       : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
-                         "c" (value),
-                         "b" (bx),
-                         "D" ((long)reg),
-                         "S" (&pci_indirect));
+               number = PCIBIOS_WRITE_CONFIG_BYTE;
                break;
        case 2:
-               __asm__("lcall *(%%esi); cld\n\t"
-                       "jc 1f\n\t"
-                       "xor %%ah, %%ah\n"
-                       "1:"
-                       : "=a" (result)
-                       : "0" (PCIBIOS_WRITE_CONFIG_WORD),
-                         "c" (value),
-                         "b" (bx),
-                         "D" ((long)reg),
-                         "S" (&pci_indirect));
+               number = PCIBIOS_WRITE_CONFIG_WORD;
                break;
        case 4:
-               __asm__("lcall *(%%esi); cld\n\t"
-                       "jc 1f\n\t"
-                       "xor %%ah, %%ah\n"
-                       "1:"
-                       : "=a" (result)
-                       : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
-                         "c" (value),
-                         "b" (bx),
-                         "D" ((long)reg),
-                         "S" (&pci_indirect));
+               number = PCIBIOS_WRITE_CONFIG_DWORD;
                break;
        }
 
+       __asm__("lcall *(%%esi); cld\n\t"
+               "jc 1f\n\t"
+               "xor %%ah, %%ah\n"
+               "1:"
+               : "=a" (result)
+               : "0" (number),
+                 "c" (value),
+                 "b" (bx),
+                 "D" ((long)reg),
+                 "S" (&pci_indirect));
+
        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
        return (int)((result & 0xff00) >> 8);
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c
new file mode 100644 (file)
index 0000000..d57e480
--- /dev/null
@@ -0,0 +1,723 @@
+/*
+ * Volume Management Device driver
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * 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/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/pci.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+
+#include <asm/irqdomain.h>
+#include <asm/device.h>
+#include <asm/msi.h>
+#include <asm/msidef.h>
+
+#define VMD_CFGBAR     0
+#define VMD_MEMBAR1    2
+#define VMD_MEMBAR2    4
+
+/*
+ * Lock for manipulating VMD IRQ lists.
+ */
+static DEFINE_RAW_SPINLOCK(list_lock);
+
+/**
+ * struct vmd_irq - private data to map driver IRQ to the VMD shared vector
+ * @node:      list item for parent traversal.
+ * @rcu:       RCU callback item for freeing.
+ * @irq:       back pointer to parent.
+ * @virq:      the virtual IRQ value provided to the requesting driver.
+ *
+ * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to
+ * a VMD IRQ using this structure.
+ */
+struct vmd_irq {
+       struct list_head        node;
+       struct rcu_head         rcu;
+       struct vmd_irq_list     *irq;
+       unsigned int            virq;
+};
+
+/**
+ * struct vmd_irq_list - list of driver requested IRQs mapping to a VMD vector
+ * @irq_list:  the list of irq's the VMD one demuxes to.
+ * @vmd_vector:        the h/w IRQ assigned to the VMD.
+ * @index:     index into the VMD MSI-X table; used for message routing.
+ * @count:     number of child IRQs assigned to this vector; used to track
+ *             sharing.
+ */
+struct vmd_irq_list {
+       struct list_head        irq_list;
+       struct vmd_dev          *vmd;
+       unsigned int            vmd_vector;
+       unsigned int            index;
+       unsigned int            count;
+};
+
+struct vmd_dev {
+       struct pci_dev          *dev;
+
+       spinlock_t              cfg_lock;
+       char __iomem            *cfgbar;
+
+       int msix_count;
+       struct msix_entry       *msix_entries;
+       struct vmd_irq_list     *irqs;
+
+       struct pci_sysdata      sysdata;
+       struct resource         resources[3];
+       struct irq_domain       *irq_domain;
+       struct pci_bus          *bus;
+
+#ifdef CONFIG_X86_DEV_DMA_OPS
+       struct dma_map_ops      dma_ops;
+       struct dma_domain       dma_domain;
+#endif
+};
+
+static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus)
+{
+       return container_of(bus->sysdata, struct vmd_dev, sysdata);
+}
+
+/*
+ * Drivers managing a device in a VMD domain allocate their own IRQs as before,
+ * but the MSI entry for the hardware it's driving will be programmed with a
+ * destination ID for the VMD MSI-X table.  The VMD muxes interrupts in its
+ * domain into one of its own, and the VMD driver de-muxes these for the
+ * handlers sharing that VMD IRQ.  The vmd irq_domain provides the operations
+ * and irq_chip to set this up.
+ */
+static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+       struct vmd_irq *vmdirq = data->chip_data;
+       struct vmd_irq_list *irq = vmdirq->irq;
+
+       msg->address_hi = MSI_ADDR_BASE_HI;
+       msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_DEST_ID(irq->index);
+       msg->data = 0;
+}
+
+/*
+ * We rely on MSI_FLAG_USE_DEF_CHIP_OPS to set the IRQ mask/unmask ops.
+ */
+static void vmd_irq_enable(struct irq_data *data)
+{
+       struct vmd_irq *vmdirq = data->chip_data;
+
+       raw_spin_lock(&list_lock);
+       list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list);
+       raw_spin_unlock(&list_lock);
+
+       data->chip->irq_unmask(data);
+}
+
+static void vmd_irq_disable(struct irq_data *data)
+{
+       struct vmd_irq *vmdirq = data->chip_data;
+
+       data->chip->irq_mask(data);
+
+       raw_spin_lock(&list_lock);
+       list_del_rcu(&vmdirq->node);
+       raw_spin_unlock(&list_lock);
+}
+
+/*
+ * XXX: Stubbed until we develop acceptable way to not create conflicts with
+ * other devices sharing the same vector.
+ */
+static int vmd_irq_set_affinity(struct irq_data *data,
+                               const struct cpumask *dest, bool force)
+{
+       return -EINVAL;
+}
+
+static struct irq_chip vmd_msi_controller = {
+       .name                   = "VMD-MSI",
+       .irq_enable             = vmd_irq_enable,
+       .irq_disable            = vmd_irq_disable,
+       .irq_compose_msi_msg    = vmd_compose_msi_msg,
+       .irq_set_affinity       = vmd_irq_set_affinity,
+};
+
+static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info,
+                                    msi_alloc_info_t *arg)
+{
+       return 0;
+}
+
+/*
+ * XXX: We can be even smarter selecting the best IRQ once we solve the
+ * affinity problem.
+ */
+static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd)
+{
+       int i, best = 0;
+
+       raw_spin_lock(&list_lock);
+       for (i = 1; i < vmd->msix_count; i++)
+               if (vmd->irqs[i].count < vmd->irqs[best].count)
+                       best = i;
+       vmd->irqs[best].count++;
+       raw_spin_unlock(&list_lock);
+
+       return &vmd->irqs[best];
+}
+
+static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
+                       unsigned int virq, irq_hw_number_t hwirq,
+                       msi_alloc_info_t *arg)
+{
+       struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(arg->desc)->bus);
+       struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);
+
+       if (!vmdirq)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&vmdirq->node);
+       vmdirq->irq = vmd_next_irq(vmd);
+       vmdirq->virq = virq;
+
+       irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip,
+                           vmdirq, handle_simple_irq, vmd, NULL);
+       return 0;
+}
+
+static void vmd_msi_free(struct irq_domain *domain,
+                       struct msi_domain_info *info, unsigned int virq)
+{
+       struct vmd_irq *vmdirq = irq_get_chip_data(virq);
+
+       /* XXX: Potential optimization to rebalance */
+       raw_spin_lock(&list_lock);
+       vmdirq->irq->count--;
+       raw_spin_unlock(&list_lock);
+
+       kfree_rcu(vmdirq, rcu);
+}
+
+static int vmd_msi_prepare(struct irq_domain *domain, struct device *dev,
+                          int nvec, msi_alloc_info_t *arg)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
+
+       if (nvec > vmd->msix_count)
+               return vmd->msix_count;
+
+       memset(arg, 0, sizeof(*arg));
+       return 0;
+}
+
+static void vmd_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+       arg->desc = desc;
+}
+
+static struct msi_domain_ops vmd_msi_domain_ops = {
+       .get_hwirq      = vmd_get_hwirq,
+       .msi_init       = vmd_msi_init,
+       .msi_free       = vmd_msi_free,
+       .msi_prepare    = vmd_msi_prepare,
+       .set_desc       = vmd_set_desc,
+};
+
+static struct msi_domain_info vmd_msi_domain_info = {
+       .flags          = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+                         MSI_FLAG_PCI_MSIX,
+       .ops            = &vmd_msi_domain_ops,
+       .chip           = &vmd_msi_controller,
+};
+
+#ifdef CONFIG_X86_DEV_DMA_OPS
+/*
+ * VMD replaces the requester ID with its own.  DMA mappings for devices in a
+ * VMD domain need to be mapped for the VMD, not the device requiring
+ * the mapping.
+ */
+static struct device *to_vmd_dev(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
+
+       return &vmd->dev->dev;
+}
+
+static struct dma_map_ops *vmd_dma_ops(struct device *dev)
+{
+       return to_vmd_dev(dev)->archdata.dma_ops;
+}
+
+static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr,
+                      gfp_t flag, struct dma_attrs *attrs)
+{
+       return vmd_dma_ops(dev)->alloc(to_vmd_dev(dev), size, addr, flag,
+                                      attrs);
+}
+
+static void vmd_free(struct device *dev, size_t size, void *vaddr,
+                    dma_addr_t addr, struct dma_attrs *attrs)
+{
+       return vmd_dma_ops(dev)->free(to_vmd_dev(dev), size, vaddr, addr,
+                                     attrs);
+}
+
+static int vmd_mmap(struct device *dev, struct vm_area_struct *vma,
+                   void *cpu_addr, dma_addr_t addr, size_t size,
+                   struct dma_attrs *attrs)
+{
+       return vmd_dma_ops(dev)->mmap(to_vmd_dev(dev), vma, cpu_addr, addr,
+                                     size, attrs);
+}
+
+static int vmd_get_sgtable(struct device *dev, struct sg_table *sgt,
+                          void *cpu_addr, dma_addr_t addr, size_t size,
+                          struct dma_attrs *attrs)
+{
+       return vmd_dma_ops(dev)->get_sgtable(to_vmd_dev(dev), sgt, cpu_addr,
+                                            addr, size, attrs);
+}
+
+static dma_addr_t vmd_map_page(struct device *dev, struct page *page,
+                              unsigned long offset, size_t size,
+                              enum dma_data_direction dir,
+                              struct dma_attrs *attrs)
+{
+       return vmd_dma_ops(dev)->map_page(to_vmd_dev(dev), page, offset, size,
+                                         dir, attrs);
+}
+
+static void vmd_unmap_page(struct device *dev, dma_addr_t addr, size_t size,
+                          enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+       vmd_dma_ops(dev)->unmap_page(to_vmd_dev(dev), addr, size, dir, attrs);
+}
+
+static int vmd_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+                     enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+       return vmd_dma_ops(dev)->map_sg(to_vmd_dev(dev), sg, nents, dir, attrs);
+}
+
+static void vmd_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+                        enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+       vmd_dma_ops(dev)->unmap_sg(to_vmd_dev(dev), sg, nents, dir, attrs);
+}
+
+static void vmd_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+                                   size_t size, enum dma_data_direction dir)
+{
+       vmd_dma_ops(dev)->sync_single_for_cpu(to_vmd_dev(dev), addr, size, dir);
+}
+
+static void vmd_sync_single_for_device(struct device *dev, dma_addr_t addr,
+                                      size_t size, enum dma_data_direction dir)
+{
+       vmd_dma_ops(dev)->sync_single_for_device(to_vmd_dev(dev), addr, size,
+                                                dir);
+}
+
+static void vmd_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction dir)
+{
+       vmd_dma_ops(dev)->sync_sg_for_cpu(to_vmd_dev(dev), sg, nents, dir);
+}
+
+static void vmd_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+                                  int nents, enum dma_data_direction dir)
+{
+       vmd_dma_ops(dev)->sync_sg_for_device(to_vmd_dev(dev), sg, nents, dir);
+}
+
+static int vmd_mapping_error(struct device *dev, dma_addr_t addr)
+{
+       return vmd_dma_ops(dev)->mapping_error(to_vmd_dev(dev), addr);
+}
+
+static int vmd_dma_supported(struct device *dev, u64 mask)
+{
+       return vmd_dma_ops(dev)->dma_supported(to_vmd_dev(dev), mask);
+}
+
+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+static u64 vmd_get_required_mask(struct device *dev)
+{
+       return vmd_dma_ops(dev)->get_required_mask(to_vmd_dev(dev));
+}
+#endif
+
+static void vmd_teardown_dma_ops(struct vmd_dev *vmd)
+{
+       struct dma_domain *domain = &vmd->dma_domain;
+
+       if (vmd->dev->dev.archdata.dma_ops)
+               del_dma_domain(domain);
+}
+
+#define ASSIGN_VMD_DMA_OPS(source, dest, fn)   \
+       do {                                    \
+               if (source->fn)                 \
+                       dest->fn = vmd_##fn;    \
+       } while (0)
+
+static void vmd_setup_dma_ops(struct vmd_dev *vmd)
+{
+       const struct dma_map_ops *source = vmd->dev->dev.archdata.dma_ops;
+       struct dma_map_ops *dest = &vmd->dma_ops;
+       struct dma_domain *domain = &vmd->dma_domain;
+
+       domain->domain_nr = vmd->sysdata.domain;
+       domain->dma_ops = dest;
+
+       if (!source)
+               return;
+       ASSIGN_VMD_DMA_OPS(source, dest, alloc);
+       ASSIGN_VMD_DMA_OPS(source, dest, free);
+       ASSIGN_VMD_DMA_OPS(source, dest, mmap);
+       ASSIGN_VMD_DMA_OPS(source, dest, get_sgtable);
+       ASSIGN_VMD_DMA_OPS(source, dest, map_page);
+       ASSIGN_VMD_DMA_OPS(source, dest, unmap_page);
+       ASSIGN_VMD_DMA_OPS(source, dest, map_sg);
+       ASSIGN_VMD_DMA_OPS(source, dest, unmap_sg);
+       ASSIGN_VMD_DMA_OPS(source, dest, sync_single_for_cpu);
+       ASSIGN_VMD_DMA_OPS(source, dest, sync_single_for_device);
+       ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_cpu);
+       ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_device);
+       ASSIGN_VMD_DMA_OPS(source, dest, mapping_error);
+       ASSIGN_VMD_DMA_OPS(source, dest, dma_supported);
+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+       ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
+#endif
+       add_dma_domain(domain);
+}
+#undef ASSIGN_VMD_DMA_OPS
+#else
+static void vmd_teardown_dma_ops(struct vmd_dev *vmd) {}
+static void vmd_setup_dma_ops(struct vmd_dev *vmd) {}
+#endif
+
+static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,
+                                 unsigned int devfn, int reg, int len)
+{
+       char __iomem *addr = vmd->cfgbar +
+                            (bus->number << 20) + (devfn << 12) + reg;
+
+       if ((addr - vmd->cfgbar) + len >=
+           resource_size(&vmd->dev->resource[VMD_CFGBAR]))
+               return NULL;
+
+       return addr;
+}
+
+/*
+ * CPU may deadlock if config space is not serialized on some versions of this
+ * hardware, so all config space access is done under a spinlock.
+ */
+static int vmd_pci_read(struct pci_bus *bus, unsigned int devfn, int reg,
+                       int len, u32 *value)
+{
+       struct vmd_dev *vmd = vmd_from_bus(bus);
+       char __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len);
+       unsigned long flags;
+       int ret = 0;
+
+       if (!addr)
+               return -EFAULT;
+
+       spin_lock_irqsave(&vmd->cfg_lock, flags);
+       switch (len) {
+       case 1:
+               *value = readb(addr);
+               break;
+       case 2:
+               *value = readw(addr);
+               break;
+       case 4:
+               *value = readl(addr);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       spin_unlock_irqrestore(&vmd->cfg_lock, flags);
+       return ret;
+}
+
+/*
+ * VMD h/w converts non-posted config writes to posted memory writes. The
+ * read-back in this function forces the completion so it returns only after
+ * the config space was written, as expected.
+ */
+static int vmd_pci_write(struct pci_bus *bus, unsigned int devfn, int reg,
+                        int len, u32 value)
+{
+       struct vmd_dev *vmd = vmd_from_bus(bus);
+       char __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len);
+       unsigned long flags;
+       int ret = 0;
+
+       if (!addr)
+               return -EFAULT;
+
+       spin_lock_irqsave(&vmd->cfg_lock, flags);
+       switch (len) {
+       case 1:
+               writeb(value, addr);
+               readb(addr);
+               break;
+       case 2:
+               writew(value, addr);
+               readw(addr);
+               break;
+       case 4:
+               writel(value, addr);
+               readl(addr);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       spin_unlock_irqrestore(&vmd->cfg_lock, flags);
+       return ret;
+}
+
+static struct pci_ops vmd_ops = {
+       .read           = vmd_pci_read,
+       .write          = vmd_pci_write,
+};
+
+/*
+ * VMD domains start at 0x1000 to not clash with ACPI _SEG domains.
+ */
+static int vmd_find_free_domain(void)
+{
+       int domain = 0xffff;
+       struct pci_bus *bus = NULL;
+
+       while ((bus = pci_find_next_bus(bus)) != NULL)
+               domain = max_t(int, domain, pci_domain_nr(bus));
+       return domain + 1;
+}
+
+static int vmd_enable_domain(struct vmd_dev *vmd)
+{
+       struct pci_sysdata *sd = &vmd->sysdata;
+       struct resource *res;
+       u32 upper_bits;
+       unsigned long flags;
+       LIST_HEAD(resources);
+
+       res = &vmd->dev->resource[VMD_CFGBAR];
+       vmd->resources[0] = (struct resource) {
+               .name  = "VMD CFGBAR",
+               .start = res->start,
+               .end   = (resource_size(res) >> 20) - 1,
+               .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,
+       };
+
+       res = &vmd->dev->resource[VMD_MEMBAR1];
+       upper_bits = upper_32_bits(res->end);
+       flags = res->flags & ~IORESOURCE_SIZEALIGN;
+       if (!upper_bits)
+               flags &= ~IORESOURCE_MEM_64;
+       vmd->resources[1] = (struct resource) {
+               .name  = "VMD MEMBAR1",
+               .start = res->start,
+               .end   = res->end,
+               .flags = flags,
+       };
+
+       res = &vmd->dev->resource[VMD_MEMBAR2];
+       upper_bits = upper_32_bits(res->end);
+       flags = res->flags & ~IORESOURCE_SIZEALIGN;
+       if (!upper_bits)
+               flags &= ~IORESOURCE_MEM_64;
+       vmd->resources[2] = (struct resource) {
+               .name  = "VMD MEMBAR2",
+               .start = res->start + 0x2000,
+               .end   = res->end,
+               .flags = flags,
+       };
+
+       sd->domain = vmd_find_free_domain();
+       if (sd->domain < 0)
+               return sd->domain;
+
+       sd->node = pcibus_to_node(vmd->dev->bus);
+
+       vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info,
+                                                   NULL);
+       if (!vmd->irq_domain)
+               return -ENODEV;
+
+       pci_add_resource(&resources, &vmd->resources[0]);
+       pci_add_resource(&resources, &vmd->resources[1]);
+       pci_add_resource(&resources, &vmd->resources[2]);
+       vmd->bus = pci_create_root_bus(&vmd->dev->dev, 0, &vmd_ops, sd,
+                                      &resources);
+       if (!vmd->bus) {
+               pci_free_resource_list(&resources);
+               irq_domain_remove(vmd->irq_domain);
+               return -ENODEV;
+       }
+
+       vmd_setup_dma_ops(vmd);
+       dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain);
+       pci_rescan_bus(vmd->bus);
+
+       WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
+                              "domain"), "Can't create symlink to domain\n");
+       return 0;
+}
+
+static irqreturn_t vmd_irq(int irq, void *data)
+{
+       struct vmd_irq_list *irqs = data;
+       struct vmd_irq *vmdirq;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(vmdirq, &irqs->irq_list, node)
+               generic_handle_irq(vmdirq->virq);
+       rcu_read_unlock();
+
+       return IRQ_HANDLED;
+}
+
+static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+       struct vmd_dev *vmd;
+       int i, err;
+
+       if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20))
+               return -ENOMEM;
+
+       vmd = devm_kzalloc(&dev->dev, sizeof(*vmd), GFP_KERNEL);
+       if (!vmd)
+               return -ENOMEM;
+
+       vmd->dev = dev;
+       err = pcim_enable_device(dev);
+       if (err < 0)
+               return err;
+
+       vmd->cfgbar = pcim_iomap(dev, VMD_CFGBAR, 0);
+       if (!vmd->cfgbar)
+               return -ENOMEM;
+
+       pci_set_master(dev);
+       if (dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64)) &&
+           dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)))
+               return -ENODEV;
+
+       vmd->msix_count = pci_msix_vec_count(dev);
+       if (vmd->msix_count < 0)
+               return -ENODEV;
+
+       vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs),
+                                GFP_KERNEL);
+       if (!vmd->irqs)
+               return -ENOMEM;
+
+       vmd->msix_entries = devm_kcalloc(&dev->dev, vmd->msix_count,
+                                        sizeof(*vmd->msix_entries),
+                                        GFP_KERNEL);
+       if (!vmd->msix_entries)
+               return -ENOMEM;
+       for (i = 0; i < vmd->msix_count; i++)
+               vmd->msix_entries[i].entry = i;
+
+       vmd->msix_count = pci_enable_msix_range(vmd->dev, vmd->msix_entries, 1,
+                                               vmd->msix_count);
+       if (vmd->msix_count < 0)
+               return vmd->msix_count;
+
+       for (i = 0; i < vmd->msix_count; i++) {
+               INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
+               vmd->irqs[i].vmd_vector = vmd->msix_entries[i].vector;
+               vmd->irqs[i].index = i;
+
+               err = devm_request_irq(&dev->dev, vmd->irqs[i].vmd_vector,
+                                      vmd_irq, 0, "vmd", &vmd->irqs[i]);
+               if (err)
+                       return err;
+       }
+
+       spin_lock_init(&vmd->cfg_lock);
+       pci_set_drvdata(dev, vmd);
+       err = vmd_enable_domain(vmd);
+       if (err)
+               return err;
+
+       dev_info(&vmd->dev->dev, "Bound to PCI domain %04x\n",
+                vmd->sysdata.domain);
+       return 0;
+}
+
+static void vmd_remove(struct pci_dev *dev)
+{
+       struct vmd_dev *vmd = pci_get_drvdata(dev);
+
+       pci_set_drvdata(dev, NULL);
+       sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
+       pci_stop_root_bus(vmd->bus);
+       pci_remove_root_bus(vmd->bus);
+       vmd_teardown_dma_ops(vmd);
+       irq_domain_remove(vmd->irq_domain);
+}
+
+#ifdef CONFIG_PM
+static int vmd_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       pci_save_state(pdev);
+       return 0;
+}
+
+static int vmd_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       pci_restore_state(pdev);
+       return 0;
+}
+#endif
+static SIMPLE_DEV_PM_OPS(vmd_dev_pm_ops, vmd_suspend, vmd_resume);
+
+static const struct pci_device_id vmd_ids[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x201d),},
+       {0,}
+};
+MODULE_DEVICE_TABLE(pci, vmd_ids);
+
+static struct pci_driver vmd_drv = {
+       .name           = "vmd",
+       .id_table       = vmd_ids,
+       .probe          = vmd_probe,
+       .remove         = vmd_remove,
+       .driver         = {
+               .pm     = &vmd_dev_pm_ops,
+       },
+};
+module_pci_driver(vmd_drv);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.6");
index 2730d77..3e75fcf 100644 (file)
@@ -70,3 +70,4 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \
                   -I$(srctree)/arch/x86/boot
 KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
+UBSAN_SANITIZE := n
index 82044f7..e9df156 100644 (file)
@@ -15,7 +15,6 @@ config XTENSA
        select GENERIC_PCI_IOMAP
        select GENERIC_SCHED_CLOCK
        select HAVE_DMA_API_DEBUG
-       select HAVE_DMA_ATTRS
        select HAVE_FUNCTION_TRACER
        select HAVE_FUTEX_CMPXCHG if !MMU
        select HAVE_IRQ_TIME_ACCOUNTING
index 66c9ba2..3fc1170 100644 (file)
@@ -13,8 +13,6 @@
 #include <asm/cache.h>
 #include <asm/io.h>
 
-#include <asm-generic/dma-coherent.h>
-
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 
@@ -30,8 +28,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
                return &xtensa_dma_map_ops;
 }
 
-#include <asm-generic/dma-mapping-common.h>
-
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                    enum dma_data_direction direction);
 
index d030594..9e079d4 100644 (file)
@@ -86,7 +86,6 @@
 #define MADV_SEQUENTIAL        2               /* expect sequential page references */
 #define MADV_WILLNEED  3               /* will need these pages */
 #define MADV_DONTNEED  4               /* don't need these pages */
-#define MADV_FREE      5               /* free pages only if memory pressure */
 
 /* common parameters: try to keep these consistent across architectures */
 #define MADV_FREE      8               /* free pages only if memory pressure */
index db5f622..9eda232 100644 (file)
@@ -5,7 +5,7 @@
 obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-tag.o blk-sysfs.o \
                        blk-flush.o blk-settings.o blk-ioc.o blk-map.o \
                        blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
-                       blk-iopoll.o blk-lib.o blk-mq.o blk-mq-tag.o \
+                       blk-lib.o blk-mq.o blk-mq-tag.o \
                        blk-mq-sysfs.o blk-mq-cpu.o blk-mq-cpumap.o ioctl.o \
                        genhd.o scsi_ioctl.o partition-generic.o ioprio.o \
                        badblocks.o partitions/
index f6325d5..711e4d8 100644 (file)
@@ -66,7 +66,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
        }
 
        if (unlikely(!bip))
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        memset(bip, 0, sizeof(*bip));
 
@@ -89,7 +89,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
        return bip;
 err:
        mempool_free(bip, bs->bio_integrity_pool);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL(bio_integrity_alloc);
 
@@ -298,10 +298,10 @@ int bio_integrity_prep(struct bio *bio)
 
        /* Allocate bio integrity payload and integrity vectors */
        bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
-       if (unlikely(bip == NULL)) {
+       if (IS_ERR(bip)) {
                printk(KERN_ERR "could not allocate data integrity bioset\n");
                kfree(buf);
-               return -EIO;
+               return PTR_ERR(bip);
        }
 
        bip->bip_flags |= BIP_BLOCK_INTEGRITY;
@@ -465,9 +465,8 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
        BUG_ON(bip_src == NULL);
 
        bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
-
-       if (bip == NULL)
-               return -EIO;
+       if (IS_ERR(bip))
+               return PTR_ERR(bip);
 
        memcpy(bip->bip_vec, bip_src->bip_vec,
               bip_src->bip_vcnt * sizeof(struct bio_vec));
index 476244d..ab51685 100644 (file)
@@ -680,6 +680,13 @@ static void blk_queue_usage_counter_release(struct percpu_ref *ref)
        wake_up_all(&q->mq_freeze_wq);
 }
 
+static void blk_rq_timed_out_timer(unsigned long data)
+{
+       struct request_queue *q = (struct request_queue *)data;
+
+       kblockd_schedule_work(&q->timeout_work);
+}
+
 struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 {
        struct request_queue *q;
@@ -841,6 +848,7 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
        if (blk_init_rl(&q->root_rl, q, GFP_KERNEL))
                goto fail;
 
+       INIT_WORK(&q->timeout_work, blk_timeout_work);
        q->request_fn           = rfn;
        q->prep_rq_fn           = NULL;
        q->unprep_rq_fn         = NULL;
diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c
deleted file mode 100644 (file)
index 0736729..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Functions related to interrupt-poll handling in the block layer. This
- * is similar to NAPI for network devices.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/bio.h>
-#include <linux/blkdev.h>
-#include <linux/interrupt.h>
-#include <linux/cpu.h>
-#include <linux/blk-iopoll.h>
-#include <linux/delay.h>
-
-#include "blk.h"
-
-static unsigned int blk_iopoll_budget __read_mostly = 256;
-
-static DEFINE_PER_CPU(struct list_head, blk_cpu_iopoll);
-
-/**
- * blk_iopoll_sched - Schedule a run of the iopoll handler
- * @iop:      The parent iopoll structure
- *
- * Description:
- *     Add this blk_iopoll structure to the pending poll list and trigger the
- *     raise of the blk iopoll softirq. The driver must already have gotten a
- *     successful return from blk_iopoll_sched_prep() before calling this.
- **/
-void blk_iopoll_sched(struct blk_iopoll *iop)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       list_add_tail(&iop->list, this_cpu_ptr(&blk_cpu_iopoll));
-       __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(blk_iopoll_sched);
-
-/**
- * __blk_iopoll_complete - Mark this @iop as un-polled again
- * @iop:      The parent iopoll structure
- *
- * Description:
- *     See blk_iopoll_complete(). This function must be called with interrupts
- *     disabled.
- **/
-void __blk_iopoll_complete(struct blk_iopoll *iop)
-{
-       list_del(&iop->list);
-       smp_mb__before_atomic();
-       clear_bit_unlock(IOPOLL_F_SCHED, &iop->state);
-}
-EXPORT_SYMBOL(__blk_iopoll_complete);
-
-/**
- * blk_iopoll_complete - Mark this @iop as un-polled again
- * @iop:      The parent iopoll structure
- *
- * Description:
- *     If a driver consumes less than the assigned budget in its run of the
- *     iopoll handler, it'll end the polled mode by calling this function. The
- *     iopoll handler will not be invoked again before blk_iopoll_sched_prep()
- *     is called.
- **/
-void blk_iopoll_complete(struct blk_iopoll *iop)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       __blk_iopoll_complete(iop);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(blk_iopoll_complete);
-
-static void blk_iopoll_softirq(struct softirq_action *h)
-{
-       struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll);
-       int rearm = 0, budget = blk_iopoll_budget;
-       unsigned long start_time = jiffies;
-
-       local_irq_disable();
-
-       while (!list_empty(list)) {
-               struct blk_iopoll *iop;
-               int work, weight;
-
-               /*
-                * If softirq window is exhausted then punt.
-                */
-               if (budget <= 0 || time_after(jiffies, start_time)) {
-                       rearm = 1;
-                       break;
-               }
-
-               local_irq_enable();
-
-               /* Even though interrupts have been re-enabled, this
-                * access is safe because interrupts can only add new
-                * entries to the tail of this list, and only ->poll()
-                * calls can remove this head entry from the list.
-                */
-               iop = list_entry(list->next, struct blk_iopoll, list);
-
-               weight = iop->weight;
-               work = 0;
-               if (test_bit(IOPOLL_F_SCHED, &iop->state))
-                       work = iop->poll(iop, weight);
-
-               budget -= work;
-
-               local_irq_disable();
-
-               /*
-                * Drivers must not modify the iopoll state, if they
-                * consume their assigned weight (or more, some drivers can't
-                * easily just stop processing, they have to complete an
-                * entire mask of commands).In such cases this code
-                * still "owns" the iopoll instance and therefore can
-                * move the instance around on the list at-will.
-                */
-               if (work >= weight) {
-                       if (blk_iopoll_disable_pending(iop))
-                               __blk_iopoll_complete(iop);
-                       else
-                               list_move_tail(&iop->list, list);
-               }
-       }
-
-       if (rearm)
-               __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ);
-
-       local_irq_enable();
-}
-
-/**
- * blk_iopoll_disable - Disable iopoll on this @iop
- * @iop:      The parent iopoll structure
- *
- * Description:
- *     Disable io polling and wait for any pending callbacks to have completed.
- **/
-void blk_iopoll_disable(struct blk_iopoll *iop)
-{
-       set_bit(IOPOLL_F_DISABLE, &iop->state);
-       while (test_and_set_bit(IOPOLL_F_SCHED, &iop->state))
-               msleep(1);
-       clear_bit(IOPOLL_F_DISABLE, &iop->state);
-}
-EXPORT_SYMBOL(blk_iopoll_disable);
-
-/**
- * blk_iopoll_enable - Enable iopoll on this @iop
- * @iop:      The parent iopoll structure
- *
- * Description:
- *     Enable iopoll on this @iop. Note that the handler run will not be
- *     scheduled, it will only mark it as active.
- **/
-void blk_iopoll_enable(struct blk_iopoll *iop)
-{
-       BUG_ON(!test_bit(IOPOLL_F_SCHED, &iop->state));
-       smp_mb__before_atomic();
-       clear_bit_unlock(IOPOLL_F_SCHED, &iop->state);
-}
-EXPORT_SYMBOL(blk_iopoll_enable);
-
-/**
- * blk_iopoll_init - Initialize this @iop
- * @iop:      The parent iopoll structure
- * @weight:   The default weight (or command completion budget)
- * @poll_fn:  The handler to invoke
- *
- * Description:
- *     Initialize this blk_iopoll structure. Before being actively used, the
- *     driver must call blk_iopoll_enable().
- **/
-void blk_iopoll_init(struct blk_iopoll *iop, int weight, blk_iopoll_fn *poll_fn)
-{
-       memset(iop, 0, sizeof(*iop));
-       INIT_LIST_HEAD(&iop->list);
-       iop->weight = weight;
-       iop->poll = poll_fn;
-       set_bit(IOPOLL_F_SCHED, &iop->state);
-}
-EXPORT_SYMBOL(blk_iopoll_init);
-
-static int blk_iopoll_cpu_notify(struct notifier_block *self,
-                                unsigned long action, void *hcpu)
-{
-       /*
-        * If a CPU goes away, splice its entries to the current CPU
-        * and trigger a run of the softirq
-        */
-       if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
-               int cpu = (unsigned long) hcpu;
-
-               local_irq_disable();
-               list_splice_init(&per_cpu(blk_cpu_iopoll, cpu),
-                                this_cpu_ptr(&blk_cpu_iopoll));
-               __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ);
-               local_irq_enable();
-       }
-
-       return NOTIFY_OK;
-}
-
-static struct notifier_block blk_iopoll_cpu_notifier = {
-       .notifier_call  = blk_iopoll_cpu_notify,
-};
-
-static __init int blk_iopoll_setup(void)
-{
-       int i;
-
-       for_each_possible_cpu(i)
-               INIT_LIST_HEAD(&per_cpu(blk_cpu_iopoll, i));
-
-       open_softirq(BLOCK_IOPOLL_SOFTIRQ, blk_iopoll_softirq);
-       register_hotcpu_notifier(&blk_iopoll_cpu_notifier);
-       return 0;
-}
-subsys_initcall(blk_iopoll_setup);
index 6889d71..4c0622f 100644 (file)
@@ -603,8 +603,6 @@ static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
                        blk_mq_complete_request(rq, -EIO);
                return;
        }
-       if (rq->cmd_flags & REQ_NO_TIMEOUT)
-               return;
 
        if (time_after_eq(jiffies, rq->deadline)) {
                if (!blk_mark_rq_complete(rq))
@@ -615,15 +613,19 @@ static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
        }
 }
 
-static void blk_mq_rq_timer(unsigned long priv)
+static void blk_mq_timeout_work(struct work_struct *work)
 {
-       struct request_queue *q = (struct request_queue *)priv;
+       struct request_queue *q =
+               container_of(work, struct request_queue, timeout_work);
        struct blk_mq_timeout_data data = {
                .next           = 0,
                .next_set       = 0,
        };
        int i;
 
+       if (blk_queue_enter(q, true))
+               return;
+
        blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &data);
 
        if (data.next_set) {
@@ -638,6 +640,7 @@ static void blk_mq_rq_timer(unsigned long priv)
                                blk_mq_tag_idle(hctx);
                }
        }
+       blk_queue_exit(q);
 }
 
 /*
@@ -2008,7 +2011,7 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
                hctxs[i]->queue_num = i;
        }
 
-       setup_timer(&q->timeout, blk_mq_rq_timer, (unsigned long) q);
+       INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
        blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
 
        q->nr_queues = nr_cpu_ids;
index 3610af5..a30441a 100644 (file)
@@ -127,13 +127,16 @@ static void blk_rq_check_expired(struct request *rq, unsigned long *next_timeout
        }
 }
 
-void blk_rq_timed_out_timer(unsigned long data)
+void blk_timeout_work(struct work_struct *work)
 {
-       struct request_queue *q = (struct request_queue *) data;
+       struct request_queue *q =
+               container_of(work, struct request_queue, timeout_work);
        unsigned long flags, next = 0;
        struct request *rq, *tmp;
        int next_set = 0;
 
+       if (blk_queue_enter(q, true))
+               return;
        spin_lock_irqsave(q->queue_lock, flags);
 
        list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list)
@@ -143,6 +146,7 @@ void blk_rq_timed_out_timer(unsigned long data)
                mod_timer(&q->timeout, round_jiffies_up(next));
 
        spin_unlock_irqrestore(q->queue_lock, flags);
+       blk_queue_exit(q);
 }
 
 /**
@@ -193,9 +197,6 @@ void blk_add_timer(struct request *req)
        struct request_queue *q = req->q;
        unsigned long expiry;
 
-       if (req->cmd_flags & REQ_NO_TIMEOUT)
-               return;
-
        /* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */
        if (!q->mq_ops && !q->rq_timed_out_fn)
                return;
index c43926d..70e4aee 100644 (file)
@@ -93,7 +93,7 @@ static inline void blk_flush_integrity(void)
 }
 #endif
 
-void blk_rq_timed_out_timer(unsigned long data);
+void blk_timeout_work(struct work_struct *work);
 unsigned long blk_rq_timeout(unsigned long timeout);
 void blk_add_timer(struct request *req);
 void blk_delete_timer(struct request *);
index 2c84683..77f5d17 100644 (file)
@@ -455,12 +455,12 @@ static int blkdev_daxset(struct block_device *bdev, unsigned long argp)
        if (arg && !blkdev_dax_capable(bdev))
                return -ENOTTY;
 
-       mutex_lock(&bdev->bd_inode->i_mutex);
+       inode_lock(bdev->bd_inode);
        if (bdev->bd_map_count == 0)
                inode_set_flags(bdev->bd_inode, arg, S_DAX);
        else
                rc = -EBUSY;
-       mutex_unlock(&bdev->bd_inode->i_mutex);
+       inode_unlock(bdev->bd_inode);
        return rc;
 }
 #else
index a8e7aa3..f5e18c2 100644 (file)
@@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type)
                goto unlock;
 
        type->ops->owner = THIS_MODULE;
+       if (type->ops_nokey)
+               type->ops_nokey->owner = THIS_MODULE;
        node->type = type;
        list_add(&node->list, &alg_types);
        err = 0;
@@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock)
 }
 EXPORT_SYMBOL_GPL(af_alg_release);
 
+void af_alg_release_parent(struct sock *sk)
+{
+       struct alg_sock *ask = alg_sk(sk);
+       unsigned int nokey = ask->nokey_refcnt;
+       bool last = nokey && !ask->refcnt;
+
+       sk = ask->parent;
+       ask = alg_sk(sk);
+
+       lock_sock(sk);
+       ask->nokey_refcnt -= nokey;
+       if (!last)
+               last = !--ask->refcnt;
+       release_sock(sk);
+
+       if (last)
+               sock_put(sk);
+}
+EXPORT_SYMBOL_GPL(af_alg_release_parent);
+
 static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        const u32 forbidden = CRYPTO_ALG_INTERNAL;
@@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct sockaddr_alg *sa = (void *)uaddr;
        const struct af_alg_type *type;
        void *private;
+       int err;
 
        if (sock->state == SS_CONNECTED)
                return -EINVAL;
@@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                return PTR_ERR(private);
        }
 
+       err = -EBUSY;
        lock_sock(sk);
+       if (ask->refcnt | ask->nokey_refcnt)
+               goto unlock;
 
        swap(ask->type, type);
        swap(ask->private, private);
 
+       err = 0;
+
+unlock:
        release_sock(sk);
 
        alg_do_release(type, private);
 
-       return 0;
+       return err;
 }
 
 static int alg_setkey(struct sock *sk, char __user *ukey,
@@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
        struct sock *sk = sock->sk;
        struct alg_sock *ask = alg_sk(sk);
        const struct af_alg_type *type;
-       int err = -ENOPROTOOPT;
+       int err = -EBUSY;
 
        lock_sock(sk);
+       if (ask->refcnt)
+               goto unlock;
+
        type = ask->type;
 
+       err = -ENOPROTOOPT;
        if (level != SOL_ALG || !type)
                goto unlock;
 
@@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
        struct alg_sock *ask = alg_sk(sk);
        const struct af_alg_type *type;
        struct sock *sk2;
+       unsigned int nokey;
        int err;
 
        lock_sock(sk);
@@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
        security_sk_clone(sk, sk2);
 
        err = type->accept(ask->private, sk2);
-       if (err) {
-               sk_free(sk2);
+
+       nokey = err == -ENOKEY;
+       if (nokey && type->accept_nokey)
+               err = type->accept_nokey(ask->private, sk2);
+
+       if (err)
                goto unlock;
-       }
 
        sk2->sk_family = PF_ALG;
 
-       sock_hold(sk);
+       if (nokey || !ask->refcnt++)
+               sock_hold(sk);
+       ask->nokey_refcnt += nokey;
        alg_sk(sk2)->parent = sk;
        alg_sk(sk2)->type = type;
+       alg_sk(sk2)->nokey_refcnt = nokey;
 
        newsock->ops = type->ops;
        newsock->state = SS_CONNECTED;
 
+       if (nokey)
+               newsock->ops = type->ops_nokey;
+
        err = 0;
 
 unlock:
index 9c1dc8d..d19b523 100644 (file)
@@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
        struct ahash_alg *alg = crypto_ahash_alg(hash);
 
        hash->setkey = ahash_nosetkey;
+       hash->has_setkey = false;
        hash->export = ahash_no_export;
        hash->import = ahash_no_import;
 
@@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
        hash->finup = alg->finup ?: ahash_def_finup;
        hash->digest = alg->digest;
 
-       if (alg->setkey)
+       if (alg->setkey) {
                hash->setkey = alg->setkey;
+               hash->has_setkey = true;
+       }
        if (alg->export)
                hash->export = alg->export;
        if (alg->import)
index b4c24fe..608a756 100644 (file)
@@ -34,6 +34,11 @@ struct hash_ctx {
        struct ahash_request req;
 };
 
+struct algif_hash_tfm {
+       struct crypto_ahash *hash;
+       bool has_key;
+};
+
 static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
                        size_t ignored)
 {
@@ -235,19 +240,151 @@ static struct proto_ops algif_hash_ops = {
        .accept         =       hash_accept,
 };
 
+static int hash_check_key(struct socket *sock)
+{
+       int err = 0;
+       struct sock *psk;
+       struct alg_sock *pask;
+       struct algif_hash_tfm *tfm;
+       struct sock *sk = sock->sk;
+       struct alg_sock *ask = alg_sk(sk);
+
+       lock_sock(sk);
+       if (ask->refcnt)
+               goto unlock_child;
+
+       psk = ask->parent;
+       pask = alg_sk(ask->parent);
+       tfm = pask->private;
+
+       err = -ENOKEY;
+       lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+       if (!tfm->has_key)
+               goto unlock;
+
+       if (!pask->refcnt++)
+               sock_hold(psk);
+
+       ask->refcnt = 1;
+       sock_put(psk);
+
+       err = 0;
+
+unlock:
+       release_sock(psk);
+unlock_child:
+       release_sock(sk);
+
+       return err;
+}
+
+static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+                             size_t size)
+{
+       int err;
+
+       err = hash_check_key(sock);
+       if (err)
+               return err;
+
+       return hash_sendmsg(sock, msg, size);
+}
+
+static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
+                                  int offset, size_t size, int flags)
+{
+       int err;
+
+       err = hash_check_key(sock);
+       if (err)
+               return err;
+
+       return hash_sendpage(sock, page, offset, size, flags);
+}
+
+static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+                             size_t ignored, int flags)
+{
+       int err;
+
+       err = hash_check_key(sock);
+       if (err)
+               return err;
+
+       return hash_recvmsg(sock, msg, ignored, flags);
+}
+
+static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
+                            int flags)
+{
+       int err;
+
+       err = hash_check_key(sock);
+       if (err)
+               return err;
+
+       return hash_accept(sock, newsock, flags);
+}
+
+static struct proto_ops algif_hash_ops_nokey = {
+       .family         =       PF_ALG,
+
+       .connect        =       sock_no_connect,
+       .socketpair     =       sock_no_socketpair,
+       .getname        =       sock_no_getname,
+       .ioctl          =       sock_no_ioctl,
+       .listen         =       sock_no_listen,
+       .shutdown       =       sock_no_shutdown,
+       .getsockopt     =       sock_no_getsockopt,
+       .mmap           =       sock_no_mmap,
+       .bind           =       sock_no_bind,
+       .setsockopt     =       sock_no_setsockopt,
+       .poll           =       sock_no_poll,
+
+       .release        =       af_alg_release,
+       .sendmsg        =       hash_sendmsg_nokey,
+       .sendpage       =       hash_sendpage_nokey,
+       .recvmsg        =       hash_recvmsg_nokey,
+       .accept         =       hash_accept_nokey,
+};
+
 static void *hash_bind(const char *name, u32 type, u32 mask)
 {
-       return crypto_alloc_ahash(name, type, mask);
+       struct algif_hash_tfm *tfm;
+       struct crypto_ahash *hash;
+
+       tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+       if (!tfm)
+               return ERR_PTR(-ENOMEM);
+
+       hash = crypto_alloc_ahash(name, type, mask);
+       if (IS_ERR(hash)) {
+               kfree(tfm);
+               return ERR_CAST(hash);
+       }
+
+       tfm->hash = hash;
+
+       return tfm;
 }
 
 static void hash_release(void *private)
 {
-       crypto_free_ahash(private);
+       struct algif_hash_tfm *tfm = private;
+
+       crypto_free_ahash(tfm->hash);
+       kfree(tfm);
 }
 
 static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-       return crypto_ahash_setkey(private, key, keylen);
+       struct algif_hash_tfm *tfm = private;
+       int err;
+
+       err = crypto_ahash_setkey(tfm->hash, key, keylen);
+       tfm->has_key = !err;
+
+       return err;
 }
 
 static void hash_sock_destruct(struct sock *sk)
@@ -261,12 +398,14 @@ static void hash_sock_destruct(struct sock *sk)
        af_alg_release_parent(sk);
 }
 
-static int hash_accept_parent(void *private, struct sock *sk)
+static int hash_accept_parent_nokey(void *private, struct sock *sk)
 {
        struct hash_ctx *ctx;
        struct alg_sock *ask = alg_sk(sk);
-       unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
-       unsigned ds = crypto_ahash_digestsize(private);
+       struct algif_hash_tfm *tfm = private;
+       struct crypto_ahash *hash = tfm->hash;
+       unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
+       unsigned ds = crypto_ahash_digestsize(hash);
 
        ctx = sock_kmalloc(sk, len, GFP_KERNEL);
        if (!ctx)
@@ -286,7 +425,7 @@ static int hash_accept_parent(void *private, struct sock *sk)
 
        ask->private = ctx;
 
-       ahash_request_set_tfm(&ctx->req, private);
+       ahash_request_set_tfm(&ctx->req, hash);
        ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                   af_alg_complete, &ctx->completion);
 
@@ -295,12 +434,24 @@ static int hash_accept_parent(void *private, struct sock *sk)
        return 0;
 }
 
+static int hash_accept_parent(void *private, struct sock *sk)
+{
+       struct algif_hash_tfm *tfm = private;
+
+       if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
+               return -ENOKEY;
+
+       return hash_accept_parent_nokey(private, sk);
+}
+
 static const struct af_alg_type algif_type_hash = {
        .bind           =       hash_bind,
        .release        =       hash_release,
        .setkey         =       hash_setkey,
        .accept         =       hash_accept_parent,
+       .accept_nokey   =       hash_accept_parent_nokey,
        .ops            =       &algif_hash_ops,
+       .ops_nokey      =       &algif_hash_ops_nokey,
        .name           =       "hash",
        .owner          =       THIS_MODULE
 };
index eaa9f9b..38c1aa8 100644 (file)
@@ -31,6 +31,11 @@ struct skcipher_sg_list {
        struct scatterlist sg[0];
 };
 
+struct skcipher_tfm {
+       struct crypto_skcipher *skcipher;
+       bool has_key;
+};
+
 struct skcipher_ctx {
        struct list_head tsgl;
        struct af_alg_sgl rsgl;
@@ -387,7 +392,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
 
                sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
                sg = sgl->sg;
-               sg_unmark_end(sg + sgl->cur);
+               if (sgl->cur)
+                       sg_unmark_end(sg + sgl->cur - 1);
                do {
                        i = sgl->cur;
                        plen = min_t(size_t, len, PAGE_SIZE);
@@ -642,13 +648,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
 
        lock_sock(sk);
        while (msg_data_left(msg)) {
-               sgl = list_first_entry(&ctx->tsgl,
-                                      struct skcipher_sg_list, list);
-               sg = sgl->sg;
-
-               while (!sg->length)
-                       sg++;
-
                if (!ctx->used) {
                        err = skcipher_wait_for_data(sk, flags);
                        if (err)
@@ -669,6 +668,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
                if (!used)
                        goto free;
 
+               sgl = list_first_entry(&ctx->tsgl,
+                                      struct skcipher_sg_list, list);
+               sg = sgl->sg;
+
+               while (!sg->length)
+                       sg++;
+
                skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
                                           ctx->iv);
 
@@ -748,19 +754,139 @@ static struct proto_ops algif_skcipher_ops = {
        .poll           =       skcipher_poll,
 };
 
+static int skcipher_check_key(struct socket *sock)
+{
+       int err = 0;
+       struct sock *psk;
+       struct alg_sock *pask;
+       struct skcipher_tfm *tfm;
+       struct sock *sk = sock->sk;
+       struct alg_sock *ask = alg_sk(sk);
+
+       lock_sock(sk);
+       if (ask->refcnt)
+               goto unlock_child;
+
+       psk = ask->parent;
+       pask = alg_sk(ask->parent);
+       tfm = pask->private;
+
+       err = -ENOKEY;
+       lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+       if (!tfm->has_key)
+               goto unlock;
+
+       if (!pask->refcnt++)
+               sock_hold(psk);
+
+       ask->refcnt = 1;
+       sock_put(psk);
+
+       err = 0;
+
+unlock:
+       release_sock(psk);
+unlock_child:
+       release_sock(sk);
+
+       return err;
+}
+
+static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+                                 size_t size)
+{
+       int err;
+
+       err = skcipher_check_key(sock);
+       if (err)
+               return err;
+
+       return skcipher_sendmsg(sock, msg, size);
+}
+
+static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
+                                      int offset, size_t size, int flags)
+{
+       int err;
+
+       err = skcipher_check_key(sock);
+       if (err)
+               return err;
+
+       return skcipher_sendpage(sock, page, offset, size, flags);
+}
+
+static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+                                 size_t ignored, int flags)
+{
+       int err;
+
+       err = skcipher_check_key(sock);
+       if (err)
+               return err;
+
+       return skcipher_recvmsg(sock, msg, ignored, flags);
+}
+
+static struct proto_ops algif_skcipher_ops_nokey = {
+       .family         =       PF_ALG,
+
+       .connect        =       sock_no_connect,
+       .socketpair     =       sock_no_socketpair,
+       .getname        =       sock_no_getname,
+       .ioctl          =       sock_no_ioctl,
+       .listen         =       sock_no_listen,
+       .shutdown       =       sock_no_shutdown,
+       .getsockopt     =       sock_no_getsockopt,
+       .mmap           =       sock_no_mmap,
+       .bind           =       sock_no_bind,
+       .accept         =       sock_no_accept,
+       .setsockopt     =       sock_no_setsockopt,
+
+       .release        =       af_alg_release,
+       .sendmsg        =       skcipher_sendmsg_nokey,
+       .sendpage       =       skcipher_sendpage_nokey,
+       .recvmsg        =       skcipher_recvmsg_nokey,
+       .poll           =       skcipher_poll,
+};
+
 static void *skcipher_bind(const char *name, u32 type, u32 mask)
 {
-       return crypto_alloc_skcipher(name, type, mask);
+       struct skcipher_tfm *tfm;
+       struct crypto_skcipher *skcipher;
+
+       tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+       if (!tfm)
+               return ERR_PTR(-ENOMEM);
+
+       skcipher = crypto_alloc_skcipher(name, type, mask);
+       if (IS_ERR(skcipher)) {
+               kfree(tfm);
+               return ERR_CAST(skcipher);
+       }
+
+       tfm->skcipher = skcipher;
+
+       return tfm;
 }
 
 static void skcipher_release(void *private)
 {
-       crypto_free_skcipher(private);
+       struct skcipher_tfm *tfm = private;
+
+       crypto_free_skcipher(tfm->skcipher);
+       kfree(tfm);
 }
 
 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-       return crypto_skcipher_setkey(private, key, keylen);
+       struct skcipher_tfm *tfm = private;
+       int err;
+
+       err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
+       tfm->has_key = !err;
+
+       return err;
 }
 
 static void skcipher_wait(struct sock *sk)
@@ -788,24 +914,26 @@ static void skcipher_sock_destruct(struct sock *sk)
        af_alg_release_parent(sk);
 }
 
-static int skcipher_accept_parent(void *private, struct sock *sk)
+static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
 {
        struct skcipher_ctx *ctx;
        struct alg_sock *ask = alg_sk(sk);
-       unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private);
+       struct skcipher_tfm *tfm = private;
+       struct crypto_skcipher *skcipher = tfm->skcipher;
+       unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(skcipher);
 
        ctx = sock_kmalloc(sk, len, GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
 
-       ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private),
+       ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
                               GFP_KERNEL);
        if (!ctx->iv) {
                sock_kfree_s(sk, ctx, len);
                return -ENOMEM;
        }
 
-       memset(ctx->iv, 0, crypto_skcipher_ivsize(private));
+       memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
 
        INIT_LIST_HEAD(&ctx->tsgl);
        ctx->len = len;
@@ -818,7 +946,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 
        ask->private = ctx;
 
-       skcipher_request_set_tfm(&ctx->req, private);
+       skcipher_request_set_tfm(&ctx->req, skcipher);
        skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                      af_alg_complete, &ctx->completion);
 
@@ -827,12 +955,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
        return 0;
 }
 
+static int skcipher_accept_parent(void *private, struct sock *sk)
+{
+       struct skcipher_tfm *tfm = private;
+
+       if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher))
+               return -ENOKEY;
+
+       return skcipher_accept_parent_nokey(private, sk);
+}
+
 static const struct af_alg_type algif_type_skcipher = {
        .bind           =       skcipher_bind,
        .release        =       skcipher_release,
        .setkey         =       skcipher_setkey,
        .accept         =       skcipher_accept_parent,
+       .accept_nokey   =       skcipher_accept_parent_nokey,
        .ops            =       &algif_skcipher_ops,
+       .ops_nokey      =       &algif_skcipher_ops_nokey,
        .name           =       "skcipher",
        .owner          =       THIS_MODULE
 };
index 06f1b60..4c0a0e2 100644 (file)
@@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CRYPTO("crc32c");
 MODULE_ALIAS_CRYPTO("crc32c-generic");
-MODULE_SOFTDEP("pre: crc32c");
index ecb1e3d..88a27de 100644 (file)
@@ -355,8 +355,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
        crt->finup = shash_async_finup;
        crt->digest = shash_async_digest;
 
-       if (alg->setkey)
+       if (alg->setkey) {
                crt->setkey = shash_async_setkey;
+               crt->has_setkey = true;
+       }
        if (alg->export)
                crt->export = shash_async_export;
        if (alg->import)
index 7591928..d199c0b 100644 (file)
@@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
        skcipher->decrypt = skcipher_decrypt_blkcipher;
 
        skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
+       skcipher->has_setkey = calg->cra_blkcipher.max_keysize;
 
        return 0;
 }
@@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
        skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
        skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
                            sizeof(struct ablkcipher_request);
+       skcipher->has_setkey = calg->cra_ablkcipher.max_keysize;
 
        return 0;
 }
index 047281a..c570b1d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/clk-lpss.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 
@@ -875,13 +876,14 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
 
        switch (action) {
        case BUS_NOTIFY_BIND_DRIVER:
-               pdev->dev.pm_domain = &acpi_lpss_pm_domain;
+               dev_pm_domain_set(&pdev->dev, &acpi_lpss_pm_domain);
                break;
        case BUS_NOTIFY_DRIVER_NOT_BOUND:
        case BUS_NOTIFY_UNBOUND_DRIVER:
                pdev->dev.pm_domain = NULL;
                break;
        case BUS_NOTIFY_ADD_DEVICE:
+               dev_pm_domain_set(&pdev->dev, &acpi_lpss_pm_domain);
                if (pdata->dev_desc->flags & LPSS_LTR)
                        return sysfs_create_group(&pdev->dev.kobj,
                                                  &lpss_attr_group);
@@ -889,6 +891,7 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
        case BUS_NOTIFY_DEL_DEVICE:
                if (pdata->dev_desc->flags & LPSS_LTR)
                        sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
+               dev_pm_domain_set(&pdev->dev, NULL);
                break;
        default:
                break;
index 06a006f..a76f8be 100644 (file)
@@ -90,10 +90,10 @@ module_param(device_id_scheme, bool, 0444);
 static bool only_lcd = false;
 module_param(only_lcd, bool, 0444);
 
-static DECLARE_COMPLETION(register_done);
-static DEFINE_MUTEX(register_done_mutex);
-static struct mutex video_list_lock;
-static struct list_head video_bus_head;
+static int register_count;
+static DEFINE_MUTEX(register_count_mutex);
+static DEFINE_MUTEX(video_list_lock);
+static LIST_HEAD(video_bus_head);
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device);
 static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
@@ -478,6 +478,15 @@ static struct dmi_system_id video_dmi_table[] = {
         * control on these systems, but do not register a backlight sysfs
         * as brightness control does not work.
         */
+       {
+        /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
+        .callback = video_disable_backlight_sysfs_if,
+        .ident = "Toshiba Portege R700",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
+               },
+       },
        {
         /* https://bugs.freedesktop.org/show_bug.cgi?id=82634 */
         .callback = video_disable_backlight_sysfs_if,
@@ -487,6 +496,15 @@ static struct dmi_system_id video_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"),
                },
        },
+       {
+        /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
+        .callback = video_disable_backlight_sysfs_if,
+        .ident = "Toshiba Satellite R830",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"),
+               },
+       },
        /*
         * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
         * but the IDs actually follow the Device ID Scheme.
@@ -2049,8 +2067,8 @@ int acpi_video_register(void)
 {
        int ret = 0;
 
-       mutex_lock(&register_done_mutex);
-       if (completion_done(&register_done)) {
+       mutex_lock(&register_count_mutex);
+       if (register_count) {
                /*
                 * if the function of acpi_video_register is already called,
                 * don't register the acpi_vide_bus again and return no error.
@@ -2058,9 +2076,6 @@ int acpi_video_register(void)
                goto leave;
        }
 
-       mutex_init(&video_list_lock);
-       INIT_LIST_HEAD(&video_bus_head);
-
        dmi_check_system(video_dmi_table);
 
        ret = acpi_bus_register_driver(&acpi_video_bus);
@@ -2071,22 +2086,22 @@ int acpi_video_register(void)
         * When the acpi_video_bus is loaded successfully, increase
         * the counter reference.
         */
-       complete(&register_done);
+       register_count = 1;
 
 leave:
-       mutex_unlock(&register_done_mutex);
+       mutex_unlock(&register_count_mutex);
        return ret;
 }
 EXPORT_SYMBOL(acpi_video_register);
 
 void acpi_video_unregister(void)
 {
-       mutex_lock(&register_done_mutex);
-       if (completion_done(&register_done)) {
+       mutex_lock(&register_count_mutex);
+       if (register_count) {
                acpi_bus_unregister_driver(&acpi_video_bus);
-               reinit_completion(&register_done);
+               register_count = 0;
        }
-       mutex_unlock(&register_done_mutex);
+       mutex_unlock(&register_count_mutex);
 }
 EXPORT_SYMBOL(acpi_video_unregister);
 
@@ -2094,21 +2109,20 @@ void acpi_video_unregister_backlight(void)
 {
        struct acpi_video_bus *video;
 
-       mutex_lock(&register_done_mutex);
-       if (completion_done(&register_done)) {
+       mutex_lock(&register_count_mutex);
+       if (register_count) {
                mutex_lock(&video_list_lock);
                list_for_each_entry(video, &video_bus_head, entry)
                        acpi_video_bus_unregister_backlight(video);
                mutex_unlock(&video_list_lock);
        }
-       mutex_unlock(&register_done_mutex);
+       mutex_unlock(&register_count_mutex);
 }
 
 bool acpi_video_handles_brightness_key_presses(void)
 {
        bool have_video_busses;
 
-       wait_for_completion(&register_done);
        mutex_lock(&video_list_lock);
        have_video_busses = !list_empty(&video_bus_head);
        mutex_unlock(&video_list_lock);
index 8b4ff40..ca2c060 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@
 /* Common info for tool signons */
 
 #define ACPICA_NAME                 "Intel ACPI Component Architecture"
-#define ACPICA_COPYRIGHT            "Copyright (c) 2000 - 2015 Intel Corporation"
+#define ACPICA_COPYRIGHT            "Copyright (c) 2000 - 2016 Intel Corporation"
 
 #if ACPI_MACHINE_WIDTH == 64
 #define ACPI_WIDTH          "-64"
index a8d8092..19d6ec8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ecb05f1..993af9e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7094dc8..dcd48bf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d18f184..010cf81 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 73462ca..55c8197 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 196a552..27addcf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e9e936e..bae1a35 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 24928ec..e4977fa 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bad5bca..411c18b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d082e62..9684ed6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2b154cf..094b042 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 324512d..ca4bda1 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 96d510a..7da639d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b9474b5..52f6bee 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6357efb..5dd58be 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f9992dc..b3b386e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 591ea95..848ad3a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9e84c05..e43ab6f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ab9f3f1..ceb4f73 100644 (file)
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ee0cdd6..dee6c7e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 328c35b..7ec62c4 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a71632c..9fee88f 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1965b48..502bb58 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -599,12 +599,14 @@ void acpi_db_display_calling_tree(void)
 
 void acpi_db_display_object_type(char *object_arg)
 {
+       acpi_size arg;
        acpi_handle handle;
        struct acpi_device_info *info;
        acpi_status status;
        u32 i;
 
-       handle = ACPI_TO_POINTER(strtoul(object_arg, NULL, 16));
+       arg = strtoul(object_arg, NULL, 16);
+       handle = ACPI_TO_POINTER(arg);
 
        status = acpi_get_object_info(handle, &info);
        if (ACPI_FAILURE(status)) {
index d713e2d..c814855 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 31f54d7..4832879 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9c66a9e..46bd65d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6203001..417c02a 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 01e5a71..f17a86f 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4f68dfc..3c23b5a 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 116f6db..1d59e8b 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index de255d9..a414e1f 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 68b4e8d..74aa381 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8c85d85..b37a2c7 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d7ff58e..e94e0d8 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 76cfced..ad0413b 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 06a6f7f..c9a663f 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1eb82bd..56c3aad 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6bca0ec..6a4b603 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c1d8af8..5aa1c5f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6585e8e..6a72047 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 03c44f2..45cbeba 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 302c91f..c303e9d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1edd66f..4cc9d98 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index fa8e292..8ca9416 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ed2f1d3..402ecc5 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b325474..d1cedcf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8a32153..0bac6e1 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2d7a044..9f32e08 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 89ac202..3a26ddb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bf6873f..80fc0b9 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b78dc7c..9f01578 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 112e821..b47e62a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c00a9f2..9275e62 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ea4c0d3..9fdd8d0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index fd5ab90..66c4b5b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 709419c..0f6be89 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8866f50..c67d78c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a43178f..47092b4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bb2e529..fda869c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0366703..3b7757c 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 012b9de..e4e9260 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 10ce48e..9179e9a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 70eb47e..9045671 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 35f9e60..d274306 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index adcb9c7..011df21 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 73c2e82..0b9f2c1 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 46be5a2..bea9612 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b223090..37a509d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ff976c4..ee30974 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ad7080b..d5d8020 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0337191..f0c5ed0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f598b39..db30ae4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 843c60a..26faa91 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b2e911a..27c11ab 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index efe7ac3..4e17506 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6dad2ca..79ef3b6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 27fb017..28eb861 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7efc9f4..e2b6348 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1f111cc..aed8d34 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1851a30..076074d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6793dcc..c1e8bfb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7f9260b..fedacf1 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 861453e..cc2c26c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d3afbcb..cd70cbc 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d1841de..13bbb2b 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ad3bc92..28b7248 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7c91c1f..ac09c31 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e4a185e..b52e848 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8ae7634..4d44bc1 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e5c5949..3ebbb09 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d0319a2..3f2fb4b 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8272f96..1c4f451 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f785ea7..3dd60c9 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 3cf77af..5ba0498 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ac5b7f7..d00c981 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 675c709..04cc940 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 29033d7..ad0a745 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b2e50d8..a01ddb3 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1ce4efa..f76e0ea 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c687b99..697af81 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e107f92..c2cf73f 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5d347a7..f45bff6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f21568b..878e8fb 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bc5ff35..af236e3 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7dc367e..7060a56 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 15e0b2e..65d58be 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -418,7 +418,8 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
         * Get the parent node. We cheat by using the next_object field
         * of the method object descriptor.
         */
-       parent_node = ACPI_CAST_PTR(struct acpi_namespace_node,
+       parent_node =
+           ACPI_CAST_PTR(struct acpi_namespace_node,
                                    method_obj->method.next_object);
        type = acpi_ns_get_type(parent_node);
 
@@ -444,9 +445,9 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
        info->prefix_node = parent_node;
 
        /*
-        * Get the currently attached parent object. Add a reference, because the
-        * ref count will be decreased when the method object is installed to
-        * the parent node.
+        * Get the currently attached parent object. Add a reference,
+        * because the ref count will be decreased when the method object
+        * is installed to the parent node.
         */
        parent_obj = acpi_ns_get_attached_object(parent_node);
        if (parent_obj) {
@@ -455,8 +456,8 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
 
        /* Install the method (module-level code) in the parent node */
 
-       status = acpi_ns_attach_object(parent_node, method_obj,
-                                      ACPI_TYPE_METHOD);
+       status =
+           acpi_ns_attach_object(parent_node, method_obj, ACPI_TYPE_METHOD);
        if (ACPI_FAILURE(status)) {
                goto exit;
        }
index ac59929..bd75d46 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 14c953e..75cdb87 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 521031f..eb6e1b8 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 677bc93..051306f 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 43b45a8..f631a47 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0c20980..6d78445 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c05a83b..9047f28 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6418863..805e36d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f6dd2a8..63edbbb 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9cc3564..61036d2 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 32f1d95..c72cc62 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c68609a..ebd731f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 429f0d2..a7deeaa 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 669e0f1..285b820 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6e1389b..c312cd4 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f3bcfa2..3052185 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a57f473..6a9f505 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e54bc2a..db0e903 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 40909dd..8e0c97d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5831090..cfd17a4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b729d9b..8038ed2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9d669cc..560c368 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index cf2f2fa..0288cdb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6cb02a2..b28b0da 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f620d43..04f98c0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4254805..04b37fc 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bdb7e73..492d5b0 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 88fce58..2b1209d 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 603e544..1297889 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 05cc560..23a17c8 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b29d9ec..5c34913 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index edecfc6..8e067cb 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5adba01..07dfbed 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 07cfa70..bc8f345 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 286ccb4..8c42dd7 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c6b8086..88b53ef 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b112c7b..ce3d0b7 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4c8c6fe..8a01296 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 33e558c..cf06e49 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 308bfd6..900933b 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4a81527..7da79ce 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a6454f4..a79e4f3 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 405529d..f2d0803 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bd87801..b661a1e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d0d1259..fd4146d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7c1b5f8..3269bef 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5559e2c..326df65 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ca2f136..278666e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index fa76a36..b9a78e4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 38a29e2..c986ec6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7a4101f..3dbdc3a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 01c8709..0cfb2b8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0d21fbd..c9a720f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ade8acf..98d53e5 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4146229..1cfc5f6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 3533135..6ba65b0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1afd742..529d6c3 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f93bb90..475932c 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6c738fa..17b9f3e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 743a0ae..6952403 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a72685c..48fffcf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8ad086e..4354fb8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 05ee76e..6fb4ec3 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index fd82a12..f91f724 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 089f78b..3cd0978 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 58b5d42..6673720 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index eab1cfe..d938c27 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 038ff84..1507337 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9c3cadc..c427a5c 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 787eccf..edad3f0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0809d73..b5cfe57 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ebb811c..813520a 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9f8e415..770a177 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 01f04da..8c218ad 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d50b41c..1de3376 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0050e00..f3d4dbd 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 958b2f7..0b00572 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ea698e9..c7c2bb8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e6cab66..81088ff 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9f3f0a1..68d4673 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f6cbaf4..6fe5959 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e38facd..721b87c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 95d6123..850de01 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6682c5d..6e6bc10 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/hardirq.h>
 #include <linux/pstore.h>
 #include <linux/vmalloc.h>
+#include <linux/mm.h> /* kvfree() */
 #include <acpi/apei.h>
 
 #include "apei-internal.h"
@@ -532,10 +533,7 @@ retry:
                        return -ENOMEM;
                memcpy(new_entries, entries,
                       erst_record_id_cache.len * sizeof(entries[0]));
-               if (erst_record_id_cache.size < PAGE_SIZE)
-                       kfree(entries);
-               else
-                       vfree(entries);
+               kvfree(entries);
                erst_record_id_cache.entries = entries = new_entries;
                erst_record_id_cache.size = new_size;
        }
index 08a02cd..cd2c3d6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/pm_qos.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
 #include "internal.h"
@@ -1059,7 +1060,7 @@ static void acpi_dev_pm_detach(struct device *dev, bool power_off)
        struct acpi_device *adev = ACPI_COMPANION(dev);
 
        if (adev && dev->pm_domain == &acpi_general_pm_domain) {
-               dev->pm_domain = NULL;
+               dev_pm_domain_set(dev, NULL);
                acpi_remove_pm_notifier(adev);
                if (power_off) {
                        /*
@@ -1111,7 +1112,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
                return -EBUSY;
 
        acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func);
-       dev->pm_domain = &acpi_general_pm_domain;
+       dev_pm_domain_set(dev, &acpi_general_pm_domain);
        if (power_on) {
                acpi_dev_pm_full_power(adev);
                acpi_device_wakeup(adev, ACPI_STATE_S0, false);
index e297a48..6322db6 100644 (file)
@@ -339,7 +339,7 @@ static int acpi_fan_probe(struct platform_device *pdev)
        } else {
                result = acpi_device_update_power(device, NULL);
                if (result) {
-                       dev_err(&device->dev, "Setting initial power state\n");
+                       dev_err(&device->dev, "Failed to set initial power state\n");
                        goto end;
                }
        }
index 4a5c9d2..294ba6f 100644 (file)
@@ -4,7 +4,7 @@ config ARM_AMBA
 if ARM_AMBA
 
 config TEGRA_AHB
-       bool "Enable AHB driver for NVIDIA Tegra SoCs"
+       bool
        default y if ARCH_TEGRA
        help
          Adds AHB configuration functionality for NVIDIA Tegra SoCs,
index 91bbb19..691eeea 100644 (file)
@@ -200,7 +200,7 @@ static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
 
 struct cpu_attr {
        struct device_attribute attr;
-       const struct cpumask *const * const map;
+       const struct cpumask *const map;
 };
 
 static ssize_t show_cpus_attr(struct device *dev,
@@ -209,7 +209,7 @@ static ssize_t show_cpus_attr(struct device *dev,
 {
        struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
 
-       return cpumap_print_to_pagebuf(true, buf, *ca->map);
+       return cpumap_print_to_pagebuf(true, buf, ca->map);
 }
 
 #define _CPU_ATTR(name, map) \
@@ -217,9 +217,9 @@ static ssize_t show_cpus_attr(struct device *dev,
 
 /* Keep in sync with cpu_subsys_attrs */
 static struct cpu_attr cpu_attrs[] = {
-       _CPU_ATTR(online, &cpu_online_mask),
-       _CPU_ATTR(possible, &cpu_possible_mask),
-       _CPU_ATTR(present, &cpu_present_mask),
+       _CPU_ATTR(online, &__cpu_online_mask),
+       _CPU_ATTR(possible, &__cpu_possible_mask),
+       _CPU_ATTR(present, &__cpu_present_mask),
 };
 
 /*
index 7399be7..c4da2df 100644 (file)
@@ -223,9 +223,23 @@ static int deferred_probe_initcall(void)
 }
 late_initcall(deferred_probe_initcall);
 
+/**
+ * device_is_bound() - Check if device is bound to a driver
+ * @dev: device to check
+ *
+ * Returns true if passed device has already finished probing successfully
+ * against a driver.
+ *
+ * This function must be called with the device lock held.
+ */
+bool device_is_bound(struct device *dev)
+{
+       return dev->p && klist_node_attached(&dev->p->knode_driver);
+}
+
 static void driver_bound(struct device *dev)
 {
-       if (klist_node_attached(&dev->p->knode_driver)) {
+       if (device_is_bound(dev)) {
                printk(KERN_WARNING "%s: device %s already bound\n",
                        __func__, kobject_name(&dev->kobj));
                return;
@@ -236,6 +250,8 @@ static void driver_bound(struct device *dev)
 
        klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
 
+       device_pm_check_callbacks(dev);
+
        /*
         * Make sure the device is no longer in one of the deferred lists and
         * kick off retrying all pending devices
@@ -601,7 +617,7 @@ static int __device_attach(struct device *dev, bool allow_async)
 
        device_lock(dev);
        if (dev->driver) {
-               if (klist_node_attached(&dev->p->knode_driver)) {
+               if (device_is_bound(dev)) {
                        ret = 1;
                        goto out_unlock;
                }
@@ -752,6 +768,7 @@ static void __device_release_driver(struct device *dev)
                pm_runtime_reinit(dev);
 
                klist_remove(&dev->p->knode_driver);
+               device_pm_check_callbacks(dev);
                if (dev->bus)
                        blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                                     BUS_NOTIFY_UNBOUND_DRIVER,
index 68f0314..44a74cf 100644 (file)
@@ -215,9 +215,9 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
                newattrs.ia_uid = uid;
                newattrs.ia_gid = gid;
                newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID;
-               mutex_lock(&d_inode(dentry)->i_mutex);
+               inode_lock(d_inode(dentry));
                notify_change(dentry, &newattrs, NULL);
-               mutex_unlock(&d_inode(dentry)->i_mutex);
+               inode_unlock(d_inode(dentry));
 
                /* mark as kernel-created inode */
                d_inode(dentry)->i_private = &thread;
@@ -244,7 +244,7 @@ static int dev_rmdir(const char *name)
                err = -ENOENT;
        }
        dput(dentry);
-       mutex_unlock(&d_inode(parent.dentry)->i_mutex);
+       inode_unlock(d_inode(parent.dentry));
        path_put(&parent);
        return err;
 }
@@ -321,9 +321,9 @@ static int handle_remove(const char *nodename, struct device *dev)
                        newattrs.ia_mode = stat.mode & ~0777;
                        newattrs.ia_valid =
                                ATTR_UID|ATTR_GID|ATTR_MODE;
-                       mutex_lock(&d_inode(dentry)->i_mutex);
+                       inode_lock(d_inode(dentry));
                        notify_change(dentry, &newattrs, NULL);
-                       mutex_unlock(&d_inode(dentry)->i_mutex);
+                       inode_unlock(d_inode(dentry));
                        err = vfs_unlink(d_inode(parent.dentry), dentry, NULL);
                        if (!err || err == -ENOENT)
                                deleted = 1;
@@ -332,7 +332,7 @@ static int handle_remove(const char *nodename, struct device *dev)
                err = -ENOENT;
        }
        dput(dentry);
-       mutex_unlock(&d_inode(parent.dentry)->i_mutex);
+       inode_unlock(d_inode(parent.dentry));
 
        path_put(&parent);
        if (deleted && strchr(nodename, '/'))
index d95c597..d799662 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <asm-generic/dma-coherent.h>
 
 /*
  * Managed DMA API
@@ -167,7 +166,7 @@ void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 }
 EXPORT_SYMBOL(dmam_free_noncoherent);
 
-#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
 
 static void dmam_coherent_decl_release(struct device *dev, void *res)
 {
@@ -247,7 +246,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
                    void *cpu_addr, dma_addr_t dma_addr, size_t size)
 {
        int ret = -ENXIO;
-#ifdef CONFIG_MMU
+#if defined(CONFIG_MMU) && !defined(CONFIG_ARCH_NO_COHERENT_DMA_MMAP)
        unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
        unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
@@ -264,7 +263,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
                                      user_count << PAGE_SHIFT,
                                      vma->vm_page_prot);
        }
-#endif /* CONFIG_MMU */
+#endif /* CONFIG_MMU && !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
 
        return ret;
 }
index 8dcbb26..73d6e5d 100644 (file)
@@ -597,7 +597,6 @@ static void platform_drv_shutdown(struct device *_dev)
 
        if (drv->shutdown)
                drv->shutdown(dev);
-       dev_pm_domain_detach(_dev, true);
 }
 
 /**
index c39b861..272a52e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/clkdev.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
 #ifdef CONFIG_PM_CLK
@@ -348,7 +349,7 @@ static int pm_clk_notify(struct notifier_block *nb,
                if (error)
                        break;
 
-               dev->pm_domain = clknb->pm_domain;
+               dev_pm_domain_set(dev, clknb->pm_domain);
                if (clknb->con_ids[0]) {
                        for (con_id = clknb->con_ids; *con_id; con_id++)
                                pm_clk_add(dev, *con_id);
@@ -361,7 +362,7 @@ static int pm_clk_notify(struct notifier_block *nb,
                if (dev->pm_domain != clknb->pm_domain)
                        break;
 
-               dev->pm_domain = NULL;
+               dev_pm_domain_set(dev, NULL);
                pm_clk_destroy(dev);
                break;
        }
index f48e333..93ed14c 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/acpi.h>
 #include <linux/pm_domain.h>
 
+#include "power.h"
+
 /**
  * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
  * @dev: Device to handle.
@@ -128,3 +130,25 @@ void dev_pm_domain_detach(struct device *dev, bool power_off)
                dev->pm_domain->detach(dev, power_off);
 }
 EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
+
+/**
+ * dev_pm_domain_set - Set PM domain of a device.
+ * @dev: Device whose PM domain is to be set.
+ * @pd: PM domain to be set, or NULL.
+ *
+ * Sets the PM domain the device belongs to. The PM domain of a device needs
+ * to be set before its probe finishes (it's bound to a driver).
+ *
+ * This function must be called with the device lock held.
+ */
+void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd)
+{
+       if (dev->pm_domain == pd)
+               return;
+
+       WARN(device_is_bound(dev),
+            "PM domains can only be changed for unbound devices\n");
+       dev->pm_domain = pd;
+       device_pm_check_callbacks(dev);
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_set);
index b803790..6ac9a7f 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/suspend.h>
 #include <linux/export.h>
 
+#include "power.h"
+
 #define GENPD_RETRY_MAX_MS     250             /* Approximate */
 
 #define GENPD_DEV_CALLBACK(genpd, type, callback, dev)         \
@@ -1188,10 +1190,11 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
        }
 
        dev->power.subsys_data->domain_data = &gpd_data->base;
-       dev->pm_domain = &genpd->domain;
 
        spin_unlock_irq(&dev->power.lock);
 
+       dev_pm_domain_set(dev, &genpd->domain);
+
        return gpd_data;
 
  err_free:
@@ -1205,9 +1208,10 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
 static void genpd_free_dev_data(struct device *dev,
                                struct generic_pm_domain_data *gpd_data)
 {
+       dev_pm_domain_set(dev, NULL);
+
        spin_lock_irq(&dev->power.lock);
 
-       dev->pm_domain = NULL;
        dev->power.subsys_data->domain_data = NULL;
 
        spin_unlock_irq(&dev->power.lock);
index 9d626ac..6e7c3cc 100644 (file)
@@ -125,6 +125,7 @@ void device_pm_add(struct device *dev)
 {
        pr_debug("PM: Adding info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
+       device_pm_check_callbacks(dev);
        mutex_lock(&dpm_list_mtx);
        if (dev->parent && dev->parent->power.is_prepared)
                dev_warn(dev, "parent %s should not be sleeping\n",
@@ -147,6 +148,7 @@ void device_pm_remove(struct device *dev)
        mutex_unlock(&dpm_list_mtx);
        device_wakeup_disable(dev);
        pm_runtime_remove(dev);
+       device_pm_check_callbacks(dev);
 }
 
 /**
@@ -1572,6 +1574,11 @@ static int device_prepare(struct device *dev, pm_message_t state)
 
        dev->power.wakeup_path = device_may_wakeup(dev);
 
+       if (dev->power.no_pm_callbacks) {
+               ret = 1;        /* Let device go direct_complete */
+               goto unlock;
+       }
+
        if (dev->pm_domain) {
                info = "preparing power domain ";
                callback = dev->pm_domain->ops.prepare;
@@ -1594,6 +1601,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
        if (callback)
                ret = callback(dev);
 
+unlock:
        device_unlock(dev);
 
        if (ret < 0) {
@@ -1736,3 +1744,30 @@ void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
        device_pm_unlock();
 }
 EXPORT_SYMBOL_GPL(dpm_for_each_dev);
+
+static bool pm_ops_is_empty(const struct dev_pm_ops *ops)
+{
+       if (!ops)
+               return true;
+
+       return !ops->prepare &&
+              !ops->suspend &&
+              !ops->suspend_late &&
+              !ops->suspend_noirq &&
+              !ops->resume_noirq &&
+              !ops->resume_early &&
+              !ops->resume &&
+              !ops->complete;
+}
+
+void device_pm_check_callbacks(struct device *dev)
+{
+       spin_lock_irq(&dev->power.lock);
+       dev->power.no_pm_callbacks =
+               (!dev->bus || pm_ops_is_empty(dev->bus->pm)) &&
+               (!dev->class || pm_ops_is_empty(dev->class->pm)) &&
+               (!dev->type || pm_ops_is_empty(dev->type->pm)) &&
+               (!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
+               (!dev->driver || pm_ops_is_empty(dev->driver->pm));
+       spin_unlock_irq(&dev->power.lock);
+}
index 8b06193..50e30e7 100644 (file)
@@ -125,6 +125,7 @@ extern void device_pm_remove(struct device *);
 extern void device_pm_move_before(struct device *, struct device *);
 extern void device_pm_move_after(struct device *, struct device *);
 extern void device_pm_move_last(struct device *);
+extern void device_pm_check_callbacks(struct device *dev);
 
 #else /* !CONFIG_PM_SLEEP */
 
@@ -143,6 +144,8 @@ static inline void device_pm_move_after(struct device *deva,
                                        struct device *devb) {}
 static inline void device_pm_move_last(struct device *dev) {}
 
+static inline void device_pm_check_callbacks(struct device *dev) {}
+
 #endif /* !CONFIG_PM_SLEEP */
 
 static inline void device_pm_init(struct device *dev)
index ad80c85..d048d20 100644 (file)
@@ -964,9 +964,9 @@ aoecmd_sleepwork(struct work_struct *work)
                ssize = get_capacity(d->gd);
                bd = bdget_disk(d->gd, 0);
                if (bd) {
-                       mutex_lock(&bd->bd_inode->i_mutex);
+                       inode_lock(bd->bd_inode);
                        i_size_write(bd->bd_inode, (loff_t)ssize<<9);
-                       mutex_unlock(&bd->bd_inode->i_mutex);
+                       inode_unlock(bd->bd_inode);
                        bdput(bd);
                }
                spin_lock_irq(&d->lock);
index b3868e7..10459a1 100644 (file)
@@ -288,7 +288,162 @@ bool drbd_al_begin_io_prepare(struct drbd_device *device, struct drbd_interval *
        return need_transaction;
 }
 
-static int al_write_transaction(struct drbd_device *device);
+#if (PAGE_SHIFT + 3) < (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT)
+/* Currently BM_BLOCK_SHIFT, BM_EXT_SHIFT and AL_EXTENT_SHIFT
+ * are still coupled, or assume too much about their relation.
+ * Code below will not work if this is violated.
+ * Will be cleaned up with some followup patch.
+ */
+# error FIXME
+#endif
+
+static unsigned int al_extent_to_bm_page(unsigned int al_enr)
+{
+       return al_enr >>
+               /* bit to page */
+               ((PAGE_SHIFT + 3) -
+               /* al extent number to bit */
+                (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT));
+}
+
+static sector_t al_tr_number_to_on_disk_sector(struct drbd_device *device)
+{
+       const unsigned int stripes = device->ldev->md.al_stripes;
+       const unsigned int stripe_size_4kB = device->ldev->md.al_stripe_size_4k;
+
+       /* transaction number, modulo on-disk ring buffer wrap around */
+       unsigned int t = device->al_tr_number % (device->ldev->md.al_size_4k);
+
+       /* ... to aligned 4k on disk block */
+       t = ((t % stripes) * stripe_size_4kB) + t/stripes;
+
+       /* ... to 512 byte sector in activity log */
+       t *= 8;
+
+       /* ... plus offset to the on disk position */
+       return device->ldev->md.md_offset + device->ldev->md.al_offset + t;
+}
+
+static int __al_write_transaction(struct drbd_device *device, struct al_transaction_on_disk *buffer)
+{
+       struct lc_element *e;
+       sector_t sector;
+       int i, mx;
+       unsigned extent_nr;
+       unsigned crc = 0;
+       int err = 0;
+
+       memset(buffer, 0, sizeof(*buffer));
+       buffer->magic = cpu_to_be32(DRBD_AL_MAGIC);
+       buffer->tr_number = cpu_to_be32(device->al_tr_number);
+
+       i = 0;
+
+       /* Even though no one can start to change this list
+        * once we set the LC_LOCKED -- from drbd_al_begin_io(),
+        * lc_try_lock_for_transaction() --, someone may still
+        * be in the process of changing it. */
+       spin_lock_irq(&device->al_lock);
+       list_for_each_entry(e, &device->act_log->to_be_changed, list) {
+               if (i == AL_UPDATES_PER_TRANSACTION) {
+                       i++;
+                       break;
+               }
+               buffer->update_slot_nr[i] = cpu_to_be16(e->lc_index);
+               buffer->update_extent_nr[i] = cpu_to_be32(e->lc_new_number);
+               if (e->lc_number != LC_FREE)
+                       drbd_bm_mark_for_writeout(device,
+                                       al_extent_to_bm_page(e->lc_number));
+               i++;
+       }
+       spin_unlock_irq(&device->al_lock);
+       BUG_ON(i > AL_UPDATES_PER_TRANSACTION);
+
+       buffer->n_updates = cpu_to_be16(i);
+       for ( ; i < AL_UPDATES_PER_TRANSACTION; i++) {
+               buffer->update_slot_nr[i] = cpu_to_be16(-1);
+               buffer->update_extent_nr[i] = cpu_to_be32(LC_FREE);
+       }
+
+       buffer->context_size = cpu_to_be16(device->act_log->nr_elements);
+       buffer->context_start_slot_nr = cpu_to_be16(device->al_tr_cycle);
+
+       mx = min_t(int, AL_CONTEXT_PER_TRANSACTION,
+                  device->act_log->nr_elements - device->al_tr_cycle);
+       for (i = 0; i < mx; i++) {
+               unsigned idx = device->al_tr_cycle + i;
+               extent_nr = lc_element_by_index(device->act_log, idx)->lc_number;
+               buffer->context[i] = cpu_to_be32(extent_nr);
+       }
+       for (; i < AL_CONTEXT_PER_TRANSACTION; i++)
+               buffer->context[i] = cpu_to_be32(LC_FREE);
+
+       device->al_tr_cycle += AL_CONTEXT_PER_TRANSACTION;
+       if (device->al_tr_cycle >= device->act_log->nr_elements)
+               device->al_tr_cycle = 0;
+
+       sector = al_tr_number_to_on_disk_sector(device);
+
+       crc = crc32c(0, buffer, 4096);
+       buffer->crc32c = cpu_to_be32(crc);
+
+       if (drbd_bm_write_hinted(device))
+               err = -EIO;
+       else {
+               bool write_al_updates;
+               rcu_read_lock();
+               write_al_updates = rcu_dereference(device->ldev->disk_conf)->al_updates;
+               rcu_read_unlock();
+               if (write_al_updates) {
+                       if (drbd_md_sync_page_io(device, device->ldev, sector, WRITE)) {
+                               err = -EIO;
+                               drbd_chk_io_error(device, 1, DRBD_META_IO_ERROR);
+                       } else {
+                               device->al_tr_number++;
+                               device->al_writ_cnt++;
+                       }
+               }
+       }
+
+       return err;
+}
+
+static int al_write_transaction(struct drbd_device *device)
+{
+       struct al_transaction_on_disk *buffer;
+       int err;
+
+       if (!get_ldev(device)) {
+               drbd_err(device, "disk is %s, cannot start al transaction\n",
+                       drbd_disk_str(device->state.disk));
+               return -EIO;
+       }
+
+       /* The bitmap write may have failed, causing a state change. */
+       if (device->state.disk < D_INCONSISTENT) {
+               drbd_err(device,
+                       "disk is %s, cannot write al transaction\n",
+                       drbd_disk_str(device->state.disk));
+               put_ldev(device);
+               return -EIO;
+       }
+
+       /* protects md_io_buffer, al_tr_cycle, ... */
+       buffer = drbd_md_get_buffer(device, __func__);
+       if (!buffer) {
+               drbd_err(device, "disk failed while waiting for md_io buffer\n");
+               put_ldev(device);
+               return -ENODEV;
+       }
+
+       err = __al_write_transaction(device, buffer);
+
+       drbd_md_put_buffer(device);
+       put_ldev(device);
+
+       return err;
+}
+
 
 void drbd_al_begin_io_commit(struct drbd_device *device)
 {
@@ -420,153 +575,6 @@ void drbd_al_complete_io(struct drbd_device *device, struct drbd_interval *i)
        wake_up(&device->al_wait);
 }
 
-#if (PAGE_SHIFT + 3) < (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT)
-/* Currently BM_BLOCK_SHIFT, BM_EXT_SHIFT and AL_EXTENT_SHIFT
- * are still coupled, or assume too much about their relation.
- * Code below will not work if this is violated.
- * Will be cleaned up with some followup patch.
- */
-# error FIXME
-#endif
-
-static unsigned int al_extent_to_bm_page(unsigned int al_enr)
-{
-       return al_enr >>
-               /* bit to page */
-               ((PAGE_SHIFT + 3) -
-               /* al extent number to bit */
-                (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT));
-}
-
-static sector_t al_tr_number_to_on_disk_sector(struct drbd_device *device)
-{
-       const unsigned int stripes = device->ldev->md.al_stripes;
-       const unsigned int stripe_size_4kB = device->ldev->md.al_stripe_size_4k;
-
-       /* transaction number, modulo on-disk ring buffer wrap around */
-       unsigned int t = device->al_tr_number % (device->ldev->md.al_size_4k);
-
-       /* ... to aligned 4k on disk block */
-       t = ((t % stripes) * stripe_size_4kB) + t/stripes;
-
-       /* ... to 512 byte sector in activity log */
-       t *= 8;
-
-       /* ... plus offset to the on disk position */
-       return device->ldev->md.md_offset + device->ldev->md.al_offset + t;
-}
-
-int al_write_transaction(struct drbd_device *device)
-{
-       struct al_transaction_on_disk *buffer;
-       struct lc_element *e;
-       sector_t sector;
-       int i, mx;
-       unsigned extent_nr;
-       unsigned crc = 0;
-       int err = 0;
-
-       if (!get_ldev(device)) {
-               drbd_err(device, "disk is %s, cannot start al transaction\n",
-                       drbd_disk_str(device->state.disk));
-               return -EIO;
-       }
-
-       /* The bitmap write may have failed, causing a state change. */
-       if (device->state.disk < D_INCONSISTENT) {
-               drbd_err(device,
-                       "disk is %s, cannot write al transaction\n",
-                       drbd_disk_str(device->state.disk));
-               put_ldev(device);
-               return -EIO;
-       }
-
-       /* protects md_io_buffer, al_tr_cycle, ... */
-       buffer = drbd_md_get_buffer(device, __func__);
-       if (!buffer) {
-               drbd_err(device, "disk failed while waiting for md_io buffer\n");
-               put_ldev(device);
-               return -ENODEV;
-       }
-
-       memset(buffer, 0, sizeof(*buffer));
-       buffer->magic = cpu_to_be32(DRBD_AL_MAGIC);
-       buffer->tr_number = cpu_to_be32(device->al_tr_number);
-
-       i = 0;
-
-       /* Even though no one can start to change this list
-        * once we set the LC_LOCKED -- from drbd_al_begin_io(),
-        * lc_try_lock_for_transaction() --, someone may still
-        * be in the process of changing it. */
-       spin_lock_irq(&device->al_lock);
-       list_for_each_entry(e, &device->act_log->to_be_changed, list) {
-               if (i == AL_UPDATES_PER_TRANSACTION) {
-                       i++;
-                       break;
-               }
-               buffer->update_slot_nr[i] = cpu_to_be16(e->lc_index);
-               buffer->update_extent_nr[i] = cpu_to_be32(e->lc_new_number);
-               if (e->lc_number != LC_FREE)
-                       drbd_bm_mark_for_writeout(device,
-                                       al_extent_to_bm_page(e->lc_number));
-               i++;
-       }
-       spin_unlock_irq(&device->al_lock);
-       BUG_ON(i > AL_UPDATES_PER_TRANSACTION);
-
-       buffer->n_updates = cpu_to_be16(i);
-       for ( ; i < AL_UPDATES_PER_TRANSACTION; i++) {
-               buffer->update_slot_nr[i] = cpu_to_be16(-1);
-               buffer->update_extent_nr[i] = cpu_to_be32(LC_FREE);
-       }
-
-       buffer->context_size = cpu_to_be16(device->act_log->nr_elements);
-       buffer->context_start_slot_nr = cpu_to_be16(device->al_tr_cycle);
-
-       mx = min_t(int, AL_CONTEXT_PER_TRANSACTION,
-                  device->act_log->nr_elements - device->al_tr_cycle);
-       for (i = 0; i < mx; i++) {
-               unsigned idx = device->al_tr_cycle + i;
-               extent_nr = lc_element_by_index(device->act_log, idx)->lc_number;
-               buffer->context[i] = cpu_to_be32(extent_nr);
-       }
-       for (; i < AL_CONTEXT_PER_TRANSACTION; i++)
-               buffer->context[i] = cpu_to_be32(LC_FREE);
-
-       device->al_tr_cycle += AL_CONTEXT_PER_TRANSACTION;
-       if (device->al_tr_cycle >= device->act_log->nr_elements)
-               device->al_tr_cycle = 0;
-
-       sector = al_tr_number_to_on_disk_sector(device);
-
-       crc = crc32c(0, buffer, 4096);
-       buffer->crc32c = cpu_to_be32(crc);
-
-       if (drbd_bm_write_hinted(device))
-               err = -EIO;
-       else {
-               bool write_al_updates;
-               rcu_read_lock();
-               write_al_updates = rcu_dereference(device->ldev->disk_conf)->al_updates;
-               rcu_read_unlock();
-               if (write_al_updates) {
-                       if (drbd_md_sync_page_io(device, device->ldev, sector, WRITE)) {
-                               err = -EIO;
-                               drbd_chk_io_error(device, 1, DRBD_META_IO_ERROR);
-                       } else {
-                               device->al_tr_number++;
-                               device->al_writ_cnt++;
-                       }
-               }
-       }
-
-       drbd_md_put_buffer(device);
-       put_ldev(device);
-
-       return err;
-}
-
 static int _try_lc_del(struct drbd_device *device, struct lc_element *al_ext)
 {
        int rv;
@@ -606,21 +614,24 @@ void drbd_al_shrink(struct drbd_device *device)
        wake_up(&device->al_wait);
 }
 
-int drbd_initialize_al(struct drbd_device *device, void *buffer)
+int drbd_al_initialize(struct drbd_device *device, void *buffer)
 {
        struct al_transaction_on_disk *al = buffer;
        struct drbd_md *md = &device->ldev->md;
-       sector_t al_base = md->md_offset + md->al_offset;
        int al_size_4k = md->al_stripes * md->al_stripe_size_4k;
        int i;
 
-       memset(al, 0, 4096);
-       al->magic = cpu_to_be32(DRBD_AL_MAGIC);
-       al->transaction_type = cpu_to_be16(AL_TR_INITIALIZED);
-       al->crc32c = cpu_to_be32(crc32c(0, al, 4096));
+       __al_write_transaction(device, al);
+       /* There may or may not have been a pending transaction. */
+       spin_lock_irq(&device->al_lock);
+       lc_committed(device->act_log);
+       spin_unlock_irq(&device->al_lock);
 
-       for (i = 0; i < al_size_4k; i++) {
-               int err = drbd_md_sync_page_io(device, device->ldev, al_base + i * 8, WRITE);
+       /* The rest of the transactions will have an empty "updates" list, and
+        * are written out only to provide the context, and to initialize the
+        * on-disk ring buffer. */
+       for (i = 1; i < al_size_4k; i++) {
+               int err = __al_write_transaction(device, al);
                if (err)
                        return err;
        }
index 9462d27..92d6fc0 100644 (file)
@@ -24,7 +24,7 @@
 
 #define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
 
-#include <linux/bitops.h>
+#include <linux/bitmap.h>
 #include <linux/vmalloc.h>
 #include <linux/string.h>
 #include <linux/drbd.h>
@@ -364,12 +364,9 @@ static void bm_free_pages(struct page **pages, unsigned long number)
        }
 }
 
-static void bm_vk_free(void *ptr, int v)
+static inline void bm_vk_free(void *ptr)
 {
-       if (v)
-               vfree(ptr);
-       else
-               kfree(ptr);
+       kvfree(ptr);
 }
 
 /*
@@ -379,7 +376,7 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
 {
        struct page **old_pages = b->bm_pages;
        struct page **new_pages, *page;
-       unsigned int i, bytes, vmalloced = 0;
+       unsigned int i, bytes;
        unsigned long have = b->bm_number_of_pages;
 
        BUG_ON(have == 0 && old_pages != NULL);
@@ -401,7 +398,6 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
                                PAGE_KERNEL);
                if (!new_pages)
                        return NULL;
-               vmalloced = 1;
        }
 
        if (want >= have) {
@@ -411,7 +407,7 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
                        page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
                        if (!page) {
                                bm_free_pages(new_pages + have, i - have);
-                               bm_vk_free(new_pages, vmalloced);
+                               bm_vk_free(new_pages);
                                return NULL;
                        }
                        /* we want to know which page it is
@@ -427,11 +423,6 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
                */
        }
 
-       if (vmalloced)
-               b->bm_flags |= BM_P_VMALLOCED;
-       else
-               b->bm_flags &= ~BM_P_VMALLOCED;
-
        return new_pages;
 }
 
@@ -469,7 +460,7 @@ void drbd_bm_cleanup(struct drbd_device *device)
        if (!expect(device->bitmap))
                return;
        bm_free_pages(device->bitmap->bm_pages, device->bitmap->bm_number_of_pages);
-       bm_vk_free(device->bitmap->bm_pages, (BM_P_VMALLOCED & device->bitmap->bm_flags));
+       bm_vk_free(device->bitmap->bm_pages);
        kfree(device->bitmap);
        device->bitmap = NULL;
 }
@@ -479,8 +470,14 @@ void drbd_bm_cleanup(struct drbd_device *device)
  * this masks out the remaining bits.
  * Returns the number of bits cleared.
  */
+#ifndef BITS_PER_PAGE
 #define BITS_PER_PAGE          (1UL << (PAGE_SHIFT + 3))
 #define BITS_PER_PAGE_MASK     (BITS_PER_PAGE - 1)
+#else
+# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3))
+#  error "ambiguous BITS_PER_PAGE"
+# endif
+#endif
 #define BITS_PER_LONG_MASK     (BITS_PER_LONG - 1)
 static int bm_clear_surplus(struct drbd_bitmap *b)
 {
@@ -559,21 +556,19 @@ static unsigned long bm_count_bits(struct drbd_bitmap *b)
        unsigned long *p_addr;
        unsigned long bits = 0;
        unsigned long mask = (1UL << (b->bm_bits & BITS_PER_LONG_MASK)) -1;
-       int idx, i, last_word;
+       int idx, last_word;
 
        /* all but last page */
        for (idx = 0; idx < b->bm_number_of_pages - 1; idx++) {
                p_addr = __bm_map_pidx(b, idx);
-               for (i = 0; i < LWPP; i++)
-                       bits += hweight_long(p_addr[i]);
+               bits += bitmap_weight(p_addr, BITS_PER_PAGE);
                __bm_unmap(p_addr);
                cond_resched();
        }
        /* last (or only) page */
        last_word = ((b->bm_bits - 1) & BITS_PER_PAGE_MASK) >> LN2_BPL;
        p_addr = __bm_map_pidx(b, idx);
-       for (i = 0; i < last_word; i++)
-               bits += hweight_long(p_addr[i]);
+       bits += bitmap_weight(p_addr, last_word * BITS_PER_LONG);
        p_addr[last_word] &= cpu_to_lel(mask);
        bits += hweight_long(p_addr[last_word]);
        /* 32bit arch, may have an unused padding long */
@@ -639,7 +634,6 @@ int drbd_bm_resize(struct drbd_device *device, sector_t capacity, int set_new_bi
        unsigned long want, have, onpages; /* number of pages */
        struct page **npages, **opages = NULL;
        int err = 0, growing;
-       int opages_vmalloced;
 
        if (!expect(b))
                return -ENOMEM;
@@ -652,8 +646,6 @@ int drbd_bm_resize(struct drbd_device *device, sector_t capacity, int set_new_bi
        if (capacity == b->bm_dev_capacity)
                goto out;
 
-       opages_vmalloced = (BM_P_VMALLOCED & b->bm_flags);
-
        if (capacity == 0) {
                spin_lock_irq(&b->bm_lock);
                opages = b->bm_pages;
@@ -667,7 +659,7 @@ int drbd_bm_resize(struct drbd_device *device, sector_t capacity, int set_new_bi
                b->bm_dev_capacity = 0;
                spin_unlock_irq(&b->bm_lock);
                bm_free_pages(opages, onpages);
-               bm_vk_free(opages, opages_vmalloced);
+               bm_vk_free(opages);
                goto out;
        }
        bits  = BM_SECT_TO_BIT(ALIGN(capacity, BM_SECT_PER_BIT));
@@ -740,7 +732,7 @@ int drbd_bm_resize(struct drbd_device *device, sector_t capacity, int set_new_bi
 
        spin_unlock_irq(&b->bm_lock);
        if (opages != npages)
-               bm_vk_free(opages, opages_vmalloced);
+               bm_vk_free(opages);
        if (!growing)
                b->bm_set = bm_count_bits(b);
        drbd_info(device, "resync bitmap: bits=%lu words=%lu pages=%lu\n", bits, words, want);
@@ -1419,6 +1411,9 @@ static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b,
        int bits;
        int changed = 0;
        unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr]);
+
+       /* I think it is more cache line friendly to hweight_long then set to ~0UL,
+        * than to first bitmap_weight() all words, then bitmap_fill() all words */
        for (i = first_word; i < last_word; i++) {
                bits = hweight_long(paddr[i]);
                paddr[i] = ~0UL;
@@ -1628,8 +1623,7 @@ int drbd_bm_e_weight(struct drbd_device *device, unsigned long enr)
                int n = e-s;
                p_addr = bm_map_pidx(b, bm_word_to_page_idx(b, s));
                bm = p_addr + MLPP(s);
-               while (n--)
-                       count += hweight_long(*bm++);
+               count += bitmap_weight(bm, n * BITS_PER_LONG);
                bm_unmap(p_addr);
        } else {
                drbd_err(device, "start offset (%d) too large in drbd_bm_e_weight\n", s);
index 6b88a35..4de95bb 100644 (file)
@@ -434,12 +434,12 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo
        if (!parent || d_really_is_negative(parent))
                goto out;
        /* serialize with d_delete() */
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        /* Make sure the object is still alive */
        if (simple_positive(file->f_path.dentry)
        && kref_get_unless_zero(kref))
                ret = 0;
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        if (!ret) {
                ret = single_open(file, show, data);
                if (ret)
@@ -771,6 +771,13 @@ static int device_data_gen_id_show(struct seq_file *m, void *ignored)
        return 0;
 }
 
+static int device_ed_gen_id_show(struct seq_file *m, void *ignored)
+{
+       struct drbd_device *device = m->private;
+       seq_printf(m, "0x%016llX\n", (unsigned long long)device->ed_uuid);
+       return 0;
+}
+
 #define drbd_debugfs_device_attr(name)                                         \
 static int device_ ## name ## _open(struct inode *inode, struct file *file)    \
 {                                                                              \
@@ -796,6 +803,7 @@ drbd_debugfs_device_attr(oldest_requests)
 drbd_debugfs_device_attr(act_log_extents)
 drbd_debugfs_device_attr(resync_extents)
 drbd_debugfs_device_attr(data_gen_id)
+drbd_debugfs_device_attr(ed_gen_id)
 
 void drbd_debugfs_device_add(struct drbd_device *device)
 {
@@ -839,6 +847,7 @@ void drbd_debugfs_device_add(struct drbd_device *device)
        DCF(act_log_extents);
        DCF(resync_extents);
        DCF(data_gen_id);
+       DCF(ed_gen_id);
 #undef DCF
        return;
 
@@ -854,6 +863,7 @@ void drbd_debugfs_device_cleanup(struct drbd_device *device)
        drbd_debugfs_remove(&device->debugfs_vol_act_log_extents);
        drbd_debugfs_remove(&device->debugfs_vol_resync_extents);
        drbd_debugfs_remove(&device->debugfs_vol_data_gen_id);
+       drbd_debugfs_remove(&device->debugfs_vol_ed_gen_id);
        drbd_debugfs_remove(&device->debugfs_vol);
 }
 
index e66d453..34bc84e 100644 (file)
@@ -77,13 +77,6 @@ extern int fault_devs;
 extern char usermode_helper[];
 
 
-/* I don't remember why XCPU ...
- * This is used to wake the asender,
- * and to interrupt sending the sending task
- * on disconnect.
- */
-#define DRBD_SIG SIGXCPU
-
 /* This is used to stop/restart our threads.
  * Cannot use SIGTERM nor SIGKILL, since these
  * are sent out by init on runlevel changes
@@ -292,6 +285,9 @@ struct drbd_device_work {
 
 extern int drbd_wait_misc(struct drbd_device *, struct drbd_interval *);
 
+extern void lock_all_resources(void);
+extern void unlock_all_resources(void);
+
 struct drbd_request {
        struct drbd_work w;
        struct drbd_device *device;
@@ -504,7 +500,6 @@ enum {
 
        MD_NO_FUA,              /* Users wants us to not use FUA/FLUSH on meta data dev */
 
-       SUSPEND_IO,             /* suspend application io */
        BITMAP_IO,              /* suspend application io;
                                   once no more io in flight, start bitmap io */
        BITMAP_IO_QUEUED,       /* Started bitmap IO */
@@ -541,9 +536,6 @@ struct drbd_bitmap; /* opaque for drbd_device */
 /* definition of bits in bm_flags to be used in drbd_bm_lock
  * and drbd_bitmap_io and friends. */
 enum bm_flag {
-       /* do we need to kfree, or vfree bm_pages? */
-       BM_P_VMALLOCED = 0x10000, /* internal use only, will be masked out */
-
        /* currently locked for bulk operation */
        BM_LOCKED_MASK = 0xf,
 
@@ -632,12 +624,6 @@ struct bm_io_work {
        void (*done)(struct drbd_device *device, int rv);
 };
 
-enum write_ordering_e {
-       WO_none,
-       WO_drain_io,
-       WO_bdev_flush,
-};
-
 struct fifo_buffer {
        unsigned int head_index;
        unsigned int size;
@@ -650,8 +636,7 @@ extern struct fifo_buffer *fifo_alloc(int fifo_size);
 enum {
        NET_CONGESTED,          /* The data socket is congested */
        RESOLVE_CONFLICTS,      /* Set on one node, cleared on the peer! */
-       SEND_PING,              /* whether asender should send a ping asap */
-       SIGNAL_ASENDER,         /* whether asender wants to be interrupted */
+       SEND_PING,
        GOT_PING_ACK,           /* set when we receive a ping_ack packet, ping_wait gets woken */
        CONN_WD_ST_CHG_REQ,     /* A cluster wide state change on the connection is active */
        CONN_WD_ST_CHG_OKAY,
@@ -670,6 +655,8 @@ enum {
        DEVICE_WORK_PENDING,    /* tell worker that some device has pending work */
 };
 
+enum which_state { NOW, OLD = NOW, NEW };
+
 struct drbd_resource {
        char *name;
 #ifdef CONFIG_DEBUG_FS
@@ -755,7 +742,8 @@ struct drbd_connection {
        unsigned long last_reconnect_jif;
        struct drbd_thread receiver;
        struct drbd_thread worker;
-       struct drbd_thread asender;
+       struct drbd_thread ack_receiver;
+       struct workqueue_struct *ack_sender;
 
        /* cached pointers,
         * so we can look up the oldest pending requests more quickly.
@@ -774,6 +762,8 @@ struct drbd_connection {
        struct drbd_thread_timing_details r_timing_details[DRBD_THREAD_DETAILS_HIST];
 
        struct {
+               unsigned long last_sent_barrier_jif;
+
                /* whether this sender thread
                 * has processed a single write yet. */
                bool seen_any_write_yet;
@@ -788,6 +778,17 @@ struct drbd_connection {
        } send;
 };
 
+static inline bool has_net_conf(struct drbd_connection *connection)
+{
+       bool has_net_conf;
+
+       rcu_read_lock();
+       has_net_conf = rcu_dereference(connection->net_conf);
+       rcu_read_unlock();
+
+       return has_net_conf;
+}
+
 void __update_timing_details(
                struct drbd_thread_timing_details *tdp,
                unsigned int *cb_nr,
@@ -811,6 +812,7 @@ struct drbd_peer_device {
        struct list_head peer_devices;
        struct drbd_device *device;
        struct drbd_connection *connection;
+       struct work_struct send_acks_work;
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_peer_dev;
 #endif
@@ -829,6 +831,7 @@ struct drbd_device {
        struct dentry *debugfs_vol_act_log_extents;
        struct dentry *debugfs_vol_resync_extents;
        struct dentry *debugfs_vol_data_gen_id;
+       struct dentry *debugfs_vol_ed_gen_id;
 #endif
 
        unsigned int vnr;       /* volume number within the connection */
@@ -873,6 +876,7 @@ struct drbd_device {
        atomic_t rs_pending_cnt; /* RS request/data packets on the wire */
        atomic_t unacked_cnt;    /* Need to send replies for */
        atomic_t local_cnt;      /* Waiting for local completion */
+       atomic_t suspend_cnt;
 
        /* Interval tree of pending local requests */
        struct rb_root read_requests;
@@ -1020,6 +1024,12 @@ static inline struct drbd_peer_device *first_peer_device(struct drbd_device *dev
        return list_first_entry_or_null(&device->peer_devices, struct drbd_peer_device, peer_devices);
 }
 
+static inline struct drbd_peer_device *
+conn_peer_device(struct drbd_connection *connection, int volume_number)
+{
+       return idr_find(&connection->peer_devices, volume_number);
+}
+
 #define for_each_resource(resource, _resources) \
        list_for_each_entry(resource, _resources, resources)
 
@@ -1113,7 +1123,7 @@ extern int drbd_send_ov_request(struct drbd_peer_device *, sector_t sector, int
 extern int drbd_send_bitmap(struct drbd_device *device);
 extern void drbd_send_sr_reply(struct drbd_peer_device *, enum drbd_state_rv retcode);
 extern void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode);
-extern void drbd_free_ldev(struct drbd_backing_dev *ldev);
+extern void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev);
 extern void drbd_device_cleanup(struct drbd_device *device);
 void drbd_print_uuids(struct drbd_device *device, const char *text);
 
@@ -1424,7 +1434,7 @@ extern struct bio_set *drbd_md_io_bio_set;
 /* to allocate from that set */
 extern struct bio *bio_alloc_drbd(gfp_t gfp_mask);
 
-extern rwlock_t global_state_lock;
+extern struct mutex resources_mutex;
 
 extern int conn_lowest_minor(struct drbd_connection *connection);
 extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor);
@@ -1454,6 +1464,9 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);
 
 
 /* drbd_nl.c */
+
+extern struct mutex notification_mutex;
+
 extern void drbd_suspend_io(struct drbd_device *device);
 extern void drbd_resume_io(struct drbd_device *device);
 extern char *ppsize(char *buf, unsigned long long size);
@@ -1536,7 +1549,9 @@ extern void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req);
 
 /* drbd_receiver.c */
 extern int drbd_receiver(struct drbd_thread *thi);
-extern int drbd_asender(struct drbd_thread *thi);
+extern int drbd_ack_receiver(struct drbd_thread *thi);
+extern void drbd_send_ping_wf(struct work_struct *ws);
+extern void drbd_send_acks_wf(struct work_struct *ws);
 extern bool drbd_rs_c_min_rate_throttle(struct drbd_device *device);
 extern bool drbd_rs_should_slow_down(struct drbd_device *device, sector_t sector,
                bool throttle_if_app_is_waiting);
@@ -1649,7 +1664,7 @@ extern int __drbd_change_sync(struct drbd_device *device, sector_t sector, int s
 #define drbd_rs_failed_io(device, sector, size) \
        __drbd_change_sync(device, sector, size, RECORD_RS_FAILED)
 extern void drbd_al_shrink(struct drbd_device *device);
-extern int drbd_initialize_al(struct drbd_device *, void *);
+extern int drbd_al_initialize(struct drbd_device *, void *);
 
 /* drbd_nl.c */
 /* state info broadcast */
@@ -1668,6 +1683,29 @@ struct sib_info {
 };
 void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib);
 
+extern void notify_resource_state(struct sk_buff *,
+                                 unsigned int,
+                                 struct drbd_resource *,
+                                 struct resource_info *,
+                                 enum drbd_notification_type);
+extern void notify_device_state(struct sk_buff *,
+                               unsigned int,
+                               struct drbd_device *,
+                               struct device_info *,
+                               enum drbd_notification_type);
+extern void notify_connection_state(struct sk_buff *,
+                                   unsigned int,
+                                   struct drbd_connection *,
+                                   struct connection_info *,
+                                   enum drbd_notification_type);
+extern void notify_peer_device_state(struct sk_buff *,
+                                    unsigned int,
+                                    struct drbd_peer_device *,
+                                    struct peer_device_info *,
+                                    enum drbd_notification_type);
+extern void notify_helper(enum drbd_notification_type, struct drbd_device *,
+                         struct drbd_connection *, const char *, int);
+
 /*
  * inline helper functions
  *************************/
@@ -1694,19 +1732,6 @@ static inline int drbd_peer_req_has_active_page(struct drbd_peer_request *peer_r
        return 0;
 }
 
-static inline enum drbd_state_rv
-_drbd_set_state(struct drbd_device *device, union drbd_state ns,
-               enum chg_state_flags flags, struct completion *done)
-{
-       enum drbd_state_rv rv;
-
-       read_lock(&global_state_lock);
-       rv = __drbd_set_state(device, ns, flags, done);
-       read_unlock(&global_state_lock);
-
-       return rv;
-}
-
 static inline union drbd_state drbd_read_state(struct drbd_device *device)
 {
        struct drbd_resource *resource = device->resource;
@@ -1937,16 +1962,21 @@ drbd_device_post_work(struct drbd_device *device, int work_bit)
 
 extern void drbd_flush_workqueue(struct drbd_work_queue *work_queue);
 
-static inline void wake_asender(struct drbd_connection *connection)
+/* To get the ack_receiver out of the blocking network stack,
+ * so it can change its sk_rcvtimeo from idle- to ping-timeout,
+ * and send a ping, we need to send a signal.
+ * Which signal we send is irrelevant. */
+static inline void wake_ack_receiver(struct drbd_connection *connection)
 {
-       if (test_bit(SIGNAL_ASENDER, &connection->flags))
-               force_sig(DRBD_SIG, connection->asender.task);
+       struct task_struct *task = connection->ack_receiver.task;
+       if (task && get_t_state(&connection->ack_receiver) == RUNNING)
+               force_sig(SIGXCPU, task);
 }
 
 static inline void request_ping(struct drbd_connection *connection)
 {
        set_bit(SEND_PING, &connection->flags);
-       wake_asender(connection);
+       wake_ack_receiver(connection);
 }
 
 extern void *conn_prepare_command(struct drbd_connection *, struct drbd_socket *);
@@ -2230,7 +2260,7 @@ static inline bool may_inc_ap_bio(struct drbd_device *device)
 
        if (drbd_suspended(device))
                return false;
-       if (test_bit(SUSPEND_IO, &device->flags))
+       if (atomic_read(&device->suspend_cnt))
                return false;
 
        /* to avoid potential deadlock or bitmap corruption,
index 74d97f4..5b43dfb 100644 (file)
@@ -117,6 +117,7 @@ module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0
  */
 struct idr drbd_devices;
 struct list_head drbd_resources;
+struct mutex resources_mutex;
 
 struct kmem_cache *drbd_request_cache;
 struct kmem_cache *drbd_ee_cache;      /* peer requests */
@@ -1435,8 +1436,8 @@ static int we_should_drop_the_connection(struct drbd_connection *connection, str
        /* long elapsed = (long)(jiffies - device->last_received); */
 
        drop_it =   connection->meta.socket == sock
-               || !connection->asender.task
-               || get_t_state(&connection->asender) != RUNNING
+               || !connection->ack_receiver.task
+               || get_t_state(&connection->ack_receiver) != RUNNING
                || connection->cstate < C_WF_REPORT_PARAMS;
 
        if (drop_it)
@@ -1793,15 +1794,6 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock,
                drbd_update_congested(connection);
        }
        do {
-               /* STRANGE
-                * tcp_sendmsg does _not_ use its size parameter at all ?
-                *
-                * -EAGAIN on timeout, -EINTR on signal.
-                */
-/* THINK
- * do we need to block DRBD_SIG if sock == &meta.socket ??
- * otherwise wake_asender() might interrupt some send_*Ack !
- */
                rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
                if (rv == -EAGAIN) {
                        if (we_should_drop_the_connection(connection, sock))
@@ -2000,7 +1992,7 @@ void drbd_device_cleanup(struct drbd_device *device)
                drbd_bm_cleanup(device);
        }
 
-       drbd_free_ldev(device->ldev);
+       drbd_backing_dev_free(device, device->ldev);
        device->ldev = NULL;
 
        clear_bit(AL_SUSPENDED, &device->flags);
@@ -2179,7 +2171,7 @@ void drbd_destroy_device(struct kref *kref)
        if (device->this_bdev)
                bdput(device->this_bdev);
 
-       drbd_free_ldev(device->ldev);
+       drbd_backing_dev_free(device, device->ldev);
        device->ldev = NULL;
 
        drbd_release_all_peer_reqs(device);
@@ -2563,7 +2555,7 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op
                cpumask_copy(resource->cpu_mask, new_cpu_mask);
                for_each_connection_rcu(connection, resource) {
                        connection->receiver.reset_cpu_mask = 1;
-                       connection->asender.reset_cpu_mask = 1;
+                       connection->ack_receiver.reset_cpu_mask = 1;
                        connection->worker.reset_cpu_mask = 1;
                }
        }
@@ -2590,7 +2582,7 @@ struct drbd_resource *drbd_create_resource(const char *name)
        kref_init(&resource->kref);
        idr_init(&resource->devices);
        INIT_LIST_HEAD(&resource->connections);
-       resource->write_ordering = WO_bdev_flush;
+       resource->write_ordering = WO_BDEV_FLUSH;
        list_add_tail_rcu(&resource->resources, &drbd_resources);
        mutex_init(&resource->conf_update);
        mutex_init(&resource->adm_mutex);
@@ -2652,8 +2644,8 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
        connection->receiver.connection = connection;
        drbd_thread_init(resource, &connection->worker, drbd_worker, "worker");
        connection->worker.connection = connection;
-       drbd_thread_init(resource, &connection->asender, drbd_asender, "asender");
-       connection->asender.connection = connection;
+       drbd_thread_init(resource, &connection->ack_receiver, drbd_ack_receiver, "ack_recv");
+       connection->ack_receiver.connection = connection;
 
        kref_init(&connection->kref);
 
@@ -2702,8 +2694,8 @@ static int init_submitter(struct drbd_device *device)
 {
        /* opencoded create_singlethread_workqueue(),
         * to be able to say "drbd%d", ..., minor */
-       device->submit.wq = alloc_workqueue("drbd%u_submit",
-                       WQ_UNBOUND | WQ_MEM_RECLAIM, 1, device->minor);
+       device->submit.wq =
+               alloc_ordered_workqueue("drbd%u_submit", WQ_MEM_RECLAIM, device->minor);
        if (!device->submit.wq)
                return -ENOMEM;
 
@@ -2820,6 +2812,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
                        goto out_idr_remove_from_resource;
                }
                kref_get(&connection->kref);
+               INIT_WORK(&peer_device->send_acks_work, drbd_send_acks_wf);
        }
 
        if (init_submitter(device)) {
@@ -2923,7 +2916,7 @@ static int __init drbd_init(void)
        drbd_proc = NULL; /* play safe for drbd_cleanup */
        idr_init(&drbd_devices);
 
-       rwlock_init(&global_state_lock);
+       mutex_init(&resources_mutex);
        INIT_LIST_HEAD(&drbd_resources);
 
        err = drbd_genl_register();
@@ -2971,18 +2964,6 @@ fail:
        return err;
 }
 
-void drbd_free_ldev(struct drbd_backing_dev *ldev)
-{
-       if (ldev == NULL)
-               return;
-
-       blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
-       blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
-
-       kfree(ldev->disk_conf);
-       kfree(ldev);
-}
-
 static void drbd_free_one_sock(struct drbd_socket *ds)
 {
        struct socket *s;
@@ -3277,6 +3258,10 @@ int drbd_md_read(struct drbd_device *device, struct drbd_backing_dev *bdev)
         * and read it. */
        bdev->md.meta_dev_idx = bdev->disk_conf->meta_dev_idx;
        bdev->md.md_offset = drbd_md_ss(bdev);
+       /* Even for (flexible or indexed) external meta data,
+        * initially restrict us to the 4k superblock for now.
+        * Affects the paranoia out-of-range access check in drbd_md_sync_page_io(). */
+       bdev->md.md_size_sect = 8;
 
        if (drbd_md_sync_page_io(device, bdev, bdev->md.md_offset, READ)) {
                /* NOTE: can't do normal error processing here as this is
@@ -3578,7 +3563,9 @@ void drbd_queue_bitmap_io(struct drbd_device *device,
 
        spin_lock_irq(&device->resource->req_lock);
        set_bit(BITMAP_IO, &device->flags);
-       if (atomic_read(&device->ap_bio_cnt) == 0) {
+       /* don't wait for pending application IO if the caller indicates that
+        * application IO does not conflict anyways. */
+       if (flags == BM_LOCKED_CHANGE_ALLOWED || atomic_read(&device->ap_bio_cnt) == 0) {
                if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
                        drbd_queue_work(&first_peer_device(device)->connection->sender_work,
                                        &device->bm_io_work.w);
@@ -3746,6 +3733,27 @@ int drbd_wait_misc(struct drbd_device *device, struct drbd_interval *i)
        return 0;
 }
 
+void lock_all_resources(void)
+{
+       struct drbd_resource *resource;
+       int __maybe_unused i = 0;
+
+       mutex_lock(&resources_mutex);
+       local_irq_disable();
+       for_each_resource(resource, &drbd_resources)
+               spin_lock_nested(&resource->req_lock, i++);
+}
+
+void unlock_all_resources(void)
+{
+       struct drbd_resource *resource;
+
+       for_each_resource(resource, &drbd_resources)
+               spin_unlock(&resource->req_lock);
+       local_irq_enable();
+       mutex_unlock(&resources_mutex);
+}
+
 #ifdef CONFIG_DRBD_FAULT_INJECTION
 /* Fault insertion support including random number generator shamelessly
  * stolen from kernel/rcutorture.c */
index e80cbef..c055c5e 100644 (file)
@@ -36,6 +36,7 @@
 #include "drbd_int.h"
 #include "drbd_protocol.h"
 #include "drbd_req.h"
+#include "drbd_state_change.h"
 #include <asm/unaligned.h>
 #include <linux/drbd_limits.h>
 #include <linux/kthread.h>
@@ -75,11 +76,24 @@ int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info);
 int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info);
 /* .dumpit */
 int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb);
+int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb);
+int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb);
+int drbd_adm_dump_devices_done(struct netlink_callback *cb);
+int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb);
+int drbd_adm_dump_connections_done(struct netlink_callback *cb);
+int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb);
+int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb);
+int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb);
 
 #include <linux/drbd_genl_api.h>
 #include "drbd_nla.h"
 #include <linux/genl_magic_func.h>
 
+static atomic_t drbd_genl_seq = ATOMIC_INIT(2); /* two. */
+static atomic_t notify_genl_seq = ATOMIC_INIT(2); /* two. */
+
+DEFINE_MUTEX(notification_mutex);
+
 /* used blkdev_get_by_path, to claim our meta data device(s) */
 static char *drbd_m_holder = "Hands off! this is DRBD's meta data device.";
 
@@ -349,6 +363,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
        sib.sib_reason = SIB_HELPER_PRE;
        sib.helper_name = cmd;
        drbd_bcast_event(device, &sib);
+       notify_helper(NOTIFY_CALL, device, connection, cmd, 0);
        ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
        if (ret)
                drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n",
@@ -361,6 +376,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
        sib.sib_reason = SIB_HELPER_POST;
        sib.helper_exit_code = ret;
        drbd_bcast_event(device, &sib);
+       notify_helper(NOTIFY_RESPONSE, device, connection, cmd, ret);
 
        if (current == connection->worker.task)
                clear_bit(CALLBACK_PENDING, &connection->flags);
@@ -388,6 +404,7 @@ static int conn_khelper(struct drbd_connection *connection, char *cmd)
 
        drbd_info(connection, "helper command: %s %s %s\n", usermode_helper, cmd, resource_name);
        /* TODO: conn_bcast_event() ?? */
+       notify_helper(NOTIFY_CALL, NULL, connection, cmd, 0);
 
        ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
        if (ret)
@@ -399,6 +416,7 @@ static int conn_khelper(struct drbd_connection *connection, char *cmd)
                          usermode_helper, cmd, resource_name,
                          (ret >> 8) & 0xff, ret);
        /* TODO: conn_bcast_event() ?? */
+       notify_helper(NOTIFY_RESPONSE, NULL, connection, cmd, ret);
 
        if (ret < 0) /* Ignore any ERRNOs we got. */
                ret = 0;
@@ -847,9 +865,11 @@ char *ppsize(char *buf, unsigned long long size)
  * and can be long lived.
  * This changes an device->flag, is triggered by drbd internals,
  * and should be short-lived. */
+/* It needs to be a counter, since multiple threads might
+   independently suspend and resume IO. */
 void drbd_suspend_io(struct drbd_device *device)
 {
-       set_bit(SUSPEND_IO, &device->flags);
+       atomic_inc(&device->suspend_cnt);
        if (drbd_suspended(device))
                return;
        wait_event(device->misc_wait, !atomic_read(&device->ap_bio_cnt));
@@ -857,8 +877,8 @@ void drbd_suspend_io(struct drbd_device *device)
 
 void drbd_resume_io(struct drbd_device *device)
 {
-       clear_bit(SUSPEND_IO, &device->flags);
-       wake_up(&device->misc_wait);
+       if (atomic_dec_and_test(&device->suspend_cnt))
+               wake_up(&device->misc_wait);
 }
 
 /**
@@ -871,27 +891,32 @@ void drbd_resume_io(struct drbd_device *device)
 enum determine_dev_size
 drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct resize_parms *rs) __must_hold(local)
 {
-       sector_t prev_first_sect, prev_size; /* previous meta location */
-       sector_t la_size_sect, u_size;
+       struct md_offsets_and_sizes {
+               u64 last_agreed_sect;
+               u64 md_offset;
+               s32 al_offset;
+               s32 bm_offset;
+               u32 md_size_sect;
+
+               u32 al_stripes;
+               u32 al_stripe_size_4k;
+       } prev;
+       sector_t u_size, size;
        struct drbd_md *md = &device->ldev->md;
-       u32 prev_al_stripe_size_4k;
-       u32 prev_al_stripes;
-       sector_t size;
        char ppb[10];
        void *buffer;
 
        int md_moved, la_size_changed;
        enum determine_dev_size rv = DS_UNCHANGED;
 
-       /* race:
-        * application request passes inc_ap_bio,
-        * but then cannot get an AL-reference.
-        * this function later may wait on ap_bio_cnt == 0. -> deadlock.
+       /* We may change the on-disk offsets of our meta data below.  Lock out
+        * anything that may cause meta data IO, to avoid acting on incomplete
+        * layout changes or scribbling over meta data that is in the process
+        * of being moved.
         *
-        * to avoid that:
-        * Suspend IO right here.
-        * still lock the act_log to not trigger ASSERTs there.
-        */
+        * Move is not exactly correct, btw, currently we have all our meta
+        * data in core memory, to "move" it we just write it all out, there
+        * are no reads. */
        drbd_suspend_io(device);
        buffer = drbd_md_get_buffer(device, __func__); /* Lock meta-data IO */
        if (!buffer) {
@@ -899,19 +924,17 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct
                return DS_ERROR;
        }
 
-       /* no wait necessary anymore, actually we could assert that */
-       wait_event(device->al_wait, lc_try_lock(device->act_log));
-
-       prev_first_sect = drbd_md_first_sector(device->ldev);
-       prev_size = device->ldev->md.md_size_sect;
-       la_size_sect = device->ldev->md.la_size_sect;
+       /* remember current offset and sizes */
+       prev.last_agreed_sect = md->la_size_sect;
+       prev.md_offset = md->md_offset;
+       prev.al_offset = md->al_offset;
+       prev.bm_offset = md->bm_offset;
+       prev.md_size_sect = md->md_size_sect;
+       prev.al_stripes = md->al_stripes;
+       prev.al_stripe_size_4k = md->al_stripe_size_4k;
 
        if (rs) {
                /* rs is non NULL if we should change the AL layout only */
-
-               prev_al_stripes = md->al_stripes;
-               prev_al_stripe_size_4k = md->al_stripe_size_4k;
-
                md->al_stripes = rs->al_stripes;
                md->al_stripe_size_4k = rs->al_stripe_size / 4;
                md->al_size_4k = (u64)rs->al_stripes * rs->al_stripe_size / 4;
@@ -924,7 +947,7 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct
        rcu_read_unlock();
        size = drbd_new_dev_size(device, device->ldev, u_size, flags & DDSF_FORCED);
 
-       if (size < la_size_sect) {
+       if (size < prev.last_agreed_sect) {
                if (rs && u_size == 0) {
                        /* Remove "rs &&" later. This check should always be active, but
                           right now the receiver expects the permissive behavior */
@@ -945,30 +968,29 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct
                err = drbd_bm_resize(device, size, !(flags & DDSF_NO_RESYNC));
                if (unlikely(err)) {
                        /* currently there is only one error: ENOMEM! */
-                       size = drbd_bm_capacity(device)>>1;
+                       size = drbd_bm_capacity(device);
                        if (size == 0) {
                                drbd_err(device, "OUT OF MEMORY! "
                                    "Could not allocate bitmap!\n");
                        } else {
                                drbd_err(device, "BM resizing failed. "
-                                   "Leaving size unchanged at size = %lu KB\n",
-                                   (unsigned long)size);
+                                   "Leaving size unchanged\n");
                        }
                        rv = DS_ERROR;
                }
                /* racy, see comments above. */
                drbd_set_my_capacity(device, size);
-               device->ldev->md.la_size_sect = size;
+               md->la_size_sect = size;
                drbd_info(device, "size = %s (%llu KB)\n", ppsize(ppb, size>>1),
                     (unsigned long long)size>>1);
        }
        if (rv <= DS_ERROR)
                goto err_out;
 
-       la_size_changed = (la_size_sect != device->ldev->md.la_size_sect);
+       la_size_changed = (prev.last_agreed_sect != md->la_size_sect);
 
-       md_moved = prev_first_sect != drbd_md_first_sector(device->ldev)
-               || prev_size       != device->ldev->md.md_size_sect;
+       md_moved = prev.md_offset    != md->md_offset
+               || prev.md_size_sect != md->md_size_sect;
 
        if (la_size_changed || md_moved || rs) {
                u32 prev_flags;
@@ -977,20 +999,29 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct
                 * Clear the timer, to avoid scary "timer expired!" messages,
                 * "Superblock" is written out at least twice below, anyways. */
                del_timer(&device->md_sync_timer);
-               drbd_al_shrink(device); /* All extents inactive. */
 
+               /* We won't change the "al-extents" setting, we just may need
+                * to move the on-disk location of the activity log ringbuffer.
+                * Lock for transaction is good enough, it may well be "dirty"
+                * or even "starving". */
+               wait_event(device->al_wait, lc_try_lock_for_transaction(device->act_log));
+
+               /* mark current on-disk bitmap and activity log as unreliable */
                prev_flags = md->flags;
-               md->flags &= ~MDF_PRIMARY_IND;
+               md->flags |= MDF_FULL_SYNC | MDF_AL_DISABLED;
                drbd_md_write(device, buffer);
 
+               drbd_al_initialize(device, buffer);
+
                drbd_info(device, "Writing the whole bitmap, %s\n",
                         la_size_changed && md_moved ? "size changed and md moved" :
                         la_size_changed ? "size changed" : "md moved");
                /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */
                drbd_bitmap_io(device, md_moved ? &drbd_bm_write_all : &drbd_bm_write,
                               "size changed", BM_LOCKED_MASK);
-               drbd_initialize_al(device, buffer);
 
+               /* on-disk bitmap and activity log is authoritative again
+                * (unless there was an IO error meanwhile...) */
                md->flags = prev_flags;
                drbd_md_write(device, buffer);
 
@@ -999,20 +1030,22 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct
                                  md->al_stripes, md->al_stripe_size_4k * 4);
        }
 
-       if (size > la_size_sect)
-               rv = la_size_sect ? DS_GREW : DS_GREW_FROM_ZERO;
-       if (size < la_size_sect)
+       if (size > prev.last_agreed_sect)
+               rv = prev.last_agreed_sect ? DS_GREW : DS_GREW_FROM_ZERO;
+       if (size < prev.last_agreed_sect)
                rv = DS_SHRUNK;
 
        if (0) {
        err_out:
-               if (rs) {
-                       md->al_stripes = prev_al_stripes;
-                       md->al_stripe_size_4k = prev_al_stripe_size_4k;
-                       md->al_size_4k = (u64)prev_al_stripes * prev_al_stripe_size_4k;
-
-                       drbd_md_set_sector_offsets(device, device->ldev);
-               }
+               /* restore previous offset and sizes */
+               md->la_size_sect = prev.last_agreed_sect;
+               md->md_offset = prev.md_offset;
+               md->al_offset = prev.al_offset;
+               md->bm_offset = prev.bm_offset;
+               md->md_size_sect = prev.md_size_sect;
+               md->al_stripes = prev.al_stripes;
+               md->al_stripe_size_4k = prev.al_stripe_size_4k;
+               md->al_size_4k = (u64)prev.al_stripes * prev.al_stripe_size_4k;
        }
        lc_unlock(device->act_log);
        wake_up(&device->al_wait);
@@ -1115,8 +1148,7 @@ static int drbd_check_al_size(struct drbd_device *device, struct disk_conf *dc)
                lc_destroy(n);
                return -EBUSY;
        } else {
-               if (t)
-                       lc_destroy(t);
+               lc_destroy(t);
        }
        drbd_md_mark_dirty(device); /* we changed device->act_log->nr_elemens */
        return 0;
@@ -1151,21 +1183,20 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
        if (b) {
                struct drbd_connection *connection = first_peer_device(device)->connection;
 
+               blk_queue_max_discard_sectors(q, DRBD_MAX_DISCARD_SECTORS);
+
                if (blk_queue_discard(b) &&
                    (connection->cstate < C_CONNECTED || connection->agreed_features & FF_TRIM)) {
-                       /* For now, don't allow more than one activity log extent worth of data
-                        * to be discarded in one go. We may need to rework drbd_al_begin_io()
-                        * to allow for even larger discard ranges */
-                       blk_queue_max_discard_sectors(q, DRBD_MAX_DISCARD_SECTORS);
-
+                       /* We don't care, stacking below should fix it for the local device.
+                        * Whether or not it is a suitable granularity on the remote device
+                        * is not our problem, really. If you care, you need to
+                        * use devices with similar topology on all peers. */
+                       q->limits.discard_granularity = 512;
                        queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
-                       /* REALLY? Is stacking secdiscard "legal"? */
-                       if (blk_queue_secdiscard(b))
-                               queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
                } else {
                        blk_queue_max_discard_sectors(q, 0);
                        queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
-                       queue_flag_clear_unlocked(QUEUE_FLAG_SECDISCARD, q);
+                       q->limits.discard_granularity = 0;
                }
 
                blk_queue_stack_limits(q, b);
@@ -1177,6 +1208,12 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
                        q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
                }
        }
+       /* To avoid confusion, if this queue does not support discard, clear
+        * max_discard_sectors, which is what lsblk -D reports to the user.  */
+       if (!blk_queue_discard(q)) {
+               blk_queue_max_discard_sectors(q, 0);
+               q->limits.discard_granularity = 0;
+       }
 }
 
 void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backing_dev *bdev)
@@ -1241,8 +1278,8 @@ static void conn_reconfig_done(struct drbd_connection *connection)
                connection->cstate == C_STANDALONE;
        spin_unlock_irq(&connection->resource->req_lock);
        if (stop_threads) {
-               /* asender is implicitly stopped by receiver
-                * in conn_disconnect() */
+               /* ack_receiver thread and ack_sender workqueue are implicitly
+                * stopped by receiver in conn_disconnect() */
                drbd_thread_stop(&connection->receiver);
                drbd_thread_stop(&connection->worker);
        }
@@ -1389,13 +1426,13 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
                goto fail_unlock;
        }
 
-       write_lock_irq(&global_state_lock);
+       lock_all_resources();
        retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after);
        if (retcode == NO_ERROR) {
                rcu_assign_pointer(device->ldev->disk_conf, new_disk_conf);
                drbd_resync_after_changed(device);
        }
-       write_unlock_irq(&global_state_lock);
+       unlock_all_resources();
 
        if (retcode != NO_ERROR)
                goto fail_unlock;
@@ -1418,7 +1455,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
                set_bit(MD_NO_FUA, &device->flags);
 
        if (write_ordering_changed(old_disk_conf, new_disk_conf))
-               drbd_bump_write_ordering(device->resource, NULL, WO_bdev_flush);
+               drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH);
 
        drbd_md_sync(device);
 
@@ -1449,6 +1486,88 @@ success:
        return 0;
 }
 
+static struct block_device *open_backing_dev(struct drbd_device *device,
+               const char *bdev_path, void *claim_ptr, bool do_bd_link)
+{
+       struct block_device *bdev;
+       int err = 0;
+
+       bdev = blkdev_get_by_path(bdev_path,
+                                 FMODE_READ | FMODE_WRITE | FMODE_EXCL, claim_ptr);
+       if (IS_ERR(bdev)) {
+               drbd_err(device, "open(\"%s\") failed with %ld\n",
+                               bdev_path, PTR_ERR(bdev));
+               return bdev;
+       }
+
+       if (!do_bd_link)
+               return bdev;
+
+       err = bd_link_disk_holder(bdev, device->vdisk);
+       if (err) {
+               blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
+               drbd_err(device, "bd_link_disk_holder(\"%s\", ...) failed with %d\n",
+                               bdev_path, err);
+               bdev = ERR_PTR(err);
+       }
+       return bdev;
+}
+
+static int open_backing_devices(struct drbd_device *device,
+               struct disk_conf *new_disk_conf,
+               struct drbd_backing_dev *nbc)
+{
+       struct block_device *bdev;
+
+       bdev = open_backing_dev(device, new_disk_conf->backing_dev, device, true);
+       if (IS_ERR(bdev))
+               return ERR_OPEN_DISK;
+       nbc->backing_bdev = bdev;
+
+       /*
+        * meta_dev_idx >= 0: external fixed size, possibly multiple
+        * drbd sharing one meta device.  TODO in that case, paranoia
+        * check that [md_bdev, meta_dev_idx] is not yet used by some
+        * other drbd minor!  (if you use drbd.conf + drbdadm, that
+        * should check it for you already; but if you don't, or
+        * someone fooled it, we need to double check here)
+        */
+       bdev = open_backing_dev(device, new_disk_conf->meta_dev,
+               /* claim ptr: device, if claimed exclusively; shared drbd_m_holder,
+                * if potentially shared with other drbd minors */
+                       (new_disk_conf->meta_dev_idx < 0) ? (void*)device : (void*)drbd_m_holder,
+               /* avoid double bd_claim_by_disk() for the same (source,target) tuple,
+                * as would happen with internal metadata. */
+                       (new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_FLEX_INT &&
+                        new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_INTERNAL));
+       if (IS_ERR(bdev))
+               return ERR_OPEN_MD_DISK;
+       nbc->md_bdev = bdev;
+       return NO_ERROR;
+}
+
+static void close_backing_dev(struct drbd_device *device, struct block_device *bdev,
+       bool do_bd_unlink)
+{
+       if (!bdev)
+               return;
+       if (do_bd_unlink)
+               bd_unlink_disk_holder(bdev, device->vdisk);
+       blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
+}
+
+void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev)
+{
+       if (ldev == NULL)
+               return;
+
+       close_backing_dev(device, ldev->md_bdev, ldev->md_bdev != ldev->backing_bdev);
+       close_backing_dev(device, ldev->backing_bdev, true);
+
+       kfree(ldev->disk_conf);
+       kfree(ldev);
+}
+
 int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 {
        struct drbd_config_context adm_ctx;
@@ -1462,7 +1581,6 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
        sector_t min_md_device_sectors;
        struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
        struct disk_conf *new_disk_conf = NULL;
-       struct block_device *bdev;
        struct lru_cache *resync_lru = NULL;
        struct fifo_buffer *new_plan = NULL;
        union drbd_state ns, os;
@@ -1478,7 +1596,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
        device = adm_ctx.device;
        mutex_lock(&adm_ctx.resource->adm_mutex);
        peer_device = first_peer_device(device);
-       connection = peer_device ? peer_device->connection : NULL;
+       connection = peer_device->connection;
        conn_reconfig_start(connection);
 
        /* if you want to reconfigure, please tear down first */
@@ -1539,12 +1657,6 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
                goto fail;
        }
 
-       write_lock_irq(&global_state_lock);
-       retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after);
-       write_unlock_irq(&global_state_lock);
-       if (retcode != NO_ERROR)
-               goto fail;
-
        rcu_read_lock();
        nc = rcu_dereference(connection->net_conf);
        if (nc) {
@@ -1556,35 +1668,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
        }
        rcu_read_unlock();
 
-       bdev = blkdev_get_by_path(new_disk_conf->backing_dev,
-                                 FMODE_READ | FMODE_WRITE | FMODE_EXCL, device);
-       if (IS_ERR(bdev)) {
-               drbd_err(device, "open(\"%s\") failed with %ld\n", new_disk_conf->backing_dev,
-                       PTR_ERR(bdev));
-               retcode = ERR_OPEN_DISK;
-               goto fail;
-       }
-       nbc->backing_bdev = bdev;
-
-       /*
-        * meta_dev_idx >= 0: external fixed size, possibly multiple
-        * drbd sharing one meta device.  TODO in that case, paranoia
-        * check that [md_bdev, meta_dev_idx] is not yet used by some
-        * other drbd minor!  (if you use drbd.conf + drbdadm, that
-        * should check it for you already; but if you don't, or
-        * someone fooled it, we need to double check here)
-        */
-       bdev = blkdev_get_by_path(new_disk_conf->meta_dev,
-                                 FMODE_READ | FMODE_WRITE | FMODE_EXCL,
-                                 (new_disk_conf->meta_dev_idx < 0) ?
-                                 (void *)device : (void *)drbd_m_holder);
-       if (IS_ERR(bdev)) {
-               drbd_err(device, "open(\"%s\") failed with %ld\n", new_disk_conf->meta_dev,
-                       PTR_ERR(bdev));
-               retcode = ERR_OPEN_MD_DISK;
+       retcode = open_backing_devices(device, new_disk_conf, nbc);
+       if (retcode != NO_ERROR)
                goto fail;
-       }
-       nbc->md_bdev = bdev;
 
        if ((nbc->backing_bdev == nbc->md_bdev) !=
            (new_disk_conf->meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
@@ -1707,6 +1793,13 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
                goto force_diskless_dec;
        }
 
+       lock_all_resources();
+       retcode = drbd_resync_after_valid(device, new_disk_conf->resync_after);
+       if (retcode != NO_ERROR) {
+               unlock_all_resources();
+               goto force_diskless_dec;
+       }
+
        /* Reset the "barriers don't work" bits here, then force meta data to
         * be written, to ensure we determine if barriers are supported. */
        if (new_disk_conf->md_flushes)
@@ -1727,7 +1820,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
        new_disk_conf = NULL;
        new_plan = NULL;
 
-       drbd_bump_write_ordering(device->resource, device->ldev, WO_bdev_flush);
+       drbd_resync_after_changed(device);
+       drbd_bump_write_ordering(device->resource, device->ldev, WO_BDEV_FLUSH);
+       unlock_all_resources();
 
        if (drbd_md_test_flag(device->ldev, MDF_CRASHED_PRIMARY))
                set_bit(CRASHED_PRIMARY, &device->flags);
@@ -1875,12 +1970,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
  fail:
        conn_reconfig_done(connection);
        if (nbc) {
-               if (nbc->backing_bdev)
-                       blkdev_put(nbc->backing_bdev,
-                                  FMODE_READ | FMODE_WRITE | FMODE_EXCL);
-               if (nbc->md_bdev)
-                       blkdev_put(nbc->md_bdev,
-                                  FMODE_READ | FMODE_WRITE | FMODE_EXCL);
+               close_backing_dev(device, nbc->md_bdev, nbc->md_bdev != nbc->backing_bdev);
+               close_backing_dev(device, nbc->backing_bdev, true);
                kfree(nbc);
        }
        kfree(new_disk_conf);
@@ -1895,6 +1986,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 static int adm_detach(struct drbd_device *device, int force)
 {
        enum drbd_state_rv retcode;
+       void *buffer;
        int ret;
 
        if (force) {
@@ -1905,13 +1997,16 @@ static int adm_detach(struct drbd_device *device, int force)
        }
 
        drbd_suspend_io(device); /* so no-one is stuck in drbd_al_begin_io */
-       drbd_md_get_buffer(device, __func__); /* make sure there is no in-flight meta-data IO */
-       retcode = drbd_request_state(device, NS(disk, D_FAILED));
-       drbd_md_put_buffer(device);
+       buffer = drbd_md_get_buffer(device, __func__); /* make sure there is no in-flight meta-data IO */
+       if (buffer) {
+               retcode = drbd_request_state(device, NS(disk, D_FAILED));
+               drbd_md_put_buffer(device);
+       } else /* already <= D_FAILED */
+               retcode = SS_NOTHING_TO_DO;
        /* D_FAILED will transition to DISKLESS. */
+       drbd_resume_io(device);
        ret = wait_event_interruptible(device->misc_wait,
                        device->state.disk != D_FAILED);
-       drbd_resume_io(device);
        if ((int)retcode == (int)SS_IS_DISKLESS)
                retcode = SS_NOTHING_TO_DO;
        if (ret)
@@ -2245,8 +2340,31 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
        return 0;
 }
 
+static void connection_to_info(struct connection_info *info,
+                              struct drbd_connection *connection)
+{
+       info->conn_connection_state = connection->cstate;
+       info->conn_role = conn_highest_peer(connection);
+}
+
+static void peer_device_to_info(struct peer_device_info *info,
+                               struct drbd_peer_device *peer_device)
+{
+       struct drbd_device *device = peer_device->device;
+
+       info->peer_repl_state =
+               max_t(enum drbd_conns, C_WF_REPORT_PARAMS, device->state.conn);
+       info->peer_disk_state = device->state.pdsk;
+       info->peer_resync_susp_user = device->state.user_isp;
+       info->peer_resync_susp_peer = device->state.peer_isp;
+       info->peer_resync_susp_dependency = device->state.aftr_isp;
+}
+
 int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
 {
+       struct connection_info connection_info;
+       enum drbd_notification_type flags;
+       unsigned int peer_devices = 0;
        struct drbd_config_context adm_ctx;
        struct drbd_peer_device *peer_device;
        struct net_conf *old_net_conf, *new_net_conf = NULL;
@@ -2347,6 +2465,22 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
        connection->peer_addr_len = nla_len(adm_ctx.peer_addr);
        memcpy(&connection->peer_addr, nla_data(adm_ctx.peer_addr), connection->peer_addr_len);
 
+       idr_for_each_entry(&connection->peer_devices, peer_device, i) {
+               peer_devices++;
+       }
+
+       connection_to_info(&connection_info, connection);
+       flags = (peer_devices--) ? NOTIFY_CONTINUES : 0;
+       mutex_lock(&notification_mutex);
+       notify_connection_state(NULL, 0, connection, &connection_info, NOTIFY_CREATE | flags);
+       idr_for_each_entry(&connection->peer_devices, peer_device, i) {
+               struct peer_device_info peer_device_info;
+
+               peer_device_to_info(&peer_device_info, peer_device);
+               flags = (peer_devices--) ? NOTIFY_CONTINUES : 0;
+               notify_peer_device_state(NULL, 0, peer_device, &peer_device_info, NOTIFY_CREATE | flags);
+       }
+       mutex_unlock(&notification_mutex);
        mutex_unlock(&adm_ctx.resource->conf_update);
 
        rcu_read_lock();
@@ -2428,6 +2562,8 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection
                        drbd_err(connection,
                                "unexpected rv2=%d in conn_try_disconnect()\n",
                                rv2);
+               /* Unlike in DRBD 9, the state engine has generated
+                * NOTIFY_DESTROY events before clearing connection->net_conf. */
        }
        return rv;
 }
@@ -2585,6 +2721,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
                mutex_unlock(&device->resource->conf_update);
                synchronize_rcu();
                kfree(old_disk_conf);
+               new_disk_conf = NULL;
        }
 
        ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0);
@@ -2618,6 +2755,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
 
  fail_ldev:
        put_ldev(device);
+       kfree(new_disk_conf);
        goto fail;
 }
 
@@ -2855,7 +2993,30 @@ int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info)
        mutex_lock(&adm_ctx.resource->adm_mutex);
        device = adm_ctx.device;
        if (test_bit(NEW_CUR_UUID, &device->flags)) {
-               drbd_uuid_new_current(device);
+               if (get_ldev_if_state(device, D_ATTACHING)) {
+                       drbd_uuid_new_current(device);
+                       put_ldev(device);
+               } else {
+                       /* This is effectively a multi-stage "forced down".
+                        * The NEW_CUR_UUID bit is supposedly only set, if we
+                        * lost the replication connection, and are configured
+                        * to freeze IO and wait for some fence-peer handler.
+                        * So we still don't have a replication connection.
+                        * And now we don't have a local disk either.  After
+                        * resume, we will fail all pending and new IO, because
+                        * we don't have any data anymore.  Which means we will
+                        * eventually be able to terminate all users of this
+                        * device, and then take it down.  By bumping the
+                        * "effective" data uuid, we make sure that you really
+                        * need to tear down before you reconfigure, we will
+                        * the refuse to re-connect or re-attach (because no
+                        * matching real data uuid exists).
+                        */
+                       u64 val;
+                       get_random_bytes(&val, sizeof(u64));
+                       drbd_set_ed_uuid(device, val);
+                       drbd_warn(device, "Resumed without access to data; please tear down before attempting to re-configure.\n");
+               }
                clear_bit(NEW_CUR_UUID, &device->flags);
        }
        drbd_suspend_io(device);
@@ -2909,6 +3070,486 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
+/*
+ * The generic netlink dump callbacks are called outside the genl_lock(), so
+ * they cannot use the simple attribute parsing code which uses global
+ * attribute tables.
+ */
+static struct nlattr *find_cfg_context_attr(const struct nlmsghdr *nlh, int attr)
+{
+       const unsigned hdrlen = GENL_HDRLEN + GENL_MAGIC_FAMILY_HDRSZ;
+       const int maxtype = ARRAY_SIZE(drbd_cfg_context_nl_policy) - 1;
+       struct nlattr *nla;
+
+       nla = nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen),
+                      DRBD_NLA_CFG_CONTEXT);
+       if (!nla)
+               return NULL;
+       return drbd_nla_find_nested(maxtype, nla, __nla_type(attr));
+}
+
+static void resource_to_info(struct resource_info *, struct drbd_resource *);
+
+int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct drbd_genlmsghdr *dh;
+       struct drbd_resource *resource;
+       struct resource_info resource_info;
+       struct resource_statistics resource_statistics;
+       int err;
+
+       rcu_read_lock();
+       if (cb->args[0]) {
+               for_each_resource_rcu(resource, &drbd_resources)
+                       if (resource == (struct drbd_resource *)cb->args[0])
+                               goto found_resource;
+               err = 0;  /* resource was probably deleted */
+               goto out;
+       }
+       resource = list_entry(&drbd_resources,
+                             struct drbd_resource, resources);
+
+found_resource:
+       list_for_each_entry_continue_rcu(resource, &drbd_resources, resources) {
+               goto put_result;
+       }
+       err = 0;
+       goto out;
+
+put_result:
+       dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
+                       cb->nlh->nlmsg_seq, &drbd_genl_family,
+                       NLM_F_MULTI, DRBD_ADM_GET_RESOURCES);
+       err = -ENOMEM;
+       if (!dh)
+               goto out;
+       dh->minor = -1U;
+       dh->ret_code = NO_ERROR;
+       err = nla_put_drbd_cfg_context(skb, resource, NULL, NULL);
+       if (err)
+               goto out;
+       err = res_opts_to_skb(skb, &resource->res_opts, !capable(CAP_SYS_ADMIN));
+       if (err)
+               goto out;
+       resource_to_info(&resource_info, resource);
+       err = resource_info_to_skb(skb, &resource_info, !capable(CAP_SYS_ADMIN));
+       if (err)
+               goto out;
+       resource_statistics.res_stat_write_ordering = resource->write_ordering;
+       err = resource_statistics_to_skb(skb, &resource_statistics, !capable(CAP_SYS_ADMIN));
+       if (err)
+               goto out;
+       cb->args[0] = (long)resource;
+       genlmsg_end(skb, dh);
+       err = 0;
+
+out:
+       rcu_read_unlock();
+       if (err)
+               return err;
+       return skb->len;
+}
+
+static void device_to_statistics(struct device_statistics *s,
+                                struct drbd_device *device)
+{
+       memset(s, 0, sizeof(*s));
+       s->dev_upper_blocked = !may_inc_ap_bio(device);
+       if (get_ldev(device)) {
+               struct drbd_md *md = &device->ldev->md;
+               u64 *history_uuids = (u64 *)s->history_uuids;
+               struct request_queue *q;
+               int n;
+
+               spin_lock_irq(&md->uuid_lock);
+               s->dev_current_uuid = md->uuid[UI_CURRENT];
+               BUILD_BUG_ON(sizeof(s->history_uuids) < UI_HISTORY_END - UI_HISTORY_START + 1);
+               for (n = 0; n < UI_HISTORY_END - UI_HISTORY_START + 1; n++)
+                       history_uuids[n] = md->uuid[UI_HISTORY_START + n];
+               for (; n < HISTORY_UUIDS; n++)
+                       history_uuids[n] = 0;
+               s->history_uuids_len = HISTORY_UUIDS;
+               spin_unlock_irq(&md->uuid_lock);
+
+               s->dev_disk_flags = md->flags;
+               q = bdev_get_queue(device->ldev->backing_bdev);
+               s->dev_lower_blocked =
+                       bdi_congested(&q->backing_dev_info,
+                                     (1 << WB_async_congested) |
+                                     (1 << WB_sync_congested));
+               put_ldev(device);
+       }
+       s->dev_size = drbd_get_capacity(device->this_bdev);
+       s->dev_read = device->read_cnt;
+       s->dev_write = device->writ_cnt;
+       s->dev_al_writes = device->al_writ_cnt;
+       s->dev_bm_writes = device->bm_writ_cnt;
+       s->dev_upper_pending = atomic_read(&device->ap_bio_cnt);
+       s->dev_lower_pending = atomic_read(&device->local_cnt);
+       s->dev_al_suspended = test_bit(AL_SUSPENDED, &device->flags);
+       s->dev_exposed_data_uuid = device->ed_uuid;
+}
+
+static int put_resource_in_arg0(struct netlink_callback *cb, int holder_nr)
+{
+       if (cb->args[0]) {
+               struct drbd_resource *resource =
+                       (struct drbd_resource *)cb->args[0];
+               kref_put(&resource->kref, drbd_destroy_resource);
+       }
+
+       return 0;
+}
+
+int drbd_adm_dump_devices_done(struct netlink_callback *cb) {
+       return put_resource_in_arg0(cb, 7);
+}
+
+static void device_to_info(struct device_info *, struct drbd_device *);
+
+int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct nlattr *resource_filter;
+       struct drbd_resource *resource;
+       struct drbd_device *uninitialized_var(device);
+       int minor, err, retcode;
+       struct drbd_genlmsghdr *dh;
+       struct device_info device_info;
+       struct device_statistics device_statistics;
+       struct idr *idr_to_search;
+
+       resource = (struct drbd_resource *)cb->args[0];
+       if (!cb->args[0] && !cb->args[1]) {
+               resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
+               if (resource_filter) {
+                       retcode = ERR_RES_NOT_KNOWN;
+                       resource = drbd_find_resource(nla_data(resource_filter));
+                       if (!resource)
+                               goto put_result;
+                       cb->args[0] = (long)resource;
+               }
+       }
+
+       rcu_read_lock();
+       minor = cb->args[1];
+       idr_to_search = resource ? &resource->devices : &drbd_devices;
+       device = idr_get_next(idr_to_search, &minor);
+       if (!device) {
+               err = 0;
+               goto out;
+       }
+       idr_for_each_entry_continue(idr_to_search, device, minor) {
+               retcode = NO_ERROR;
+               goto put_result;  /* only one iteration */
+       }
+       err = 0;
+       goto out;  /* no more devices */
+
+put_result:
+       dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
+                       cb->nlh->nlmsg_seq, &drbd_genl_family,
+                       NLM_F_MULTI, DRBD_ADM_GET_DEVICES);
+       err = -ENOMEM;
+       if (!dh)
+               goto out;
+       dh->ret_code = retcode;
+       dh->minor = -1U;
+       if (retcode == NO_ERROR) {
+               dh->minor = device->minor;
+               err = nla_put_drbd_cfg_context(skb, device->resource, NULL, device);
+               if (err)
+                       goto out;
+               if (get_ldev(device)) {
+                       struct disk_conf *disk_conf =
+                               rcu_dereference(device->ldev->disk_conf);
+
+                       err = disk_conf_to_skb(skb, disk_conf, !capable(CAP_SYS_ADMIN));
+                       put_ldev(device);
+                       if (err)
+                               goto out;
+               }
+               device_to_info(&device_info, device);
+               err = device_info_to_skb(skb, &device_info, !capable(CAP_SYS_ADMIN));
+               if (err)
+                       goto out;
+
+               device_to_statistics(&device_statistics, device);
+               err = device_statistics_to_skb(skb, &device_statistics, !capable(CAP_SYS_ADMIN));
+               if (err)
+                       goto out;
+               cb->args[1] = minor + 1;
+       }
+       genlmsg_end(skb, dh);
+       err = 0;
+
+out:
+       rcu_read_unlock();
+       if (err)
+               return err;
+       return skb->len;
+}
+
+int drbd_adm_dump_connections_done(struct netlink_callback *cb)
+{
+       return put_resource_in_arg0(cb, 6);
+}
+
+enum { SINGLE_RESOURCE, ITERATE_RESOURCES };
+
+int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct nlattr *resource_filter;
+       struct drbd_resource *resource = NULL, *next_resource;
+       struct drbd_connection *uninitialized_var(connection);
+       int err = 0, retcode;
+       struct drbd_genlmsghdr *dh;
+       struct connection_info connection_info;
+       struct connection_statistics connection_statistics;
+
+       rcu_read_lock();
+       resource = (struct drbd_resource *)cb->args[0];
+       if (!cb->args[0]) {
+               resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
+               if (resource_filter) {
+                       retcode = ERR_RES_NOT_KNOWN;
+                       resource = drbd_find_resource(nla_data(resource_filter));
+                       if (!resource)
+                               goto put_result;
+                       cb->args[0] = (long)resource;
+                       cb->args[1] = SINGLE_RESOURCE;
+               }
+       }
+       if (!resource) {
+               if (list_empty(&drbd_resources))
+                       goto out;
+               resource = list_first_entry(&drbd_resources, struct drbd_resource, resources);
+               kref_get(&resource->kref);
+               cb->args[0] = (long)resource;
+               cb->args[1] = ITERATE_RESOURCES;
+       }
+
+    next_resource:
+       rcu_read_unlock();
+       mutex_lock(&resource->conf_update);
+       rcu_read_lock();
+       if (cb->args[2]) {
+               for_each_connection_rcu(connection, resource)
+                       if (connection == (struct drbd_connection *)cb->args[2])
+                               goto found_connection;
+               /* connection was probably deleted */
+               goto no_more_connections;
+       }
+       connection = list_entry(&resource->connections, struct drbd_connection, connections);
+
+found_connection:
+       list_for_each_entry_continue_rcu(connection, &resource->connections, connections) {
+               if (!has_net_conf(connection))
+                       continue;
+               retcode = NO_ERROR;
+               goto put_result;  /* only one iteration */
+       }
+
+no_more_connections:
+       if (cb->args[1] == ITERATE_RESOURCES) {
+               for_each_resource_rcu(next_resource, &drbd_resources) {
+                       if (next_resource == resource)
+                               goto found_resource;
+               }
+               /* resource was probably deleted */
+       }
+       goto out;
+
+found_resource:
+       list_for_each_entry_continue_rcu(next_resource, &drbd_resources, resources) {
+               mutex_unlock(&resource->conf_update);
+               kref_put(&resource->kref, drbd_destroy_resource);
+               resource = next_resource;
+               kref_get(&resource->kref);
+               cb->args[0] = (long)resource;
+               cb->args[2] = 0;
+               goto next_resource;
+       }
+       goto out;  /* no more resources */
+
+put_result:
+       dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
+                       cb->nlh->nlmsg_seq, &drbd_genl_family,
+                       NLM_F_MULTI, DRBD_ADM_GET_CONNECTIONS);
+       err = -ENOMEM;
+       if (!dh)
+               goto out;
+       dh->ret_code = retcode;
+       dh->minor = -1U;
+       if (retcode == NO_ERROR) {
+               struct net_conf *net_conf;
+
+               err = nla_put_drbd_cfg_context(skb, resource, connection, NULL);
+               if (err)
+                       goto out;
+               net_conf = rcu_dereference(connection->net_conf);
+               if (net_conf) {
+                       err = net_conf_to_skb(skb, net_conf, !capable(CAP_SYS_ADMIN));
+                       if (err)
+                               goto out;
+               }
+               connection_to_info(&connection_info, connection);
+               err = connection_info_to_skb(skb, &connection_info, !capable(CAP_SYS_ADMIN));
+               if (err)
+                       goto out;
+               connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags);
+               err = connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN));
+               if (err)
+                       goto out;
+               cb->args[2] = (long)connection;
+       }
+       genlmsg_end(skb, dh);
+       err = 0;
+
+out:
+       rcu_read_unlock();
+       if (resource)
+               mutex_unlock(&resource->conf_update);
+       if (err)
+               return err;
+       return skb->len;
+}
+
+enum mdf_peer_flag {
+       MDF_PEER_CONNECTED =    1 << 0,
+       MDF_PEER_OUTDATED =     1 << 1,
+       MDF_PEER_FENCING =      1 << 2,
+       MDF_PEER_FULL_SYNC =    1 << 3,
+};
+
+static void peer_device_to_statistics(struct peer_device_statistics *s,
+                                     struct drbd_peer_device *peer_device)
+{
+       struct drbd_device *device = peer_device->device;
+
+       memset(s, 0, sizeof(*s));
+       s->peer_dev_received = device->recv_cnt;
+       s->peer_dev_sent = device->send_cnt;
+       s->peer_dev_pending = atomic_read(&device->ap_pending_cnt) +
+                             atomic_read(&device->rs_pending_cnt);
+       s->peer_dev_unacked = atomic_read(&device->unacked_cnt);
+       s->peer_dev_out_of_sync = drbd_bm_total_weight(device) << (BM_BLOCK_SHIFT - 9);
+       s->peer_dev_resync_failed = device->rs_failed << (BM_BLOCK_SHIFT - 9);
+       if (get_ldev(device)) {
+               struct drbd_md *md = &device->ldev->md;
+
+               spin_lock_irq(&md->uuid_lock);
+               s->peer_dev_bitmap_uuid = md->uuid[UI_BITMAP];
+               spin_unlock_irq(&md->uuid_lock);
+               s->peer_dev_flags =
+                       (drbd_md_test_flag(device->ldev, MDF_CONNECTED_IND) ?
+                               MDF_PEER_CONNECTED : 0) +
+                       (drbd_md_test_flag(device->ldev, MDF_CONSISTENT) &&
+                        !drbd_md_test_flag(device->ldev, MDF_WAS_UP_TO_DATE) ?
+                               MDF_PEER_OUTDATED : 0) +
+                       /* FIXME: MDF_PEER_FENCING? */
+                       (drbd_md_test_flag(device->ldev, MDF_FULL_SYNC) ?
+                               MDF_PEER_FULL_SYNC : 0);
+               put_ldev(device);
+       }
+}
+
+int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb)
+{
+       return put_resource_in_arg0(cb, 9);
+}
+
+int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct nlattr *resource_filter;
+       struct drbd_resource *resource;
+       struct drbd_device *uninitialized_var(device);
+       struct drbd_peer_device *peer_device = NULL;
+       int minor, err, retcode;
+       struct drbd_genlmsghdr *dh;
+       struct idr *idr_to_search;
+
+       resource = (struct drbd_resource *)cb->args[0];
+       if (!cb->args[0] && !cb->args[1]) {
+               resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
+               if (resource_filter) {
+                       retcode = ERR_RES_NOT_KNOWN;
+                       resource = drbd_find_resource(nla_data(resource_filter));
+                       if (!resource)
+                               goto put_result;
+               }
+               cb->args[0] = (long)resource;
+       }
+
+       rcu_read_lock();
+       minor = cb->args[1];
+       idr_to_search = resource ? &resource->devices : &drbd_devices;
+       device = idr_find(idr_to_search, minor);
+       if (!device) {
+next_device:
+               minor++;
+               cb->args[2] = 0;
+               device = idr_get_next(idr_to_search, &minor);
+               if (!device) {
+                       err = 0;
+                       goto out;
+               }
+       }
+       if (cb->args[2]) {
+               for_each_peer_device(peer_device, device)
+                       if (peer_device == (struct drbd_peer_device *)cb->args[2])
+                               goto found_peer_device;
+               /* peer device was probably deleted */
+               goto next_device;
+       }
+       /* Make peer_device point to the list head (not the first entry). */
+       peer_device = list_entry(&device->peer_devices, struct drbd_peer_device, peer_devices);
+
+found_peer_device:
+       list_for_each_entry_continue_rcu(peer_device, &device->peer_devices, peer_devices) {
+               if (!has_net_conf(peer_device->connection))
+                       continue;
+               retcode = NO_ERROR;
+               goto put_result;  /* only one iteration */
+       }
+       goto next_device;
+
+put_result:
+       dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
+                       cb->nlh->nlmsg_seq, &drbd_genl_family,
+                       NLM_F_MULTI, DRBD_ADM_GET_PEER_DEVICES);
+       err = -ENOMEM;
+       if (!dh)
+               goto out;
+       dh->ret_code = retcode;
+       dh->minor = -1U;
+       if (retcode == NO_ERROR) {
+               struct peer_device_info peer_device_info;
+               struct peer_device_statistics peer_device_statistics;
+
+               dh->minor = minor;
+               err = nla_put_drbd_cfg_context(skb, device->resource, peer_device->connection, device);
+               if (err)
+                       goto out;
+               peer_device_to_info(&peer_device_info, peer_device);
+               err = peer_device_info_to_skb(skb, &peer_device_info, !capable(CAP_SYS_ADMIN));
+               if (err)
+                       goto out;
+               peer_device_to_statistics(&peer_device_statistics, peer_device);
+               err = peer_device_statistics_to_skb(skb, &peer_device_statistics, !capable(CAP_SYS_ADMIN));
+               if (err)
+                       goto out;
+               cb->args[1] = minor;
+               cb->args[2] = (long)peer_device;
+       }
+       genlmsg_end(skb, dh);
+       err = 0;
+
+out:
+       rcu_read_unlock();
+       if (err)
+               return err;
+       return skb->len;
+}
 /*
  * Return the connection of @resource if @resource has exactly one connection.
  */
@@ -3414,8 +4055,18 @@ drbd_check_resource_name(struct drbd_config_context *adm_ctx)
        return NO_ERROR;
 }
 
+static void resource_to_info(struct resource_info *info,
+                            struct drbd_resource *resource)
+{
+       info->res_role = conn_highest_role(first_connection(resource));
+       info->res_susp = resource->susp;
+       info->res_susp_nod = resource->susp_nod;
+       info->res_susp_fen = resource->susp_fen;
+}
+
 int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
 {
+       struct drbd_connection *connection;
        struct drbd_config_context adm_ctx;
        enum drbd_ret_code retcode;
        struct res_opts res_opts;
@@ -3449,13 +4100,33 @@ int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
        }
 
        /* not yet safe for genl_family.parallel_ops */
-       if (!conn_create(adm_ctx.resource_name, &res_opts))
+       mutex_lock(&resources_mutex);
+       connection = conn_create(adm_ctx.resource_name, &res_opts);
+       mutex_unlock(&resources_mutex);
+
+       if (connection) {
+               struct resource_info resource_info;
+
+               mutex_lock(&notification_mutex);
+               resource_to_info(&resource_info, connection->resource);
+               notify_resource_state(NULL, 0, connection->resource,
+                                     &resource_info, NOTIFY_CREATE);
+               mutex_unlock(&notification_mutex);
+       } else
                retcode = ERR_NOMEM;
+
 out:
        drbd_adm_finish(&adm_ctx, info, retcode);
        return 0;
 }
 
+static void device_to_info(struct device_info *info,
+                          struct drbd_device *device)
+{
+       info->dev_disk_state = device->state.disk;
+}
+
+
 int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info)
 {
        struct drbd_config_context adm_ctx;
@@ -3490,6 +4161,36 @@ int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info)
 
        mutex_lock(&adm_ctx.resource->adm_mutex);
        retcode = drbd_create_device(&adm_ctx, dh->minor);
+       if (retcode == NO_ERROR) {
+               struct drbd_device *device;
+               struct drbd_peer_device *peer_device;
+               struct device_info info;
+               unsigned int peer_devices = 0;
+               enum drbd_notification_type flags;
+
+               device = minor_to_device(dh->minor);
+               for_each_peer_device(peer_device, device) {
+                       if (!has_net_conf(peer_device->connection))
+                               continue;
+                       peer_devices++;
+               }
+
+               device_to_info(&info, device);
+               mutex_lock(&notification_mutex);
+               flags = (peer_devices--) ? NOTIFY_CONTINUES : 0;
+               notify_device_state(NULL, 0, device, &info, NOTIFY_CREATE | flags);
+               for_each_peer_device(peer_device, device) {
+                       struct peer_device_info peer_device_info;
+
+                       if (!has_net_conf(peer_device->connection))
+                               continue;
+                       peer_device_to_info(&peer_device_info, peer_device);
+                       flags = (peer_devices--) ? NOTIFY_CONTINUES : 0;
+                       notify_peer_device_state(NULL, 0, peer_device, &peer_device_info,
+                                                NOTIFY_CREATE | flags);
+               }
+               mutex_unlock(&notification_mutex);
+       }
        mutex_unlock(&adm_ctx.resource->adm_mutex);
 out:
        drbd_adm_finish(&adm_ctx, info, retcode);
@@ -3498,13 +4199,35 @@ out:
 
 static enum drbd_ret_code adm_del_minor(struct drbd_device *device)
 {
+       struct drbd_peer_device *peer_device;
+
        if (device->state.disk == D_DISKLESS &&
            /* no need to be device->state.conn == C_STANDALONE &&
             * we may want to delete a minor from a live replication group.
             */
            device->state.role == R_SECONDARY) {
+               struct drbd_connection *connection =
+                       first_connection(device->resource);
+
                _drbd_request_state(device, NS(conn, C_WF_REPORT_PARAMS),
                                    CS_VERBOSE + CS_WAIT_COMPLETE);
+
+               /* If the state engine hasn't stopped the sender thread yet, we
+                * need to flush the sender work queue before generating the
+                * DESTROY events here. */
+               if (get_t_state(&connection->worker) == RUNNING)
+                       drbd_flush_workqueue(&connection->sender_work);
+
+               mutex_lock(&notification_mutex);
+               for_each_peer_device(peer_device, device) {
+                       if (!has_net_conf(peer_device->connection))
+                               continue;
+                       notify_peer_device_state(NULL, 0, peer_device, NULL,
+                                                NOTIFY_DESTROY | NOTIFY_CONTINUES);
+               }
+               notify_device_state(NULL, 0, device, NULL, NOTIFY_DESTROY);
+               mutex_unlock(&notification_mutex);
+
                drbd_delete_device(device);
                return NO_ERROR;
        } else
@@ -3541,7 +4264,16 @@ static int adm_del_resource(struct drbd_resource *resource)
        if (!idr_is_empty(&resource->devices))
                return ERR_RES_IN_USE;
 
+       /* The state engine has stopped the sender thread, so we don't
+        * need to flush the sender work queue before generating the
+        * DESTROY event here. */
+       mutex_lock(&notification_mutex);
+       notify_resource_state(NULL, 0, resource, NULL, NOTIFY_DESTROY);
+       mutex_unlock(&notification_mutex);
+
+       mutex_lock(&resources_mutex);
        list_del_rcu(&resource->resources);
+       mutex_unlock(&resources_mutex);
        /* Make sure all threads have actually stopped: state handling only
         * does drbd_thread_stop_nowait(). */
        list_for_each_entry(connection, &resource->connections, connections)
@@ -3637,7 +4369,6 @@ finish:
 
 void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib)
 {
-       static atomic_t drbd_genl_seq = ATOMIC_INIT(2); /* two. */
        struct sk_buff *msg;
        struct drbd_genlmsghdr *d_out;
        unsigned seq;
@@ -3658,7 +4389,7 @@ void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib)
        if (nla_put_status_info(msg, device, sib))
                goto nla_put_failure;
        genlmsg_end(msg, d_out);
-       err = drbd_genl_multicast_events(msg, 0);
+       err = drbd_genl_multicast_events(msg, GFP_NOWAIT);
        /* msg has been consumed or freed in netlink_broadcast() */
        if (err && err != -ESRCH)
                goto failed;
@@ -3672,3 +4403,405 @@ failed:
                        "Event seq:%u sib_reason:%u\n",
                        err, seq, sib->sib_reason);
 }
+
+static int nla_put_notification_header(struct sk_buff *msg,
+                                      enum drbd_notification_type type)
+{
+       struct drbd_notification_header nh = {
+               .nh_type = type,
+       };
+
+       return drbd_notification_header_to_skb(msg, &nh, true);
+}
+
+void notify_resource_state(struct sk_buff *skb,
+                          unsigned int seq,
+                          struct drbd_resource *resource,
+                          struct resource_info *resource_info,
+                          enum drbd_notification_type type)
+{
+       struct resource_statistics resource_statistics;
+       struct drbd_genlmsghdr *dh;
+       bool multicast = false;
+       int err;
+
+       if (!skb) {
+               seq = atomic_inc_return(&notify_genl_seq);
+               skb = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO);
+               err = -ENOMEM;
+               if (!skb)
+                       goto failed;
+               multicast = true;
+       }
+
+       err = -EMSGSIZE;
+       dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_RESOURCE_STATE);
+       if (!dh)
+               goto nla_put_failure;
+       dh->minor = -1U;
+       dh->ret_code = NO_ERROR;
+       if (nla_put_drbd_cfg_context(skb, resource, NULL, NULL) ||
+           nla_put_notification_header(skb, type) ||
+           ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
+            resource_info_to_skb(skb, resource_info, true)))
+               goto nla_put_failure;
+       resource_statistics.res_stat_write_ordering = resource->write_ordering;
+       err = resource_statistics_to_skb(skb, &resource_statistics, !capable(CAP_SYS_ADMIN));
+       if (err)
+               goto nla_put_failure;
+       genlmsg_end(skb, dh);
+       if (multicast) {
+               err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
+               /* skb has been consumed or freed in netlink_broadcast() */
+               if (err && err != -ESRCH)
+                       goto failed;
+       }
+       return;
+
+nla_put_failure:
+       nlmsg_free(skb);
+failed:
+       drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n",
+                       err, seq);
+}
+
+void notify_device_state(struct sk_buff *skb,
+                        unsigned int seq,
+                        struct drbd_device *device,
+                        struct device_info *device_info,
+                        enum drbd_notification_type type)
+{
+       struct device_statistics device_statistics;
+       struct drbd_genlmsghdr *dh;
+       bool multicast = false;
+       int err;
+
+       if (!skb) {
+               seq = atomic_inc_return(&notify_genl_seq);
+               skb = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO);
+               err = -ENOMEM;
+               if (!skb)
+                       goto failed;
+               multicast = true;
+       }
+
+       err = -EMSGSIZE;
+       dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_DEVICE_STATE);
+       if (!dh)
+               goto nla_put_failure;
+       dh->minor = device->minor;
+       dh->ret_code = NO_ERROR;
+       if (nla_put_drbd_cfg_context(skb, device->resource, NULL, device) ||
+           nla_put_notification_header(skb, type) ||
+           ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
+            device_info_to_skb(skb, device_info, true)))
+               goto nla_put_failure;
+       device_to_statistics(&device_statistics, device);
+       device_statistics_to_skb(skb, &device_statistics, !capable(CAP_SYS_ADMIN));
+       genlmsg_end(skb, dh);
+       if (multicast) {
+               err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
+               /* skb has been consumed or freed in netlink_broadcast() */
+               if (err && err != -ESRCH)
+                       goto failed;
+       }
+       return;
+
+nla_put_failure:
+       nlmsg_free(skb);
+failed:
+       drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n",
+                err, seq);
+}
+
+void notify_connection_state(struct sk_buff *skb,
+                            unsigned int seq,
+                            struct drbd_connection *connection,
+                            struct connection_info *connection_info,
+                            enum drbd_notification_type type)
+{
+       struct connection_statistics connection_statistics;
+       struct drbd_genlmsghdr *dh;
+       bool multicast = false;
+       int err;
+
+       if (!skb) {
+               seq = atomic_inc_return(&notify_genl_seq);
+               skb = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO);
+               err = -ENOMEM;
+               if (!skb)
+                       goto failed;
+               multicast = true;
+       }
+
+       err = -EMSGSIZE;
+       dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_CONNECTION_STATE);
+       if (!dh)
+               goto nla_put_failure;
+       dh->minor = -1U;
+       dh->ret_code = NO_ERROR;
+       if (nla_put_drbd_cfg_context(skb, connection->resource, connection, NULL) ||
+           nla_put_notification_header(skb, type) ||
+           ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
+            connection_info_to_skb(skb, connection_info, true)))
+               goto nla_put_failure;
+       connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags);
+       connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN));
+       genlmsg_end(skb, dh);
+       if (multicast) {
+               err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
+               /* skb has been consumed or freed in netlink_broadcast() */
+               if (err && err != -ESRCH)
+                       goto failed;
+       }
+       return;
+
+nla_put_failure:
+       nlmsg_free(skb);
+failed:
+       drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n",
+                err, seq);
+}
+
+void notify_peer_device_state(struct sk_buff *skb,
+                             unsigned int seq,
+                             struct drbd_peer_device *peer_device,
+                             struct peer_device_info *peer_device_info,
+                             enum drbd_notification_type type)
+{
+       struct peer_device_statistics peer_device_statistics;
+       struct drbd_resource *resource = peer_device->device->resource;
+       struct drbd_genlmsghdr *dh;
+       bool multicast = false;
+       int err;
+
+       if (!skb) {
+               seq = atomic_inc_return(&notify_genl_seq);
+               skb = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO);
+               err = -ENOMEM;
+               if (!skb)
+                       goto failed;
+               multicast = true;
+       }
+
+       err = -EMSGSIZE;
+       dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_PEER_DEVICE_STATE);
+       if (!dh)
+               goto nla_put_failure;
+       dh->minor = -1U;
+       dh->ret_code = NO_ERROR;
+       if (nla_put_drbd_cfg_context(skb, resource, peer_device->connection, peer_device->device) ||
+           nla_put_notification_header(skb, type) ||
+           ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
+            peer_device_info_to_skb(skb, peer_device_info, true)))
+               goto nla_put_failure;
+       peer_device_to_statistics(&peer_device_statistics, peer_device);
+       peer_device_statistics_to_skb(skb, &peer_device_statistics, !capable(CAP_SYS_ADMIN));
+       genlmsg_end(skb, dh);
+       if (multicast) {
+               err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
+               /* skb has been consumed or freed in netlink_broadcast() */
+               if (err && err != -ESRCH)
+                       goto failed;
+       }
+       return;
+
+nla_put_failure:
+       nlmsg_free(skb);
+failed:
+       drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n",
+                err, seq);
+}
+
+void notify_helper(enum drbd_notification_type type,
+                  struct drbd_device *device, struct drbd_connection *connection,
+                  const char *name, int status)
+{
+       struct drbd_resource *resource = device ? device->resource : connection->resource;
+       struct drbd_helper_info helper_info;
+       unsigned int seq = atomic_inc_return(&notify_genl_seq);
+       struct sk_buff *skb = NULL;
+       struct drbd_genlmsghdr *dh;
+       int err;
+
+       strlcpy(helper_info.helper_name, name, sizeof(helper_info.helper_name));
+       helper_info.helper_name_len = min(strlen(name), sizeof(helper_info.helper_name));
+       helper_info.helper_status = status;
+
+       skb = genlmsg_new(NLMSG_GOODSIZE, GFP_NOIO);
+       err = -ENOMEM;
+       if (!skb)
+               goto fail;
+
+       err = -EMSGSIZE;
+       dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_HELPER);
+       if (!dh)
+               goto fail;
+       dh->minor = device ? device->minor : -1;
+       dh->ret_code = NO_ERROR;
+       mutex_lock(&notification_mutex);
+       if (nla_put_drbd_cfg_context(skb, resource, connection, device) ||
+           nla_put_notification_header(skb, type) ||
+           drbd_helper_info_to_skb(skb, &helper_info, true))
+               goto unlock_fail;
+       genlmsg_end(skb, dh);
+       err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
+       skb = NULL;
+       /* skb has been consumed or freed in netlink_broadcast() */
+       if (err && err != -ESRCH)
+               goto unlock_fail;
+       mutex_unlock(&notification_mutex);
+       return;
+
+unlock_fail:
+       mutex_unlock(&notification_mutex);
+fail:
+       nlmsg_free(skb);
+       drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n",
+                err, seq);
+}
+
+static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
+{
+       struct drbd_genlmsghdr *dh;
+       int err;
+
+       err = -EMSGSIZE;
+       dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_INITIAL_STATE_DONE);
+       if (!dh)
+               goto nla_put_failure;
+       dh->minor = -1U;
+       dh->ret_code = NO_ERROR;
+       if (nla_put_notification_header(skb, NOTIFY_EXISTS))
+               goto nla_put_failure;
+       genlmsg_end(skb, dh);
+       return;
+
+nla_put_failure:
+       nlmsg_free(skb);
+       pr_err("Error %d sending event. Event seq:%u\n", err, seq);
+}
+
+static void free_state_changes(struct list_head *list)
+{
+       while (!list_empty(list)) {
+               struct drbd_state_change *state_change =
+                       list_first_entry(list, struct drbd_state_change, list);
+               list_del(&state_change->list);
+               forget_state_change(state_change);
+       }
+}
+
+static unsigned int notifications_for_state_change(struct drbd_state_change *state_change)
+{
+       return 1 +
+              state_change->n_connections +
+              state_change->n_devices +
+              state_change->n_devices * state_change->n_connections;
+}
+
+static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct drbd_state_change *state_change = (struct drbd_state_change *)cb->args[0];
+       unsigned int seq = cb->args[2];
+       unsigned int n;
+       enum drbd_notification_type flags = 0;
+
+       /* There is no need for taking notification_mutex here: it doesn't
+          matter if the initial state events mix with later state chage
+          events; we can always tell the events apart by the NOTIFY_EXISTS
+          flag. */
+
+       cb->args[5]--;
+       if (cb->args[5] == 1) {
+               notify_initial_state_done(skb, seq);
+               goto out;
+       }
+       n = cb->args[4]++;
+       if (cb->args[4] < cb->args[3])
+               flags |= NOTIFY_CONTINUES;
+       if (n < 1) {
+               notify_resource_state_change(skb, seq, state_change->resource,
+                                            NOTIFY_EXISTS | flags);
+               goto next;
+       }
+       n--;
+       if (n < state_change->n_connections) {
+               notify_connection_state_change(skb, seq, &state_change->connections[n],
+                                              NOTIFY_EXISTS | flags);
+               goto next;
+       }
+       n -= state_change->n_connections;
+       if (n < state_change->n_devices) {
+               notify_device_state_change(skb, seq, &state_change->devices[n],
+                                          NOTIFY_EXISTS | flags);
+               goto next;
+       }
+       n -= state_change->n_devices;
+       if (n < state_change->n_devices * state_change->n_connections) {
+               notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n],
+                                               NOTIFY_EXISTS | flags);
+               goto next;
+       }
+
+next:
+       if (cb->args[4] == cb->args[3]) {
+               struct drbd_state_change *next_state_change =
+                       list_entry(state_change->list.next,
+                                  struct drbd_state_change, list);
+               cb->args[0] = (long)next_state_change;
+               cb->args[3] = notifications_for_state_change(next_state_change);
+               cb->args[4] = 0;
+       }
+out:
+       return skb->len;
+}
+
+int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct drbd_resource *resource;
+       LIST_HEAD(head);
+
+       if (cb->args[5] >= 1) {
+               if (cb->args[5] > 1)
+                       return get_initial_state(skb, cb);
+               if (cb->args[0]) {
+                       struct drbd_state_change *state_change =
+                               (struct drbd_state_change *)cb->args[0];
+
+                       /* connect list to head */
+                       list_add(&head, &state_change->list);
+                       free_state_changes(&head);
+               }
+               return 0;
+       }
+
+       cb->args[5] = 2;  /* number of iterations */
+       mutex_lock(&resources_mutex);
+       for_each_resource(resource, &drbd_resources) {
+               struct drbd_state_change *state_change;
+
+               state_change = remember_old_state(resource, GFP_KERNEL);
+               if (!state_change) {
+                       if (!list_empty(&head))
+                               free_state_changes(&head);
+                       mutex_unlock(&resources_mutex);
+                       return -ENOMEM;
+               }
+               copy_old_to_new_state_change(state_change);
+               list_add_tail(&state_change->list, &head);
+               cb->args[5] += notifications_for_state_change(state_change);
+       }
+       mutex_unlock(&resources_mutex);
+
+       if (!list_empty(&head)) {
+               struct drbd_state_change *state_change =
+                       list_entry(head.next, struct drbd_state_change, list);
+               cb->args[0] = (long)state_change;
+               cb->args[3] = notifications_for_state_change(state_change);
+               list_del(&head);  /* detach list from head */
+       }
+
+       cb->args[2] = cb->nlh->nlmsg_seq;
+       return get_initial_state(skb, cb);
+}
index 3b10fa6..6537b25 100644 (file)
@@ -245,9 +245,9 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
        char wp;
 
        static char write_ordering_chars[] = {
-               [WO_none] = 'n',
-               [WO_drain_io] = 'd',
-               [WO_bdev_flush] = 'f',
+               [WO_NONE] = 'n',
+               [WO_DRAIN_IO] = 'd',
+               [WO_BDEV_FLUSH] = 'f',
        };
 
        seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
index 2da9104..ef92453 100644 (file)
@@ -23,7 +23,7 @@ enum drbd_packet {
        P_AUTH_RESPONSE       = 0x11,
        P_STATE_CHG_REQ       = 0x12,
 
-       /* asender (meta socket */
+       /* (meta socket) */
        P_PING                = 0x13,
        P_PING_ACK            = 0x14,
        P_RECV_ACK            = 0x15, /* Used in protocol B */
index b4b5680..1957fe8 100644 (file)
@@ -215,7 +215,7 @@ static void reclaim_finished_net_peer_reqs(struct drbd_device *device,
        }
 }
 
-static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
+static void drbd_reclaim_net_peer_reqs(struct drbd_device *device)
 {
        LIST_HEAD(reclaimed);
        struct drbd_peer_request *peer_req, *t;
@@ -223,11 +223,30 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_device *device)
        spin_lock_irq(&device->resource->req_lock);
        reclaim_finished_net_peer_reqs(device, &reclaimed);
        spin_unlock_irq(&device->resource->req_lock);
-
        list_for_each_entry_safe(peer_req, t, &reclaimed, w.list)
                drbd_free_net_peer_req(device, peer_req);
 }
 
+static void conn_reclaim_net_peer_reqs(struct drbd_connection *connection)
+{
+       struct drbd_peer_device *peer_device;
+       int vnr;
+
+       rcu_read_lock();
+       idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
+               struct drbd_device *device = peer_device->device;
+               if (!atomic_read(&device->pp_in_use_by_net))
+                       continue;
+
+               kref_get(&device->kref);
+               rcu_read_unlock();
+               drbd_reclaim_net_peer_reqs(device);
+               kref_put(&device->kref, drbd_destroy_device);
+               rcu_read_lock();
+       }
+       rcu_read_unlock();
+}
+
 /**
  * drbd_alloc_pages() - Returns @number pages, retries forever (or until signalled)
  * @device:    DRBD device.
@@ -265,10 +284,15 @@ struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int
        if (atomic_read(&device->pp_in_use) < mxb)
                page = __drbd_alloc_pages(device, number);
 
+       /* Try to keep the fast path fast, but occasionally we need
+        * to reclaim the pages we lended to the network stack. */
+       if (page && atomic_read(&device->pp_in_use_by_net) > 512)
+               drbd_reclaim_net_peer_reqs(device);
+
        while (page == NULL) {
                prepare_to_wait(&drbd_pp_wait, &wait, TASK_INTERRUPTIBLE);
 
-               drbd_kick_lo_and_reclaim_net(device);
+               drbd_reclaim_net_peer_reqs(device);
 
                if (atomic_read(&device->pp_in_use) < mxb) {
                        page = __drbd_alloc_pages(device, number);
@@ -1099,7 +1123,15 @@ randomize:
                return 0;
        }
 
-       drbd_thread_start(&connection->asender);
+       drbd_thread_start(&connection->ack_receiver);
+       /* opencoded create_singlethread_workqueue(),
+        * to be able to use format string arguments */
+       connection->ack_sender =
+               alloc_ordered_workqueue("drbd_as_%s", WQ_MEM_RECLAIM, connection->resource->name);
+       if (!connection->ack_sender) {
+               drbd_err(connection, "Failed to create workqueue ack_sender\n");
+               return 0;
+       }
 
        mutex_lock(&connection->resource->conf_update);
        /* The discard_my_data flag is a single-shot modifier to the next
@@ -1178,7 +1210,7 @@ static void drbd_flush(struct drbd_connection *connection)
        struct drbd_peer_device *peer_device;
        int vnr;
 
-       if (connection->resource->write_ordering >= WO_bdev_flush) {
+       if (connection->resource->write_ordering >= WO_BDEV_FLUSH) {
                rcu_read_lock();
                idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
                        struct drbd_device *device = peer_device->device;
@@ -1203,7 +1235,7 @@ static void drbd_flush(struct drbd_connection *connection)
                                /* would rather check on EOPNOTSUPP, but that is not reliable.
                                 * don't try again for ANY return value != 0
                                 * if (rv == -EOPNOTSUPP) */
-                               drbd_bump_write_ordering(connection->resource, NULL, WO_drain_io);
+                               drbd_bump_write_ordering(connection->resource, NULL, WO_DRAIN_IO);
                        }
                        put_ldev(device);
                        kref_put(&device->kref, drbd_destroy_device);
@@ -1299,10 +1331,10 @@ max_allowed_wo(struct drbd_backing_dev *bdev, enum write_ordering_e wo)
 
        dc = rcu_dereference(bdev->disk_conf);
 
-       if (wo == WO_bdev_flush && !dc->disk_flushes)
-               wo = WO_drain_io;
-       if (wo == WO_drain_io && !dc->disk_drain)
-               wo = WO_none;
+       if (wo == WO_BDEV_FLUSH && !dc->disk_flushes)
+               wo = WO_DRAIN_IO;
+       if (wo == WO_DRAIN_IO && !dc->disk_drain)
+               wo = WO_NONE;
 
        return wo;
 }
@@ -1319,13 +1351,13 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin
        enum write_ordering_e pwo;
        int vnr;
        static char *write_ordering_str[] = {
-               [WO_none] = "none",
-               [WO_drain_io] = "drain",
-               [WO_bdev_flush] = "flush",
+               [WO_NONE] = "none",
+               [WO_DRAIN_IO] = "drain",
+               [WO_BDEV_FLUSH] = "flush",
        };
 
        pwo = resource->write_ordering;
-       if (wo != WO_bdev_flush)
+       if (wo != WO_BDEV_FLUSH)
                wo = min(pwo, wo);
        rcu_read_lock();
        idr_for_each_entry(&resource->devices, device, vnr) {
@@ -1343,7 +1375,7 @@ void drbd_bump_write_ordering(struct drbd_resource *resource, struct drbd_backin
        rcu_read_unlock();
 
        resource->write_ordering = wo;
-       if (pwo != resource->write_ordering || wo == WO_bdev_flush)
+       if (pwo != resource->write_ordering || wo == WO_BDEV_FLUSH)
                drbd_info(resource, "Method to ensure write ordering: %s\n", write_ordering_str[resource->write_ordering]);
 }
 
@@ -1380,7 +1412,7 @@ int drbd_submit_peer_request(struct drbd_device *device,
        if (peer_req->flags & EE_IS_TRIM_USE_ZEROOUT) {
                /* wait for all pending IO completions, before we start
                 * zeroing things out. */
-               conn_wait_active_ee_empty(first_peer_device(device)->connection);
+               conn_wait_active_ee_empty(peer_req->peer_device->connection);
                /* add it to the active list now,
                 * so we can find it to present it in debugfs */
                peer_req->submit_jif = jiffies;
@@ -1508,12 +1540,6 @@ static void conn_wait_active_ee_empty(struct drbd_connection *connection)
        rcu_read_unlock();
 }
 
-static struct drbd_peer_device *
-conn_peer_device(struct drbd_connection *connection, int volume_number)
-{
-       return idr_find(&connection->peer_devices, volume_number);
-}
-
 static int receive_Barrier(struct drbd_connection *connection, struct packet_info *pi)
 {
        int rv;
@@ -1533,7 +1559,7 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf
         * Therefore we must send the barrier_ack after the barrier request was
         * completed. */
        switch (connection->resource->write_ordering) {
-       case WO_none:
+       case WO_NONE:
                if (rv == FE_RECYCLED)
                        return 0;
 
@@ -1546,8 +1572,8 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf
                        drbd_warn(connection, "Allocation of an epoch failed, slowing down\n");
                        /* Fall through */
 
-       case WO_bdev_flush:
-       case WO_drain_io:
+       case WO_BDEV_FLUSH:
+       case WO_DRAIN_IO:
                conn_wait_active_ee_empty(connection);
                drbd_flush(connection);
 
@@ -1752,7 +1778,7 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req
 }
 
 /*
- * e_end_resync_block() is called in asender context via
+ * e_end_resync_block() is called in ack_sender context via
  * drbd_finish_peer_reqs().
  */
 static int e_end_resync_block(struct drbd_work *w, int unused)
@@ -1926,7 +1952,7 @@ static void restart_conflicting_writes(struct drbd_device *device,
 }
 
 /*
- * e_end_block() is called in asender context via drbd_finish_peer_reqs().
+ * e_end_block() is called in ack_sender context via drbd_finish_peer_reqs().
  */
 static int e_end_block(struct drbd_work *w, int cancel)
 {
@@ -1966,7 +1992,7 @@ static int e_end_block(struct drbd_work *w, int cancel)
        } else
                D_ASSERT(device, drbd_interval_empty(&peer_req->i));
 
-       drbd_may_finish_epoch(first_peer_device(device)->connection, peer_req->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
+       drbd_may_finish_epoch(peer_device->connection, peer_req->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
 
        return err;
 }
@@ -2098,7 +2124,7 @@ static int wait_for_and_update_peer_seq(struct drbd_peer_device *peer_device, co
                }
 
                rcu_read_lock();
-               tp = rcu_dereference(first_peer_device(device)->connection->net_conf)->two_primaries;
+               tp = rcu_dereference(peer_device->connection->net_conf)->two_primaries;
                rcu_read_unlock();
 
                if (!tp)
@@ -2217,7 +2243,7 @@ static int handle_write_conflicts(struct drbd_device *device,
                        peer_req->w.cb = superseded ? e_send_superseded :
                                                   e_send_retry_write;
                        list_add_tail(&peer_req->w.list, &device->done_ee);
-                       wake_asender(connection);
+                       queue_work(connection->ack_sender, &peer_req->peer_device->send_acks_work);
 
                        err = -ENOENT;
                        goto out;
@@ -2364,7 +2390,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
        if (dp_flags & DP_SEND_RECEIVE_ACK) {
                /* I really don't like it that the receiver thread
                 * sends on the msock, but anyways */
-               drbd_send_ack(first_peer_device(device), P_RECV_ACK, peer_req);
+               drbd_send_ack(peer_device, P_RECV_ACK, peer_req);
        }
 
        if (tp) {
@@ -4056,7 +4082,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
        os = ns = drbd_read_state(device);
        spin_unlock_irq(&device->resource->req_lock);
 
-       /* If some other part of the code (asender thread, timeout)
+       /* If some other part of the code (ack_receiver thread, timeout)
         * already decided to close the connection again,
         * we must not "re-establish" it here. */
        if (os.conn <= C_TEAR_DOWN)
@@ -4661,8 +4687,12 @@ static void conn_disconnect(struct drbd_connection *connection)
         */
        conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
 
-       /* asender does not clean up anything. it must not interfere, either */
-       drbd_thread_stop(&connection->asender);
+       /* ack_receiver does not clean up anything. it must not interfere, either */
+       drbd_thread_stop(&connection->ack_receiver);
+       if (connection->ack_sender) {
+               destroy_workqueue(connection->ack_sender);
+               connection->ack_sender = NULL;
+       }
        drbd_free_sock(connection);
 
        rcu_read_lock();
@@ -5431,49 +5461,39 @@ static int got_skip(struct drbd_connection *connection, struct packet_info *pi)
        return 0;
 }
 
-static int connection_finish_peer_reqs(struct drbd_connection *connection)
+struct meta_sock_cmd {
+       size_t pkt_size;
+       int (*fn)(struct drbd_connection *connection, struct packet_info *);
+};
+
+static void set_rcvtimeo(struct drbd_connection *connection, bool ping_timeout)
 {
-       struct drbd_peer_device *peer_device;
-       int vnr, not_empty = 0;
+       long t;
+       struct net_conf *nc;
 
-       do {
-               clear_bit(SIGNAL_ASENDER, &connection->flags);
-               flush_signals(current);
+       rcu_read_lock();
+       nc = rcu_dereference(connection->net_conf);
+       t = ping_timeout ? nc->ping_timeo : nc->ping_int;
+       rcu_read_unlock();
 
-               rcu_read_lock();
-               idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
-                       struct drbd_device *device = peer_device->device;
-                       kref_get(&device->kref);
-                       rcu_read_unlock();
-                       if (drbd_finish_peer_reqs(device)) {
-                               kref_put(&device->kref, drbd_destroy_device);
-                               return 1;
-                       }
-                       kref_put(&device->kref, drbd_destroy_device);
-                       rcu_read_lock();
-               }
-               set_bit(SIGNAL_ASENDER, &connection->flags);
+       t *= HZ;
+       if (ping_timeout)
+               t /= 10;
 
-               spin_lock_irq(&connection->resource->req_lock);
-               idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
-                       struct drbd_device *device = peer_device->device;
-                       not_empty = !list_empty(&device->done_ee);
-                       if (not_empty)
-                               break;
-               }
-               spin_unlock_irq(&connection->resource->req_lock);
-               rcu_read_unlock();
-       } while (not_empty);
+       connection->meta.socket->sk->sk_rcvtimeo = t;
+}
 
-       return 0;
+static void set_ping_timeout(struct drbd_connection *connection)
+{
+       set_rcvtimeo(connection, 1);
 }
 
-struct asender_cmd {
-       size_t pkt_size;
-       int (*fn)(struct drbd_connection *connection, struct packet_info *);
-};
+static void set_idle_timeout(struct drbd_connection *connection)
+{
+       set_rcvtimeo(connection, 0);
+}
 
-static struct asender_cmd asender_tbl[] = {
+static struct meta_sock_cmd ack_receiver_tbl[] = {
        [P_PING]            = { 0, got_Ping },
        [P_PING_ACK]        = { 0, got_PingAck },
        [P_RECV_ACK]        = { sizeof(struct p_block_ack), got_BlockAck },
@@ -5493,64 +5513,40 @@ static struct asender_cmd asender_tbl[] = {
        [P_RETRY_WRITE]     = { sizeof(struct p_block_ack), got_BlockAck },
 };
 
-int drbd_asender(struct drbd_thread *thi)
+int drbd_ack_receiver(struct drbd_thread *thi)
 {
        struct drbd_connection *connection = thi->connection;
-       struct asender_cmd *cmd = NULL;
+       struct meta_sock_cmd *cmd = NULL;
        struct packet_info pi;
+       unsigned long pre_recv_jif;
        int rv;
        void *buf    = connection->meta.rbuf;
        int received = 0;
        unsigned int header_size = drbd_header_size(connection);
        int expect   = header_size;
        bool ping_timeout_active = false;
-       struct net_conf *nc;
-       int ping_timeo, tcp_cork, ping_int;
        struct sched_param param = { .sched_priority = 2 };
 
        rv = sched_setscheduler(current, SCHED_RR, &param);
        if (rv < 0)
-               drbd_err(connection, "drbd_asender: ERROR set priority, ret=%d\n", rv);
+               drbd_err(connection, "drbd_ack_receiver: ERROR set priority, ret=%d\n", rv);
 
        while (get_t_state(thi) == RUNNING) {
                drbd_thread_current_set_cpu(thi);
 
-               rcu_read_lock();
-               nc = rcu_dereference(connection->net_conf);
-               ping_timeo = nc->ping_timeo;
-               tcp_cork = nc->tcp_cork;
-               ping_int = nc->ping_int;
-               rcu_read_unlock();
+               conn_reclaim_net_peer_reqs(connection);
 
                if (test_and_clear_bit(SEND_PING, &connection->flags)) {
                        if (drbd_send_ping(connection)) {
                                drbd_err(connection, "drbd_send_ping has failed\n");
                                goto reconnect;
                        }
-                       connection->meta.socket->sk->sk_rcvtimeo = ping_timeo * HZ / 10;
+                       set_ping_timeout(connection);
                        ping_timeout_active = true;
                }
 
-               /* TODO: conditionally cork; it may hurt latency if we cork without
-                  much to send */
-               if (tcp_cork)
-                       drbd_tcp_cork(connection->meta.socket);
-               if (connection_finish_peer_reqs(connection)) {
-                       drbd_err(connection, "connection_finish_peer_reqs() failed\n");
-                       goto reconnect;
-               }
-               /* but unconditionally uncork unless disabled */
-               if (tcp_cork)
-                       drbd_tcp_uncork(connection->meta.socket);
-
-               /* short circuit, recv_msg would return EINTR anyways. */
-               if (signal_pending(current))
-                       continue;
-
+               pre_recv_jif = jiffies;
                rv = drbd_recv_short(connection->meta.socket, buf, expect-received, 0);
-               clear_bit(SIGNAL_ASENDER, &connection->flags);
-
-               flush_signals(current);
 
                /* Note:
                 * -EINTR        (on meta) we got a signal
@@ -5562,7 +5558,6 @@ int drbd_asender(struct drbd_thread *thi)
                 * rv <  expected: "woken" by signal during receive
                 * rv == 0       : "connection shut down by peer"
                 */
-received_more:
                if (likely(rv > 0)) {
                        received += rv;
                        buf      += rv;
@@ -5584,8 +5579,7 @@ received_more:
                } else if (rv == -EAGAIN) {
                        /* If the data socket received something meanwhile,
                         * that is good enough: peer is still alive. */
-                       if (time_after(connection->last_received,
-                               jiffies - connection->meta.socket->sk->sk_rcvtimeo))
+                       if (time_after(connection->last_received, pre_recv_jif))
                                continue;
                        if (ping_timeout_active) {
                                drbd_err(connection, "PingAck did not arrive in time.\n");
@@ -5594,6 +5588,10 @@ received_more:
                        set_bit(SEND_PING, &connection->flags);
                        continue;
                } else if (rv == -EINTR) {
+                       /* maybe drbd_thread_stop(): the while condition will notice.
+                        * maybe woken for send_ping: we'll send a ping above,
+                        * and change the rcvtimeo */
+                       flush_signals(current);
                        continue;
                } else {
                        drbd_err(connection, "sock_recvmsg returned %d\n", rv);
@@ -5603,8 +5601,8 @@ received_more:
                if (received == expect && cmd == NULL) {
                        if (decode_header(connection, connection->meta.rbuf, &pi))
                                goto reconnect;
-                       cmd = &asender_tbl[pi.cmd];
-                       if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd->fn) {
+                       cmd = &ack_receiver_tbl[pi.cmd];
+                       if (pi.cmd >= ARRAY_SIZE(ack_receiver_tbl) || !cmd->fn) {
                                drbd_err(connection, "Unexpected meta packet %s (0x%04x)\n",
                                         cmdname(pi.cmd), pi.cmd);
                                goto disconnect;
@@ -5627,9 +5625,8 @@ received_more:
 
                        connection->last_received = jiffies;
 
-                       if (cmd == &asender_tbl[P_PING_ACK]) {
-                               /* restore idle timeout */
-                               connection->meta.socket->sk->sk_rcvtimeo = ping_int * HZ;
+                       if (cmd == &ack_receiver_tbl[P_PING_ACK]) {
+                               set_idle_timeout(connection);
                                ping_timeout_active = false;
                        }
 
@@ -5638,11 +5635,6 @@ received_more:
                        expect   = header_size;
                        cmd      = NULL;
                }
-               if (test_bit(SEND_PING, &connection->flags))
-                       continue;
-               rv = drbd_recv_short(connection->meta.socket, buf, expect-received, MSG_DONTWAIT);
-               if (rv > 0)
-                       goto received_more;
        }
 
        if (0) {
@@ -5654,9 +5646,41 @@ reconnect:
 disconnect:
                conn_request_state(connection, NS(conn, C_DISCONNECTING), CS_HARD);
        }
-       clear_bit(SIGNAL_ASENDER, &connection->flags);
 
-       drbd_info(connection, "asender terminated\n");
+       drbd_info(connection, "ack_receiver terminated\n");
 
        return 0;
 }
+
+void drbd_send_acks_wf(struct work_struct *ws)
+{
+       struct drbd_peer_device *peer_device =
+               container_of(ws, struct drbd_peer_device, send_acks_work);
+       struct drbd_connection *connection = peer_device->connection;
+       struct drbd_device *device = peer_device->device;
+       struct net_conf *nc;
+       int tcp_cork, err;
+
+       rcu_read_lock();
+       nc = rcu_dereference(connection->net_conf);
+       tcp_cork = nc->tcp_cork;
+       rcu_read_unlock();
+
+       if (tcp_cork)
+               drbd_tcp_cork(connection->meta.socket);
+
+       err = drbd_finish_peer_reqs(device);
+       kref_put(&device->kref, drbd_destroy_device);
+       /* get is in drbd_endio_write_sec_final(). That is necessary to keep the
+          struct work_struct send_acks_work alive, which is in the peer_device object */
+
+       if (err) {
+               conn_request_state(connection, NS(conn, C_NETWORK_FAILURE), CS_HARD);
+               return;
+       }
+
+       if (tcp_cork)
+               drbd_tcp_uncork(connection->meta.socket);
+
+       return;
+}
index 3ae2c00..2255dcf 100644 (file)
@@ -453,12 +453,12 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
                kref_get(&req->kref); /* wait for the DONE */
 
        if (!(s & RQ_NET_SENT) && (set & RQ_NET_SENT)) {
-               /* potentially already completed in the asender thread */
+               /* potentially already completed in the ack_receiver thread */
                if (!(s & RQ_NET_DONE)) {
                        atomic_add(req->i.size >> 9, &device->ap_in_flight);
                        set_if_null_req_not_net_done(peer_device, req);
                }
-               if (s & RQ_NET_PENDING)
+               if (req->rq_state & RQ_NET_PENDING)
                        set_if_null_req_ack_pending(peer_device, req);
        }
 
@@ -1095,6 +1095,24 @@ static bool do_remote_read(struct drbd_request *req)
        return false;
 }
 
+bool drbd_should_do_remote(union drbd_dev_state s)
+{
+       return s.pdsk == D_UP_TO_DATE ||
+               (s.pdsk >= D_INCONSISTENT &&
+                s.conn >= C_WF_BITMAP_T &&
+                s.conn < C_AHEAD);
+       /* Before proto 96 that was >= CONNECTED instead of >= C_WF_BITMAP_T.
+          That is equivalent since before 96 IO was frozen in the C_WF_BITMAP*
+          states. */
+}
+
+static bool drbd_should_send_out_of_sync(union drbd_dev_state s)
+{
+       return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S;
+       /* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary
+          since we enter state C_AHEAD only if proto >= 96 */
+}
+
 /* returns number of connections (== 1, for drbd 8.4)
  * expected to actually write this data,
  * which does NOT include those that we are L_AHEAD for. */
@@ -1149,7 +1167,6 @@ drbd_submit_req_private_bio(struct drbd_request *req)
         * stable storage, and this is a WRITE, we may not even submit
         * this bio. */
        if (get_ldev(device)) {
-               req->pre_submit_jif = jiffies;
                if (drbd_insert_fault(device,
                                      rw == WRITE ? DRBD_FAULT_DT_WR
                                    : rw == READ  ? DRBD_FAULT_DT_RD
@@ -1293,6 +1310,7 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request
                        &device->pending_master_completion[rw == WRITE]);
        if (req->private_bio) {
                /* needs to be marked within the same spinlock */
+               req->pre_submit_jif = jiffies;
                list_add_tail(&req->req_pending_local,
                        &device->pending_completion[rw == WRITE]);
                _req_mod(req, TO_BE_SUBMITTED);
@@ -1513,6 +1531,78 @@ blk_qc_t drbd_make_request(struct request_queue *q, struct bio *bio)
        return BLK_QC_T_NONE;
 }
 
+static bool net_timeout_reached(struct drbd_request *net_req,
+               struct drbd_connection *connection,
+               unsigned long now, unsigned long ent,
+               unsigned int ko_count, unsigned int timeout)
+{
+       struct drbd_device *device = net_req->device;
+
+       if (!time_after(now, net_req->pre_send_jif + ent))
+               return false;
+
+       if (time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent))
+               return false;
+
+       if (net_req->rq_state & RQ_NET_PENDING) {
+               drbd_warn(device, "Remote failed to finish a request within %ums > ko-count (%u) * timeout (%u * 0.1s)\n",
+                       jiffies_to_msecs(now - net_req->pre_send_jif), ko_count, timeout);
+               return true;
+       }
+
+       /* We received an ACK already (or are using protocol A),
+        * but are waiting for the epoch closing barrier ack.
+        * Check if we sent the barrier already.  We should not blame the peer
+        * for being unresponsive, if we did not even ask it yet. */
+       if (net_req->epoch == connection->send.current_epoch_nr) {
+               drbd_warn(device,
+                       "We did not send a P_BARRIER for %ums > ko-count (%u) * timeout (%u * 0.1s); drbd kernel thread blocked?\n",
+                       jiffies_to_msecs(now - net_req->pre_send_jif), ko_count, timeout);
+               return false;
+       }
+
+       /* Worst case: we may have been blocked for whatever reason, then
+        * suddenly are able to send a lot of requests (and epoch separating
+        * barriers) in quick succession.
+        * The timestamp of the net_req may be much too old and not correspond
+        * to the sending time of the relevant unack'ed barrier packet, so
+        * would trigger a spurious timeout.  The latest barrier packet may
+        * have a too recent timestamp to trigger the timeout, potentially miss
+        * a timeout.  Right now we don't have a place to conveniently store
+        * these timestamps.
+        * But in this particular situation, the application requests are still
+        * completed to upper layers, DRBD should still "feel" responsive.
+        * No need yet to kill this connection, it may still recover.
+        * If not, eventually we will have queued enough into the network for
+        * us to block. From that point of view, the timestamp of the last sent
+        * barrier packet is relevant enough.
+        */
+       if (time_after(now, connection->send.last_sent_barrier_jif + ent)) {
+               drbd_warn(device, "Remote failed to answer a P_BARRIER (sent at %lu jif; now=%lu jif) within %ums > ko-count (%u) * timeout (%u * 0.1s)\n",
+                       connection->send.last_sent_barrier_jif, now,
+                       jiffies_to_msecs(now - connection->send.last_sent_barrier_jif), ko_count, timeout);
+               return true;
+       }
+       return false;
+}
+
+/* A request is considered timed out, if
+ * - we have some effective timeout from the configuration,
+ *   with some state restrictions applied,
+ * - the oldest request is waiting for a response from the network
+ *   resp. the local disk,
+ * - the oldest request is in fact older than the effective timeout,
+ * - the connection was established (resp. disk was attached)
+ *   for longer than the timeout already.
+ * Note that for 32bit jiffies and very stable connections/disks,
+ * we may have a wrap around, which is catched by
+ *   !time_in_range(now, last_..._jif, last_..._jif + timeout).
+ *
+ * Side effect: once per 32bit wrap-around interval, which means every
+ * ~198 days with 250 HZ, we have a window where the timeout would need
+ * to expire twice (worst case) to become effective. Good enough.
+ */
+
 void request_timer_fn(unsigned long data)
 {
        struct drbd_device *device = (struct drbd_device *) data;
@@ -1522,11 +1612,14 @@ void request_timer_fn(unsigned long data)
        unsigned long oldest_submit_jif;
        unsigned long ent = 0, dt = 0, et, nt; /* effective timeout = ko_count * timeout */
        unsigned long now;
+       unsigned int ko_count = 0, timeout = 0;
 
        rcu_read_lock();
        nc = rcu_dereference(connection->net_conf);
-       if (nc && device->state.conn >= C_WF_REPORT_PARAMS)
-               ent = nc->timeout * HZ/10 * nc->ko_count;
+       if (nc && device->state.conn >= C_WF_REPORT_PARAMS) {
+               ko_count = nc->ko_count;
+               timeout = nc->timeout;
+       }
 
        if (get_ldev(device)) { /* implicit state.disk >= D_INCONSISTENT */
                dt = rcu_dereference(device->ldev->disk_conf)->disk_timeout * HZ / 10;
@@ -1534,6 +1627,8 @@ void request_timer_fn(unsigned long data)
        }
        rcu_read_unlock();
 
+
+       ent = timeout * HZ/10 * ko_count;
        et = min_not_zero(dt, ent);
 
        if (!et)
@@ -1545,11 +1640,22 @@ void request_timer_fn(unsigned long data)
        spin_lock_irq(&device->resource->req_lock);
        req_read = list_first_entry_or_null(&device->pending_completion[0], struct drbd_request, req_pending_local);
        req_write = list_first_entry_or_null(&device->pending_completion[1], struct drbd_request, req_pending_local);
-       req_peer = connection->req_not_net_done;
+
        /* maybe the oldest request waiting for the peer is in fact still
-        * blocking in tcp sendmsg */
-       if (!req_peer && connection->req_next && connection->req_next->pre_send_jif)
-               req_peer = connection->req_next;
+        * blocking in tcp sendmsg.  That's ok, though, that's handled via the
+        * socket send timeout, requesting a ping, and bumping ko-count in
+        * we_should_drop_the_connection().
+        */
+
+       /* check the oldest request we did successfully sent,
+        * but which is still waiting for an ACK. */
+       req_peer = connection->req_ack_pending;
+
+       /* if we don't have such request (e.g. protocoll A)
+        * check the oldest requests which is still waiting on its epoch
+        * closing barrier ack. */
+       if (!req_peer)
+               req_peer = connection->req_not_net_done;
 
        /* evaluate the oldest peer request only in one timer! */
        if (req_peer && req_peer->device != device)
@@ -1566,28 +1672,9 @@ void request_timer_fn(unsigned long data)
                : req_write ? req_write->pre_submit_jif
                : req_read ? req_read->pre_submit_jif : now;
 
-       /* The request is considered timed out, if
-        * - we have some effective timeout from the configuration,
-        *   with above state restrictions applied,
-        * - the oldest request is waiting for a response from the network
-        *   resp. the local disk,
-        * - the oldest request is in fact older than the effective timeout,
-        * - the connection was established (resp. disk was attached)
-        *   for longer than the timeout already.
-        * Note that for 32bit jiffies and very stable connections/disks,
-        * we may have a wrap around, which is catched by
-        *   !time_in_range(now, last_..._jif, last_..._jif + timeout).
-        *
-        * Side effect: once per 32bit wrap-around interval, which means every
-        * ~198 days with 250 HZ, we have a window where the timeout would need
-        * to expire twice (worst case) to become effective. Good enough.
-        */
-       if (ent && req_peer &&
-                time_after(now, req_peer->pre_send_jif + ent) &&
-               !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) {
-               drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n");
+       if (ent && req_peer && net_timeout_reached(req_peer, connection, now, ent, ko_count, timeout))
                _conn_request_state(connection, NS(conn, C_TIMEOUT), CS_VERBOSE | CS_HARD);
-       }
+
        if (dt && oldest_submit_jif != now &&
                 time_after(now, oldest_submit_jif + dt) &&
                !time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) {
index 9f6a040..bb2ef78 100644 (file)
@@ -331,21 +331,6 @@ static inline int req_mod(struct drbd_request *req,
        return rv;
 }
 
-static inline bool drbd_should_do_remote(union drbd_dev_state s)
-{
-       return s.pdsk == D_UP_TO_DATE ||
-               (s.pdsk >= D_INCONSISTENT &&
-                s.conn >= C_WF_BITMAP_T &&
-                s.conn < C_AHEAD);
-       /* Before proto 96 that was >= CONNECTED instead of >= C_WF_BITMAP_T.
-          That is equivalent since before 96 IO was frozen in the C_WF_BITMAP*
-          states. */
-}
-static inline bool drbd_should_send_out_of_sync(union drbd_dev_state s)
-{
-       return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S;
-       /* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary
-          since we enter state C_AHEAD only if proto >= 96 */
-}
+extern bool drbd_should_do_remote(union drbd_dev_state);
 
 #endif
index 2d7dd26..5a7ef78 100644 (file)
@@ -29,6 +29,7 @@
 #include "drbd_int.h"
 #include "drbd_protocol.h"
 #include "drbd_req.h"
+#include "drbd_state_change.h"
 
 struct after_state_chg_work {
        struct drbd_work w;
@@ -37,6 +38,7 @@ struct after_state_chg_work {
        union drbd_state ns;
        enum chg_state_flags flags;
        struct completion *done;
+       struct drbd_state_change *state_change;
 };
 
 enum sanitize_state_warnings {
@@ -48,9 +50,248 @@ enum sanitize_state_warnings {
        IMPLICITLY_UPGRADED_PDSK,
 };
 
+static void count_objects(struct drbd_resource *resource,
+                         unsigned int *n_devices,
+                         unsigned int *n_connections)
+{
+       struct drbd_device *device;
+       struct drbd_connection *connection;
+       int vnr;
+
+       *n_devices = 0;
+       *n_connections = 0;
+
+       idr_for_each_entry(&resource->devices, device, vnr)
+               (*n_devices)++;
+       for_each_connection(connection, resource)
+               (*n_connections)++;
+}
+
+static struct drbd_state_change *alloc_state_change(unsigned int n_devices, unsigned int n_connections, gfp_t gfp)
+{
+       struct drbd_state_change *state_change;
+       unsigned int size, n;
+
+       size = sizeof(struct drbd_state_change) +
+              n_devices * sizeof(struct drbd_device_state_change) +
+              n_connections * sizeof(struct drbd_connection_state_change) +
+              n_devices * n_connections * sizeof(struct drbd_peer_device_state_change);
+       state_change = kmalloc(size, gfp);
+       if (!state_change)
+               return NULL;
+       state_change->n_devices = n_devices;
+       state_change->n_connections = n_connections;
+       state_change->devices = (void *)(state_change + 1);
+       state_change->connections = (void *)&state_change->devices[n_devices];
+       state_change->peer_devices = (void *)&state_change->connections[n_connections];
+       state_change->resource->resource = NULL;
+       for (n = 0; n < n_devices; n++)
+               state_change->devices[n].device = NULL;
+       for (n = 0; n < n_connections; n++)
+               state_change->connections[n].connection = NULL;
+       return state_change;
+}
+
+struct drbd_state_change *remember_old_state(struct drbd_resource *resource, gfp_t gfp)
+{
+       struct drbd_state_change *state_change;
+       struct drbd_device *device;
+       unsigned int n_devices;
+       struct drbd_connection *connection;
+       unsigned int n_connections;
+       int vnr;
+
+       struct drbd_device_state_change *device_state_change;
+       struct drbd_peer_device_state_change *peer_device_state_change;
+       struct drbd_connection_state_change *connection_state_change;
+
+       /* Caller holds req_lock spinlock.
+        * No state, no device IDR, no connections lists can change. */
+       count_objects(resource, &n_devices, &n_connections);
+       state_change = alloc_state_change(n_devices, n_connections, gfp);
+       if (!state_change)
+               return NULL;
+
+       kref_get(&resource->kref);
+       state_change->resource->resource = resource;
+       state_change->resource->role[OLD] =
+               conn_highest_role(first_connection(resource));
+       state_change->resource->susp[OLD] = resource->susp;
+       state_change->resource->susp_nod[OLD] = resource->susp_nod;
+       state_change->resource->susp_fen[OLD] = resource->susp_fen;
+
+       connection_state_change = state_change->connections;
+       for_each_connection(connection, resource) {
+               kref_get(&connection->kref);
+               connection_state_change->connection = connection;
+               connection_state_change->cstate[OLD] =
+                       connection->cstate;
+               connection_state_change->peer_role[OLD] =
+                       conn_highest_peer(connection);
+               connection_state_change++;
+       }
+
+       device_state_change = state_change->devices;
+       peer_device_state_change = state_change->peer_devices;
+       idr_for_each_entry(&resource->devices, device, vnr) {
+               kref_get(&device->kref);
+               device_state_change->device = device;
+               device_state_change->disk_state[OLD] = device->state.disk;
+
+               /* The peer_devices for each device have to be enumerated in
+                  the order of the connections. We may not use for_each_peer_device() here. */
+               for_each_connection(connection, resource) {
+                       struct drbd_peer_device *peer_device;
+
+                       peer_device = conn_peer_device(connection, device->vnr);
+                       peer_device_state_change->peer_device = peer_device;
+                       peer_device_state_change->disk_state[OLD] =
+                               device->state.pdsk;
+                       peer_device_state_change->repl_state[OLD] =
+                               max_t(enum drbd_conns,
+                                     C_WF_REPORT_PARAMS, device->state.conn);
+                       peer_device_state_change->resync_susp_user[OLD] =
+                               device->state.user_isp;
+                       peer_device_state_change->resync_susp_peer[OLD] =
+                               device->state.peer_isp;
+                       peer_device_state_change->resync_susp_dependency[OLD] =
+                               device->state.aftr_isp;
+                       peer_device_state_change++;
+               }
+               device_state_change++;
+       }
+
+       return state_change;
+}
+
+static void remember_new_state(struct drbd_state_change *state_change)
+{
+       struct drbd_resource_state_change *resource_state_change;
+       struct drbd_resource *resource;
+       unsigned int n;
+
+       if (!state_change)
+               return;
+
+       resource_state_change = &state_change->resource[0];
+       resource = resource_state_change->resource;
+
+       resource_state_change->role[NEW] =
+               conn_highest_role(first_connection(resource));
+       resource_state_change->susp[NEW] = resource->susp;
+       resource_state_change->susp_nod[NEW] = resource->susp_nod;
+       resource_state_change->susp_fen[NEW] = resource->susp_fen;
+
+       for (n = 0; n < state_change->n_devices; n++) {
+               struct drbd_device_state_change *device_state_change =
+                       &state_change->devices[n];
+               struct drbd_device *device = device_state_change->device;
+
+               device_state_change->disk_state[NEW] = device->state.disk;
+       }
+
+       for (n = 0; n < state_change->n_connections; n++) {
+               struct drbd_connection_state_change *connection_state_change =
+                       &state_change->connections[n];
+               struct drbd_connection *connection =
+                       connection_state_change->connection;
+
+               connection_state_change->cstate[NEW] = connection->cstate;
+               connection_state_change->peer_role[NEW] =
+                       conn_highest_peer(connection);
+       }
+
+       for (n = 0; n < state_change->n_devices * state_change->n_connections; n++) {
+               struct drbd_peer_device_state_change *peer_device_state_change =
+                       &state_change->peer_devices[n];
+               struct drbd_device *device =
+                       peer_device_state_change->peer_device->device;
+               union drbd_dev_state state = device->state;
+
+               peer_device_state_change->disk_state[NEW] = state.pdsk;
+               peer_device_state_change->repl_state[NEW] =
+                       max_t(enum drbd_conns, C_WF_REPORT_PARAMS, state.conn);
+               peer_device_state_change->resync_susp_user[NEW] =
+                       state.user_isp;
+               peer_device_state_change->resync_susp_peer[NEW] =
+                       state.peer_isp;
+               peer_device_state_change->resync_susp_dependency[NEW] =
+                       state.aftr_isp;
+       }
+}
+
+void copy_old_to_new_state_change(struct drbd_state_change *state_change)
+{
+       struct drbd_resource_state_change *resource_state_change = &state_change->resource[0];
+       unsigned int n_device, n_connection, n_peer_device, n_peer_devices;
+
+#define OLD_TO_NEW(x) \
+       (x[NEW] = x[OLD])
+
+       OLD_TO_NEW(resource_state_change->role);
+       OLD_TO_NEW(resource_state_change->susp);
+       OLD_TO_NEW(resource_state_change->susp_nod);
+       OLD_TO_NEW(resource_state_change->susp_fen);
+
+       for (n_connection = 0; n_connection < state_change->n_connections; n_connection++) {
+               struct drbd_connection_state_change *connection_state_change =
+                               &state_change->connections[n_connection];
+
+               OLD_TO_NEW(connection_state_change->peer_role);
+               OLD_TO_NEW(connection_state_change->cstate);
+       }
+
+       for (n_device = 0; n_device < state_change->n_devices; n_device++) {
+               struct drbd_device_state_change *device_state_change =
+                       &state_change->devices[n_device];
+
+               OLD_TO_NEW(device_state_change->disk_state);
+       }
+
+       n_peer_devices = state_change->n_devices * state_change->n_connections;
+       for (n_peer_device = 0; n_peer_device < n_peer_devices; n_peer_device++) {
+               struct drbd_peer_device_state_change *p =
+                       &state_change->peer_devices[n_peer_device];
+
+               OLD_TO_NEW(p->disk_state);
+               OLD_TO_NEW(p->repl_state);
+               OLD_TO_NEW(p->resync_susp_user);
+               OLD_TO_NEW(p->resync_susp_peer);
+               OLD_TO_NEW(p->resync_susp_dependency);
+       }
+
+#undef OLD_TO_NEW
+}
+
+void forget_state_change(struct drbd_state_change *state_change)
+{
+       unsigned int n;
+
+       if (!state_change)
+               return;
+
+       if (state_change->resource->resource)
+               kref_put(&state_change->resource->resource->kref, drbd_destroy_resource);
+       for (n = 0; n < state_change->n_devices; n++) {
+               struct drbd_device *device = state_change->devices[n].device;
+
+               if (device)
+                       kref_put(&device->kref, drbd_destroy_device);
+       }
+       for (n = 0; n < state_change->n_connections; n++) {
+               struct drbd_connection *connection =
+                       state_change->connections[n].connection;
+
+               if (connection)
+                       kref_put(&connection->kref, drbd_destroy_connection);
+       }
+       kfree(state_change);
+}
+
 static int w_after_state_ch(struct drbd_work *w, int unused);
 static void after_state_ch(struct drbd_device *device, union drbd_state os,
-                          union drbd_state ns, enum chg_state_flags flags);
+                          union drbd_state ns, enum chg_state_flags flags,
+                          struct drbd_state_change *);
 static enum drbd_state_rv is_valid_state(struct drbd_device *, union drbd_state);
 static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state, struct drbd_connection *);
 static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
@@ -93,6 +334,7 @@ static enum drbd_role max_role(enum drbd_role role1, enum drbd_role role2)
                return R_SECONDARY;
        return R_UNKNOWN;
 }
+
 static enum drbd_role min_role(enum drbd_role role1, enum drbd_role role2)
 {
        if (role1 == R_UNKNOWN || role2 == R_UNKNOWN)
@@ -937,7 +1179,7 @@ void drbd_resume_al(struct drbd_device *device)
                drbd_info(device, "Resumed AL updates\n");
 }
 
-/* helper for __drbd_set_state */
+/* helper for _drbd_set_state */
 static void set_ov_position(struct drbd_device *device, enum drbd_conns cs)
 {
        if (first_peer_device(device)->connection->agreed_pro_version < 90)
@@ -965,17 +1207,17 @@ static void set_ov_position(struct drbd_device *device, enum drbd_conns cs)
 }
 
 /**
- * __drbd_set_state() - Set a new DRBD state
+ * _drbd_set_state() - Set a new DRBD state
  * @device:    DRBD device.
  * @ns:                new state.
  * @flags:     Flags
  * @done:      Optional completion, that will get completed after the after_state_ch() finished
  *
- * Caller needs to hold req_lock, and global_state_lock. Do not call directly.
+ * Caller needs to hold req_lock. Do not call directly.
  */
 enum drbd_state_rv
-__drbd_set_state(struct drbd_device *device, union drbd_state ns,
-                enum chg_state_flags flags, struct completion *done)
+_drbd_set_state(struct drbd_device *device, union drbd_state ns,
+               enum chg_state_flags flags, struct completion *done)
 {
        struct drbd_peer_device *peer_device = first_peer_device(device);
        struct drbd_connection *connection = peer_device ? peer_device->connection : NULL;
@@ -983,6 +1225,7 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
        enum drbd_state_rv rv = SS_SUCCESS;
        enum sanitize_state_warnings ssw;
        struct after_state_chg_work *ascw;
+       struct drbd_state_change *state_change;
 
        os = drbd_read_state(device);
 
@@ -1037,6 +1280,9 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
        if (!is_sync_state(os.conn) && is_sync_state(ns.conn))
                clear_bit(RS_DONE, &device->flags);
 
+       /* FIXME: Have any flags been set earlier in this function already? */
+       state_change = remember_old_state(device->resource, GFP_ATOMIC);
+
        /* changes to local_cnt and device flags should be visible before
         * changes to state, which again should be visible before anything else
         * depending on that change happens. */
@@ -1047,6 +1293,8 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
        device->resource->susp_fen = ns.susp_fen;
        smp_wmb();
 
+       remember_new_state(state_change);
+
        /* put replicated vs not-replicated requests in seperate epochs */
        if (drbd_should_do_remote((union drbd_dev_state)os.i) !=
            drbd_should_do_remote((union drbd_dev_state)ns.i))
@@ -1184,6 +1432,7 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
                ascw->w.cb = w_after_state_ch;
                ascw->device = device;
                ascw->done = done;
+               ascw->state_change = state_change;
                drbd_queue_work(&connection->sender_work,
                                &ascw->w);
        } else {
@@ -1199,7 +1448,8 @@ static int w_after_state_ch(struct drbd_work *w, int unused)
                container_of(w, struct after_state_chg_work, w);
        struct drbd_device *device = ascw->device;
 
-       after_state_ch(device, ascw->os, ascw->ns, ascw->flags);
+       after_state_ch(device, ascw->os, ascw->ns, ascw->flags, ascw->state_change);
+       forget_state_change(ascw->state_change);
        if (ascw->flags & CS_WAIT_COMPLETE)
                complete(ascw->done);
        kfree(ascw);
@@ -1234,7 +1484,7 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device,
        D_ASSERT(device, current == first_peer_device(device)->connection->worker.task);
 
        /* open coded non-blocking drbd_suspend_io(device); */
-       set_bit(SUSPEND_IO, &device->flags);
+       atomic_inc(&device->suspend_cnt);
 
        drbd_bm_lock(device, why, flags);
        rv = io_fn(device);
@@ -1245,6 +1495,139 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device,
        return rv;
 }
 
+void notify_resource_state_change(struct sk_buff *skb,
+                                 unsigned int seq,
+                                 struct drbd_resource_state_change *resource_state_change,
+                                 enum drbd_notification_type type)
+{
+       struct drbd_resource *resource = resource_state_change->resource;
+       struct resource_info resource_info = {
+               .res_role = resource_state_change->role[NEW],
+               .res_susp = resource_state_change->susp[NEW],
+               .res_susp_nod = resource_state_change->susp_nod[NEW],
+               .res_susp_fen = resource_state_change->susp_fen[NEW],
+       };
+
+       notify_resource_state(skb, seq, resource, &resource_info, type);
+}
+
+void notify_connection_state_change(struct sk_buff *skb,
+                                   unsigned int seq,
+                                   struct drbd_connection_state_change *connection_state_change,
+                                   enum drbd_notification_type type)
+{
+       struct drbd_connection *connection = connection_state_change->connection;
+       struct connection_info connection_info = {
+               .conn_connection_state = connection_state_change->cstate[NEW],
+               .conn_role = connection_state_change->peer_role[NEW],
+       };
+
+       notify_connection_state(skb, seq, connection, &connection_info, type);
+}
+
+void notify_device_state_change(struct sk_buff *skb,
+                               unsigned int seq,
+                               struct drbd_device_state_change *device_state_change,
+                               enum drbd_notification_type type)
+{
+       struct drbd_device *device = device_state_change->device;
+       struct device_info device_info = {
+               .dev_disk_state = device_state_change->disk_state[NEW],
+       };
+
+       notify_device_state(skb, seq, device, &device_info, type);
+}
+
+void notify_peer_device_state_change(struct sk_buff *skb,
+                                    unsigned int seq,
+                                    struct drbd_peer_device_state_change *p,
+                                    enum drbd_notification_type type)
+{
+       struct drbd_peer_device *peer_device = p->peer_device;
+       struct peer_device_info peer_device_info = {
+               .peer_repl_state = p->repl_state[NEW],
+               .peer_disk_state = p->disk_state[NEW],
+               .peer_resync_susp_user = p->resync_susp_user[NEW],
+               .peer_resync_susp_peer = p->resync_susp_peer[NEW],
+               .peer_resync_susp_dependency = p->resync_susp_dependency[NEW],
+       };
+
+       notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type);
+}
+
+static void broadcast_state_change(struct drbd_state_change *state_change)
+{
+       struct drbd_resource_state_change *resource_state_change = &state_change->resource[0];
+       bool resource_state_has_changed;
+       unsigned int n_device, n_connection, n_peer_device, n_peer_devices;
+       void (*last_func)(struct sk_buff *, unsigned int, void *,
+                         enum drbd_notification_type) = NULL;
+       void *uninitialized_var(last_arg);
+
+#define HAS_CHANGED(state) ((state)[OLD] != (state)[NEW])
+#define FINAL_STATE_CHANGE(type) \
+       ({ if (last_func) \
+               last_func(NULL, 0, last_arg, type); \
+       })
+#define REMEMBER_STATE_CHANGE(func, arg, type) \
+       ({ FINAL_STATE_CHANGE(type | NOTIFY_CONTINUES); \
+          last_func = (typeof(last_func))func; \
+          last_arg = arg; \
+        })
+
+       mutex_lock(&notification_mutex);
+
+       resource_state_has_changed =
+           HAS_CHANGED(resource_state_change->role) ||
+           HAS_CHANGED(resource_state_change->susp) ||
+           HAS_CHANGED(resource_state_change->susp_nod) ||
+           HAS_CHANGED(resource_state_change->susp_fen);
+
+       if (resource_state_has_changed)
+               REMEMBER_STATE_CHANGE(notify_resource_state_change,
+                                     resource_state_change, NOTIFY_CHANGE);
+
+       for (n_connection = 0; n_connection < state_change->n_connections; n_connection++) {
+               struct drbd_connection_state_change *connection_state_change =
+                               &state_change->connections[n_connection];
+
+               if (HAS_CHANGED(connection_state_change->peer_role) ||
+                   HAS_CHANGED(connection_state_change->cstate))
+                       REMEMBER_STATE_CHANGE(notify_connection_state_change,
+                                             connection_state_change, NOTIFY_CHANGE);
+       }
+
+       for (n_device = 0; n_device < state_change->n_devices; n_device++) {
+               struct drbd_device_state_change *device_state_change =
+                       &state_change->devices[n_device];
+
+               if (HAS_CHANGED(device_state_change->disk_state))
+                       REMEMBER_STATE_CHANGE(notify_device_state_change,
+                                             device_state_change, NOTIFY_CHANGE);
+       }
+
+       n_peer_devices = state_change->n_devices * state_change->n_connections;
+       for (n_peer_device = 0; n_peer_device < n_peer_devices; n_peer_device++) {
+               struct drbd_peer_device_state_change *p =
+                       &state_change->peer_devices[n_peer_device];
+
+               if (HAS_CHANGED(p->disk_state) ||
+                   HAS_CHANGED(p->repl_state) ||
+                   HAS_CHANGED(p->resync_susp_user) ||
+                   HAS_CHANGED(p->resync_susp_peer) ||
+                   HAS_CHANGED(p->resync_susp_dependency))
+                       REMEMBER_STATE_CHANGE(notify_peer_device_state_change,
+                                             p, NOTIFY_CHANGE);
+       }
+
+       FINAL_STATE_CHANGE(NOTIFY_CHANGE);
+       mutex_unlock(&notification_mutex);
+
+#undef HAS_CHANGED
+#undef FINAL_STATE_CHANGE
+#undef REMEMBER_STATE_CHANGE
+}
+
 /**
  * after_state_ch() - Perform after state change actions that may sleep
  * @device:    DRBD device.
@@ -1253,13 +1636,16 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device,
  * @flags:     Flags
  */
 static void after_state_ch(struct drbd_device *device, union drbd_state os,
-                          union drbd_state ns, enum chg_state_flags flags)
+                          union drbd_state ns, enum chg_state_flags flags,
+                          struct drbd_state_change *state_change)
 {
        struct drbd_resource *resource = device->resource;
        struct drbd_peer_device *peer_device = first_peer_device(device);
        struct drbd_connection *connection = peer_device ? peer_device->connection : NULL;
        struct sib_info sib;
 
+       broadcast_state_change(state_change);
+
        sib.sib_reason = SIB_STATE_CHANGE;
        sib.os = os;
        sib.ns = ns;
@@ -1377,7 +1763,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
        }
 
        if (ns.pdsk < D_INCONSISTENT && get_ldev(device)) {
-               if (os.peer == R_SECONDARY && ns.peer == R_PRIMARY &&
+               if (os.peer != R_PRIMARY && ns.peer == R_PRIMARY &&
                    device->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
                        drbd_uuid_new_current(device);
                        drbd_send_uuids(peer_device);
@@ -1444,7 +1830,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
        if (os.disk != D_FAILED && ns.disk == D_FAILED) {
                enum drbd_io_error_p eh = EP_PASS_ON;
                int was_io_error = 0;
-               /* corresponding get_ldev was in __drbd_set_state, to serialize
+               /* corresponding get_ldev was in _drbd_set_state, to serialize
                 * our cleanup here with the transition to D_DISKLESS.
                 * But is is still not save to dreference ldev here, since
                 * we might come from an failed Attach before ldev was set. */
@@ -1455,6 +1841,10 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
 
                        was_io_error = test_and_clear_bit(WAS_IO_ERROR, &device->flags);
 
+                       /* Intentionally call this handler first, before drbd_send_state().
+                        * See: 2932204 drbd: call local-io-error handler early
+                        * People may chose to hard-reset the box from this handler.
+                        * It is useful if this looks like a "regular node crash". */
                        if (was_io_error && eh == EP_CALL_HELPER)
                                drbd_khelper(device, "local-io-error");
 
@@ -1572,6 +1962,7 @@ struct after_conn_state_chg_work {
        union drbd_state ns_max; /* new, max state, over all devices */
        enum chg_state_flags flags;
        struct drbd_connection *connection;
+       struct drbd_state_change *state_change;
 };
 
 static int w_after_conn_state_ch(struct drbd_work *w, int unused)
@@ -1584,6 +1975,8 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
        struct drbd_peer_device *peer_device;
        int vnr;
 
+       broadcast_state_change(acscw->state_change);
+       forget_state_change(acscw->state_change);
        kfree(acscw);
 
        /* Upon network configuration, we need to start the receiver */
@@ -1593,6 +1986,13 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
        if (oc == C_DISCONNECTING && ns_max.conn == C_STANDALONE) {
                struct net_conf *old_conf;
 
+               mutex_lock(&notification_mutex);
+               idr_for_each_entry(&connection->peer_devices, peer_device, vnr)
+                       notify_peer_device_state(NULL, 0, peer_device, NULL,
+                                                NOTIFY_DESTROY | NOTIFY_CONTINUES);
+               notify_connection_state(NULL, 0, connection, NULL, NOTIFY_DESTROY);
+               mutex_unlock(&notification_mutex);
+
                mutex_lock(&connection->resource->conf_update);
                old_conf = connection->net_conf;
                connection->my_addr_len = 0;
@@ -1759,7 +2159,7 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union
                if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED)
                        ns.disk = os.disk;
 
-               rv = __drbd_set_state(device, ns, flags, NULL);
+               rv = _drbd_set_state(device, ns, flags, NULL);
                if (rv < SS_SUCCESS)
                        BUG();
 
@@ -1823,6 +2223,7 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
        enum drbd_conns oc = connection->cstate;
        union drbd_state ns_max, ns_min, os;
        bool have_mutex = false;
+       struct drbd_state_change *state_change;
 
        if (mask.conn) {
                rv = is_valid_conn_transition(oc, val.conn);
@@ -1868,10 +2269,12 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
                        goto abort;
        }
 
+       state_change = remember_old_state(connection->resource, GFP_ATOMIC);
        conn_old_common_state(connection, &os, &flags);
        flags |= CS_DC_SUSP;
        conn_set_state(connection, mask, val, &ns_min, &ns_max, flags);
        conn_pr_state_change(connection, os, ns_max, flags);
+       remember_new_state(state_change);
 
        acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC);
        if (acscw) {
@@ -1882,6 +2285,7 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u
                acscw->w.cb = w_after_conn_state_ch;
                kref_get(&connection->kref);
                acscw->connection = connection;
+               acscw->state_change = state_change;
                drbd_queue_work(&connection->sender_work, &acscw->w);
        } else {
                drbd_err(connection, "Could not kmalloc an acscw\n");
index 7f53c40..bd98953 100644 (file)
@@ -122,9 +122,9 @@ extern enum drbd_state_rv
 _drbd_request_state_holding_state_mutex(struct drbd_device *, union drbd_state,
                                        union drbd_state, enum chg_state_flags);
 
-extern enum drbd_state_rv __drbd_set_state(struct drbd_device *, union drbd_state,
-                                          enum chg_state_flags,
-                                          struct completion *done);
+extern enum drbd_state_rv _drbd_set_state(struct drbd_device *, union drbd_state,
+                                         enum chg_state_flags,
+                                         struct completion *done);
 extern void print_st_err(struct drbd_device *, union drbd_state,
                        union drbd_state, int);
 
diff --git a/drivers/block/drbd/drbd_state_change.h b/drivers/block/drbd/drbd_state_change.h
new file mode 100644 (file)
index 0000000..9e503a1
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef DRBD_STATE_CHANGE_H
+#define DRBD_STATE_CHANGE_H
+
+struct drbd_resource_state_change {
+       struct drbd_resource *resource;
+       enum drbd_role role[2];
+       bool susp[2];
+       bool susp_nod[2];
+       bool susp_fen[2];
+};
+
+struct drbd_device_state_change {
+       struct drbd_device *device;
+       enum drbd_disk_state disk_state[2];
+};
+
+struct drbd_connection_state_change {
+       struct drbd_connection *connection;
+       enum drbd_conns cstate[2];  /* drbd9: enum drbd_conn_state */
+       enum drbd_role peer_role[2];
+};
+
+struct drbd_peer_device_state_change {
+       struct drbd_peer_device *peer_device;
+       enum drbd_disk_state disk_state[2];
+       enum drbd_conns repl_state[2];  /* drbd9: enum drbd_repl_state */
+       bool resync_susp_user[2];
+       bool resync_susp_peer[2];
+       bool resync_susp_dependency[2];
+};
+
+struct drbd_state_change {
+       struct list_head list;
+       unsigned int n_devices;
+       unsigned int n_connections;
+       struct drbd_resource_state_change resource[1];
+       struct drbd_device_state_change *devices;
+       struct drbd_connection_state_change *connections;
+       struct drbd_peer_device_state_change *peer_devices;
+};
+
+extern struct drbd_state_change *remember_old_state(struct drbd_resource *, gfp_t);
+extern void copy_old_to_new_state_change(struct drbd_state_change *);
+extern void forget_state_change(struct drbd_state_change *);
+
+extern void notify_resource_state_change(struct sk_buff *,
+                                        unsigned int,
+                                        struct drbd_resource_state_change *,
+                                        enum drbd_notification_type type);
+extern void notify_connection_state_change(struct sk_buff *,
+                                          unsigned int,
+                                          struct drbd_connection_state_change *,
+                                          enum drbd_notification_type type);
+extern void notify_device_state_change(struct sk_buff *,
+                                      unsigned int,
+                                      struct drbd_device_state_change *,
+                                      enum drbd_notification_type type);
+extern void notify_peer_device_state_change(struct sk_buff *,
+                                           unsigned int,
+                                           struct drbd_peer_device_state_change *,
+                                           enum drbd_notification_type type);
+
+#endif  /* DRBD_STATE_CHANGE_H */
index 5578c14..eff716c 100644 (file)
@@ -55,13 +55,6 @@ static int make_resync_request(struct drbd_device *, int);
  *
  */
 
-
-/* About the global_state_lock
-   Each state transition on an device holds a read lock. In case we have
-   to evaluate the resync after dependencies, we grab a write lock, because
-   we need stable states on all devices for that.  */
-rwlock_t global_state_lock;
-
 /* used for synchronous meta data and bitmap IO
  * submitted by drbd_md_sync_page_io()
  */
@@ -120,6 +113,7 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
        unsigned long flags = 0;
        struct drbd_peer_device *peer_device = peer_req->peer_device;
        struct drbd_device *device = peer_device->device;
+       struct drbd_connection *connection = peer_device->connection;
        struct drbd_interval i;
        int do_wake;
        u64 block_id;
@@ -152,6 +146,12 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
         * ((peer_req->flags & (EE_WAS_ERROR|EE_IS_TRIM)) == EE_WAS_ERROR) */
        if (peer_req->flags & EE_WAS_ERROR)
                __drbd_chk_io_error(device, DRBD_WRITE_ERROR);
+
+       if (connection->cstate >= C_WF_REPORT_PARAMS) {
+               kref_get(&device->kref); /* put is in drbd_send_acks_wf() */
+               if (!queue_work(connection->ack_sender, &peer_device->send_acks_work))
+                       kref_put(&device->kref, drbd_destroy_device);
+       }
        spin_unlock_irqrestore(&device->resource->req_lock, flags);
 
        if (block_id == ID_SYNCER)
@@ -163,7 +163,6 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
        if (do_al_complete_io)
                drbd_al_complete_io(device, &i);
 
-       wake_asender(peer_device->connection);
        put_ldev(device);
 }
 
@@ -195,6 +194,12 @@ void drbd_peer_request_endio(struct bio *bio)
        }
 }
 
+void drbd_panic_after_delayed_completion_of_aborted_request(struct drbd_device *device)
+{
+       panic("drbd%u %s/%u potential random memory corruption caused by delayed completion of aborted local request\n",
+               device->minor, device->resource->name, device->vnr);
+}
+
 /* read, readA or write requests on R_PRIMARY coming from drbd_make_request
  */
 void drbd_request_endio(struct bio *bio)
@@ -238,7 +243,7 @@ void drbd_request_endio(struct bio *bio)
                        drbd_emerg(device, "delayed completion of aborted local request; disk-timeout may be too aggressive\n");
 
                if (!bio->bi_error)
-                       panic("possible random memory corruption caused by delayed completion of aborted local request\n");
+                       drbd_panic_after_delayed_completion_of_aborted_request(device);
        }
 
        /* to avoid recursion in __req_mod */
@@ -1291,6 +1296,7 @@ static int drbd_send_barrier(struct drbd_connection *connection)
        p->barrier = connection->send.current_epoch_nr;
        p->pad = 0;
        connection->send.current_epoch_writes = 0;
+       connection->send.last_sent_barrier_jif = jiffies;
 
        return conn_send_command(connection, sock, P_BARRIER, sizeof(*p), NULL, 0);
 }
@@ -1315,6 +1321,7 @@ static void re_init_if_first_write(struct drbd_connection *connection, unsigned
                connection->send.seen_any_write_yet = true;
                connection->send.current_epoch_nr = epoch;
                connection->send.current_epoch_writes = 0;
+               connection->send.last_sent_barrier_jif = jiffies;
        }
 }
 
@@ -1456,70 +1463,73 @@ static int _drbd_may_sync_now(struct drbd_device *device)
 }
 
 /**
- * _drbd_pause_after() - Pause resync on all devices that may not resync now
+ * drbd_pause_after() - Pause resync on all devices that may not resync now
  * @device:    DRBD device.
  *
  * Called from process context only (admin command and after_state_ch).
  */
-static int _drbd_pause_after(struct drbd_device *device)
+static bool drbd_pause_after(struct drbd_device *device)
 {
+       bool changed = false;
        struct drbd_device *odev;
-       int i, rv = 0;
+       int i;
 
        rcu_read_lock();
        idr_for_each_entry(&drbd_devices, odev, i) {
                if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS)
                        continue;
-               if (!_drbd_may_sync_now(odev))
-                       rv |= (__drbd_set_state(_NS(odev, aftr_isp, 1), CS_HARD, NULL)
-                              != SS_NOTHING_TO_DO);
+               if (!_drbd_may_sync_now(odev) &&
+                   _drbd_set_state(_NS(odev, aftr_isp, 1),
+                                   CS_HARD, NULL) != SS_NOTHING_TO_DO)
+                       changed = true;
        }
        rcu_read_unlock();
 
-       return rv;
+       return changed;
 }
 
 /**
- * _drbd_resume_next() - Resume resync on all devices that may resync now
+ * drbd_resume_next() - Resume resync on all devices that may resync now
  * @device:    DRBD device.
  *
  * Called from process context only (admin command and worker).
  */
-static int _drbd_resume_next(struct drbd_device *device)
+static bool drbd_resume_next(struct drbd_device *device)
 {
+       bool changed = false;
        struct drbd_device *odev;
-       int i, rv = 0;
+       int i;
 
        rcu_read_lock();
        idr_for_each_entry(&drbd_devices, odev, i) {
                if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS)
                        continue;
                if (odev->state.aftr_isp) {
-                       if (_drbd_may_sync_now(odev))
-                               rv |= (__drbd_set_state(_NS(odev, aftr_isp, 0),
-                                                       CS_HARD, NULL)
-                                      != SS_NOTHING_TO_DO) ;
+                       if (_drbd_may_sync_now(odev) &&
+                           _drbd_set_state(_NS(odev, aftr_isp, 0),
+                                           CS_HARD, NULL) != SS_NOTHING_TO_DO)
+                               changed = true;
                }
        }
        rcu_read_unlock();
-       return rv;
+       return changed;
 }
 
 void resume_next_sg(struct drbd_device *device)
 {
-       write_lock_irq(&global_state_lock);
-       _drbd_resume_next(device);
-       write_unlock_irq(&global_state_lock);
+       lock_all_resources();
+       drbd_resume_next(device);
+       unlock_all_resources();
 }
 
 void suspend_other_sg(struct drbd_device *device)
 {
-       write_lock_irq(&global_state_lock);
-       _drbd_pause_after(device);
-       write_unlock_irq(&global_state_lock);
+       lock_all_resources();
+       drbd_pause_after(device);
+       unlock_all_resources();
 }
 
-/* caller must hold global_state_lock */
+/* caller must lock_all_resources() */
 enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor)
 {
        struct drbd_device *odev;
@@ -1557,15 +1567,15 @@ enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_min
        }
 }
 
-/* caller must hold global_state_lock */
+/* caller must lock_all_resources() */
 void drbd_resync_after_changed(struct drbd_device *device)
 {
-       int changes;
+       int changed;
 
        do {
-               changes  = _drbd_pause_after(device);
-               changes |= _drbd_resume_next(device);
-       } while (changes);
+               changed  = drbd_pause_after(device);
+               changed |= drbd_resume_next(device);
+       } while (changed);
 }
 
 void drbd_rs_controller_reset(struct drbd_device *device)
@@ -1685,19 +1695,14 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
        } else {
                mutex_lock(device->state_mutex);
        }
-       clear_bit(B_RS_H_DONE, &device->flags);
 
-       /* req_lock: serialize with drbd_send_and_submit() and others
-        * global_state_lock: for stable sync-after dependencies */
-       spin_lock_irq(&device->resource->req_lock);
-       write_lock(&global_state_lock);
+       lock_all_resources();
+       clear_bit(B_RS_H_DONE, &device->flags);
        /* Did some connection breakage or IO error race with us? */
        if (device->state.conn < C_CONNECTED
        || !get_ldev_if_state(device, D_NEGOTIATING)) {
-               write_unlock(&global_state_lock);
-               spin_unlock_irq(&device->resource->req_lock);
-               mutex_unlock(device->state_mutex);
-               return;
+               unlock_all_resources();
+               goto out;
        }
 
        ns = drbd_read_state(device);
@@ -1711,7 +1716,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
        else /* side == C_SYNC_SOURCE */
                ns.pdsk = D_INCONSISTENT;
 
-       r = __drbd_set_state(device, ns, CS_VERBOSE, NULL);
+       r = _drbd_set_state(device, ns, CS_VERBOSE, NULL);
        ns = drbd_read_state(device);
 
        if (ns.conn < C_CONNECTED)
@@ -1732,7 +1737,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
                        device->rs_mark_left[i] = tw;
                        device->rs_mark_time[i] = now;
                }
-               _drbd_pause_after(device);
+               drbd_pause_after(device);
                /* Forget potentially stale cached per resync extent bit-counts.
                 * Open coded drbd_rs_cancel_all(device), we already have IRQs
                 * disabled, and know the disk state is ok. */
@@ -1742,8 +1747,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
                device->resync_wenr = LC_FREE;
                spin_unlock(&device->al_lock);
        }
-       write_unlock(&global_state_lock);
-       spin_unlock_irq(&device->resource->req_lock);
+       unlock_all_resources();
 
        if (r == SS_SUCCESS) {
                wake_up(&device->al_wait); /* for lc_reset() above */
@@ -1807,6 +1811,7 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
                drbd_md_sync(device);
        }
        put_ldev(device);
+out:
        mutex_unlock(device->state_mutex);
 }
 
@@ -1836,7 +1841,7 @@ static void drbd_ldev_destroy(struct drbd_device *device)
        device->act_log = NULL;
 
        __acquire(local);
-       drbd_free_ldev(device->ldev);
+       drbd_backing_dev_free(device, device->ldev);
        device->ldev = NULL;
        __release(local);
 
index 15bec40..9b180db 100644 (file)
 /* Device instance number, incremented each time a device is probed. */
 static int instance;
 
-struct list_head online_list;
-struct list_head removing_list;
-spinlock_t dev_lock;
+static struct list_head online_list;
+static struct list_head removing_list;
+static spinlock_t dev_lock;
 
 /*
  * Global variable used to hold the major block device number
index 95dff91..8ba1e97 100644 (file)
@@ -436,9 +436,8 @@ static void null_del_dev(struct nullb *nullb)
 static void null_lnvm_end_io(struct request *rq, int error)
 {
        struct nvm_rq *rqd = rq->end_io_data;
-       struct nvm_dev *dev = rqd->dev;
 
-       dev->mt->end_io(rqd, error);
+       nvm_end_io(rqd, error);
 
        blk_put_request(rq);
 }
@@ -495,17 +494,17 @@ static int null_lnvm_id(struct nvm_dev *dev, struct nvm_id *id)
        id->ppaf.ch_offset = 56;
        id->ppaf.ch_len = 8;
 
-       do_div(size, bs); /* convert size to pages */
-       do_div(size, 256); /* concert size to pgs pr blk */
+       sector_div(size, bs); /* convert size to pages */
+       size >>= 8; /* concert size to pgs pr blk */
        grp = &id->groups[0];
        grp->mtype = 0;
        grp->fmtype = 0;
        grp->num_ch = 1;
        grp->num_pg = 256;
        blksize = size;
-       do_div(size, (1 << 16));
+       size >>= 16;
        grp->num_lun = size + 1;
-       do_div(blksize, grp->num_lun);
+       sector_div(blksize, grp->num_lun);
        grp->num_blk = blksize;
        grp->num_pln = 1;
 
index 81ea69f..4a87678 100644 (file)
@@ -5185,8 +5185,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
 
 out_err:
        rbd_dev_unparent(rbd_dev);
-       if (parent)
-               rbd_dev_destroy(parent);
+       rbd_dev_destroy(parent);
        return ret;
 }
 
index 59c91d4..ba4bfe9 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
-#include <linux/time.h>
+#include <linux/ktime.h>
 #include <linux/hdreg.h>
 #include <linux/dma-mapping.h>
 #include <linux/completion.h>
@@ -671,16 +671,15 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func)
 static unsigned int carm_fill_sync_time(struct carm_host *host,
                                        unsigned int idx, void *mem)
 {
-       struct timeval tv;
        struct carm_msg_sync_time *st = mem;
 
-       do_gettimeofday(&tv);
+       time64_t tv = ktime_get_real_seconds();
 
        memset(st, 0, sizeof(*st));
        st->type        = CARM_MSG_MISC;
        st->subtype     = MISC_SET_TIME;
        st->handle      = cpu_to_le32(TAG_ENCODE(idx));
-       st->timestamp   = cpu_to_le32(tv.tv_sec);
+       st->timestamp   = cpu_to_le32(tv);
 
        return sizeof(struct carm_msg_sync_time);
 }
index 41fb1a9..4809c15 100644 (file)
@@ -83,6 +83,16 @@ module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
 MODULE_PARM_DESC(max_persistent_grants,
                  "Maximum number of grants to map persistently");
 
+/*
+ * Maximum number of rings/queues blkback supports, allow as many queues as there
+ * are CPUs if user has not specified a value.
+ */
+unsigned int xenblk_max_queues;
+module_param_named(max_queues, xenblk_max_queues, uint, 0644);
+MODULE_PARM_DESC(max_queues,
+                "Maximum number of hardware queues per virtual disk." \
+                "By default it is the number of online CPUs.");
+
 /*
  * Maximum order of pages to be used for the shared ring between front and
  * backend, 4KB page granularity is used.
@@ -113,71 +123,71 @@ module_param(log_stats, int, 0644);
 /* Number of free pages to remove on each call to gnttab_free_pages */
 #define NUM_BATCH_FREE_PAGES 10
 
-static inline int get_free_page(struct xen_blkif *blkif, struct page **page)
+static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&blkif->free_pages_lock, flags);
-       if (list_empty(&blkif->free_pages)) {
-               BUG_ON(blkif->free_pages_num != 0);
-               spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+       spin_lock_irqsave(&ring->free_pages_lock, flags);
+       if (list_empty(&ring->free_pages)) {
+               BUG_ON(ring->free_pages_num != 0);
+               spin_unlock_irqrestore(&ring->free_pages_lock, flags);
                return gnttab_alloc_pages(1, page);
        }
-       BUG_ON(blkif->free_pages_num == 0);
-       page[0] = list_first_entry(&blkif->free_pages, struct page, lru);
+       BUG_ON(ring->free_pages_num == 0);
+       page[0] = list_first_entry(&ring->free_pages, struct page, lru);
        list_del(&page[0]->lru);
-       blkif->free_pages_num--;
-       spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+       ring->free_pages_num--;
+       spin_unlock_irqrestore(&ring->free_pages_lock, flags);
 
        return 0;
 }
 
-static inline void put_free_pages(struct xen_blkif *blkif, struct page **page,
+static inline void put_free_pages(struct xen_blkif_ring *ring, struct page **page,
                                   int num)
 {
        unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&blkif->free_pages_lock, flags);
+       spin_lock_irqsave(&ring->free_pages_lock, flags);
        for (i = 0; i < num; i++)
-               list_add(&page[i]->lru, &blkif->free_pages);
-       blkif->free_pages_num += num;
-       spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+               list_add(&page[i]->lru, &ring->free_pages);
+       ring->free_pages_num += num;
+       spin_unlock_irqrestore(&ring->free_pages_lock, flags);
 }
 
-static inline void shrink_free_pagepool(struct xen_blkif *blkif, int num)
+static inline void shrink_free_pagepool(struct xen_blkif_ring *ring, int num)
 {
        /* Remove requested pages in batches of NUM_BATCH_FREE_PAGES */
        struct page *page[NUM_BATCH_FREE_PAGES];
        unsigned int num_pages = 0;
        unsigned long flags;
 
-       spin_lock_irqsave(&blkif->free_pages_lock, flags);
-       while (blkif->free_pages_num > num) {
-               BUG_ON(list_empty(&blkif->free_pages));
-               page[num_pages] = list_first_entry(&blkif->free_pages,
+       spin_lock_irqsave(&ring->free_pages_lock, flags);
+       while (ring->free_pages_num > num) {
+               BUG_ON(list_empty(&ring->free_pages));
+               page[num_pages] = list_first_entry(&ring->free_pages,
                                                   struct page, lru);
                list_del(&page[num_pages]->lru);
-               blkif->free_pages_num--;
+               ring->free_pages_num--;
                if (++num_pages == NUM_BATCH_FREE_PAGES) {
-                       spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+                       spin_unlock_irqrestore(&ring->free_pages_lock, flags);
                        gnttab_free_pages(num_pages, page);
-                       spin_lock_irqsave(&blkif->free_pages_lock, flags);
+                       spin_lock_irqsave(&ring->free_pages_lock, flags);
                        num_pages = 0;
                }
        }
-       spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+       spin_unlock_irqrestore(&ring->free_pages_lock, flags);
        if (num_pages != 0)
                gnttab_free_pages(num_pages, page);
 }
 
 #define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page)))
 
-static int do_block_io_op(struct xen_blkif *blkif);
-static int dispatch_rw_block_io(struct xen_blkif *blkif,
+static int do_block_io_op(struct xen_blkif_ring *ring);
+static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
                                struct blkif_request *req,
                                struct pending_req *pending_req);
-static void make_response(struct xen_blkif *blkif, u64 id,
+static void make_response(struct xen_blkif_ring *ring, u64 id,
                          unsigned short op, int st);
 
 #define foreach_grant_safe(pos, n, rbtree, node) \
@@ -190,7 +200,7 @@ static void make_response(struct xen_blkif *blkif, u64 id,
 
 /*
  * We don't need locking around the persistent grant helpers
- * because blkback uses a single-thread for each backed, so we
+ * because blkback uses a single-thread for each backend, so we
  * can be sure that this functions will never be called recursively.
  *
  * The only exception to that is put_persistent_grant, that can be called
@@ -198,19 +208,20 @@ static void make_response(struct xen_blkif *blkif, u64 id,
  * bit operations to modify the flags of a persistent grant and to count
  * the number of used grants.
  */
-static int add_persistent_gnt(struct xen_blkif *blkif,
+static int add_persistent_gnt(struct xen_blkif_ring *ring,
                               struct persistent_gnt *persistent_gnt)
 {
        struct rb_node **new = NULL, *parent = NULL;
        struct persistent_gnt *this;
+       struct xen_blkif *blkif = ring->blkif;
 
-       if (blkif->persistent_gnt_c >= xen_blkif_max_pgrants) {
+       if (ring->persistent_gnt_c >= xen_blkif_max_pgrants) {
                if (!blkif->vbd.overflow_max_grants)
                        blkif->vbd.overflow_max_grants = 1;
                return -EBUSY;
        }
        /* Figure out where to put new node */
-       new = &blkif->persistent_gnts.rb_node;
+       new = &ring->persistent_gnts.rb_node;
        while (*new) {
                this = container_of(*new, struct persistent_gnt, node);
 
@@ -229,19 +240,19 @@ static int add_persistent_gnt(struct xen_blkif *blkif,
        set_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
        /* Add new node and rebalance tree. */
        rb_link_node(&(persistent_gnt->node), parent, new);
-       rb_insert_color(&(persistent_gnt->node), &blkif->persistent_gnts);
-       blkif->persistent_gnt_c++;
-       atomic_inc(&blkif->persistent_gnt_in_use);
+       rb_insert_color(&(persistent_gnt->node), &ring->persistent_gnts);
+       ring->persistent_gnt_c++;
+       atomic_inc(&ring->persistent_gnt_in_use);
        return 0;
 }
 
-static struct persistent_gnt *get_persistent_gnt(struct xen_blkif *blkif,
+static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
                                                 grant_ref_t gref)
 {
        struct persistent_gnt *data;
        struct rb_node *node = NULL;
 
-       node = blkif->persistent_gnts.rb_node;
+       node = ring->persistent_gnts.rb_node;
        while (node) {
                data = container_of(node, struct persistent_gnt, node);
 
@@ -255,24 +266,24 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif *blkif,
                                return NULL;
                        }
                        set_bit(PERSISTENT_GNT_ACTIVE, data->flags);
-                       atomic_inc(&blkif->persistent_gnt_in_use);
+                       atomic_inc(&ring->persistent_gnt_in_use);
                        return data;
                }
        }
        return NULL;
 }
 
-static void put_persistent_gnt(struct xen_blkif *blkif,
+static void put_persistent_gnt(struct xen_blkif_ring *ring,
                                struct persistent_gnt *persistent_gnt)
 {
        if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
                pr_alert_ratelimited("freeing a grant already unused\n");
        set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
        clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
-       atomic_dec(&blkif->persistent_gnt_in_use);
+       atomic_dec(&ring->persistent_gnt_in_use);
 }
 
-static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root,
+static void free_persistent_gnts(struct xen_blkif_ring *ring, struct rb_root *root,
                                  unsigned int num)
 {
        struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
@@ -303,7 +314,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root,
                        unmap_data.count = segs_to_unmap;
                        BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
 
-                       put_free_pages(blkif, pages, segs_to_unmap);
+                       put_free_pages(ring, pages, segs_to_unmap);
                        segs_to_unmap = 0;
                }
 
@@ -320,15 +331,15 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
        struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct persistent_gnt *persistent_gnt;
        int segs_to_unmap = 0;
-       struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work);
+       struct xen_blkif_ring *ring = container_of(work, typeof(*ring), persistent_purge_work);
        struct gntab_unmap_queue_data unmap_data;
 
        unmap_data.pages = pages;
        unmap_data.unmap_ops = unmap;
        unmap_data.kunmap_ops = NULL;
 
-       while(!list_empty(&blkif->persistent_purge_list)) {
-               persistent_gnt = list_first_entry(&blkif->persistent_purge_list,
+       while(!list_empty(&ring->persistent_purge_list)) {
+               persistent_gnt = list_first_entry(&ring->persistent_purge_list,
                                                  struct persistent_gnt,
                                                  remove_node);
                list_del(&persistent_gnt->remove_node);
@@ -343,7 +354,7 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
                if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
                        unmap_data.count = segs_to_unmap;
                        BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
-                       put_free_pages(blkif, pages, segs_to_unmap);
+                       put_free_pages(ring, pages, segs_to_unmap);
                        segs_to_unmap = 0;
                }
                kfree(persistent_gnt);
@@ -351,11 +362,11 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
        if (segs_to_unmap > 0) {
                unmap_data.count = segs_to_unmap;
                BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
-               put_free_pages(blkif, pages, segs_to_unmap);
+               put_free_pages(ring, pages, segs_to_unmap);
        }
 }
 
-static void purge_persistent_gnt(struct xen_blkif *blkif)
+static void purge_persistent_gnt(struct xen_blkif_ring *ring)
 {
        struct persistent_gnt *persistent_gnt;
        struct rb_node *n;
@@ -363,23 +374,23 @@ static void purge_persistent_gnt(struct xen_blkif *blkif)
        bool scan_used = false, clean_used = false;
        struct rb_root *root;
 
-       if (blkif->persistent_gnt_c < xen_blkif_max_pgrants ||
-           (blkif->persistent_gnt_c == xen_blkif_max_pgrants &&
-           !blkif->vbd.overflow_max_grants)) {
-               return;
+       if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
+           (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
+           !ring->blkif->vbd.overflow_max_grants)) {
+               goto out;
        }
 
-       if (work_busy(&blkif->persistent_purge_work)) {
+       if (work_busy(&ring->persistent_purge_work)) {
                pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
-               return;
+               goto out;
        }
 
        num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
-       num_clean = blkif->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
-       num_clean = min(blkif->persistent_gnt_c, num_clean);
+       num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
+       num_clean = min(ring->persistent_gnt_c, num_clean);
        if ((num_clean == 0) ||
-           (num_clean > (blkif->persistent_gnt_c - atomic_read(&blkif->persistent_gnt_in_use))))
-               return;
+           (num_clean > (ring->persistent_gnt_c - atomic_read(&ring->persistent_gnt_in_use))))
+               goto out;
 
        /*
         * At this point, we can assure that there will be no calls
@@ -394,8 +405,8 @@ static void purge_persistent_gnt(struct xen_blkif *blkif)
 
        pr_debug("Going to purge %u persistent grants\n", num_clean);
 
-       BUG_ON(!list_empty(&blkif->persistent_purge_list));
-       root = &blkif->persistent_gnts;
+       BUG_ON(!list_empty(&ring->persistent_purge_list));
+       root = &ring->persistent_gnts;
 purge_list:
        foreach_grant_safe(persistent_gnt, n, root, node) {
                BUG_ON(persistent_gnt->handle ==
@@ -414,7 +425,7 @@ purge_list:
 
                rb_erase(&persistent_gnt->node, root);
                list_add(&persistent_gnt->remove_node,
-                        &blkif->persistent_purge_list);
+                        &ring->persistent_purge_list);
                if (--num_clean == 0)
                        goto finished;
        }
@@ -435,30 +446,32 @@ finished:
                goto purge_list;
        }
 
-       blkif->persistent_gnt_c -= (total - num_clean);
-       blkif->vbd.overflow_max_grants = 0;
+       ring->persistent_gnt_c -= (total - num_clean);
+       ring->blkif->vbd.overflow_max_grants = 0;
 
        /* We can defer this work */
-       schedule_work(&blkif->persistent_purge_work);
+       schedule_work(&ring->persistent_purge_work);
        pr_debug("Purged %u/%u\n", (total - num_clean), total);
+
+out:
        return;
 }
 
 /*
  * Retrieve from the 'pending_reqs' a free pending_req structure to be used.
  */
-static struct pending_req *alloc_req(struct xen_blkif *blkif)
+static struct pending_req *alloc_req(struct xen_blkif_ring *ring)
 {
        struct pending_req *req = NULL;
        unsigned long flags;
 
-       spin_lock_irqsave(&blkif->pending_free_lock, flags);
-       if (!list_empty(&blkif->pending_free)) {
-               req = list_entry(blkif->pending_free.next, struct pending_req,
+       spin_lock_irqsave(&ring->pending_free_lock, flags);
+       if (!list_empty(&ring->pending_free)) {
+               req = list_entry(ring->pending_free.next, struct pending_req,
                                 free_list);
                list_del(&req->free_list);
        }
-       spin_unlock_irqrestore(&blkif->pending_free_lock, flags);
+       spin_unlock_irqrestore(&ring->pending_free_lock, flags);
        return req;
 }
 
@@ -466,17 +479,17 @@ static struct pending_req *alloc_req(struct xen_blkif *blkif)
  * Return the 'pending_req' structure back to the freepool. We also
  * wake up the thread if it was waiting for a free page.
  */
-static void free_req(struct xen_blkif *blkif, struct pending_req *req)
+static void free_req(struct xen_blkif_ring *ring, struct pending_req *req)
 {
        unsigned long flags;
        int was_empty;
 
-       spin_lock_irqsave(&blkif->pending_free_lock, flags);
-       was_empty = list_empty(&blkif->pending_free);
-       list_add(&req->free_list, &blkif->pending_free);
-       spin_unlock_irqrestore(&blkif->pending_free_lock, flags);
+       spin_lock_irqsave(&ring->pending_free_lock, flags);
+       was_empty = list_empty(&ring->pending_free);
+       list_add(&req->free_list, &ring->pending_free);
+       spin_unlock_irqrestore(&ring->pending_free_lock, flags);
        if (was_empty)
-               wake_up(&blkif->pending_free_wq);
+               wake_up(&ring->pending_free_wq);
 }
 
 /*
@@ -556,10 +569,10 @@ abort:
 /*
  * Notification from the guest OS.
  */
-static void blkif_notify_work(struct xen_blkif *blkif)
+static void blkif_notify_work(struct xen_blkif_ring *ring)
 {
-       blkif->waiting_reqs = 1;
-       wake_up(&blkif->wq);
+       ring->waiting_reqs = 1;
+       wake_up(&ring->wq);
 }
 
 irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
@@ -572,31 +585,33 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
  * SCHEDULER FUNCTIONS
  */
 
-static void print_stats(struct xen_blkif *blkif)
+static void print_stats(struct xen_blkif_ring *ring)
 {
        pr_info("(%s): oo %3llu  |  rd %4llu  |  wr %4llu  |  f %4llu"
                 "  |  ds %4llu | pg: %4u/%4d\n",
-                current->comm, blkif->st_oo_req,
-                blkif->st_rd_req, blkif->st_wr_req,
-                blkif->st_f_req, blkif->st_ds_req,
-                blkif->persistent_gnt_c,
+                current->comm, ring->st_oo_req,
+                ring->st_rd_req, ring->st_wr_req,
+                ring->st_f_req, ring->st_ds_req,
+                ring->persistent_gnt_c,
                 xen_blkif_max_pgrants);
-       blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
-       blkif->st_rd_req = 0;
-       blkif->st_wr_req = 0;
-       blkif->st_oo_req = 0;
-       blkif->st_ds_req = 0;
+       ring->st_print = jiffies + msecs_to_jiffies(10 * 1000);
+       ring->st_rd_req = 0;
+       ring->st_wr_req = 0;
+       ring->st_oo_req = 0;
+       ring->st_ds_req = 0;
 }
 
 int xen_blkif_schedule(void *arg)
 {
-       struct xen_blkif *blkif = arg;
+       struct xen_blkif_ring *ring = arg;
+       struct xen_blkif *blkif = ring->blkif;
        struct xen_vbd *vbd = &blkif->vbd;
        unsigned long timeout;
        int ret;
 
        xen_blkif_get(blkif);
 
+       set_freezable();
        while (!kthread_should_stop()) {
                if (try_to_freeze())
                        continue;
@@ -606,50 +621,50 @@ int xen_blkif_schedule(void *arg)
                timeout = msecs_to_jiffies(LRU_INTERVAL);
 
                timeout = wait_event_interruptible_timeout(
-                       blkif->wq,
-                       blkif->waiting_reqs || kthread_should_stop(),
+                       ring->wq,
+                       ring->waiting_reqs || kthread_should_stop(),
                        timeout);
                if (timeout == 0)
                        goto purge_gnt_list;
                timeout = wait_event_interruptible_timeout(
-                       blkif->pending_free_wq,
-                       !list_empty(&blkif->pending_free) ||
+                       ring->pending_free_wq,
+                       !list_empty(&ring->pending_free) ||
                        kthread_should_stop(),
                        timeout);
                if (timeout == 0)
                        goto purge_gnt_list;
 
-               blkif->waiting_reqs = 0;
+               ring->waiting_reqs = 0;
                smp_mb(); /* clear flag *before* checking for work */
 
-               ret = do_block_io_op(blkif);
+               ret = do_block_io_op(ring);
                if (ret > 0)
-                       blkif->waiting_reqs = 1;
+                       ring->waiting_reqs = 1;
                if (ret == -EACCES)
-                       wait_event_interruptible(blkif->shutdown_wq,
+                       wait_event_interruptible(ring->shutdown_wq,
                                                 kthread_should_stop());
 
 purge_gnt_list:
                if (blkif->vbd.feature_gnt_persistent &&
-                   time_after(jiffies, blkif->next_lru)) {
-                       purge_persistent_gnt(blkif);
-                       blkif->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL);
+                   time_after(jiffies, ring->next_lru)) {
+                       purge_persistent_gnt(ring);
+                       ring->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL);
                }
 
                /* Shrink if we have more than xen_blkif_max_buffer_pages */
-               shrink_free_pagepool(blkif, xen_blkif_max_buffer_pages);
+               shrink_free_pagepool(ring, xen_blkif_max_buffer_pages);
 
-               if (log_stats && time_after(jiffies, blkif->st_print))
-                       print_stats(blkif);
+               if (log_stats && time_after(jiffies, ring->st_print))
+                       print_stats(ring);
        }
 
        /* Drain pending purge work */
-       flush_work(&blkif->persistent_purge_work);
+       flush_work(&ring->persistent_purge_work);
 
        if (log_stats)
-               print_stats(blkif);
+               print_stats(ring);
 
-       blkif->xenblkd = NULL;
+       ring->xenblkd = NULL;
        xen_blkif_put(blkif);
 
        return 0;
@@ -658,22 +673,22 @@ purge_gnt_list:
 /*
  * Remove persistent grants and empty the pool of free pages
  */
-void xen_blkbk_free_caches(struct xen_blkif *blkif)
+void xen_blkbk_free_caches(struct xen_blkif_ring *ring)
 {
        /* Free all persistent grant pages */
-       if (!RB_EMPTY_ROOT(&blkif->persistent_gnts))
-               free_persistent_gnts(blkif, &blkif->persistent_gnts,
-                       blkif->persistent_gnt_c);
+       if (!RB_EMPTY_ROOT(&ring->persistent_gnts))
+               free_persistent_gnts(ring, &ring->persistent_gnts,
+                       ring->persistent_gnt_c);
 
-       BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts));
-       blkif->persistent_gnt_c = 0;
+       BUG_ON(!RB_EMPTY_ROOT(&ring->persistent_gnts));
+       ring->persistent_gnt_c = 0;
 
        /* Since we are shutting down remove all pages from the buffer */
-       shrink_free_pagepool(blkif, 0 /* All */);
+       shrink_free_pagepool(ring, 0 /* All */);
 }
 
 static unsigned int xen_blkbk_unmap_prepare(
-       struct xen_blkif *blkif,
+       struct xen_blkif_ring *ring,
        struct grant_page **pages,
        unsigned int num,
        struct gnttab_unmap_grant_ref *unmap_ops,
@@ -683,7 +698,7 @@ static unsigned int xen_blkbk_unmap_prepare(
 
        for (i = 0; i < num; i++) {
                if (pages[i]->persistent_gnt != NULL) {
-                       put_persistent_gnt(blkif, pages[i]->persistent_gnt);
+                       put_persistent_gnt(ring, pages[i]->persistent_gnt);
                        continue;
                }
                if (pages[i]->handle == BLKBACK_INVALID_HANDLE)
@@ -700,17 +715,18 @@ static unsigned int xen_blkbk_unmap_prepare(
 
 static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_queue_data *data)
 {
-       struct pending_req* pending_req = (struct pending_req*) (data->data);
-       struct xen_blkif *blkif = pending_req->blkif;
+       struct pending_req *pending_req = (struct pending_req *)(data->data);
+       struct xen_blkif_ring *ring = pending_req->ring;
+       struct xen_blkif *blkif = ring->blkif;
 
        /* BUG_ON used to reproduce existing behaviour,
           but is this the best way to deal with this? */
        BUG_ON(result);
 
-       put_free_pages(blkif, data->pages, data->count);
-       make_response(blkif, pending_req->id,
+       put_free_pages(ring, data->pages, data->count);
+       make_response(ring, pending_req->id,
                      pending_req->operation, pending_req->status);
-       free_req(blkif, pending_req);
+       free_req(ring, pending_req);
        /*
         * Make sure the request is freed before releasing blkif,
         * or there could be a race between free_req and the
@@ -723,7 +739,7 @@ static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_
         * pending_free_wq if there's a drain going on, but it has
         * to be taken into account if the current model is changed.
         */
-       if (atomic_dec_and_test(&blkif->inflight) && atomic_read(&blkif->drain)) {
+       if (atomic_dec_and_test(&ring->inflight) && atomic_read(&blkif->drain)) {
                complete(&blkif->drain_complete);
        }
        xen_blkif_put(blkif);
@@ -732,11 +748,11 @@ static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_
 static void xen_blkbk_unmap_and_respond(struct pending_req *req)
 {
        struct gntab_unmap_queue_data* work = &req->gnttab_unmap_data;
-       struct xen_blkif *blkif = req->blkif;
+       struct xen_blkif_ring *ring = req->ring;
        struct grant_page **pages = req->segments;
        unsigned int invcount;
 
-       invcount = xen_blkbk_unmap_prepare(blkif, pages, req->nr_segs,
+       invcount = xen_blkbk_unmap_prepare(ring, pages, req->nr_segs,
                                           req->unmap, req->unmap_pages);
 
        work->data = req;
@@ -757,7 +773,7 @@ static void xen_blkbk_unmap_and_respond(struct pending_req *req)
  * of hypercalls, but since this is only used in error paths there's
  * no real need.
  */
-static void xen_blkbk_unmap(struct xen_blkif *blkif,
+static void xen_blkbk_unmap(struct xen_blkif_ring *ring,
                             struct grant_page *pages[],
                             int num)
 {
@@ -768,20 +784,20 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif,
 
        while (num) {
                unsigned int batch = min(num, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-               
-               invcount = xen_blkbk_unmap_prepare(blkif, pages, batch,
+
+               invcount = xen_blkbk_unmap_prepare(ring, pages, batch,
                                                   unmap, unmap_pages);
                if (invcount) {
                        ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount);
                        BUG_ON(ret);
-                       put_free_pages(blkif, unmap_pages, invcount);
+                       put_free_pages(ring, unmap_pages, invcount);
                }
                pages += batch;
                num -= batch;
        }
 }
 
-static int xen_blkbk_map(struct xen_blkif *blkif,
+static int xen_blkbk_map(struct xen_blkif_ring *ring,
                         struct grant_page *pages[],
                         int num, bool ro)
 {
@@ -794,6 +810,7 @@ static int xen_blkbk_map(struct xen_blkif *blkif,
        int ret = 0;
        int last_map = 0, map_until = 0;
        int use_persistent_gnts;
+       struct xen_blkif *blkif = ring->blkif;
 
        use_persistent_gnts = (blkif->vbd.feature_gnt_persistent);
 
@@ -806,10 +823,11 @@ again:
        for (i = map_until; i < num; i++) {
                uint32_t flags;
 
-               if (use_persistent_gnts)
+               if (use_persistent_gnts) {
                        persistent_gnt = get_persistent_gnt(
-                               blkif,
+                               ring,
                                pages[i]->gref);
+               }
 
                if (persistent_gnt) {
                        /*
@@ -819,7 +837,7 @@ again:
                        pages[i]->page = persistent_gnt->page;
                        pages[i]->persistent_gnt = persistent_gnt;
                } else {
-                       if (get_free_page(blkif, &pages[i]->page))
+                       if (get_free_page(ring, &pages[i]->page))
                                goto out_of_memory;
                        addr = vaddr(pages[i]->page);
                        pages_to_gnt[segs_to_map] = pages[i]->page;
@@ -852,7 +870,7 @@ again:
                        BUG_ON(new_map_idx >= segs_to_map);
                        if (unlikely(map[new_map_idx].status != 0)) {
                                pr_debug("invalid buffer -- could not remap it\n");
-                               put_free_pages(blkif, &pages[seg_idx]->page, 1);
+                               put_free_pages(ring, &pages[seg_idx]->page, 1);
                                pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE;
                                ret |= 1;
                                goto next;
@@ -862,7 +880,7 @@ again:
                        continue;
                }
                if (use_persistent_gnts &&
-                   blkif->persistent_gnt_c < xen_blkif_max_pgrants) {
+                   ring->persistent_gnt_c < xen_blkif_max_pgrants) {
                        /*
                         * We are using persistent grants, the grant is
                         * not mapped but we might have room for it.
@@ -880,7 +898,7 @@ again:
                        persistent_gnt->gnt = map[new_map_idx].ref;
                        persistent_gnt->handle = map[new_map_idx].handle;
                        persistent_gnt->page = pages[seg_idx]->page;
-                       if (add_persistent_gnt(blkif,
+                       if (add_persistent_gnt(ring,
                                               persistent_gnt)) {
                                kfree(persistent_gnt);
                                persistent_gnt = NULL;
@@ -888,7 +906,7 @@ again:
                        }
                        pages[seg_idx]->persistent_gnt = persistent_gnt;
                        pr_debug("grant %u added to the tree of persistent grants, using %u/%u\n",
-                                persistent_gnt->gnt, blkif->persistent_gnt_c,
+                                persistent_gnt->gnt, ring->persistent_gnt_c,
                                 xen_blkif_max_pgrants);
                        goto next;
                }
@@ -913,7 +931,7 @@ next:
 
 out_of_memory:
        pr_alert("%s: out of memory\n", __func__);
-       put_free_pages(blkif, pages_to_gnt, segs_to_map);
+       put_free_pages(ring, pages_to_gnt, segs_to_map);
        return -ENOMEM;
 }
 
@@ -921,7 +939,7 @@ static int xen_blkbk_map_seg(struct pending_req *pending_req)
 {
        int rc;
 
-       rc = xen_blkbk_map(pending_req->blkif, pending_req->segments,
+       rc = xen_blkbk_map(pending_req->ring, pending_req->segments,
                           pending_req->nr_segs,
                           (pending_req->operation != BLKIF_OP_READ));
 
@@ -934,7 +952,7 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
                                    struct phys_req *preq)
 {
        struct grant_page **pages = pending_req->indirect_pages;
-       struct xen_blkif *blkif = pending_req->blkif;
+       struct xen_blkif_ring *ring = pending_req->ring;
        int indirect_grefs, rc, n, nseg, i;
        struct blkif_request_segment *segments = NULL;
 
@@ -945,7 +963,7 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
        for (i = 0; i < indirect_grefs; i++)
                pages[i]->gref = req->u.indirect.indirect_grefs[i];
 
-       rc = xen_blkbk_map(blkif, pages, indirect_grefs, true);
+       rc = xen_blkbk_map(ring, pages, indirect_grefs, true);
        if (rc)
                goto unmap;
 
@@ -977,15 +995,16 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
 unmap:
        if (segments)
                kunmap_atomic(segments);
-       xen_blkbk_unmap(blkif, pages, indirect_grefs);
+       xen_blkbk_unmap(ring, pages, indirect_grefs);
        return rc;
 }
 
-static int dispatch_discard_io(struct xen_blkif *blkif,
+static int dispatch_discard_io(struct xen_blkif_ring *ring,
                                struct blkif_request *req)
 {
        int err = 0;
        int status = BLKIF_RSP_OKAY;
+       struct xen_blkif *blkif = ring->blkif;
        struct block_device *bdev = blkif->vbd.bdev;
        unsigned long secure;
        struct phys_req preq;
@@ -1002,7 +1021,7 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
                        preq.sector_number + preq.nr_sects, blkif->vbd.pdevice);
                goto fail_response;
        }
-       blkif->st_ds_req++;
+       ring->st_ds_req++;
 
        secure = (blkif->vbd.discard_secure &&
                 (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
@@ -1018,26 +1037,28 @@ fail_response:
        } else if (err)
                status = BLKIF_RSP_ERROR;
 
-       make_response(blkif, req->u.discard.id, req->operation, status);
+       make_response(ring, req->u.discard.id, req->operation, status);
        xen_blkif_put(blkif);
        return err;
 }
 
-static int dispatch_other_io(struct xen_blkif *blkif,
+static int dispatch_other_io(struct xen_blkif_ring *ring,
                             struct blkif_request *req,
                             struct pending_req *pending_req)
 {
-       free_req(blkif, pending_req);
-       make_response(blkif, req->u.other.id, req->operation,
+       free_req(ring, pending_req);
+       make_response(ring, req->u.other.id, req->operation,
                      BLKIF_RSP_EOPNOTSUPP);
        return -EIO;
 }
 
-static void xen_blk_drain_io(struct xen_blkif *blkif)
+static void xen_blk_drain_io(struct xen_blkif_ring *ring)
 {
+       struct xen_blkif *blkif = ring->blkif;
+
        atomic_set(&blkif->drain, 1);
        do {
-               if (atomic_read(&blkif->inflight) == 0)
+               if (atomic_read(&ring->inflight) == 0)
                        break;
                wait_for_completion_interruptible_timeout(
                                &blkif->drain_complete, HZ);
@@ -1058,12 +1079,12 @@ static void __end_block_io_op(struct pending_req *pending_req, int error)
        if ((pending_req->operation == BLKIF_OP_FLUSH_DISKCACHE) &&
            (error == -EOPNOTSUPP)) {
                pr_debug("flush diskcache op failed, not supported\n");
-               xen_blkbk_flush_diskcache(XBT_NIL, pending_req->blkif->be, 0);
+               xen_blkbk_flush_diskcache(XBT_NIL, pending_req->ring->blkif->be, 0);
                pending_req->status = BLKIF_RSP_EOPNOTSUPP;
        } else if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) &&
                    (error == -EOPNOTSUPP)) {
                pr_debug("write barrier op failed, not supported\n");
-               xen_blkbk_barrier(XBT_NIL, pending_req->blkif->be, 0);
+               xen_blkbk_barrier(XBT_NIL, pending_req->ring->blkif->be, 0);
                pending_req->status = BLKIF_RSP_EOPNOTSUPP;
        } else if (error) {
                pr_debug("Buffer not up-to-date at end of operation,"
@@ -1097,9 +1118,9 @@ static void end_block_io_op(struct bio *bio)
  * and transmute  it to the block API to hand it over to the proper block disk.
  */
 static int
-__do_block_io_op(struct xen_blkif *blkif)
+__do_block_io_op(struct xen_blkif_ring *ring)
 {
-       union blkif_back_rings *blk_rings = &blkif->blk_rings;
+       union blkif_back_rings *blk_rings = &ring->blk_rings;
        struct blkif_request req;
        struct pending_req *pending_req;
        RING_IDX rc, rp;
@@ -1112,7 +1133,7 @@ __do_block_io_op(struct xen_blkif *blkif)
        if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) {
                rc = blk_rings->common.rsp_prod_pvt;
                pr_warn("Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n",
-                       rp, rc, rp - rc, blkif->vbd.pdevice);
+                       rp, rc, rp - rc, ring->blkif->vbd.pdevice);
                return -EACCES;
        }
        while (rc != rp) {
@@ -1125,14 +1146,14 @@ __do_block_io_op(struct xen_blkif *blkif)
                        break;
                }
 
-               pending_req = alloc_req(blkif);
+               pending_req = alloc_req(ring);
                if (NULL == pending_req) {
-                       blkif->st_oo_req++;
+                       ring->st_oo_req++;
                        more_to_do = 1;
                        break;
                }
 
-               switch (blkif->blk_protocol) {
+               switch (ring->blkif->blk_protocol) {
                case BLKIF_PROTOCOL_NATIVE:
                        memcpy(&req, RING_GET_REQUEST(&blk_rings->native, rc), sizeof(req));
                        break;
@@ -1156,16 +1177,16 @@ __do_block_io_op(struct xen_blkif *blkif)
                case BLKIF_OP_WRITE_BARRIER:
                case BLKIF_OP_FLUSH_DISKCACHE:
                case BLKIF_OP_INDIRECT:
-                       if (dispatch_rw_block_io(blkif, &req, pending_req))
+                       if (dispatch_rw_block_io(ring, &req, pending_req))
                                goto done;
                        break;
                case BLKIF_OP_DISCARD:
-                       free_req(blkif, pending_req);
-                       if (dispatch_discard_io(blkif, &req))
+                       free_req(ring, pending_req);
+                       if (dispatch_discard_io(ring, &req))
                                goto done;
                        break;
                default:
-                       if (dispatch_other_io(blkif, &req, pending_req))
+                       if (dispatch_other_io(ring, &req, pending_req))
                                goto done;
                        break;
                }
@@ -1178,13 +1199,13 @@ done:
 }
 
 static int
-do_block_io_op(struct xen_blkif *blkif)
+do_block_io_op(struct xen_blkif_ring *ring)
 {
-       union blkif_back_rings *blk_rings = &blkif->blk_rings;
+       union blkif_back_rings *blk_rings = &ring->blk_rings;
        int more_to_do;
 
        do {
-               more_to_do = __do_block_io_op(blkif);
+               more_to_do = __do_block_io_op(ring);
                if (more_to_do)
                        break;
 
@@ -1197,7 +1218,7 @@ do_block_io_op(struct xen_blkif *blkif)
  * Transmutation of the 'struct blkif_request' to a proper 'struct bio'
  * and call the 'submit_bio' to pass it to the underlying storage.
  */
-static int dispatch_rw_block_io(struct xen_blkif *blkif,
+static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
                                struct blkif_request *req,
                                struct pending_req *pending_req)
 {
@@ -1225,17 +1246,17 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
        switch (req_operation) {
        case BLKIF_OP_READ:
-               blkif->st_rd_req++;
+               ring->st_rd_req++;
                operation = READ;
                break;
        case BLKIF_OP_WRITE:
-               blkif->st_wr_req++;
+               ring->st_wr_req++;
                operation = WRITE_ODIRECT;
                break;
        case BLKIF_OP_WRITE_BARRIER:
                drain = true;
        case BLKIF_OP_FLUSH_DISKCACHE:
-               blkif->st_f_req++;
+               ring->st_f_req++;
                operation = WRITE_FLUSH;
                break;
        default:
@@ -1260,7 +1281,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
        preq.nr_sects      = 0;
 
-       pending_req->blkif     = blkif;
+       pending_req->ring      = ring;
        pending_req->id        = req->u.rw.id;
        pending_req->operation = req_operation;
        pending_req->status    = BLKIF_RSP_OKAY;
@@ -1287,12 +1308,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                        goto fail_response;
        }
 
-       if (xen_vbd_translate(&preq, blkif, operation) != 0) {
+       if (xen_vbd_translate(&preq, ring->blkif, operation) != 0) {
                pr_debug("access denied: %s of [%llu,%llu] on dev=%04x\n",
                         operation == READ ? "read" : "write",
                         preq.sector_number,
                         preq.sector_number + preq.nr_sects,
-                        blkif->vbd.pdevice);
+                        ring->blkif->vbd.pdevice);
                goto fail_response;
        }
 
@@ -1304,7 +1325,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                if (((int)preq.sector_number|(int)seg[i].nsec) &
                    ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) {
                        pr_debug("Misaligned I/O request from domain %d\n",
-                                blkif->domid);
+                                ring->blkif->domid);
                        goto fail_response;
                }
        }
@@ -1313,7 +1334,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
         * issue the WRITE_FLUSH.
         */
        if (drain)
-               xen_blk_drain_io(pending_req->blkif);
+               xen_blk_drain_io(pending_req->ring);
 
        /*
         * If we have failed at this point, we need to undo the M2P override,
@@ -1328,8 +1349,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
         * This corresponding xen_blkif_put is done in __end_block_io_op, or
         * below (in "!bio") if we are handling a BLKIF_OP_DISCARD.
         */
-       xen_blkif_get(blkif);
-       atomic_inc(&blkif->inflight);
+       xen_blkif_get(ring->blkif);
+       atomic_inc(&ring->inflight);
 
        for (i = 0; i < nseg; i++) {
                while ((bio == NULL) ||
@@ -1377,19 +1398,19 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
        blk_finish_plug(&plug);
 
        if (operation == READ)
-               blkif->st_rd_sect += preq.nr_sects;
+               ring->st_rd_sect += preq.nr_sects;
        else if (operation & WRITE)
-               blkif->st_wr_sect += preq.nr_sects;
+               ring->st_wr_sect += preq.nr_sects;
 
        return 0;
 
  fail_flush:
-       xen_blkbk_unmap(blkif, pending_req->segments,
+       xen_blkbk_unmap(ring, pending_req->segments,
                        pending_req->nr_segs);
  fail_response:
        /* Haven't submitted any bio's yet. */
-       make_response(blkif, req->u.rw.id, req_operation, BLKIF_RSP_ERROR);
-       free_req(blkif, pending_req);
+       make_response(ring, req->u.rw.id, req_operation, BLKIF_RSP_ERROR);
+       free_req(ring, pending_req);
        msleep(1); /* back off a bit */
        return -EIO;
 
@@ -1407,21 +1428,22 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 /*
  * Put a response on the ring on how the operation fared.
  */
-static void make_response(struct xen_blkif *blkif, u64 id,
+static void make_response(struct xen_blkif_ring *ring, u64 id,
                          unsigned short op, int st)
 {
        struct blkif_response  resp;
        unsigned long     flags;
-       union blkif_back_rings *blk_rings = &blkif->blk_rings;
+       union blkif_back_rings *blk_rings;
        int notify;
 
        resp.id        = id;
        resp.operation = op;
        resp.status    = st;
 
-       spin_lock_irqsave(&blkif->blk_ring_lock, flags);
+       spin_lock_irqsave(&ring->blk_ring_lock, flags);
+       blk_rings = &ring->blk_rings;
        /* Place on the response ring for the relevant domain. */
-       switch (blkif->blk_protocol) {
+       switch (ring->blkif->blk_protocol) {
        case BLKIF_PROTOCOL_NATIVE:
                memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt),
                       &resp, sizeof(resp));
@@ -1439,9 +1461,9 @@ static void make_response(struct xen_blkif *blkif, u64 id,
        }
        blk_rings->common.rsp_prod_pvt++;
        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify);
-       spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
+       spin_unlock_irqrestore(&ring->blk_ring_lock, flags);
        if (notify)
-               notify_remote_via_irq(blkif->irq);
+               notify_remote_via_irq(ring->irq);
 }
 
 static int __init xen_blkif_init(void)
@@ -1457,6 +1479,9 @@ static int __init xen_blkif_init(void)
                xen_blkif_max_ring_order = XENBUS_MAX_RING_GRANT_ORDER;
        }
 
+       if (xenblk_max_queues == 0)
+               xenblk_max_queues = num_online_cpus();
+
        rc = xen_blkif_interface_init();
        if (rc)
                goto failed_init;
index c929ae2..dea61f6 100644 (file)
@@ -46,6 +46,7 @@
 #include <xen/interface/io/protocols.h>
 
 extern unsigned int xen_blkif_max_ring_order;
+extern unsigned int xenblk_max_queues;
 /*
  * This is the maximum number of segments that would be allowed in indirect
  * requests. This value will also be passed to the frontend.
@@ -269,68 +270,79 @@ struct persistent_gnt {
        struct list_head remove_node;
 };
 
-struct xen_blkif {
-       /* Unique identifier for this interface. */
-       domid_t                 domid;
-       unsigned int            handle;
+/* Per-ring information. */
+struct xen_blkif_ring {
        /* Physical parameters of the comms window. */
        unsigned int            irq;
-       /* Comms information. */
-       enum blkif_protocol     blk_protocol;
        union blkif_back_rings  blk_rings;
        void                    *blk_ring;
-       /* The VBD attached to this interface. */
-       struct xen_vbd          vbd;
-       /* Back pointer to the backend_info. */
-       struct backend_info     *be;
        /* Private fields. */
        spinlock_t              blk_ring_lock;
-       atomic_t                refcnt;
 
        wait_queue_head_t       wq;
-       /* for barrier (drain) requests */
-       struct completion       drain_complete;
-       atomic_t                drain;
        atomic_t                inflight;
-       /* One thread per one blkif. */
+       /* One thread per blkif ring. */
        struct task_struct      *xenblkd;
        unsigned int            waiting_reqs;
 
-       /* tree to store persistent grants */
+       /* List of all 'pending_req' available */
+       struct list_head        pending_free;
+       /* And its spinlock. */
+       spinlock_t              pending_free_lock;
+       wait_queue_head_t       pending_free_wq;
+
+       /* Tree to store persistent grants. */
+       spinlock_t              pers_gnts_lock;
        struct rb_root          persistent_gnts;
        unsigned int            persistent_gnt_c;
        atomic_t                persistent_gnt_in_use;
        unsigned long           next_lru;
 
-       /* used by the kworker that offload work from the persistent purge */
+       /* Statistics. */
+       unsigned long           st_print;
+       unsigned long long      st_rd_req;
+       unsigned long long      st_wr_req;
+       unsigned long long      st_oo_req;
+       unsigned long long      st_f_req;
+       unsigned long long      st_ds_req;
+       unsigned long long      st_rd_sect;
+       unsigned long long      st_wr_sect;
+
+       /* Used by the kworker that offload work from the persistent purge. */
        struct list_head        persistent_purge_list;
        struct work_struct      persistent_purge_work;
 
-       /* buffer of free pages to map grant refs */
+       /* Buffer of free pages to map grant refs. */
        spinlock_t              free_pages_lock;
        int                     free_pages_num;
        struct list_head        free_pages;
 
-       /* List of all 'pending_req' available */
-       struct list_head        pending_free;
-       /* And its spinlock. */
-       spinlock_t              pending_free_lock;
-       wait_queue_head_t       pending_free_wq;
-
-       /* statistics */
-       unsigned long           st_print;
-       unsigned long long                      st_rd_req;
-       unsigned long long                      st_wr_req;
-       unsigned long long                      st_oo_req;
-       unsigned long long                      st_f_req;
-       unsigned long long                      st_ds_req;
-       unsigned long long                      st_rd_sect;
-       unsigned long long                      st_wr_sect;
-
        struct work_struct      free_work;
        /* Thread shutdown wait queue. */
        wait_queue_head_t       shutdown_wq;
-       unsigned int nr_ring_pages;
+       struct xen_blkif        *blkif;
+};
+
+struct xen_blkif {
+       /* Unique identifier for this interface. */
+       domid_t                 domid;
+       unsigned int            handle;
+       /* Comms information. */
+       enum blkif_protocol     blk_protocol;
+       /* The VBD attached to this interface. */
+       struct xen_vbd          vbd;
+       /* Back pointer to the backend_info. */
+       struct backend_info     *be;
+       atomic_t                refcnt;
+       /* for barrier (drain) requests */
+       struct completion       drain_complete;
+       atomic_t                drain;
+
+       struct work_struct      free_work;
+       unsigned int            nr_ring_pages;
+       /* All rings for this device. */
+       struct xen_blkif_ring   *rings;
+       unsigned int            nr_rings;
 };
 
 struct seg_buf {
@@ -352,7 +364,7 @@ struct grant_page {
  * response queued for it, with the saved 'id' passed back.
  */
 struct pending_req {
-       struct xen_blkif        *blkif;
+       struct xen_blkif_ring   *ring;
        u64                     id;
        int                     nr_segs;
        atomic_t                pendcnt;
@@ -394,7 +406,7 @@ int xen_blkif_xenbus_init(void);
 irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
 int xen_blkif_schedule(void *arg);
 int xen_blkif_purge_persistent(void *arg);
-void xen_blkbk_free_caches(struct xen_blkif *blkif);
+void xen_blkbk_free_caches(struct xen_blkif_ring *ring);
 
 int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
                              struct backend_info *be, int state);
index f53cff4..876763f 100644 (file)
@@ -86,9 +86,11 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
 {
        int err;
        char name[BLKBACK_NAME_LEN];
+       struct xen_blkif_ring *ring;
+       int i;
 
        /* Not ready to connect? */
-       if (!blkif->irq || !blkif->vbd.bdev)
+       if (!blkif->rings || !blkif->rings[0].irq || !blkif->vbd.bdev)
                return;
 
        /* Already connected? */
@@ -113,13 +115,55 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
        }
        invalidate_inode_pages2(blkif->vbd.bdev->bd_inode->i_mapping);
 
-       blkif->xenblkd = kthread_run(xen_blkif_schedule, blkif, "%s", name);
-       if (IS_ERR(blkif->xenblkd)) {
-               err = PTR_ERR(blkif->xenblkd);
-               blkif->xenblkd = NULL;
-               xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
-               return;
+       for (i = 0; i < blkif->nr_rings; i++) {
+               ring = &blkif->rings[i];
+               ring->xenblkd = kthread_run(xen_blkif_schedule, ring, "%s-%d", name, i);
+               if (IS_ERR(ring->xenblkd)) {
+                       err = PTR_ERR(ring->xenblkd);
+                       ring->xenblkd = NULL;
+                       xenbus_dev_fatal(blkif->be->dev, err,
+                                       "start %s-%d xenblkd", name, i);
+                       goto out;
+               }
+       }
+       return;
+
+out:
+       while (--i >= 0) {
+               ring = &blkif->rings[i];
+               kthread_stop(ring->xenblkd);
+       }
+       return;
+}
+
+static int xen_blkif_alloc_rings(struct xen_blkif *blkif)
+{
+       unsigned int r;
+
+       blkif->rings = kzalloc(blkif->nr_rings * sizeof(struct xen_blkif_ring), GFP_KERNEL);
+       if (!blkif->rings)
+               return -ENOMEM;
+
+       for (r = 0; r < blkif->nr_rings; r++) {
+               struct xen_blkif_ring *ring = &blkif->rings[r];
+
+               spin_lock_init(&ring->blk_ring_lock);
+               init_waitqueue_head(&ring->wq);
+               INIT_LIST_HEAD(&ring->pending_free);
+               INIT_LIST_HEAD(&ring->persistent_purge_list);
+               INIT_WORK(&ring->persistent_purge_work, xen_blkbk_unmap_purged_grants);
+               spin_lock_init(&ring->free_pages_lock);
+               INIT_LIST_HEAD(&ring->free_pages);
+
+               spin_lock_init(&ring->pending_free_lock);
+               init_waitqueue_head(&ring->pending_free_wq);
+               init_waitqueue_head(&ring->shutdown_wq);
+               ring->blkif = blkif;
+               ring->st_print = jiffies;
+               xen_blkif_get(blkif);
        }
+
+       return 0;
 }
 
 static struct xen_blkif *xen_blkif_alloc(domid_t domid)
@@ -133,41 +177,25 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
                return ERR_PTR(-ENOMEM);
 
        blkif->domid = domid;
-       spin_lock_init(&blkif->blk_ring_lock);
        atomic_set(&blkif->refcnt, 1);
-       init_waitqueue_head(&blkif->wq);
        init_completion(&blkif->drain_complete);
-       atomic_set(&blkif->drain, 0);
-       blkif->st_print = jiffies;
-       blkif->persistent_gnts.rb_node = NULL;
-       spin_lock_init(&blkif->free_pages_lock);
-       INIT_LIST_HEAD(&blkif->free_pages);
-       INIT_LIST_HEAD(&blkif->persistent_purge_list);
-       blkif->free_pages_num = 0;
-       atomic_set(&blkif->persistent_gnt_in_use, 0);
-       atomic_set(&blkif->inflight, 0);
-       INIT_WORK(&blkif->persistent_purge_work, xen_blkbk_unmap_purged_grants);
-
-       INIT_LIST_HEAD(&blkif->pending_free);
        INIT_WORK(&blkif->free_work, xen_blkif_deferred_free);
-       spin_lock_init(&blkif->pending_free_lock);
-       init_waitqueue_head(&blkif->pending_free_wq);
-       init_waitqueue_head(&blkif->shutdown_wq);
 
        return blkif;
 }
 
-static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
+static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref,
                         unsigned int nr_grefs, unsigned int evtchn)
 {
        int err;
+       struct xen_blkif *blkif = ring->blkif;
 
        /* Already connected through? */
-       if (blkif->irq)
+       if (ring->irq)
                return 0;
 
        err = xenbus_map_ring_valloc(blkif->be->dev, gref, nr_grefs,
-                                    &blkif->blk_ring);
+                                    &ring->blk_ring);
        if (err < 0)
                return err;
 
@@ -175,24 +203,24 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
        case BLKIF_PROTOCOL_NATIVE:
        {
                struct blkif_sring *sring;
-               sring = (struct blkif_sring *)blkif->blk_ring;
-               BACK_RING_INIT(&blkif->blk_rings.native, sring,
+               sring = (struct blkif_sring *)ring->blk_ring;
+               BACK_RING_INIT(&ring->blk_rings.native, sring,
                               XEN_PAGE_SIZE * nr_grefs);
                break;
        }
        case BLKIF_PROTOCOL_X86_32:
        {
                struct blkif_x86_32_sring *sring_x86_32;
-               sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring;
-               BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32,
+               sring_x86_32 = (struct blkif_x86_32_sring *)ring->blk_ring;
+               BACK_RING_INIT(&ring->blk_rings.x86_32, sring_x86_32,
                               XEN_PAGE_SIZE * nr_grefs);
                break;
        }
        case BLKIF_PROTOCOL_X86_64:
        {
                struct blkif_x86_64_sring *sring_x86_64;
-               sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring;
-               BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64,
+               sring_x86_64 = (struct blkif_x86_64_sring *)ring->blk_ring;
+               BACK_RING_INIT(&ring->blk_rings.x86_64, sring_x86_64,
                               XEN_PAGE_SIZE * nr_grefs);
                break;
        }
@@ -202,13 +230,13 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
 
        err = bind_interdomain_evtchn_to_irqhandler(blkif->domid, evtchn,
                                                    xen_blkif_be_int, 0,
-                                                   "blkif-backend", blkif);
+                                                   "blkif-backend", ring);
        if (err < 0) {
-               xenbus_unmap_ring_vfree(blkif->be->dev, blkif->blk_ring);
-               blkif->blk_rings.common.sring = NULL;
+               xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring);
+               ring->blk_rings.common.sring = NULL;
                return err;
        }
-       blkif->irq = err;
+       ring->irq = err;
 
        return 0;
 }
@@ -216,50 +244,69 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
 static int xen_blkif_disconnect(struct xen_blkif *blkif)
 {
        struct pending_req *req, *n;
-       int i = 0, j;
+       unsigned int j, r;
 
-       if (blkif->xenblkd) {
-               kthread_stop(blkif->xenblkd);
-               wake_up(&blkif->shutdown_wq);
-               blkif->xenblkd = NULL;
-       }
+       for (r = 0; r < blkif->nr_rings; r++) {
+               struct xen_blkif_ring *ring = &blkif->rings[r];
+               unsigned int i = 0;
 
-       /* The above kthread_stop() guarantees that at this point we
-        * don't have any discard_io or other_io requests. So, checking
-        * for inflight IO is enough.
-        */
-       if (atomic_read(&blkif->inflight) > 0)
-               return -EBUSY;
+               if (ring->xenblkd) {
+                       kthread_stop(ring->xenblkd);
+                       wake_up(&ring->shutdown_wq);
+                       ring->xenblkd = NULL;
+               }
 
-       if (blkif->irq) {
-               unbind_from_irqhandler(blkif->irq, blkif);
-               blkif->irq = 0;
-       }
+               /* The above kthread_stop() guarantees that at this point we
+                * don't have any discard_io or other_io requests. So, checking
+                * for inflight IO is enough.
+                */
+               if (atomic_read(&ring->inflight) > 0)
+                       return -EBUSY;
 
-       if (blkif->blk_rings.common.sring) {
-               xenbus_unmap_ring_vfree(blkif->be->dev, blkif->blk_ring);
-               blkif->blk_rings.common.sring = NULL;
-       }
+               if (ring->irq) {
+                       unbind_from_irqhandler(ring->irq, ring);
+                       ring->irq = 0;
+               }
 
-       /* Remove all persistent grants and the cache of ballooned pages. */
-       xen_blkbk_free_caches(blkif);
+               if (ring->blk_rings.common.sring) {
+                       xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring);
+                       ring->blk_rings.common.sring = NULL;
+               }
 
-       /* Check that there is no request in use */
-       list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) {
-               list_del(&req->free_list);
+               /* Remove all persistent grants and the cache of ballooned pages. */
+               xen_blkbk_free_caches(ring);
 
-               for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++)
-                       kfree(req->segments[j]);
+               /* Check that there is no request in use */
+               list_for_each_entry_safe(req, n, &ring->pending_free, free_list) {
+                       list_del(&req->free_list);
 
-               for (j = 0; j < MAX_INDIRECT_PAGES; j++)
-                       kfree(req->indirect_pages[j]);
+                       for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++)
+                               kfree(req->segments[j]);
 
-               kfree(req);
-               i++;
-       }
+                       for (j = 0; j < MAX_INDIRECT_PAGES; j++)
+                               kfree(req->indirect_pages[j]);
+
+                       kfree(req);
+                       i++;
+               }
 
-       WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
+               BUG_ON(atomic_read(&ring->persistent_gnt_in_use) != 0);
+               BUG_ON(!list_empty(&ring->persistent_purge_list));
+               BUG_ON(!RB_EMPTY_ROOT(&ring->persistent_gnts));
+               BUG_ON(!list_empty(&ring->free_pages));
+               BUG_ON(ring->free_pages_num != 0);
+               BUG_ON(ring->persistent_gnt_c != 0);
+               WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
+               xen_blkif_put(blkif);
+       }
        blkif->nr_ring_pages = 0;
+       /*
+        * blkif->rings was allocated in connect_ring, so we should free it in
+        * here.
+        */
+       kfree(blkif->rings);
+       blkif->rings = NULL;
+       blkif->nr_rings = 0;
 
        return 0;
 }
@@ -271,13 +318,6 @@ static void xen_blkif_free(struct xen_blkif *blkif)
        xen_vbd_free(&blkif->vbd);
 
        /* Make sure everything is drained before shutting down */
-       BUG_ON(blkif->persistent_gnt_c != 0);
-       BUG_ON(atomic_read(&blkif->persistent_gnt_in_use) != 0);
-       BUG_ON(blkif->free_pages_num != 0);
-       BUG_ON(!list_empty(&blkif->persistent_purge_list));
-       BUG_ON(!list_empty(&blkif->free_pages));
-       BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts));
-
        kmem_cache_free(xen_blkif_cachep, blkif);
 }
 
@@ -296,25 +336,38 @@ int __init xen_blkif_interface_init(void)
  *  sysfs interface for VBD I/O requests
  */
 
-#define VBD_SHOW(name, format, args...)                                        \
+#define VBD_SHOW_ALLRING(name, format)                                 \
        static ssize_t show_##name(struct device *_dev,                 \
                                   struct device_attribute *attr,       \
                                   char *buf)                           \
        {                                                               \
                struct xenbus_device *dev = to_xenbus_device(_dev);     \
                struct backend_info *be = dev_get_drvdata(&dev->dev);   \
+               struct xen_blkif *blkif = be->blkif;                    \
+               unsigned int i;                                         \
+               unsigned long long result = 0;                          \
                                                                        \
-               return sprintf(buf, format, ##args);                    \
+               if (!blkif->rings)                              \
+                       goto out;                                       \
+                                                                       \
+               for (i = 0; i < blkif->nr_rings; i++) {         \
+                       struct xen_blkif_ring *ring = &blkif->rings[i]; \
+                                                                       \
+                       result += ring->st_##name;                      \
+               }                                                       \
+                                                                       \
+out:                                                                   \
+               return sprintf(buf, format, result);                    \
        }                                                               \
        static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
 
-VBD_SHOW(oo_req,  "%llu\n", be->blkif->st_oo_req);
-VBD_SHOW(rd_req,  "%llu\n", be->blkif->st_rd_req);
-VBD_SHOW(wr_req,  "%llu\n", be->blkif->st_wr_req);
-VBD_SHOW(f_req,  "%llu\n", be->blkif->st_f_req);
-VBD_SHOW(ds_req,  "%llu\n", be->blkif->st_ds_req);
-VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect);
-VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect);
+VBD_SHOW_ALLRING(oo_req,  "%llu\n");
+VBD_SHOW_ALLRING(rd_req,  "%llu\n");
+VBD_SHOW_ALLRING(wr_req,  "%llu\n");
+VBD_SHOW_ALLRING(f_req,  "%llu\n");
+VBD_SHOW_ALLRING(ds_req,  "%llu\n");
+VBD_SHOW_ALLRING(rd_sect, "%llu\n");
+VBD_SHOW_ALLRING(wr_sect, "%llu\n");
 
 static struct attribute *xen_vbdstat_attrs[] = {
        &dev_attr_oo_req.attr,
@@ -332,6 +385,18 @@ static struct attribute_group xen_vbdstat_group = {
        .attrs = xen_vbdstat_attrs,
 };
 
+#define VBD_SHOW(name, format, args...)                                        \
+       static ssize_t show_##name(struct device *_dev,                 \
+                                  struct device_attribute *attr,       \
+                                  char *buf)                           \
+       {                                                               \
+               struct xenbus_device *dev = to_xenbus_device(_dev);     \
+               struct backend_info *be = dev_get_drvdata(&dev->dev);   \
+                                                                       \
+               return sprintf(buf, format, ##args);                    \
+       }                                                               \
+       static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
 VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
 VBD_SHOW(mode, "%s\n", be->mode);
 
@@ -440,11 +505,11 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
 
        dev_set_drvdata(&dev->dev, NULL);
 
-       if (be->blkif) {
+       if (be->blkif)
                xen_blkif_disconnect(be->blkif);
-               xen_blkif_put(be->blkif);
-       }
 
+       /* Put the reference we set in xen_blkif_alloc(). */
+       xen_blkif_put(be->blkif);
        kfree(be->mode);
        kfree(be);
        return 0;
@@ -553,6 +618,12 @@ static int xen_blkbk_probe(struct xenbus_device *dev,
                goto fail;
        }
 
+       /* Multi-queue: advertise how many queues are supported by us.*/
+       err = xenbus_printf(XBT_NIL, dev->nodename,
+                           "multi-queue-max-queues", "%u", xenblk_max_queues);
+       if (err)
+               pr_warn("Error writing multi-queue-max-queues\n");
+
        /* setup back pointer */
        be->blkif->be = be;
 
@@ -708,8 +779,14 @@ static void frontend_changed(struct xenbus_device *dev,
                }
 
                err = connect_ring(be);
-               if (err)
+               if (err) {
+                       /*
+                        * Clean up so that memory resources can be used by
+                        * other devices. connect_ring reported already error.
+                        */
+                       xen_blkif_disconnect(be->blkif);
                        break;
+               }
                xen_update_blkif_status(be->blkif);
                break;
 
@@ -825,50 +902,43 @@ again:
        xenbus_transaction_end(xbt, 1);
 }
 
-
-static int connect_ring(struct backend_info *be)
+/*
+ * Each ring may have multi pages, depends on "ring-page-order".
+ */
+static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir)
 {
-       struct xenbus_device *dev = be->dev;
        unsigned int ring_ref[XENBUS_MAX_RING_GRANTS];
-       unsigned int evtchn, nr_grefs, ring_page_order;
-       unsigned int pers_grants;
-       char protocol[64] = "";
        struct pending_req *req, *n;
        int err, i, j;
+       struct xen_blkif *blkif = ring->blkif;
+       struct xenbus_device *dev = blkif->be->dev;
+       unsigned int ring_page_order, nr_grefs, evtchn;
 
-       pr_debug("%s %s\n", __func__, dev->otherend);
-
-       err = xenbus_scanf(XBT_NIL, dev->otherend, "event-channel", "%u",
+       err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u",
                          &evtchn);
        if (err != 1) {
                err = -EINVAL;
-               xenbus_dev_fatal(dev, err, "reading %s/event-channel",
-                                dev->otherend);
+               xenbus_dev_fatal(dev, err, "reading %s/event-channel", dir);
                return err;
        }
-       pr_info("event-channel %u\n", evtchn);
 
        err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u",
                          &ring_page_order);
        if (err != 1) {
-               err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-ref",
-                                 "%u", &ring_ref[0]);
+               err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", &ring_ref[0]);
                if (err != 1) {
                        err = -EINVAL;
-                       xenbus_dev_fatal(dev, err, "reading %s/ring-ref",
-                                        dev->otherend);
+                       xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir);
                        return err;
                }
                nr_grefs = 1;
-               pr_info("%s:using single page: ring-ref %d\n", dev->otherend,
-                       ring_ref[0]);
        } else {
                unsigned int i;
 
                if (ring_page_order > xen_blkif_max_ring_order) {
                        err = -EINVAL;
                        xenbus_dev_fatal(dev, err, "%s/request %d ring page order exceed max:%d",
-                                        dev->otherend, ring_page_order,
+                                        dir, ring_page_order,
                                         xen_blkif_max_ring_order);
                        return err;
                }
@@ -878,52 +948,23 @@ static int connect_ring(struct backend_info *be)
                        char ring_ref_name[RINGREF_NAME_LEN];
 
                        snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i);
-                       err = xenbus_scanf(XBT_NIL, dev->otherend, ring_ref_name,
+                       err = xenbus_scanf(XBT_NIL, dir, ring_ref_name,
                                           "%u", &ring_ref[i]);
                        if (err != 1) {
                                err = -EINVAL;
                                xenbus_dev_fatal(dev, err, "reading %s/%s",
-                                                dev->otherend, ring_ref_name);
+                                                dir, ring_ref_name);
                                return err;
                        }
-                       pr_info("ring-ref%u: %u\n", i, ring_ref[i]);
                }
        }
-
-       be->blkif->blk_protocol = BLKIF_PROTOCOL_DEFAULT;
-       err = xenbus_gather(XBT_NIL, dev->otherend, "protocol",
-                           "%63s", protocol, NULL);
-       if (err)
-               strcpy(protocol, "unspecified, assuming default");
-       else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
-               be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
-       else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32))
-               be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32;
-       else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64))
-               be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64;
-       else {
-               xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
-               return -1;
-       }
-       err = xenbus_gather(XBT_NIL, dev->otherend,
-                           "feature-persistent", "%u",
-                           &pers_grants, NULL);
-       if (err)
-               pers_grants = 0;
-
-       be->blkif->vbd.feature_gnt_persistent = pers_grants;
-       be->blkif->vbd.overflow_max_grants = 0;
-       be->blkif->nr_ring_pages = nr_grefs;
-
-       pr_info("ring-pages:%d, event-channel %d, protocol %d (%s) %s\n",
-               nr_grefs, evtchn, be->blkif->blk_protocol, protocol,
-               pers_grants ? "persistent grants" : "");
+       blkif->nr_ring_pages = nr_grefs;
 
        for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) {
                req = kzalloc(sizeof(*req), GFP_KERNEL);
                if (!req)
                        goto fail;
-               list_add_tail(&req->free_list, &be->blkif->pending_free);
+               list_add_tail(&req->free_list, &ring->pending_free);
                for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) {
                        req->segments[j] = kzalloc(sizeof(*req->segments[0]), GFP_KERNEL);
                        if (!req->segments[j])
@@ -938,7 +979,7 @@ static int connect_ring(struct backend_info *be)
        }
 
        /* Map the shared frame, irq etc. */
-       err = xen_blkif_map(be->blkif, ring_ref, nr_grefs, evtchn);
+       err = xen_blkif_map(ring, ring_ref, nr_grefs, evtchn);
        if (err) {
                xenbus_dev_fatal(dev, err, "mapping ring-ref port %u", evtchn);
                return err;
@@ -947,7 +988,7 @@ static int connect_ring(struct backend_info *be)
        return 0;
 
 fail:
-       list_for_each_entry_safe(req, n, &be->blkif->pending_free, free_list) {
+       list_for_each_entry_safe(req, n, &ring->pending_free, free_list) {
                list_del(&req->free_list);
                for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) {
                        if (!req->segments[j])
@@ -962,6 +1003,93 @@ fail:
                kfree(req);
        }
        return -ENOMEM;
+
+}
+
+static int connect_ring(struct backend_info *be)
+{
+       struct xenbus_device *dev = be->dev;
+       unsigned int pers_grants;
+       char protocol[64] = "";
+       int err, i;
+       char *xspath;
+       size_t xspathsize;
+       const size_t xenstore_path_ext_size = 11; /* sufficient for "/queue-NNN" */
+       unsigned int requested_num_queues = 0;
+
+       pr_debug("%s %s\n", __func__, dev->otherend);
+
+       be->blkif->blk_protocol = BLKIF_PROTOCOL_DEFAULT;
+       err = xenbus_gather(XBT_NIL, dev->otherend, "protocol",
+                           "%63s", protocol, NULL);
+       if (err)
+               strcpy(protocol, "unspecified, assuming default");
+       else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
+               be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
+       else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32))
+               be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32;
+       else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64))
+               be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64;
+       else {
+               xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
+               return -ENOSYS;
+       }
+       err = xenbus_gather(XBT_NIL, dev->otherend,
+                           "feature-persistent", "%u",
+                           &pers_grants, NULL);
+       if (err)
+               pers_grants = 0;
+
+       be->blkif->vbd.feature_gnt_persistent = pers_grants;
+       be->blkif->vbd.overflow_max_grants = 0;
+
+       /*
+        * Read the number of hardware queues from frontend.
+        */
+       err = xenbus_scanf(XBT_NIL, dev->otherend, "multi-queue-num-queues",
+                          "%u", &requested_num_queues);
+       if (err < 0) {
+               requested_num_queues = 1;
+       } else {
+               if (requested_num_queues > xenblk_max_queues
+                   || requested_num_queues == 0) {
+                       /* Buggy or malicious guest. */
+                       xenbus_dev_fatal(dev, err,
+                                       "guest requested %u queues, exceeding the maximum of %u.",
+                                       requested_num_queues, xenblk_max_queues);
+                       return -ENOSYS;
+               }
+       }
+       be->blkif->nr_rings = requested_num_queues;
+       if (xen_blkif_alloc_rings(be->blkif))
+               return -ENOMEM;
+
+       pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename,
+                be->blkif->nr_rings, be->blkif->blk_protocol, protocol,
+                pers_grants ? "persistent grants" : "");
+
+       if (be->blkif->nr_rings == 1)
+               return read_per_ring_refs(&be->blkif->rings[0], dev->otherend);
+       else {
+               xspathsize = strlen(dev->otherend) + xenstore_path_ext_size;
+               xspath = kmalloc(xspathsize, GFP_KERNEL);
+               if (!xspath) {
+                       xenbus_dev_fatal(dev, -ENOMEM, "reading ring references");
+                       return -ENOMEM;
+               }
+
+               for (i = 0; i < be->blkif->nr_rings; i++) {
+                       memset(xspath, 0, xspathsize);
+                       snprintf(xspath, xspathsize, "%s/queue-%u", dev->otherend, i);
+                       err = read_per_ring_refs(&be->blkif->rings[i], xspath);
+                       if (err) {
+                               kfree(xspath);
+                               return err;
+                       }
+               }
+               kfree(xspath);
+       }
+       return 0;
 }
 
 static const struct xenbus_device_id xen_blkbk_ids[] = {
index 2fee2ee..8a8dc91 100644 (file)
 
 #include <asm/xen/hypervisor.h>
 
+/*
+ * The minimal size of segment supported by the block framework is PAGE_SIZE.
+ * When Linux is using a different page size than Xen, it may not be possible
+ * to put all the data in a single segment.
+ * This can happen when the backend doesn't support indirect descriptor and
+ * therefore the maximum amount of data that a request can carry is
+ * BLKIF_MAX_SEGMENTS_PER_REQUEST * XEN_PAGE_SIZE = 44KB
+ *
+ * Note that we only support one extra request. So the Linux page size
+ * should be <= ( 2 * BLKIF_MAX_SEGMENTS_PER_REQUEST * XEN_PAGE_SIZE) =
+ * 88KB.
+ */
+#define HAS_EXTRA_REQ (BLKIF_MAX_SEGMENTS_PER_REQUEST < XEN_PFN_PER_PAGE)
+
 enum blkif_state {
        BLKIF_STATE_DISCONNECTED,
        BLKIF_STATE_CONNECTED,
@@ -72,6 +86,13 @@ struct grant {
        struct list_head node;
 };
 
+enum blk_req_status {
+       REQ_WAITING,
+       REQ_DONE,
+       REQ_ERROR,
+       REQ_EOPNOTSUPP,
+};
+
 struct blk_shadow {
        struct blkif_request req;
        struct request *request;
@@ -79,6 +100,14 @@ struct blk_shadow {
        struct grant **indirect_grants;
        struct scatterlist *sg;
        unsigned int num_sg;
+       enum blk_req_status status;
+
+       #define NO_ASSOCIATED_ID ~0UL
+       /*
+        * Id of the sibling if we ever need 2 requests when handling a
+        * block I/O request
+        */
+       unsigned long associated_id;
 };
 
 struct split_bio {
@@ -99,6 +128,10 @@ static unsigned int xen_blkif_max_segments = 32;
 module_param_named(max, xen_blkif_max_segments, int, S_IRUGO);
 MODULE_PARM_DESC(max, "Maximum amount of segments in indirect requests (default is 32)");
 
+static unsigned int xen_blkif_max_queues = 4;
+module_param_named(max_queues, xen_blkif_max_queues, uint, S_IRUGO);
+MODULE_PARM_DESC(max_queues, "Maximum number of hardware queues/rings used per virtual disk");
+
 /*
  * Maximum order of pages to be used for the shared ring between front and
  * backend, 4KB page granularity is used.
@@ -114,10 +147,35 @@ MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the
        __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * XENBUS_MAX_RING_GRANTS)
 
 /*
- * ring-ref%i i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
- * characters are enough. Define to 20 to keep consist with backend.
+ * ring-ref%u i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
+ * characters are enough. Define to 20 to keep consistent with backend.
  */
 #define RINGREF_NAME_LEN (20)
+/*
+ * queue-%u would take 7 + 10(UINT_MAX) = 17 characters.
+ */
+#define QUEUE_NAME_LEN (17)
+
+/*
+ *  Per-ring info.
+ *  Every blkfront device can associate with one or more blkfront_ring_info,
+ *  depending on how many hardware queues/rings to be used.
+ */
+struct blkfront_ring_info {
+       /* Lock to protect data in every ring buffer. */
+       spinlock_t ring_lock;
+       struct blkif_front_ring ring;
+       unsigned int ring_ref[XENBUS_MAX_RING_GRANTS];
+       unsigned int evtchn, irq;
+       struct work_struct work;
+       struct gnttab_free_callback callback;
+       struct blk_shadow shadow[BLK_MAX_RING_SIZE];
+       struct list_head indirect_pages;
+       struct list_head grants;
+       unsigned int persistent_gnts_c;
+       unsigned long shadow_free;
+       struct blkfront_info *dev_info;
+};
 
 /*
  * We have one of these per vbd, whether ide, scsi or 'other'.  They
@@ -126,25 +184,15 @@ MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the
  */
 struct blkfront_info
 {
-       spinlock_t io_lock;
        struct mutex mutex;
        struct xenbus_device *xbdev;
        struct gendisk *gd;
        int vdevice;
        blkif_vdev_t handle;
        enum blkif_state connected;
-       int ring_ref[XENBUS_MAX_RING_GRANTS];
+       /* Number of pages per ring buffer. */
        unsigned int nr_ring_pages;
-       struct blkif_front_ring ring;
-       unsigned int evtchn, irq;
        struct request_queue *rq;
-       struct work_struct work;
-       struct gnttab_free_callback callback;
-       struct blk_shadow shadow[BLK_MAX_RING_SIZE];
-       struct list_head grants;
-       struct list_head indirect_pages;
-       unsigned int persistent_gnts_c;
-       unsigned long shadow_free;
        unsigned int feature_flush;
        unsigned int feature_discard:1;
        unsigned int feature_secdiscard:1;
@@ -155,6 +203,8 @@ struct blkfront_info
        unsigned int max_indirect_segments;
        int is_ready;
        struct blk_mq_tag_set tag_set;
+       struct blkfront_ring_info *rinfo;
+       unsigned int nr_rings;
 };
 
 static unsigned int nr_minors;
@@ -198,38 +248,40 @@ static DEFINE_SPINLOCK(minor_lock);
 
 #define GREFS(_psegs)  ((_psegs) * GRANTS_PER_PSEG)
 
-static int blkfront_setup_indirect(struct blkfront_info *info);
-static int blkfront_gather_backend_features(struct blkfront_info *info);
+static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo);
+static void blkfront_gather_backend_features(struct blkfront_info *info);
 
-static int get_id_from_freelist(struct blkfront_info *info)
+static int get_id_from_freelist(struct blkfront_ring_info *rinfo)
 {
-       unsigned long free = info->shadow_free;
-       BUG_ON(free >= BLK_RING_SIZE(info));
-       info->shadow_free = info->shadow[free].req.u.rw.id;
-       info->shadow[free].req.u.rw.id = 0x0fffffee; /* debug */
+       unsigned long free = rinfo->shadow_free;
+
+       BUG_ON(free >= BLK_RING_SIZE(rinfo->dev_info));
+       rinfo->shadow_free = rinfo->shadow[free].req.u.rw.id;
+       rinfo->shadow[free].req.u.rw.id = 0x0fffffee; /* debug */
        return free;
 }
 
-static int add_id_to_freelist(struct blkfront_info *info,
-                              unsigned long id)
+static int add_id_to_freelist(struct blkfront_ring_info *rinfo,
+                             unsigned long id)
 {
-       if (info->shadow[id].req.u.rw.id != id)
+       if (rinfo->shadow[id].req.u.rw.id != id)
                return -EINVAL;
-       if (info->shadow[id].request == NULL)
+       if (rinfo->shadow[id].request == NULL)
                return -EINVAL;
-       info->shadow[id].req.u.rw.id  = info->shadow_free;
-       info->shadow[id].request = NULL;
-       info->shadow_free = id;
+       rinfo->shadow[id].req.u.rw.id  = rinfo->shadow_free;
+       rinfo->shadow[id].request = NULL;
+       rinfo->shadow_free = id;
        return 0;
 }
 
-static int fill_grant_buffer(struct blkfront_info *info, int num)
+static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num)
 {
+       struct blkfront_info *info = rinfo->dev_info;
        struct page *granted_page;
        struct grant *gnt_list_entry, *n;
        int i = 0;
 
-       while(i < num) {
+       while (i < num) {
                gnt_list_entry = kzalloc(sizeof(struct grant), GFP_NOIO);
                if (!gnt_list_entry)
                        goto out_of_memory;
@@ -244,7 +296,7 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
                }
 
                gnt_list_entry->gref = GRANT_INVALID_REF;
-               list_add(&gnt_list_entry->node, &info->grants);
+               list_add(&gnt_list_entry->node, &rinfo->grants);
                i++;
        }
 
@@ -252,7 +304,7 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
 
 out_of_memory:
        list_for_each_entry_safe(gnt_list_entry, n,
-                                &info->grants, node) {
+                                &rinfo->grants, node) {
                list_del(&gnt_list_entry->node);
                if (info->feature_persistent)
                        __free_page(gnt_list_entry->page);
@@ -263,17 +315,17 @@ out_of_memory:
        return -ENOMEM;
 }
 
-static struct grant *get_free_grant(struct blkfront_info *info)
+static struct grant *get_free_grant(struct blkfront_ring_info *rinfo)
 {
        struct grant *gnt_list_entry;
 
-       BUG_ON(list_empty(&info->grants));
-       gnt_list_entry = list_first_entry(&info->grants, struct grant,
+       BUG_ON(list_empty(&rinfo->grants));
+       gnt_list_entry = list_first_entry(&rinfo->grants, struct grant,
                                          node);
        list_del(&gnt_list_entry->node);
 
        if (gnt_list_entry->gref != GRANT_INVALID_REF)
-               info->persistent_gnts_c--;
+               rinfo->persistent_gnts_c--;
 
        return gnt_list_entry;
 }
@@ -289,9 +341,10 @@ static inline void grant_foreign_access(const struct grant *gnt_list_entry,
 
 static struct grant *get_grant(grant_ref_t *gref_head,
                               unsigned long gfn,
-                              struct blkfront_info *info)
+                              struct blkfront_ring_info *rinfo)
 {
-       struct grant *gnt_list_entry = get_free_grant(info);
+       struct grant *gnt_list_entry = get_free_grant(rinfo);
+       struct blkfront_info *info = rinfo->dev_info;
 
        if (gnt_list_entry->gref != GRANT_INVALID_REF)
                return gnt_list_entry;
@@ -312,9 +365,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
 }
 
 static struct grant *get_indirect_grant(grant_ref_t *gref_head,
-                                       struct blkfront_info *info)
+                                       struct blkfront_ring_info *rinfo)
 {
-       struct grant *gnt_list_entry = get_free_grant(info);
+       struct grant *gnt_list_entry = get_free_grant(rinfo);
+       struct blkfront_info *info = rinfo->dev_info;
 
        if (gnt_list_entry->gref != GRANT_INVALID_REF)
                return gnt_list_entry;
@@ -326,8 +380,8 @@ static struct grant *get_indirect_grant(grant_ref_t *gref_head,
                struct page *indirect_page;
 
                /* Fetch a pre-allocated page to use for indirect grefs */
-               BUG_ON(list_empty(&info->indirect_pages));
-               indirect_page = list_first_entry(&info->indirect_pages,
+               BUG_ON(list_empty(&rinfo->indirect_pages));
+               indirect_page = list_first_entry(&rinfo->indirect_pages,
                                                 struct page, lru);
                list_del(&indirect_page->lru);
                gnt_list_entry->page = indirect_page;
@@ -403,8 +457,8 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr)
 
 static void blkif_restart_queue_callback(void *arg)
 {
-       struct blkfront_info *info = (struct blkfront_info *)arg;
-       schedule_work(&info->work);
+       struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)arg;
+       schedule_work(&rinfo->work);
 }
 
 static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
@@ -456,16 +510,33 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
        return 0;
 }
 
-static int blkif_queue_discard_req(struct request *req)
+static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
+                                           struct request *req,
+                                           struct blkif_request **ring_req)
 {
-       struct blkfront_info *info = req->rq_disk->private_data;
+       unsigned long id;
+
+       *ring_req = RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt);
+       rinfo->ring.req_prod_pvt++;
+
+       id = get_id_from_freelist(rinfo);
+       rinfo->shadow[id].request = req;
+       rinfo->shadow[id].status = REQ_WAITING;
+       rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID;
+
+       (*ring_req)->u.rw.id = id;
+
+       return id;
+}
+
+static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
+{
+       struct blkfront_info *info = rinfo->dev_info;
        struct blkif_request *ring_req;
        unsigned long id;
 
        /* Fill out a communications ring structure. */
-       ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
-       id = get_id_from_freelist(info);
-       info->shadow[id].request = req;
+       id = blkif_ring_get_request(rinfo, req, &ring_req);
 
        ring_req->operation = BLKIF_OP_DISCARD;
        ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
@@ -476,10 +547,8 @@ static int blkif_queue_discard_req(struct request *req)
        else
                ring_req->u.discard.flag = 0;
 
-       info->ring.req_prod_pvt++;
-
        /* Keep a private copy so we can reissue requests when recovering. */
-       info->shadow[id].req = *ring_req;
+       rinfo->shadow[id].req = *ring_req;
 
        return 0;
 }
@@ -487,7 +556,7 @@ static int blkif_queue_discard_req(struct request *req)
 struct setup_rw_req {
        unsigned int grant_idx;
        struct blkif_request_segment *segments;
-       struct blkfront_info *info;
+       struct blkfront_ring_info *rinfo;
        struct blkif_request *ring_req;
        grant_ref_t gref_head;
        unsigned int id;
@@ -495,6 +564,9 @@ struct setup_rw_req {
        bool need_copy;
        unsigned int bvec_off;
        char *bvec_data;
+
+       bool require_extra_req;
+       struct blkif_request *extra_ring_req;
 };
 
 static void blkif_setup_rw_req_grant(unsigned long gfn, unsigned int offset,
@@ -507,8 +579,24 @@ static void blkif_setup_rw_req_grant(unsigned long gfn, unsigned int offset,
        /* Convenient aliases */
        unsigned int grant_idx = setup->grant_idx;
        struct blkif_request *ring_req = setup->ring_req;
-       struct blkfront_info *info = setup->info;
-       struct blk_shadow *shadow = &info->shadow[setup->id];
+       struct blkfront_ring_info *rinfo = setup->rinfo;
+       /*
+        * We always use the shadow of the first request to store the list
+        * of grant associated to the block I/O request. This made the
+        * completion more easy to handle even if the block I/O request is
+        * split.
+        */
+       struct blk_shadow *shadow = &rinfo->shadow[setup->id];
+
+       if (unlikely(setup->require_extra_req &&
+                    grant_idx >= BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
+               /*
+                * We are using the second request, setup grant_idx
+                * to be the index of the segment array.
+                */
+               grant_idx -= BLKIF_MAX_SEGMENTS_PER_REQUEST;
+               ring_req = setup->extra_ring_req;
+       }
 
        if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
            (grant_idx % GRANTS_PER_INDIRECT_FRAME == 0)) {
@@ -516,15 +604,19 @@ static void blkif_setup_rw_req_grant(unsigned long gfn, unsigned int offset,
                        kunmap_atomic(setup->segments);
 
                n = grant_idx / GRANTS_PER_INDIRECT_FRAME;
-               gnt_list_entry = get_indirect_grant(&setup->gref_head, info);
+               gnt_list_entry = get_indirect_grant(&setup->gref_head, rinfo);
                shadow->indirect_grants[n] = gnt_list_entry;
                setup->segments = kmap_atomic(gnt_list_entry->page);
                ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
        }
 
-       gnt_list_entry = get_grant(&setup->gref_head, gfn, info);
+       gnt_list_entry = get_grant(&setup->gref_head, gfn, rinfo);
        ref = gnt_list_entry->gref;
-       shadow->grants_used[grant_idx] = gnt_list_entry;
+       /*
+        * All the grants are stored in the shadow of the first
+        * request. Therefore we have to use the global index.
+        */
+       shadow->grants_used[setup->grant_idx] = gnt_list_entry;
 
        if (setup->need_copy) {
                void *shared_data;
@@ -566,16 +658,36 @@ static void blkif_setup_rw_req_grant(unsigned long gfn, unsigned int offset,
        (setup->grant_idx)++;
 }
 
-static int blkif_queue_rw_req(struct request *req)
+static void blkif_setup_extra_req(struct blkif_request *first,
+                                 struct blkif_request *second)
 {
-       struct blkfront_info *info = req->rq_disk->private_data;
-       struct blkif_request *ring_req;
-       unsigned long id;
+       uint16_t nr_segments = first->u.rw.nr_segments;
+
+       /*
+        * The second request is only present when the first request uses
+        * all its segments. It's always the continuity of the first one.
+        */
+       first->u.rw.nr_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+       second->u.rw.nr_segments = nr_segments - BLKIF_MAX_SEGMENTS_PER_REQUEST;
+       second->u.rw.sector_number = first->u.rw.sector_number +
+               (BLKIF_MAX_SEGMENTS_PER_REQUEST * XEN_PAGE_SIZE) / 512;
+
+       second->u.rw.handle = first->u.rw.handle;
+       second->operation = first->operation;
+}
+
+static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *rinfo)
+{
+       struct blkfront_info *info = rinfo->dev_info;
+       struct blkif_request *ring_req, *extra_ring_req = NULL;
+       unsigned long id, extra_id = NO_ASSOCIATED_ID;
+       bool require_extra_req = false;
        int i;
        struct setup_rw_req setup = {
                .grant_idx = 0,
                .segments = NULL,
-               .info = info,
+               .rinfo = rinfo,
                .need_copy = rq_data_dir(req) && info->feature_persistent,
        };
 
@@ -584,7 +696,6 @@ static int blkif_queue_rw_req(struct request *req)
         * existing persistent grants, or if we have to get new grants,
         * as there are not sufficiently many free.
         */
-       bool new_persistent_gnts;
        struct scatterlist *sg;
        int num_sg, max_grefs, num_grant;
 
@@ -596,41 +707,36 @@ static int blkif_queue_rw_req(struct request *req)
                 */
                max_grefs += INDIRECT_GREFS(max_grefs);
 
-       /* Check if we have enough grants to allocate a requests */
-       if (info->persistent_gnts_c < max_grefs) {
-               new_persistent_gnts = 1;
-               if (gnttab_alloc_grant_references(
-                   max_grefs - info->persistent_gnts_c,
-                   &setup.gref_head) < 0) {
+       /*
+        * We have to reserve 'max_grefs' grants because persistent
+        * grants are shared by all rings.
+        */
+       if (max_grefs > 0)
+               if (gnttab_alloc_grant_references(max_grefs, &setup.gref_head) < 0) {
                        gnttab_request_free_callback(
-                               &info->callback,
+                               &rinfo->callback,
                                blkif_restart_queue_callback,
-                               info,
+                               rinfo,
                                max_grefs);
                        return 1;
                }
-       } else
-               new_persistent_gnts = 0;
 
        /* Fill out a communications ring structure. */
-       ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
-       id = get_id_from_freelist(info);
-       info->shadow[id].request = req;
-
-       BUG_ON(info->max_indirect_segments == 0 &&
-              GREFS(req->nr_phys_segments) > BLKIF_MAX_SEGMENTS_PER_REQUEST);
-       BUG_ON(info->max_indirect_segments &&
-              GREFS(req->nr_phys_segments) > info->max_indirect_segments);
+       id = blkif_ring_get_request(rinfo, req, &ring_req);
 
-       num_sg = blk_rq_map_sg(req->q, req, info->shadow[id].sg);
+       num_sg = blk_rq_map_sg(req->q, req, rinfo->shadow[id].sg);
        num_grant = 0;
        /* Calculate the number of grant used */
-       for_each_sg(info->shadow[id].sg, sg, num_sg, i)
+       for_each_sg(rinfo->shadow[id].sg, sg, num_sg, i)
               num_grant += gnttab_count_grant(sg->offset, sg->length);
 
-       ring_req->u.rw.id = id;
-       info->shadow[id].num_sg = num_sg;
-       if (num_grant > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+       require_extra_req = info->max_indirect_segments == 0 &&
+               num_grant > BLKIF_MAX_SEGMENTS_PER_REQUEST;
+       BUG_ON(!HAS_EXTRA_REQ && require_extra_req);
+
+       rinfo->shadow[id].num_sg = num_sg;
+       if (num_grant > BLKIF_MAX_SEGMENTS_PER_REQUEST &&
+           likely(!require_extra_req)) {
                /*
                 * The indirect operation can only be a BLKIF_OP_READ or
                 * BLKIF_OP_WRITE
@@ -670,11 +776,31 @@ static int blkif_queue_rw_req(struct request *req)
                        }
                }
                ring_req->u.rw.nr_segments = num_grant;
+               if (unlikely(require_extra_req)) {
+                       extra_id = blkif_ring_get_request(rinfo, req,
+                                                         &extra_ring_req);
+                       /*
+                        * Only the first request contains the scatter-gather
+                        * list.
+                        */
+                       rinfo->shadow[extra_id].num_sg = 0;
+
+                       blkif_setup_extra_req(ring_req, extra_ring_req);
+
+                       /* Link the 2 requests together */
+                       rinfo->shadow[extra_id].associated_id = id;
+                       rinfo->shadow[id].associated_id = extra_id;
+               }
        }
 
        setup.ring_req = ring_req;
        setup.id = id;
-       for_each_sg(info->shadow[id].sg, sg, num_sg, i) {
+
+       setup.require_extra_req = require_extra_req;
+       if (unlikely(require_extra_req))
+               setup.extra_ring_req = extra_ring_req;
+
+       for_each_sg(rinfo->shadow[id].sg, sg, num_sg, i) {
                BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
                if (setup.need_copy) {
@@ -694,12 +820,12 @@ static int blkif_queue_rw_req(struct request *req)
        if (setup.segments)
                kunmap_atomic(setup.segments);
 
-       info->ring.req_prod_pvt++;
-
        /* Keep a private copy so we can reissue requests when recovering. */
-       info->shadow[id].req = *ring_req;
+       rinfo->shadow[id].req = *ring_req;
+       if (unlikely(require_extra_req))
+               rinfo->shadow[extra_id].req = *extra_ring_req;
 
-       if (new_persistent_gnts)
+       if (max_grefs > 0)
                gnttab_free_grant_references(setup.gref_head);
 
        return 0;
@@ -711,27 +837,25 @@ static int blkif_queue_rw_req(struct request *req)
  *
  * @req: a request struct
  */
-static int blkif_queue_request(struct request *req)
+static int blkif_queue_request(struct request *req, struct blkfront_ring_info *rinfo)
 {
-       struct blkfront_info *info = req->rq_disk->private_data;
-
-       if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
+       if (unlikely(rinfo->dev_info->connected != BLKIF_STATE_CONNECTED))
                return 1;
 
        if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE)))
-               return blkif_queue_discard_req(req);
+               return blkif_queue_discard_req(req, rinfo);
        else
-               return blkif_queue_rw_req(req);
+               return blkif_queue_rw_req(req, rinfo);
 }
 
-static inline void flush_requests(struct blkfront_info *info)
+static inline void flush_requests(struct blkfront_ring_info *rinfo)
 {
        int notify;
 
-       RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify);
+       RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&rinfo->ring, notify);
 
        if (notify)
-               notify_remote_via_irq(info->irq);
+               notify_remote_via_irq(rinfo->irq);
 }
 
 static inline bool blkif_request_flush_invalid(struct request *req,
@@ -745,38 +869,50 @@ static inline bool blkif_request_flush_invalid(struct request *req,
 }
 
 static int blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
-                          const struct blk_mq_queue_data *qd)
+                         const struct blk_mq_queue_data *qd)
 {
-       struct blkfront_info *info = qd->rq->rq_disk->private_data;
+       unsigned long flags;
+       struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)hctx->driver_data;
 
        blk_mq_start_request(qd->rq);
-       spin_lock_irq(&info->io_lock);
-       if (RING_FULL(&info->ring))
+       spin_lock_irqsave(&rinfo->ring_lock, flags);
+       if (RING_FULL(&rinfo->ring))
                goto out_busy;
 
-       if (blkif_request_flush_invalid(qd->rq, info))
+       if (blkif_request_flush_invalid(qd->rq, rinfo->dev_info))
                goto out_err;
 
-       if (blkif_queue_request(qd->rq))
+       if (blkif_queue_request(qd->rq, rinfo))
                goto out_busy;
 
-       flush_requests(info);
-       spin_unlock_irq(&info->io_lock);
+       flush_requests(rinfo);
+       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
        return BLK_MQ_RQ_QUEUE_OK;
 
 out_err:
-       spin_unlock_irq(&info->io_lock);
+       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
        return BLK_MQ_RQ_QUEUE_ERROR;
 
 out_busy:
-       spin_unlock_irq(&info->io_lock);
+       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
        blk_mq_stop_hw_queue(hctx);
        return BLK_MQ_RQ_QUEUE_BUSY;
 }
 
+static int blk_mq_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
+                           unsigned int index)
+{
+       struct blkfront_info *info = (struct blkfront_info *)data;
+
+       BUG_ON(info->nr_rings <= index);
+       hctx->driver_data = &info->rinfo[index];
+       return 0;
+}
+
 static struct blk_mq_ops blkfront_mq_ops = {
        .queue_rq = blkif_queue_rq,
        .map_queue = blk_mq_map_queue,
+       .init_hctx = blk_mq_init_hctx,
 };
 
 static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
@@ -788,19 +924,28 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
 
        memset(&info->tag_set, 0, sizeof(info->tag_set));
        info->tag_set.ops = &blkfront_mq_ops;
-       info->tag_set.nr_hw_queues = 1;
-       info->tag_set.queue_depth =  BLK_RING_SIZE(info);
+       info->tag_set.nr_hw_queues = info->nr_rings;
+       if (HAS_EXTRA_REQ && info->max_indirect_segments == 0) {
+               /*
+                * When indirect descriptior is not supported, the I/O request
+                * will be split between multiple request in the ring.
+                * To avoid problems when sending the request, divide by
+                * 2 the depth of the queue.
+                */
+               info->tag_set.queue_depth =  BLK_RING_SIZE(info) / 2;
+       } else
+               info->tag_set.queue_depth = BLK_RING_SIZE(info);
        info->tag_set.numa_node = NUMA_NO_NODE;
        info->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE;
        info->tag_set.cmd_size = 0;
        info->tag_set.driver_data = info;
 
        if (blk_mq_alloc_tag_set(&info->tag_set))
-               return -1;
+               return -EINVAL;
        rq = blk_mq_init_queue(&info->tag_set);
        if (IS_ERR(rq)) {
                blk_mq_free_tag_set(&info->tag_set);
-               return -1;
+               return PTR_ERR(rq);
        }
 
        queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
@@ -1028,7 +1173,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
 
 static void xlvbd_release_gendisk(struct blkfront_info *info)
 {
-       unsigned int minor, nr_minors;
+       unsigned int minor, nr_minors, i;
 
        if (info->rq == NULL)
                return;
@@ -1036,11 +1181,15 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
        /* No more blkif_request(). */
        blk_mq_stop_hw_queues(info->rq);
 
-       /* No more gnttab callback work. */
-       gnttab_cancel_free_callback(&info->callback);
+       for (i = 0; i < info->nr_rings; i++) {
+               struct blkfront_ring_info *rinfo = &info->rinfo[i];
 
-       /* Flush gnttab callback work. Must be done with no locks held. */
-       flush_work(&info->work);
+               /* No more gnttab callback work. */
+               gnttab_cancel_free_callback(&rinfo->callback);
+
+               /* Flush gnttab callback work. Must be done with no locks held. */
+               flush_work(&rinfo->work);
+       }
 
        del_gendisk(info->gd);
 
@@ -1056,88 +1205,87 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
        info->gd = NULL;
 }
 
-/* Must be called with io_lock holded */
-static void kick_pending_request_queues(struct blkfront_info *info)
+/* Already hold rinfo->ring_lock. */
+static inline void kick_pending_request_queues_locked(struct blkfront_ring_info *rinfo)
 {
-       if (!RING_FULL(&info->ring))
-               blk_mq_start_stopped_hw_queues(info->rq, true);
+       if (!RING_FULL(&rinfo->ring))
+               blk_mq_start_stopped_hw_queues(rinfo->dev_info->rq, true);
 }
 
-static void blkif_restart_queue(struct work_struct *work)
+static void kick_pending_request_queues(struct blkfront_ring_info *rinfo)
 {
-       struct blkfront_info *info = container_of(work, struct blkfront_info, work);
+       unsigned long flags;
 
-       spin_lock_irq(&info->io_lock);
-       if (info->connected == BLKIF_STATE_CONNECTED)
-               kick_pending_request_queues(info);
-       spin_unlock_irq(&info->io_lock);
+       spin_lock_irqsave(&rinfo->ring_lock, flags);
+       kick_pending_request_queues_locked(rinfo);
+       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
 }
 
-static void blkif_free(struct blkfront_info *info, int suspend)
+static void blkif_restart_queue(struct work_struct *work)
 {
-       struct grant *persistent_gnt;
-       struct grant *n;
-       int i, j, segs;
+       struct blkfront_ring_info *rinfo = container_of(work, struct blkfront_ring_info, work);
 
-       /* Prevent new requests being issued until we fix things up. */
-       spin_lock_irq(&info->io_lock);
-       info->connected = suspend ?
-               BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
-       /* No more blkif_request(). */
-       if (info->rq)
-               blk_mq_stop_hw_queues(info->rq);
+       if (rinfo->dev_info->connected == BLKIF_STATE_CONNECTED)
+               kick_pending_request_queues(rinfo);
+}
 
-       /* Remove all persistent grants */
-       if (!list_empty(&info->grants)) {
-               list_for_each_entry_safe(persistent_gnt, n,
-                                        &info->grants, node) {
-                       list_del(&persistent_gnt->node);
-                       if (persistent_gnt->gref != GRANT_INVALID_REF) {
-                               gnttab_end_foreign_access(persistent_gnt->gref,
-                                                         0, 0UL);
-                               info->persistent_gnts_c--;
-                       }
-                       if (info->feature_persistent)
-                               __free_page(persistent_gnt->page);
-                       kfree(persistent_gnt);
-               }
-       }
-       BUG_ON(info->persistent_gnts_c != 0);
+static void blkif_free_ring(struct blkfront_ring_info *rinfo)
+{
+       struct grant *persistent_gnt, *n;
+       struct blkfront_info *info = rinfo->dev_info;
+       int i, j, segs;
 
        /*
         * Remove indirect pages, this only happens when using indirect
         * descriptors but not persistent grants
         */
-       if (!list_empty(&info->indirect_pages)) {
+       if (!list_empty(&rinfo->indirect_pages)) {
                struct page *indirect_page, *n;
 
                BUG_ON(info->feature_persistent);
-               list_for_each_entry_safe(indirect_page, n, &info->indirect_pages, lru) {
+               list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) {
                        list_del(&indirect_page->lru);
                        __free_page(indirect_page);
                }
        }
 
+       /* Remove all persistent grants. */
+       if (!list_empty(&rinfo->grants)) {
+               list_for_each_entry_safe(persistent_gnt, n,
+                                        &rinfo->grants, node) {
+                       list_del(&persistent_gnt->node);
+                       if (persistent_gnt->gref != GRANT_INVALID_REF) {
+                               gnttab_end_foreign_access(persistent_gnt->gref,
+                                                         0, 0UL);
+                               rinfo->persistent_gnts_c--;
+                       }
+                       if (info->feature_persistent)
+                               __free_page(persistent_gnt->page);
+                       kfree(persistent_gnt);
+               }
+       }
+       BUG_ON(rinfo->persistent_gnts_c != 0);
+
        for (i = 0; i < BLK_RING_SIZE(info); i++) {
                /*
                 * Clear persistent grants present in requests already
                 * on the shared ring
                 */
-               if (!info->shadow[i].request)
+               if (!rinfo->shadow[i].request)
                        goto free_shadow;
 
-               segs = info->shadow[i].req.operation == BLKIF_OP_INDIRECT ?
-                      info->shadow[i].req.u.indirect.nr_segments :
-                      info->shadow[i].req.u.rw.nr_segments;
+               segs = rinfo->shadow[i].req.operation == BLKIF_OP_INDIRECT ?
+                      rinfo->shadow[i].req.u.indirect.nr_segments :
+                      rinfo->shadow[i].req.u.rw.nr_segments;
                for (j = 0; j < segs; j++) {
-                       persistent_gnt = info->shadow[i].grants_used[j];
+                       persistent_gnt = rinfo->shadow[i].grants_used[j];
                        gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
                        if (info->feature_persistent)
                                __free_page(persistent_gnt->page);
                        kfree(persistent_gnt);
                }
 
-               if (info->shadow[i].req.operation != BLKIF_OP_INDIRECT)
+               if (rinfo->shadow[i].req.operation != BLKIF_OP_INDIRECT)
                        /*
                         * If this is not an indirect operation don't try to
                         * free indirect segments
@@ -1145,42 +1293,59 @@ static void blkif_free(struct blkfront_info *info, int suspend)
                        goto free_shadow;
 
                for (j = 0; j < INDIRECT_GREFS(segs); j++) {
-                       persistent_gnt = info->shadow[i].indirect_grants[j];
+                       persistent_gnt = rinfo->shadow[i].indirect_grants[j];
                        gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
                        __free_page(persistent_gnt->page);
                        kfree(persistent_gnt);
                }
 
 free_shadow:
-               kfree(info->shadow[i].grants_used);
-               info->shadow[i].grants_used = NULL;
-               kfree(info->shadow[i].indirect_grants);
-               info->shadow[i].indirect_grants = NULL;
-               kfree(info->shadow[i].sg);
-               info->shadow[i].sg = NULL;
+               kfree(rinfo->shadow[i].grants_used);
+               rinfo->shadow[i].grants_used = NULL;
+               kfree(rinfo->shadow[i].indirect_grants);
+               rinfo->shadow[i].indirect_grants = NULL;
+               kfree(rinfo->shadow[i].sg);
+               rinfo->shadow[i].sg = NULL;
        }
 
        /* No more gnttab callback work. */
-       gnttab_cancel_free_callback(&info->callback);
-       spin_unlock_irq(&info->io_lock);
+       gnttab_cancel_free_callback(&rinfo->callback);
 
        /* Flush gnttab callback work. Must be done with no locks held. */
-       flush_work(&info->work);
+       flush_work(&rinfo->work);
 
        /* Free resources associated with old device channel. */
        for (i = 0; i < info->nr_ring_pages; i++) {
-               if (info->ring_ref[i] != GRANT_INVALID_REF) {
-                       gnttab_end_foreign_access(info->ring_ref[i], 0, 0);
-                       info->ring_ref[i] = GRANT_INVALID_REF;
+               if (rinfo->ring_ref[i] != GRANT_INVALID_REF) {
+                       gnttab_end_foreign_access(rinfo->ring_ref[i], 0, 0);
+                       rinfo->ring_ref[i] = GRANT_INVALID_REF;
                }
        }
-       free_pages((unsigned long)info->ring.sring, get_order(info->nr_ring_pages * PAGE_SIZE));
-       info->ring.sring = NULL;
+       free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * PAGE_SIZE));
+       rinfo->ring.sring = NULL;
 
-       if (info->irq)
-               unbind_from_irqhandler(info->irq, info);
-       info->evtchn = info->irq = 0;
+       if (rinfo->irq)
+               unbind_from_irqhandler(rinfo->irq, rinfo);
+       rinfo->evtchn = rinfo->irq = 0;
+}
 
+static void blkif_free(struct blkfront_info *info, int suspend)
+{
+       unsigned int i;
+
+       /* Prevent new requests being issued until we fix things up. */
+       info->connected = suspend ?
+               BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
+       /* No more blkif_request(). */
+       if (info->rq)
+               blk_mq_stop_hw_queues(info->rq);
+
+       for (i = 0; i < info->nr_rings; i++)
+               blkif_free_ring(&info->rinfo[i]);
+
+       kfree(info->rinfo);
+       info->rinfo = NULL;
+       info->nr_rings = 0;
 }
 
 struct copy_from_grant {
@@ -1209,19 +1374,93 @@ static void blkif_copy_from_grant(unsigned long gfn, unsigned int offset,
        kunmap_atomic(shared_data);
 }
 
-static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
+static enum blk_req_status blkif_rsp_to_req_status(int rsp)
+{
+       switch (rsp)
+       {
+       case BLKIF_RSP_OKAY:
+               return REQ_DONE;
+       case BLKIF_RSP_EOPNOTSUPP:
+               return REQ_EOPNOTSUPP;
+       case BLKIF_RSP_ERROR:
+               /* Fallthrough. */
+       default:
+               return REQ_ERROR;
+       }
+}
+
+/*
+ * Get the final status of the block request based on two ring response
+ */
+static int blkif_get_final_status(enum blk_req_status s1,
+                                 enum blk_req_status s2)
+{
+       BUG_ON(s1 == REQ_WAITING);
+       BUG_ON(s2 == REQ_WAITING);
+
+       if (s1 == REQ_ERROR || s2 == REQ_ERROR)
+               return BLKIF_RSP_ERROR;
+       else if (s1 == REQ_EOPNOTSUPP || s2 == REQ_EOPNOTSUPP)
+               return BLKIF_RSP_EOPNOTSUPP;
+       return BLKIF_RSP_OKAY;
+}
+
+static bool blkif_completion(unsigned long *id,
+                            struct blkfront_ring_info *rinfo,
                             struct blkif_response *bret)
 {
        int i = 0;
        struct scatterlist *sg;
        int num_sg, num_grant;
+       struct blkfront_info *info = rinfo->dev_info;
+       struct blk_shadow *s = &rinfo->shadow[*id];
        struct copy_from_grant data = {
-               .s = s,
                .grant_idx = 0,
        };
 
        num_grant = s->req.operation == BLKIF_OP_INDIRECT ?
                s->req.u.indirect.nr_segments : s->req.u.rw.nr_segments;
+
+       /* The I/O request may be split in two. */
+       if (unlikely(s->associated_id != NO_ASSOCIATED_ID)) {
+               struct blk_shadow *s2 = &rinfo->shadow[s->associated_id];
+
+               /* Keep the status of the current response in shadow. */
+               s->status = blkif_rsp_to_req_status(bret->status);
+
+               /* Wait the second response if not yet here. */
+               if (s2->status == REQ_WAITING)
+                       return 0;
+
+               bret->status = blkif_get_final_status(s->status,
+                                                     s2->status);
+
+               /*
+                * All the grants is stored in the first shadow in order
+                * to make the completion code simpler.
+                */
+               num_grant += s2->req.u.rw.nr_segments;
+
+               /*
+                * The two responses may not come in order. Only the
+                * first request will store the scatter-gather list.
+                */
+               if (s2->num_sg != 0) {
+                       /* Update "id" with the ID of the first response. */
+                       *id = s->associated_id;
+                       s = s2;
+               }
+
+               /*
+                * We don't need anymore the second request, so recycling
+                * it now.
+                */
+               if (add_id_to_freelist(rinfo, s->associated_id))
+                       WARN(1, "%s: can't recycle the second part (id = %ld) of the request\n",
+                            info->gd->disk_name, s->associated_id);
+       }
+
+       data.s = s;
        num_sg = s->num_sg;
 
        if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
@@ -1252,8 +1491,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                        if (!info->feature_persistent)
                                pr_alert_ratelimited("backed has not unmapped grant: %u\n",
                                                     s->grants_used[i]->gref);
-                       list_add(&s->grants_used[i]->node, &info->grants);
-                       info->persistent_gnts_c++;
+                       list_add(&s->grants_used[i]->node, &rinfo->grants);
+                       rinfo->persistent_gnts_c++;
                } else {
                        /*
                         * If the grant is not mapped by the backend we end the
@@ -1263,7 +1502,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                         */
                        gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
                        s->grants_used[i]->gref = GRANT_INVALID_REF;
-                       list_add_tail(&s->grants_used[i]->node, &info->grants);
+                       list_add_tail(&s->grants_used[i]->node, &rinfo->grants);
                }
        }
        if (s->req.operation == BLKIF_OP_INDIRECT) {
@@ -1272,8 +1511,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                                if (!info->feature_persistent)
                                        pr_alert_ratelimited("backed has not unmapped grant: %u\n",
                                                             s->indirect_grants[i]->gref);
-                               list_add(&s->indirect_grants[i]->node, &info->grants);
-                               info->persistent_gnts_c++;
+                               list_add(&s->indirect_grants[i]->node, &rinfo->grants);
+                               rinfo->persistent_gnts_c++;
                        } else {
                                struct page *indirect_page;
 
@@ -1284,13 +1523,15 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                                 */
                                if (!info->feature_persistent) {
                                        indirect_page = s->indirect_grants[i]->page;
-                                       list_add(&indirect_page->lru, &info->indirect_pages);
+                                       list_add(&indirect_page->lru, &rinfo->indirect_pages);
                                }
                                s->indirect_grants[i]->gref = GRANT_INVALID_REF;
-                               list_add_tail(&s->indirect_grants[i]->node, &info->grants);
+                               list_add_tail(&s->indirect_grants[i]->node, &rinfo->grants);
                        }
                }
        }
+
+       return 1;
 }
 
 static irqreturn_t blkif_interrupt(int irq, void *dev_id)
@@ -1299,24 +1540,22 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
        struct blkif_response *bret;
        RING_IDX i, rp;
        unsigned long flags;
-       struct blkfront_info *info = (struct blkfront_info *)dev_id;
+       struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
+       struct blkfront_info *info = rinfo->dev_info;
        int error;
 
-       spin_lock_irqsave(&info->io_lock, flags);
-
-       if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
-               spin_unlock_irqrestore(&info->io_lock, flags);
+       if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
                return IRQ_HANDLED;
-       }
 
+       spin_lock_irqsave(&rinfo->ring_lock, flags);
  again:
-       rp = info->ring.sring->rsp_prod;
+       rp = rinfo->ring.sring->rsp_prod;
        rmb(); /* Ensure we see queued responses up to 'rp'. */
 
-       for (i = info->ring.rsp_cons; i != rp; i++) {
+       for (i = rinfo->ring.rsp_cons; i != rp; i++) {
                unsigned long id;
 
-               bret = RING_GET_RESPONSE(&info->ring, i);
+               bret = RING_GET_RESPONSE(&rinfo->ring, i);
                id   = bret->id;
                /*
                 * The backend has messed up and given us an id that we would
@@ -1330,12 +1569,18 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                         * the id is busted. */
                        continue;
                }
-               req  = info->shadow[id].request;
+               req  = rinfo->shadow[id].request;
 
-               if (bret->operation != BLKIF_OP_DISCARD)
-                       blkif_completion(&info->shadow[id], info, bret);
+               if (bret->operation != BLKIF_OP_DISCARD) {
+                       /*
+                        * We may need to wait for an extra response if the
+                        * I/O request is split in 2
+                        */
+                       if (!blkif_completion(&id, rinfo, bret))
+                               continue;
+               }
 
-               if (add_id_to_freelist(info, id)) {
+               if (add_id_to_freelist(rinfo, id)) {
                        WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n",
                             info->gd->disk_name, op_name(bret->operation), id);
                        continue;
@@ -1364,7 +1609,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                                error = -EOPNOTSUPP;
                        }
                        if (unlikely(bret->status == BLKIF_RSP_ERROR &&
-                                    info->shadow[id].req.u.rw.nr_segments == 0)) {
+                                    rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
                                printk(KERN_WARNING "blkfront: %s: empty %s op failed\n",
                                       info->gd->disk_name, op_name(bret->operation));
                                error = -EOPNOTSUPP;
@@ -1389,34 +1634,35 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                }
        }
 
-       info->ring.rsp_cons = i;
+       rinfo->ring.rsp_cons = i;
 
-       if (i != info->ring.req_prod_pvt) {
+       if (i != rinfo->ring.req_prod_pvt) {
                int more_to_do;
-               RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
+               RING_FINAL_CHECK_FOR_RESPONSES(&rinfo->ring, more_to_do);
                if (more_to_do)
                        goto again;
        } else
-               info->ring.sring->rsp_event = i + 1;
+               rinfo->ring.sring->rsp_event = i + 1;
 
-       kick_pending_request_queues(info);
+       kick_pending_request_queues_locked(rinfo);
 
-       spin_unlock_irqrestore(&info->io_lock, flags);
+       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
 
        return IRQ_HANDLED;
 }
 
 
 static int setup_blkring(struct xenbus_device *dev,
-                        struct blkfront_info *info)
+                        struct blkfront_ring_info *rinfo)
 {
        struct blkif_sring *sring;
        int err, i;
+       struct blkfront_info *info = rinfo->dev_info;
        unsigned long ring_size = info->nr_ring_pages * XEN_PAGE_SIZE;
        grant_ref_t gref[XENBUS_MAX_RING_GRANTS];
 
        for (i = 0; i < info->nr_ring_pages; i++)
-               info->ring_ref[i] = GRANT_INVALID_REF;
+               rinfo->ring_ref[i] = GRANT_INVALID_REF;
 
        sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH,
                                                       get_order(ring_size));
@@ -1425,29 +1671,29 @@ static int setup_blkring(struct xenbus_device *dev,
                return -ENOMEM;
        }
        SHARED_RING_INIT(sring);
-       FRONT_RING_INIT(&info->ring, sring, ring_size);
+       FRONT_RING_INIT(&rinfo->ring, sring, ring_size);
 
-       err = xenbus_grant_ring(dev, info->ring.sring, info->nr_ring_pages, gref);
+       err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref);
        if (err < 0) {
                free_pages((unsigned long)sring, get_order(ring_size));
-               info->ring.sring = NULL;
+               rinfo->ring.sring = NULL;
                goto fail;
        }
        for (i = 0; i < info->nr_ring_pages; i++)
-               info->ring_ref[i] = gref[i];
+               rinfo->ring_ref[i] = gref[i];
 
-       err = xenbus_alloc_evtchn(dev, &info->evtchn);
+       err = xenbus_alloc_evtchn(dev, &rinfo->evtchn);
        if (err)
                goto fail;
 
-       err = bind_evtchn_to_irqhandler(info->evtchn, blkif_interrupt, 0,
-                                       "blkif", info);
+       err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0,
+                                       "blkif", rinfo);
        if (err <= 0) {
                xenbus_dev_fatal(dev, err,
                                 "bind_evtchn_to_irqhandler failed");
                goto fail;
        }
-       info->irq = err;
+       rinfo->irq = err;
 
        return 0;
 fail:
@@ -1455,6 +1701,53 @@ fail:
        return err;
 }
 
+/*
+ * Write out per-ring/queue nodes including ring-ref and event-channel, and each
+ * ring buffer may have multi pages depending on ->nr_ring_pages.
+ */
+static int write_per_ring_nodes(struct xenbus_transaction xbt,
+                               struct blkfront_ring_info *rinfo, const char *dir)
+{
+       int err;
+       unsigned int i;
+       const char *message = NULL;
+       struct blkfront_info *info = rinfo->dev_info;
+
+       if (info->nr_ring_pages == 1) {
+               err = xenbus_printf(xbt, dir, "ring-ref", "%u", rinfo->ring_ref[0]);
+               if (err) {
+                       message = "writing ring-ref";
+                       goto abort_transaction;
+               }
+       } else {
+               for (i = 0; i < info->nr_ring_pages; i++) {
+                       char ring_ref_name[RINGREF_NAME_LEN];
+
+                       snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i);
+                       err = xenbus_printf(xbt, dir, ring_ref_name,
+                                           "%u", rinfo->ring_ref[i]);
+                       if (err) {
+                               message = "writing ring-ref";
+                               goto abort_transaction;
+                       }
+               }
+       }
+
+       err = xenbus_printf(xbt, dir, "event-channel", "%u", rinfo->evtchn);
+       if (err) {
+               message = "writing event-channel";
+               goto abort_transaction;
+       }
+
+       return 0;
+
+abort_transaction:
+       xenbus_transaction_end(xbt, 1);
+       if (message)
+               xenbus_dev_fatal(info->xbdev, err, "%s", message);
+
+       return err;
+}
 
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_blkback(struct xenbus_device *dev,
@@ -1462,8 +1755,8 @@ static int talk_to_blkback(struct xenbus_device *dev,
 {
        const char *message = NULL;
        struct xenbus_transaction xbt;
-       int err, i;
-       unsigned int max_page_order = 0;
+       int err;
+       unsigned int i, max_page_order = 0;
        unsigned int ring_page_order = 0;
 
        err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
@@ -1475,10 +1768,14 @@ static int talk_to_blkback(struct xenbus_device *dev,
                info->nr_ring_pages = 1 << ring_page_order;
        }
 
-       /* Create shared ring, alloc event channel. */
-       err = setup_blkring(dev, info);
-       if (err)
-               goto out;
+       for (i = 0; i < info->nr_rings; i++) {
+               struct blkfront_ring_info *rinfo = &info->rinfo[i];
+
+               /* Create shared ring, alloc event channel. */
+               err = setup_blkring(dev, rinfo);
+               if (err)
+                       goto destroy_blkring;
+       }
 
 again:
        err = xenbus_transaction_start(&xbt);
@@ -1487,38 +1784,49 @@ again:
                goto destroy_blkring;
        }
 
-       if (info->nr_ring_pages == 1) {
-               err = xenbus_printf(xbt, dev->nodename,
-                                   "ring-ref", "%u", info->ring_ref[0]);
+       if (info->nr_ring_pages > 1) {
+               err = xenbus_printf(xbt, dev->nodename, "ring-page-order", "%u",
+                                   ring_page_order);
                if (err) {
-                       message = "writing ring-ref";
+                       message = "writing ring-page-order";
                        goto abort_transaction;
                }
+       }
+
+       /* We already got the number of queues/rings in _probe */
+       if (info->nr_rings == 1) {
+               err = write_per_ring_nodes(xbt, &info->rinfo[0], dev->nodename);
+               if (err)
+                       goto destroy_blkring;
        } else {
-               err = xenbus_printf(xbt, dev->nodename,
-                                   "ring-page-order", "%u", ring_page_order);
+               char *path;
+               size_t pathsize;
+
+               err = xenbus_printf(xbt, dev->nodename, "multi-queue-num-queues", "%u",
+                                   info->nr_rings);
                if (err) {
-                       message = "writing ring-page-order";
+                       message = "writing multi-queue-num-queues";
                        goto abort_transaction;
                }
 
-               for (i = 0; i < info->nr_ring_pages; i++) {
-                       char ring_ref_name[RINGREF_NAME_LEN];
+               pathsize = strlen(dev->nodename) + QUEUE_NAME_LEN;
+               path = kmalloc(pathsize, GFP_KERNEL);
+               if (!path) {
+                       err = -ENOMEM;
+                       message = "ENOMEM while writing ring references";
+                       goto abort_transaction;
+               }
 
-                       snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i);
-                       err = xenbus_printf(xbt, dev->nodename, ring_ref_name,
-                                           "%u", info->ring_ref[i]);
+               for (i = 0; i < info->nr_rings; i++) {
+                       memset(path, 0, pathsize);
+                       snprintf(path, pathsize, "%s/queue-%u", dev->nodename, i);
+                       err = write_per_ring_nodes(xbt, &info->rinfo[i], path);
                        if (err) {
-                               message = "writing ring-ref";
-                               goto abort_transaction;
+                               kfree(path);
+                               goto destroy_blkring;
                        }
                }
-       }
-       err = xenbus_printf(xbt, dev->nodename,
-                           "event-channel", "%u", info->evtchn);
-       if (err) {
-               message = "writing event-channel";
-               goto abort_transaction;
+               kfree(path);
        }
        err = xenbus_printf(xbt, dev->nodename, "protocol", "%s",
                            XEN_IO_PROTO_ABI_NATIVE);
@@ -1540,9 +1848,14 @@ again:
                goto destroy_blkring;
        }
 
-       for (i = 0; i < BLK_RING_SIZE(info); i++)
-               info->shadow[i].req.u.rw.id = i+1;
-       info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
+       for (i = 0; i < info->nr_rings; i++) {
+               unsigned int j;
+               struct blkfront_ring_info *rinfo = &info->rinfo[i];
+
+               for (j = 0; j < BLK_RING_SIZE(info); j++)
+                       rinfo->shadow[j].req.u.rw.id = j + 1;
+               rinfo->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
+       }
        xenbus_switch_state(dev, XenbusStateInitialised);
 
        return 0;
@@ -1553,7 +1866,10 @@ again:
                xenbus_dev_fatal(dev, err, "%s", message);
  destroy_blkring:
        blkif_free(info, 0);
- out:
+
+       kfree(info);
+       dev_set_drvdata(&dev->dev, NULL);
+
        return err;
 }
 
@@ -1567,7 +1883,9 @@ static int blkfront_probe(struct xenbus_device *dev,
                          const struct xenbus_device_id *id)
 {
        int err, vdevice;
+       unsigned int r_index;
        struct blkfront_info *info;
+       unsigned int backend_max_queues = 0;
 
        /* FIXME: Use dynamic device id if this is not set. */
        err = xenbus_scanf(XBT_NIL, dev->nodename,
@@ -1617,15 +1935,39 @@ static int blkfront_probe(struct xenbus_device *dev,
                return -ENOMEM;
        }
 
-       mutex_init(&info->mutex);
-       spin_lock_init(&info->io_lock);
        info->xbdev = dev;
+       /* Check if backend supports multiple queues. */
+       err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+                          "multi-queue-max-queues", "%u", &backend_max_queues);
+       if (err < 0)
+               backend_max_queues = 1;
+
+       info->nr_rings = min(backend_max_queues, xen_blkif_max_queues);
+       /* We need at least one ring. */
+       if (!info->nr_rings)
+               info->nr_rings = 1;
+
+       info->rinfo = kzalloc(sizeof(struct blkfront_ring_info) * info->nr_rings, GFP_KERNEL);
+       if (!info->rinfo) {
+               xenbus_dev_fatal(dev, -ENOMEM, "allocating ring_info structure");
+               kfree(info);
+               return -ENOMEM;
+       }
+
+       for (r_index = 0; r_index < info->nr_rings; r_index++) {
+               struct blkfront_ring_info *rinfo;
+
+               rinfo = &info->rinfo[r_index];
+               INIT_LIST_HEAD(&rinfo->indirect_pages);
+               INIT_LIST_HEAD(&rinfo->grants);
+               rinfo->dev_info = info;
+               INIT_WORK(&rinfo->work, blkif_restart_queue);
+               spin_lock_init(&rinfo->ring_lock);
+       }
+
+       mutex_init(&info->mutex);
        info->vdevice = vdevice;
-       INIT_LIST_HEAD(&info->grants);
-       INIT_LIST_HEAD(&info->indirect_pages);
-       info->persistent_gnts_c = 0;
        info->connected = BLKIF_STATE_DISCONNECTED;
-       INIT_WORK(&info->work, blkif_restart_queue);
 
        /* Front end dir is a number, which is used as the id. */
        info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
@@ -1649,7 +1991,7 @@ static void split_bio_end(struct bio *bio)
 
 static int blkif_recover(struct blkfront_info *info)
 {
-       int i;
+       unsigned int i, r_index;
        struct request *req, *n;
        struct blk_shadow *copy;
        int rc;
@@ -1660,64 +2002,73 @@ static int blkif_recover(struct blkfront_info *info)
        struct split_bio *split_bio;
        struct list_head requests;
 
-       /* Stage 1: Make a safe copy of the shadow state. */
-       copy = kmemdup(info->shadow, sizeof(info->shadow),
-                      GFP_NOIO | __GFP_REPEAT | __GFP_HIGH);
-       if (!copy)
-               return -ENOMEM;
-
-       /* Stage 2: Set up free list. */
-       memset(&info->shadow, 0, sizeof(info->shadow));
-       for (i = 0; i < BLK_RING_SIZE(info); i++)
-               info->shadow[i].req.u.rw.id = i+1;
-       info->shadow_free = info->ring.req_prod_pvt;
-       info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
-
-       rc = blkfront_gather_backend_features(info);
-       if (rc) {
-               kfree(copy);
-               return rc;
-       }
-
+       blkfront_gather_backend_features(info);
        segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST;
        blk_queue_max_segments(info->rq, segs);
        bio_list_init(&bio_list);
        INIT_LIST_HEAD(&requests);
-       for (i = 0; i < BLK_RING_SIZE(info); i++) {
-               /* Not in use? */
-               if (!copy[i].request)
-                       continue;
 
-               /*
-                * Get the bios in the request so we can re-queue them.
-                */
-               if (copy[i].request->cmd_flags &
-                   (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
+       for (r_index = 0; r_index < info->nr_rings; r_index++) {
+               struct blkfront_ring_info *rinfo;
+
+               rinfo = &info->rinfo[r_index];
+               /* Stage 1: Make a safe copy of the shadow state. */
+               copy = kmemdup(rinfo->shadow, sizeof(rinfo->shadow),
+                              GFP_NOIO | __GFP_REPEAT | __GFP_HIGH);
+               if (!copy)
+                       return -ENOMEM;
+
+               /* Stage 2: Set up free list. */
+               memset(&rinfo->shadow, 0, sizeof(rinfo->shadow));
+               for (i = 0; i < BLK_RING_SIZE(info); i++)
+                       rinfo->shadow[i].req.u.rw.id = i+1;
+               rinfo->shadow_free = rinfo->ring.req_prod_pvt;
+               rinfo->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
+
+               rc = blkfront_setup_indirect(rinfo);
+               if (rc) {
+                       kfree(copy);
+                       return rc;
+               }
+
+               for (i = 0; i < BLK_RING_SIZE(info); i++) {
+                       /* Not in use? */
+                       if (!copy[i].request)
+                               continue;
+
                        /*
-                        * Flush operations don't contain bios, so
-                        * we need to requeue the whole request
+                        * Get the bios in the request so we can re-queue them.
                         */
-                       list_add(&copy[i].request->queuelist, &requests);
-                       continue;
+                       if (copy[i].request->cmd_flags &
+                           (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
+                               /*
+                                * Flush operations don't contain bios, so
+                                * we need to requeue the whole request
+                                */
+                               list_add(&copy[i].request->queuelist, &requests);
+                               continue;
+                       }
+                       merge_bio.head = copy[i].request->bio;
+                       merge_bio.tail = copy[i].request->biotail;
+                       bio_list_merge(&bio_list, &merge_bio);
+                       copy[i].request->bio = NULL;
+                       blk_end_request_all(copy[i].request, 0);
                }
-               merge_bio.head = copy[i].request->bio;
-               merge_bio.tail = copy[i].request->biotail;
-               bio_list_merge(&bio_list, &merge_bio);
-               copy[i].request->bio = NULL;
-               blk_end_request_all(copy[i].request, 0);
-       }
-
-       kfree(copy);
 
+               kfree(copy);
+       }
        xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
-       spin_lock_irq(&info->io_lock);
-
        /* Now safe for us to use the shared ring */
        info->connected = BLKIF_STATE_CONNECTED;
 
-       /* Kick any other new requests queued since we resumed */
-       kick_pending_request_queues(info);
+       for (r_index = 0; r_index < info->nr_rings; r_index++) {
+               struct blkfront_ring_info *rinfo;
+
+               rinfo = &info->rinfo[r_index];
+               /* Kick any other new requests queued since we resumed */
+               kick_pending_request_queues(rinfo);
+       }
 
        list_for_each_entry_safe(req, n, &requests, queuelist) {
                /* Requeue pending requests (flush or discard) */
@@ -1725,7 +2076,6 @@ static int blkif_recover(struct blkfront_info *info)
                BUG_ON(req->nr_phys_segments > segs);
                blk_mq_requeue_request(req);
        }
-       spin_unlock_irq(&info->io_lock);
        blk_mq_kick_requeue_list(info->rq);
 
        while ((bio = bio_list_pop(&bio_list)) != NULL) {
@@ -1790,8 +2140,7 @@ static int blkfront_resume(struct xenbus_device *dev)
        return err;
 }
 
-static void
-blkfront_closing(struct blkfront_info *info)
+static void blkfront_closing(struct blkfront_info *info)
 {
        struct xenbus_device *xbdev = info->xbdev;
        struct block_device *bdev = NULL;
@@ -1851,18 +2200,29 @@ static void blkfront_setup_discard(struct blkfront_info *info)
                info->feature_secdiscard = !!discard_secure;
 }
 
-static int blkfront_setup_indirect(struct blkfront_info *info)
+static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
 {
        unsigned int psegs, grants;
        int err, i;
+       struct blkfront_info *info = rinfo->dev_info;
 
-       if (info->max_indirect_segments == 0)
-               grants = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+       if (info->max_indirect_segments == 0) {
+               if (!HAS_EXTRA_REQ)
+                       grants = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+               else {
+                       /*
+                        * When an extra req is required, the maximum
+                        * grants supported is related to the size of the
+                        * Linux block segment.
+                        */
+                       grants = GRANTS_PER_PSEG;
+               }
+       }
        else
                grants = info->max_indirect_segments;
        psegs = grants / GRANTS_PER_PSEG;
 
-       err = fill_grant_buffer(info,
+       err = fill_grant_buffer(rinfo,
                                (grants + INDIRECT_GREFS(grants)) * BLK_RING_SIZE(info));
        if (err)
                goto out_of_memory;
@@ -1875,31 +2235,31 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
                 */
                int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info);
 
-               BUG_ON(!list_empty(&info->indirect_pages));
+               BUG_ON(!list_empty(&rinfo->indirect_pages));
                for (i = 0; i < num; i++) {
                        struct page *indirect_page = alloc_page(GFP_NOIO);
                        if (!indirect_page)
                                goto out_of_memory;
-                       list_add(&indirect_page->lru, &info->indirect_pages);
+                       list_add(&indirect_page->lru, &rinfo->indirect_pages);
                }
        }
 
        for (i = 0; i < BLK_RING_SIZE(info); i++) {
-               info->shadow[i].grants_used = kzalloc(
-                       sizeof(info->shadow[i].grants_used[0]) * grants,
+               rinfo->shadow[i].grants_used = kzalloc(
+                       sizeof(rinfo->shadow[i].grants_used[0]) * grants,
                        GFP_NOIO);
-               info->shadow[i].sg = kzalloc(sizeof(info->shadow[i].sg[0]) * psegs, GFP_NOIO);
+               rinfo->shadow[i].sg = kzalloc(sizeof(rinfo->shadow[i].sg[0]) * psegs, GFP_NOIO);
                if (info->max_indirect_segments)
-                       info->shadow[i].indirect_grants = kzalloc(
-                               sizeof(info->shadow[i].indirect_grants[0]) *
+                       rinfo->shadow[i].indirect_grants = kzalloc(
+                               sizeof(rinfo->shadow[i].indirect_grants[0]) *
                                INDIRECT_GREFS(grants),
                                GFP_NOIO);
-               if ((info->shadow[i].grants_used == NULL) ||
-                       (info->shadow[i].sg == NULL) ||
+               if ((rinfo->shadow[i].grants_used == NULL) ||
+                       (rinfo->shadow[i].sg == NULL) ||
                     (info->max_indirect_segments &&
-                    (info->shadow[i].indirect_grants == NULL)))
+                    (rinfo->shadow[i].indirect_grants == NULL)))
                        goto out_of_memory;
-               sg_init_table(info->shadow[i].sg, psegs);
+               sg_init_table(rinfo->shadow[i].sg, psegs);
        }
 
 
@@ -1907,16 +2267,16 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
 
 out_of_memory:
        for (i = 0; i < BLK_RING_SIZE(info); i++) {
-               kfree(info->shadow[i].grants_used);
-               info->shadow[i].grants_used = NULL;
-               kfree(info->shadow[i].sg);
-               info->shadow[i].sg = NULL;
-               kfree(info->shadow[i].indirect_grants);
-               info->shadow[i].indirect_grants = NULL;
-       }
-       if (!list_empty(&info->indirect_pages)) {
+               kfree(rinfo->shadow[i].grants_used);
+               rinfo->shadow[i].grants_used = NULL;
+               kfree(rinfo->shadow[i].sg);
+               rinfo->shadow[i].sg = NULL;
+               kfree(rinfo->shadow[i].indirect_grants);
+               rinfo->shadow[i].indirect_grants = NULL;
+       }
+       if (!list_empty(&rinfo->indirect_pages)) {
                struct page *indirect_page, *n;
-               list_for_each_entry_safe(indirect_page, n, &info->indirect_pages, lru) {
+               list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) {
                        list_del(&indirect_page->lru);
                        __free_page(indirect_page);
                }
@@ -1927,7 +2287,7 @@ out_of_memory:
 /*
  * Gather all backend feature-*
  */
-static int blkfront_gather_backend_features(struct blkfront_info *info)
+static void blkfront_gather_backend_features(struct blkfront_info *info)
 {
        int err;
        int barrier, flush, discard, persistent;
@@ -1982,8 +2342,6 @@ static int blkfront_gather_backend_features(struct blkfront_info *info)
        else
                info->max_indirect_segments = min(indirect_segments,
                                                  xen_blkif_max_segments);
-
-       return blkfront_setup_indirect(info);
 }
 
 /*
@@ -1996,7 +2354,7 @@ static void blkfront_connect(struct blkfront_info *info)
        unsigned long sector_size;
        unsigned int physical_sector_size;
        unsigned int binfo;
-       int err;
+       int err, i;
 
        switch (info->connected) {
        case BLKIF_STATE_CONNECTED:
@@ -2053,11 +2411,15 @@ static void blkfront_connect(struct blkfront_info *info)
        if (err != 1)
                physical_sector_size = sector_size;
 
-       err = blkfront_gather_backend_features(info);
-       if (err) {
-               xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
-                                info->xbdev->otherend);
-               return;
+       blkfront_gather_backend_features(info);
+       for (i = 0; i < info->nr_rings; i++) {
+               err = blkfront_setup_indirect(&info->rinfo[i]);
+               if (err) {
+                       xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
+                                        info->xbdev->otherend);
+                       blkif_free(info, 0);
+                       break;
+               }
        }
 
        err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size,
@@ -2071,10 +2433,9 @@ static void blkfront_connect(struct blkfront_info *info)
        xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
        /* Kick pending requests. */
-       spin_lock_irq(&info->io_lock);
        info->connected = BLKIF_STATE_CONNECTED;
-       kick_pending_request_queues(info);
-       spin_unlock_irq(&info->io_lock);
+       for (i = 0; i < info->nr_rings; i++)
+               kick_pending_request_queues(&info->rinfo[i]);
 
        add_disk(info->gd);
 
@@ -2095,11 +2456,8 @@ static void blkback_changed(struct xenbus_device *dev,
        case XenbusStateInitWait:
                if (dev->state != XenbusStateInitialising)
                        break;
-               if (talk_to_blkback(dev, info)) {
-                       kfree(info);
-                       dev_set_drvdata(&dev->dev, NULL);
+               if (talk_to_blkback(dev, info))
                        break;
-               }
        case XenbusStateInitialising:
        case XenbusStateInitialised:
        case XenbusStateReconfiguring:
@@ -2108,6 +2466,10 @@ static void blkback_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateConnected:
+               if (dev->state != XenbusStateInitialised) {
+                       if (talk_to_blkback(dev, info))
+                               break;
+               }
                blkfront_connect(info);
                break;
 
@@ -2281,6 +2643,7 @@ static struct xenbus_driver blkfront_driver = {
 static int __init xlblk_init(void)
 {
        int ret;
+       int nr_cpus = num_online_cpus();
 
        if (!xen_domain())
                return -ENODEV;
@@ -2288,7 +2651,13 @@ static int __init xlblk_init(void)
        if (xen_blkif_max_ring_order > XENBUS_MAX_RING_GRANT_ORDER) {
                pr_info("Invalid max_ring_order (%d), will use default max: %d.\n",
                        xen_blkif_max_ring_order, XENBUS_MAX_RING_GRANT_ORDER);
-               xen_blkif_max_ring_order = 0;
+               xen_blkif_max_ring_order = XENBUS_MAX_RING_GRANT_ORDER;
+       }
+
+       if (xen_blkif_max_queues > nr_cpus) {
+               pr_info("Invalid max_queues (%d), will use default max: %d.\n",
+                       xen_blkif_max_queues, nr_cpus);
+               xen_blkif_max_queues = nr_cpus;
        }
 
        if (!xen_has_pv_disk_devices())
index 116b363..129d47b 100644 (file)
@@ -131,6 +131,14 @@ config SUNXI_RSB
          with various RSB based devices, such as AXP223, AXP8XX PMICs,
          and AC100/AC200 ICs.
 
+config UNIPHIER_SYSTEM_BUS
+       bool "UniPhier System Bus driver"
+       depends on ARCH_UNIPHIER && OF
+       default y
+       help
+         Support for UniPhier System Bus, a simple external bus.  This is
+         needed to use on-board devices connected to UniPhier SoCs.
+
 config VEXPRESS_CONFIG
        bool "Versatile Express configuration bus"
        default y if ARCH_VEXPRESS
index fcb9f97..ccff007 100644 (file)
@@ -17,4 +17,5 @@ obj-$(CONFIG_OMAP_INTERCONNECT)       += omap_l3_smx.o omap_l3_noc.o
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
 obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
 obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
+obj-$(CONFIG_UNIPHIER_SYSTEM_BUS)      += uniphier-system-bus.o
 obj-$(CONFIG_VEXPRESS_CONFIG)  += vexpress-config.o
diff --git a/drivers/bus/uniphier-system-bus.c b/drivers/bus/uniphier-system-bus.c
new file mode 100644 (file)
index 0000000..834a2ae
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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.
+ */
+
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+/* System Bus Controller registers */
+#define UNIPHIER_SBC_BASE      0x100   /* base address of bank0 space */
+#define    UNIPHIER_SBC_BASE_BE                BIT(0)  /* bank_enable */
+#define UNIPHIER_SBC_CTRL0     0x200   /* timing parameter 0 of bank0 */
+#define UNIPHIER_SBC_CTRL1     0x204   /* timing parameter 1 of bank0 */
+#define UNIPHIER_SBC_CTRL2     0x208   /* timing parameter 2 of bank0 */
+#define UNIPHIER_SBC_CTRL3     0x20c   /* timing parameter 3 of bank0 */
+#define UNIPHIER_SBC_CTRL4     0x300   /* timing parameter 4 of bank0 */
+
+#define UNIPHIER_SBC_STRIDE    0x10    /* register stride to next bank */
+#define UNIPHIER_SBC_NR_BANKS  8       /* number of banks (chip select) */
+#define UNIPHIER_SBC_BASE_DUMMY        0xffffffff      /* data to squash bank 0, 1 */
+
+struct uniphier_system_bus_bank {
+       u32 base;
+       u32 end;
+};
+
+struct uniphier_system_bus_priv {
+       struct device *dev;
+       void __iomem *membase;
+       struct uniphier_system_bus_bank bank[UNIPHIER_SBC_NR_BANKS];
+};
+
+static int uniphier_system_bus_add_bank(struct uniphier_system_bus_priv *priv,
+                                       int bank, u32 addr, u64 paddr, u32 size)
+{
+       u64 end, mask;
+
+       dev_dbg(priv->dev,
+               "range found: bank = %d, addr = %08x, paddr = %08llx, size = %08x\n",
+               bank, addr, paddr, size);
+
+       if (bank >= ARRAY_SIZE(priv->bank)) {
+               dev_err(priv->dev, "unsupported bank number %d\n", bank);
+               return -EINVAL;
+       }
+
+       if (priv->bank[bank].base || priv->bank[bank].end) {
+               dev_err(priv->dev,
+                       "range for bank %d has already been specified\n", bank);
+               return -EINVAL;
+       }
+
+       if (paddr > U32_MAX) {
+               dev_err(priv->dev, "base address %llx is too high\n", paddr);
+               return -EINVAL;
+       }
+
+       end = paddr + size;
+
+       if (addr > paddr) {
+               dev_err(priv->dev,
+                       "base %08x cannot be mapped to %08llx of parent\n",
+                       addr, paddr);
+               return -EINVAL;
+       }
+       paddr -= addr;
+
+       paddr = round_down(paddr, 0x00020000);
+       end = round_up(end, 0x00020000);
+
+       if (end > U32_MAX) {
+               dev_err(priv->dev, "end address %08llx is too high\n", end);
+               return -EINVAL;
+       }
+       mask = paddr ^ (end - 1);
+       mask = roundup_pow_of_two(mask);
+
+       paddr = round_down(paddr, mask);
+       end = round_up(end, mask);
+
+       priv->bank[bank].base = paddr;
+       priv->bank[bank].end = end;
+
+       dev_dbg(priv->dev, "range added: bank = %d, addr = %08x, end = %08x\n",
+               bank, priv->bank[bank].base, priv->bank[bank].end);
+
+       return 0;
+}
+
+static int uniphier_system_bus_check_overlap(
+                               const struct uniphier_system_bus_priv *priv)
+{
+       int i, j;
+
+       for (i = 0; i < ARRAY_SIZE(priv->bank); i++) {
+               for (j = i + 1; j < ARRAY_SIZE(priv->bank); j++) {
+                       if (priv->bank[i].end > priv->bank[j].base ||
+                           priv->bank[i].base < priv->bank[j].end) {
+                               dev_err(priv->dev,
+                                       "region overlap between bank%d and bank%d\n",
+                                       i, j);
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static void uniphier_system_bus_check_boot_swap(
+                                       struct uniphier_system_bus_priv *priv)
+{
+       void __iomem *base_reg = priv->membase + UNIPHIER_SBC_BASE;
+       int is_swapped;
+
+       is_swapped = !(readl(base_reg) & UNIPHIER_SBC_BASE_BE);
+
+       dev_dbg(priv->dev, "Boot Swap: %s\n", is_swapped ? "on" : "off");
+
+       /*
+        * If BOOT_SWAP was asserted on power-on-reset, the CS0 and CS1 are
+        * swapped.  In this case, bank0 and bank1 should be swapped as well.
+        */
+       if (is_swapped)
+               swap(priv->bank[0], priv->bank[1]);
+}
+
+static void uniphier_system_bus_set_reg(
+                               const struct uniphier_system_bus_priv *priv)
+{
+       void __iomem *base_reg = priv->membase + UNIPHIER_SBC_BASE;
+       u32 base, end, mask, val;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(priv->bank); i++) {
+               base = priv->bank[i].base;
+               end = priv->bank[i].end;
+
+               if (base == end) {
+                       /*
+                        * If SBC_BASE0 or SBC_BASE1 is set to zero, the access
+                        * to anywhere in the system bus space is routed to
+                        * bank 0 (if boot swap if off) or bank 1 (if boot swap
+                        * if on).  It means that CPUs cannot get access to
+                        * bank 2 or later.  In other words, bank 0/1 cannot
+                        * be disabled even if its bank_enable bits is cleared.
+                        * This seems odd, but it is how this hardware goes.
+                        * As a workaround, dummy data (0xffffffff) should be
+                        * set when the bank 0/1 is unused.  As for bank 2 and
+                        * later, they can be simply disable by clearing the
+                        * bank_enable bit.
+                        */
+                       if (i < 2)
+                               val = UNIPHIER_SBC_BASE_DUMMY;
+                       else
+                               val = 0;
+               } else {
+                       mask = base ^ (end - 1);
+
+                       val = base & 0xfffe0000;
+                       val |= (~mask >> 16) & 0xfffe;
+                       val |= UNIPHIER_SBC_BASE_BE;
+               }
+               dev_dbg(priv->dev, "SBC_BASE[%d] = 0x%08x\n", i, val);
+
+               writel(val, base_reg + UNIPHIER_SBC_STRIDE * i);
+       }
+}
+
+static int uniphier_system_bus_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct uniphier_system_bus_priv *priv;
+       struct resource *regs;
+       const __be32 *ranges;
+       u32 cells, addr, size;
+       u64 paddr;
+       int pna, bank, rlen, rone, ret;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->membase = devm_ioremap_resource(dev, regs);
+       if (IS_ERR(priv->membase))
+               return PTR_ERR(priv->membase);
+
+       priv->dev = dev;
+
+       pna = of_n_addr_cells(dev->of_node);
+
+       ret = of_property_read_u32(dev->of_node, "#address-cells", &cells);
+       if (ret) {
+               dev_err(dev, "failed to get #address-cells\n");
+               return ret;
+       }
+       if (cells != 2) {
+               dev_err(dev, "#address-cells must be 2\n");
+               return -EINVAL;
+       }
+
+       ret = of_property_read_u32(dev->of_node, "#size-cells", &cells);
+       if (ret) {
+               dev_err(dev, "failed to get #size-cells\n");
+               return ret;
+       }
+       if (cells != 1) {
+               dev_err(dev, "#size-cells must be 1\n");
+               return -EINVAL;
+       }
+
+       ranges = of_get_property(dev->of_node, "ranges", &rlen);
+       if (!ranges) {
+               dev_err(dev, "failed to get ranges property\n");
+               return -ENOENT;
+       }
+
+       rlen /= sizeof(*ranges);
+       rone = pna + 2;
+
+       for (; rlen >= rone; rlen -= rone) {
+               bank = be32_to_cpup(ranges++);
+               addr = be32_to_cpup(ranges++);
+               paddr = of_translate_address(dev->of_node, ranges);
+               if (paddr == OF_BAD_ADDR)
+                       return -EINVAL;
+               ranges += pna;
+               size = be32_to_cpup(ranges++);
+
+               ret = uniphier_system_bus_add_bank(priv, bank, addr,
+                                                  paddr, size);
+               if (ret)
+                       return ret;
+       }
+
+       ret = uniphier_system_bus_check_overlap(priv);
+       if (ret)
+               return ret;
+
+       uniphier_system_bus_check_boot_swap(priv);
+
+       uniphier_system_bus_set_reg(priv);
+
+       /* Now, the bus is configured.  Populate platform_devices below it */
+       return of_platform_populate(dev->of_node, of_default_bus_match_table,
+                                   NULL, dev);
+}
+
+static const struct of_device_id uniphier_system_bus_match[] = {
+       { .compatible = "socionext,uniphier-system-bus" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, uniphier_system_bus_match);
+
+static struct platform_driver uniphier_system_bus_driver = {
+       .probe          = uniphier_system_bus_probe,
+       .driver = {
+               .name   = "uniphier-system-bus",
+               .of_match_table = uniphier_system_bus_match,
+       },
+};
+module_platform_driver(uniphier_system_bus_driver);
+
+MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier System Bus driver");
+MODULE_LICENSE("GPL");
index 6b1721f..4f6f94c 100644 (file)
@@ -689,7 +689,7 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
 {
        loff_t ret;
 
-       mutex_lock(&file_inode(file)->i_mutex);
+       inode_lock(file_inode(file));
        switch (orig) {
        case SEEK_CUR:
                offset += file->f_pos;
@@ -706,7 +706,7 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
        default:
                ret = -EINVAL;
        }
-       mutex_unlock(&file_inode(file)->i_mutex);
+       inode_unlock(file_inode(file));
        return ret;
 }
 
index f1d7fa4..f3f92d5 100644 (file)
@@ -93,14 +93,11 @@ struct vma_data {
        spinlock_t lock;        /* Serialize access to this structure. */
        int count;              /* Number of pages allocated. */
        enum mspec_page_type type; /* Type of pages allocated. */
-       int flags;              /* See VMD_xxx below. */
        unsigned long vm_start; /* Original (unsplit) base. */
        unsigned long vm_end;   /* Original (unsplit) end. */
        unsigned long maddr[0]; /* Array of MSPEC addresses. */
 };
 
-#define VMD_VMALLOCED 0x1      /* vmalloc'd rather than kmalloc'd */
-
 /* used on shub2 to clear FOP cache in the HUB */
 static unsigned long scratch_page[MAX_NUMNODES];
 #define SH2_AMO_CACHE_ENTRIES  4
@@ -185,10 +182,7 @@ mspec_close(struct vm_area_struct *vma)
                               "failed to zero page %ld\n", my_page);
        }
 
-       if (vdata->flags & VMD_VMALLOCED)
-               vfree(vdata);
-       else
-               kfree(vdata);
+       kvfree(vdata);
 }
 
 /*
@@ -256,7 +250,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
                                        enum mspec_page_type type)
 {
        struct vma_data *vdata;
-       int pages, vdata_size, flags = 0;
+       int pages, vdata_size;
 
        if (vma->vm_pgoff != 0)
                return -EINVAL;
@@ -271,16 +265,13 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
        vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
        if (vdata_size <= PAGE_SIZE)
                vdata = kzalloc(vdata_size, GFP_KERNEL);
-       else {
+       else
                vdata = vzalloc(vdata_size);
-               flags = VMD_VMALLOCED;
-       }
        if (!vdata)
                return -ENOMEM;
 
        vdata->vm_start = vma->vm_start;
        vdata->vm_end = vma->vm_end;
-       vdata->flags = flags;
        vdata->type = type;
        spin_lock_init(&vdata->lock);
        atomic_set(&vdata->refcnt, 1);
index 0b311fa..b526dc1 100644 (file)
@@ -290,9 +290,9 @@ static int ps3flash_fsync(struct file *file, loff_t start, loff_t end, int datas
 {
        struct inode *inode = file_inode(file);
        int err;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        err = ps3flash_writeback(ps3flash_dev);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err;
 }
 
index 71fd293..38931db 100644 (file)
@@ -17,8 +17,6 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 
-#include <mach/addr-map.h>
-
 #include "clk.h"
 
 #define APBC_RTC       0x0
@@ -74,7 +72,8 @@ static const char *sdh_parent[] = {"pll1_4", "pll2", "usb_pll", "pll1"};
 static const char *disp_parent[] = {"pll1", "pll1_16", "pll2", "vctcxo"};
 static const char *ccic_parent[] = {"pll1_2", "pll1_16", "vctcxo"};
 
-void __init mmp2_clk_init(void)
+void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+                         phys_addr_t apbc_phys)
 {
        struct clk *clk;
        struct clk *vctcxo;
@@ -82,19 +81,19 @@ void __init mmp2_clk_init(void)
        void __iomem *apmu_base;
        void __iomem *apbc_base;
 
-       mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K);
+       mpmu_base = ioremap(mpmu_phys, SZ_4K);
        if (mpmu_base == NULL) {
                pr_err("error to ioremap MPMU base\n");
                return;
        }
 
-       apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K);
+       apmu_base = ioremap(apmu_phys, SZ_4K);
        if (apmu_base == NULL) {
                pr_err("error to ioremap APMU base\n");
                return;
        }
 
-       apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K);
+       apbc_base = ioremap(apbc_phys, SZ_4K);
        if (apbc_base == NULL) {
                pr_err("error to ioremap APBC base\n");
                return;
index 7524491..0dd83fb 100644 (file)
@@ -17,8 +17,6 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 
-#include <mach/addr-map.h>
-
 #include "clk.h"
 
 #define APBC_RTC       0x28
@@ -67,7 +65,8 @@ static const char *disp_parent[] = {"pll1_2", "pll1_12"};
 static const char *ccic_parent[] = {"pll1_2", "pll1_12"};
 static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"};
 
-void __init pxa168_clk_init(void)
+void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+                           phys_addr_t apbc_phys)
 {
        struct clk *clk;
        struct clk *uart_pll;
@@ -75,19 +74,19 @@ void __init pxa168_clk_init(void)
        void __iomem *apmu_base;
        void __iomem *apbc_base;
 
-       mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K);
+       mpmu_base = ioremap(mpmu_phys, SZ_4K);
        if (mpmu_base == NULL) {
                pr_err("error to ioremap MPMU base\n");
                return;
        }
 
-       apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K);
+       apmu_base = ioremap(apmu_phys, SZ_4K);
        if (apmu_base == NULL) {
                pr_err("error to ioremap APMU base\n");
                return;
        }
 
-       apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K);
+       apbc_base = ioremap(apbc_phys, SZ_4K);
        if (apbc_base == NULL) {
                pr_err("error to ioremap APBC base\n");
                return;
index 37ba04b..e1d2ce2 100644 (file)
@@ -17,8 +17,6 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 
-#include <mach/addr-map.h>
-
 #include "clk.h"
 
 #define APBC_RTC       0x28
@@ -65,7 +63,8 @@ static const char *disp_parent[] = {"pll1_2", "pll1_12"};
 static const char *ccic_parent[] = {"pll1_2", "pll1_12"};
 static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"};
 
-void __init pxa910_clk_init(void)
+void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+                           phys_addr_t apbc_phys, phys_addr_t apbcp_phys)
 {
        struct clk *clk;
        struct clk *uart_pll;
@@ -74,25 +73,25 @@ void __init pxa910_clk_init(void)
        void __iomem *apbcp_base;
        void __iomem *apbc_base;
 
-       mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K);
+       mpmu_base = ioremap(mpmu_phys, SZ_4K);
        if (mpmu_base == NULL) {
                pr_err("error to ioremap MPMU base\n");
                return;
        }
 
-       apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K);
+       apmu_base = ioremap(apmu_phys, SZ_4K);
        if (apmu_base == NULL) {
                pr_err("error to ioremap APMU base\n");
                return;
        }
 
-       apbcp_base = ioremap(APB_PHYS_BASE + 0x3b000, SZ_4K);
+       apbcp_base = ioremap(apbcp_phys, SZ_4K);
        if (apbcp_base == NULL) {
                pr_err("error to ioremap APBC extension base\n");
                return;
        }
 
-       apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K);
+       apbc_base = ioremap(apbc_phys, SZ_4K);
        if (apbc_base == NULL) {
                pr_err("error to ioremap APBC base\n");
                return;
index 542e45e..b774722 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/clkdev.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <mach/pxa25x.h>
 #include <mach/pxa2xx-regs.h>
 
 #include <dt-bindings/clock/pxa-clock.h>
index 7f370d3..ac03e4f 100644 (file)
@@ -1024,6 +1024,7 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
                        0, 0),
        GATE(CLK_AC97, "ac97", "aclk100", GATE_IP_PERIL, 27,
                        0, 0),
+       GATE(CLK_SSS, "sss", "aclk133", GATE_IP_DMC, 4, 0, 0),
        GATE(CLK_PPMUDMC0, "ppmudmc0", "aclk133", GATE_IP_DMC, 8, 0, 0),
        GATE(CLK_PPMUDMC1, "ppmudmc1", "aclk133", GATE_IP_DMC, 9, 0, 0),
        GATE(CLK_PPMUCPU, "ppmucpu", "aclk133", GATE_IP_DMC, 10, 0, 0),
index 48c83ef..16e0aee 100644 (file)
@@ -32,7 +32,7 @@
 static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
                   unsigned long parent_rate)
 {
-       s64 divider_ux1 = parent_rate;
+       u64 divider_ux1 = parent_rate;
        u8 flags = divider->flags;
        int mul;
 
@@ -54,7 +54,7 @@ static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
 
        divider_ux1 -= mul;
 
-       if (divider_ux1 < 0)
+       if ((s64)divider_ux1 < 0)
                return 0;
 
        if (divider_ux1 > get_max_div(divider))
index e172920..9e85fcc 100644 (file)
@@ -14,10 +14,14 @@ static struct ti_dt_clk dm814_clks[] = {
        DT_CLK(NULL, "devosc_ck", "devosc_ck"),
        DT_CLK(NULL, "mpu_ck", "mpu_ck"),
        DT_CLK(NULL, "sysclk4_ck", "sysclk4_ck"),
+       DT_CLK(NULL, "sysclk5_ck", "sysclk5_ck"),
        DT_CLK(NULL, "sysclk6_ck", "sysclk6_ck"),
+       DT_CLK(NULL, "sysclk8_ck", "sysclk8_ck"),
        DT_CLK(NULL, "sysclk10_ck", "sysclk10_ck"),
        DT_CLK(NULL, "sysclk18_ck", "sysclk18_ck"),
        DT_CLK(NULL, "timer_sys_ck", "devosc_ck"),
+       DT_CLK(NULL, "timer1_fck", "timer1_fck"),
+       DT_CLK(NULL, "timer2_fck", "timer2_fck"),
        DT_CLK(NULL, "cpsw_125mhz_gclk", "cpsw_125mhz_gclk"),
        DT_CLK(NULL, "cpsw_cpts_rft_clk", "cpsw_cpts_rft_clk"),
        { .node_name = NULL },
index fc50b62..a6da2aa 100644 (file)
@@ -1,6 +1,9 @@
 config COMMON_CLK_VERSATILE
        bool "Clock driver for ARM Reference designs"
-       depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 || COMPILE_TEST
+       depends on ARCH_INTEGRATOR || ARCH_REALVIEW || \
+               ARCH_VERSATILE || ARCH_VEXPRESS || ARM64 || \
+               COMPILE_TEST
+       select REGMAP_MMIO
        ---help---
           Supports clocking on ARM Reference designs:
          - Integrator/AP and Integrator/CP
index 08c5ee9..e62f8cb 100644 (file)
@@ -3,7 +3,7 @@
  * We wrap the custom interface from <asm/hardware/icst.h> into the generic
  * clock framework.
  *
- * Copyright (C) 2012 Linus Walleij
+ * Copyright (C) 2012-2015 Linus Walleij
  *
  * 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
 #include <linux/err.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 
 #include "clk-icst.h"
 
+/* Magic unlocking token used on all Versatile boards */
+#define VERSATILE_LOCK_VAL     0xA05F
+
 /**
  * struct clk_icst - ICST VCO clock wrapper
  * @hw: corresponding clock hardware entry
@@ -32,8 +37,9 @@
  */
 struct clk_icst {
        struct clk_hw hw;
-       void __iomem *vcoreg;
-       void __iomem *lockreg;
+       struct regmap *map;
+       u32 vcoreg_off;
+       u32 lockreg_off;
        struct icst_params *params;
        unsigned long rate;
 };
@@ -41,53 +47,67 @@ struct clk_icst {
 #define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
 
 /**
- * vco_get() - get ICST VCO settings from a certain register
- * @vcoreg: register containing the VCO settings
+ * vco_get() - get ICST VCO settings from a certain ICST
+ * @icst: the ICST clock to get
+ * @vco: the VCO struct to return the value in
  */
-static struct icst_vco vco_get(void __iomem *vcoreg)
+static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
 {
        u32 val;
-       struct icst_vco vco;
+       int ret;
 
-       val = readl(vcoreg);
-       vco.v = val & 0x1ff;
-       vco.r = (val >> 9) & 0x7f;
-       vco.s = (val >> 16) & 03;
-       return vco;
+       ret = regmap_read(icst->map, icst->vcoreg_off, &val);
+       if (ret)
+               return ret;
+       vco->v = val & 0x1ff;
+       vco->r = (val >> 9) & 0x7f;
+       vco->s = (val >> 16) & 03;
+       return 0;
 }
 
 /**
  * vco_set() - commit changes to an ICST VCO
- * @locreg: register to poke to unlock the VCO for writing
- * @vcoreg: register containing the VCO settings
- * @vco: ICST VCO parameters to commit
+ * @icst: the ICST clock to set
+ * @vco: the VCO struct to set the changes from
  */
-static void vco_set(void __iomem *lockreg,
-                       void __iomem *vcoreg,
-                       struct icst_vco vco)
+static int vco_set(struct clk_icst *icst, struct icst_vco vco)
 {
        u32 val;
+       int ret;
 
-       val = readl(vcoreg) & ~0x7ffff;
+       ret = regmap_read(icst->map, icst->vcoreg_off, &val);
+       if (ret)
+               return ret;
        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
        /* This magic unlocks the VCO so it can be controlled */
-       writel(0xa05f, lockreg);
-       writel(val, vcoreg);
+       ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL);
+       if (ret)
+               return ret;
+       ret = regmap_write(icst->map, icst->vcoreg_off, val);
+       if (ret)
+               return ret;
        /* This locks the VCO again */
-       writel(0, lockreg);
+       ret = regmap_write(icst->map, icst->lockreg_off, 0);
+       if (ret)
+               return ret;
+       return 0;
 }
 
-
 static unsigned long icst_recalc_rate(struct clk_hw *hw,
                                      unsigned long parent_rate)
 {
        struct clk_icst *icst = to_icst(hw);
        struct icst_vco vco;
+       int ret;
 
        if (parent_rate)
                icst->params->ref = parent_rate;
-       vco = vco_get(icst->vcoreg);
+       ret = vco_get(icst, &vco);
+       if (ret) {
+               pr_err("ICST: could not get VCO setting\n");
+               return 0;
+       }
        icst->rate = icst_hz(icst->params, vco);
        return icst->rate;
 }
@@ -112,8 +132,7 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
                icst->params->ref = parent_rate;
        vco = icst_hz_to_vco(icst->params, rate);
        icst->rate = icst_hz(icst->params, vco);
-       vco_set(icst->lockreg, icst->vcoreg, vco);
-       return 0;
+       return vco_set(icst, vco);
 }
 
 static const struct clk_ops icst_ops = {
@@ -122,11 +141,11 @@ static const struct clk_ops icst_ops = {
        .set_rate = icst_set_rate,
 };
 
-struct clk *icst_clk_register(struct device *dev,
-                       const struct clk_icst_desc *desc,
-                       const char *name,
-                       const char *parent_name,
-                       void __iomem *base)
+static struct clk *icst_clk_setup(struct device *dev,
+                                 const struct clk_icst_desc *desc,
+                                 const char *name,
+                                 const char *parent_name,
+                                 struct regmap *map)
 {
        struct clk *clk;
        struct clk_icst *icst;
@@ -151,10 +170,11 @@ struct clk *icst_clk_register(struct device *dev,
        init.flags = CLK_IS_ROOT;
        init.parent_names = (parent_name ? &parent_name : NULL);
        init.num_parents = (parent_name ? 1 : 0);
+       icst->map = map;
        icst->hw.init = &init;
        icst->params = pclone;
-       icst->vcoreg = base + desc->vco_offset;
-       icst->lockreg = base + desc->lock_offset;
+       icst->vcoreg_off = desc->vco_offset;
+       icst->lockreg_off = desc->lock_offset;
 
        clk = clk_register(dev, &icst->hw);
        if (IS_ERR(clk)) {
@@ -164,4 +184,112 @@ struct clk *icst_clk_register(struct device *dev,
 
        return clk;
 }
+
+struct clk *icst_clk_register(struct device *dev,
+                       const struct clk_icst_desc *desc,
+                       const char *name,
+                       const char *parent_name,
+                       void __iomem *base)
+{
+       struct regmap_config icst_regmap_conf = {
+               .reg_bits = 32,
+               .val_bits = 32,
+               .reg_stride = 4,
+       };
+       struct regmap *map;
+
+       map = regmap_init_mmio(dev, base, &icst_regmap_conf);
+       if (IS_ERR(map)) {
+               pr_err("could not initialize ICST regmap\n");
+               return ERR_CAST(map);
+       }
+       return icst_clk_setup(dev, desc, name, parent_name, map);
+}
 EXPORT_SYMBOL_GPL(icst_clk_register);
+
+#ifdef CONFIG_OF
+/*
+ * In a device tree, an memory-mapped ICST clock appear as a child
+ * of a syscon node. Assume this and probe it only as a child of a
+ * syscon.
+ */
+
+static const struct icst_params icst525_params = {
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
+       .vd_min         = 8,
+       .vd_max         = 263,
+       .rd_min         = 3,
+       .rd_max         = 65,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
+};
+
+static const struct icst_params icst307_params = {
+       .vco_max        = ICST307_VCO_MAX,
+       .vco_min        = ICST307_VCO_MIN,
+       .vd_min         = 4 + 8,
+       .vd_max         = 511 + 8,
+       .rd_min         = 1 + 2,
+       .rd_max         = 127 + 2,
+       .s2div          = icst307_s2div,
+       .idx2s          = icst307_idx2s,
+};
+
+static void __init of_syscon_icst_setup(struct device_node *np)
+{
+       struct device_node *parent;
+       struct regmap *map;
+       struct clk_icst_desc icst_desc;
+       const char *name = np->name;
+       const char *parent_name;
+       struct clk *regclk;
+
+       /* We do not release this reference, we are using it perpetually */
+       parent = of_get_parent(np);
+       if (!parent) {
+               pr_err("no parent node for syscon ICST clock\n");
+               return;
+       }
+       map = syscon_node_to_regmap(parent);
+       if (IS_ERR(map)) {
+               pr_err("no regmap for syscon ICST clock parent\n");
+               return;
+       }
+
+       if (of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) {
+               pr_err("no VCO register offset for ICST clock\n");
+               return;
+       }
+       if (of_property_read_u32(np, "lock-offset", &icst_desc.lock_offset)) {
+               pr_err("no lock register offset for ICST clock\n");
+               return;
+       }
+
+       if (of_device_is_compatible(np, "arm,syscon-icst525"))
+               icst_desc.params = &icst525_params;
+       else if (of_device_is_compatible(np, "arm,syscon-icst307"))
+               icst_desc.params = &icst307_params;
+       else {
+               pr_err("unknown ICST clock %s\n", name);
+               return;
+       }
+
+       /* Parent clock name is not the same as node parent */
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map);
+       if (IS_ERR(regclk)) {
+               pr_err("error setting up syscon ICST clock %s\n", name);
+               return;
+       }
+       of_clk_add_provider(np, of_clk_src_simple_get, regclk);
+       pr_debug("registered syscon ICST clock %s\n", name);
+}
+
+CLK_OF_DECLARE(arm_syscon_icst525_clk,
+              "arm,syscon-icst525", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_icst307_clk,
+              "arm,syscon-icst307", of_syscon_icst_setup);
+
+#endif
index 86f7099..bd4dd24 100644 (file)
 #include <linux/io.h>
 #include <linux/clk-provider.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
 #include "clk-icst.h"
 
+#define REALVIEW_SYS_OSC0_OFFSET             0x0C
+#define REALVIEW_SYS_OSC1_OFFSET             0x10
+#define REALVIEW_SYS_OSC2_OFFSET             0x14
+#define REALVIEW_SYS_OSC3_OFFSET             0x18
+#define REALVIEW_SYS_OSC4_OFFSET             0x1C      /* OSC1 for RealView/AB */
+#define REALVIEW_SYS_LOCK_OFFSET             0x20
+
 /*
  * Implementation of the ARM RealView clock trees.
  */
index b375106..dfad6eb 100644 (file)
@@ -12,8 +12,9 @@
  * power domain.  We use the Timer 4 for our always-on clock
  * source on DB8500.
  */
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/clockchips.h>
-#include <linux/clksrc-dbx500-prcmu.h>
 #include <linux/sched_clock.h>
 
 #define RATE_32K               32768
@@ -63,9 +64,9 @@ static u64 notrace dbx500_prcmu_sched_clock_read(void)
 
 #endif
 
-void __init clksrc_dbx500_prcmu_init(void __iomem *base)
+static void __init clksrc_dbx500_prcmu_init(struct device_node *node)
 {
-       clksrc_dbx500_timer_base = base;
+       clksrc_dbx500_timer_base = of_iomap(node, 0);
 
        /*
         * The A9 sub system expects the timer to be configured as
@@ -85,3 +86,5 @@ void __init clksrc_dbx500_prcmu_init(void __iomem *base)
 #endif
        clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K);
 }
+CLOCKSOURCE_OF_DECLARE(dbx500_prcmu, "stericsson,db8500-prcmu-timer-4",
+                      clksrc_dbx500_prcmu_init);
index 8c7930b..7e48eb5 100644 (file)
@@ -19,11 +19,9 @@ config CPU_IDLE_MULTIPLE_DRIVERS
 
 config CPU_IDLE_GOV_LADDER
        bool "Ladder governor (for periodic timer tick)"
-       default y
 
 config CPU_IDLE_GOV_MENU
        bool "Menu governor (for tickless system)"
-       default y
 
 config DT_IDLE_STATES
        bool
index 17a6dc0..046423b 100644 (file)
@@ -79,9 +79,9 @@ static int find_deepest_state(struct cpuidle_driver *drv,
                              bool freeze)
 {
        unsigned int latency_req = 0;
-       int i, ret = -ENXIO;
+       int i, ret = 0;
 
-       for (i = 0; i < drv->state_count; i++) {
+       for (i = 1; i < drv->state_count; i++) {
                struct cpuidle_state *s = &drv->states[i];
                struct cpuidle_state_usage *su = &dev->states_usage[i];
 
@@ -243,7 +243,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
  * @drv: the cpuidle driver
  * @dev: the cpuidle device
  *
- * Returns the index of the idle state.
+ * Returns the index of the idle state.  The return value must not be negative.
  */
 int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 {
index 401c010..63bd5a4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/pm_qos.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
+#include <linux/tick.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -184,6 +185,14 @@ static struct cpuidle_governor ladder_governor = {
  */
 static int __init init_ladder(void)
 {
+       /*
+        * When NO_HZ is disabled, or when booting with nohz=off, the ladder
+        * governor is better so give it a higher rating than the menu
+        * governor.
+        */
+       if (!tick_nohz_enabled)
+               ladder_governor.rating = 25;
+
        return cpuidle_register_governor(&ladder_governor);
 }
 
index 7b0971d..0742b32 100644 (file)
@@ -294,8 +294,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
                data->needs_update = 0;
        }
 
-       data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1;
-
        /* Special case when user has set very strict latency requirement */
        if (unlikely(latency_req == 0))
                return 0;
@@ -326,20 +324,25 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
        if (latency_req > interactivity_req)
                latency_req = interactivity_req;
 
-       /*
-        * We want to default to C1 (hlt), not to busy polling
-        * unless the timer is happening really really soon.
-        */
-       if (interactivity_req > 20 &&
-           !drv->states[CPUIDLE_DRIVER_STATE_START].disabled &&
-               dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0)
+       if (CPUIDLE_DRIVER_STATE_START > 0) {
+               data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1;
+               /*
+                * We want to default to C1 (hlt), not to busy polling
+                * unless the timer is happening really really soon.
+                */
+               if (interactivity_req > 20 &&
+                   !drv->states[CPUIDLE_DRIVER_STATE_START].disabled &&
+                       dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0)
+                       data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
+       } else {
                data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
+       }
 
        /*
         * Find the idle state with the lowest power while satisfying
         * our constraints.
         */
-       for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
+       for (i = data->last_state_idx + 1; i < drv->state_count; i++) {
                struct cpuidle_state *s = &drv->states[i];
                struct cpuidle_state_usage *su = &dev->states_usage[i];
 
index 3dd69df..07d4942 100644 (file)
@@ -381,6 +381,7 @@ config CRYPTO_DEV_BFIN_CRC
 
 config CRYPTO_DEV_ATMEL_AES
        tristate "Support for Atmel AES hw accelerator"
+       depends on HAS_DMA
        depends on AT_XDMAC || AT_HDMAC || COMPILE_TEST
        select CRYPTO_AES
        select CRYPTO_AEAD
index 5621612..6dd3317 100644 (file)
@@ -280,6 +280,7 @@ static const char *atmel_aes_reg_name(u32 offset, char *tmp, size_t sz)
        case AES_GCMHR(2):
        case AES_GCMHR(3):
                snprintf(tmp, sz, "GCMHR[%u]", (offset - AES_GCMHR(0)) >> 2);
+               break;
 
        default:
                snprintf(tmp, sz, "0x%02x", offset);
index 0ac0ba8..1e480f1 100644 (file)
@@ -389,7 +389,7 @@ static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle)
 {
        unsigned int base_cnt, cur_cnt;
        unsigned char ae;
-       unsigned int times = MAX_RETRY_TIMES;
+       int times = MAX_RETRY_TIMES;
 
        for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
                qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT,
@@ -402,7 +402,7 @@ static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle)
                        cur_cnt &= 0xffff;
                } while (times-- && (cur_cnt == base_cnt));
 
-               if (!times) {
+               if (times < 0) {
                        pr_err("QAT: AE%d is inactive!!\n", ae);
                        return -EFAULT;
                }
@@ -453,7 +453,11 @@ static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle)
        void __iomem *csr_addr =
                        (void __iomem *)((uintptr_t)handle->hal_ep_csr_addr_v +
                        ESRAM_AUTO_INIT_CSR_OFFSET);
-       unsigned int csr_val, times = 30;
+       unsigned int csr_val;
+       int times = 30;
+
+       if (handle->pci_dev->device == ADF_C3XXX_PCI_DEVICE_ID)
+               return 0;
 
        csr_val = ADF_CSR_RD(csr_addr, 0);
        if ((csr_val & ESRAM_AUTO_TINIT) && (csr_val & ESRAM_AUTO_TINIT_DONE))
@@ -467,7 +471,7 @@ static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle)
                qat_hal_wait_cycles(handle, 0, ESRAM_AUTO_INIT_USED_CYCLES, 0);
                csr_val = ADF_CSR_RD(csr_addr, 0);
        } while (!(csr_val & ESRAM_AUTO_TINIT_DONE) && times--);
-       if ((!times)) {
+       if ((times < 0)) {
                pr_err("QAT: Fail to init eSram!\n");
                return -EFAULT;
        }
@@ -658,7 +662,7 @@ static int qat_hal_clear_gpr(struct icp_qat_fw_loader_handle *handle)
                        ret = qat_hal_wait_cycles(handle, ae, 20, 1);
                } while (ret && times--);
 
-               if (!times) {
+               if (times < 0) {
                        pr_err("QAT: clear GPR of AE %d failed", ae);
                        return -EINVAL;
                }
@@ -693,14 +697,12 @@ int qat_hal_init(struct adf_accel_dev *accel_dev)
        struct adf_hw_device_data *hw_data = accel_dev->hw_device;
        struct adf_bar *misc_bar =
                        &pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)];
-       struct adf_bar *sram_bar =
-                       &pci_info->pci_bars[hw_data->get_sram_bar_id(hw_data)];
+       struct adf_bar *sram_bar;
 
        handle = kzalloc(sizeof(*handle), GFP_KERNEL);
        if (!handle)
                return -ENOMEM;
 
-       handle->hal_sram_addr_v = sram_bar->virt_addr;
        handle->hal_cap_g_ctl_csr_addr_v =
                (void __iomem *)((uintptr_t)misc_bar->virt_addr +
                                 ICP_QAT_CAP_OFFSET);
@@ -714,6 +716,11 @@ int qat_hal_init(struct adf_accel_dev *accel_dev)
                (void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v +
                                 LOCAL_TO_XFER_REG_OFFSET);
        handle->pci_dev = pci_info->pci_dev;
+       if (handle->pci_dev->device != ADF_C3XXX_PCI_DEVICE_ID) {
+               sram_bar =
+                       &pci_info->pci_bars[hw_data->get_sram_bar_id(hw_data)];
+               handle->hal_sram_addr_v = sram_bar->virt_addr;
+       }
        handle->fw_auth = (handle->pci_dev->device ==
                           ADF_DH895XCC_PCI_DEVICE_ID) ? false : true;
        handle->hal_handle = kzalloc(sizeof(*handle->hal_handle), GFP_KERNEL);
index f304a02..38bf144 100644 (file)
@@ -226,17 +226,12 @@ struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(struct device *dev,
        struct device_node *node;
        struct devfreq_event_dev *edev;
 
-       if (!dev->of_node) {
-               dev_err(dev, "device does not have a device node entry\n");
+       if (!dev->of_node)
                return ERR_PTR(-EINVAL);
-       }
 
        node = of_parse_phandle(dev->of_node, "devfreq-events", index);
-       if (!node) {
-               dev_err(dev, "failed to get phandle in %s node\n",
-                       dev->of_node->full_name);
+       if (!node)
                return ERR_PTR(-ENODEV);
-       }
 
        mutex_lock(&devfreq_event_list_lock);
        list_for_each_entry(edev, &devfreq_event_list, node) {
@@ -248,8 +243,6 @@ out:
        mutex_unlock(&devfreq_event_list_lock);
 
        if (!edev) {
-               dev_err(dev, "unable to get devfreq-event device : %s\n",
-                       node->name);
                of_node_put(node);
                return ERR_PTR(-ENODEV);
        }
@@ -277,7 +270,7 @@ int devfreq_event_get_edev_count(struct device *dev)
 
        count = of_property_count_elems_of_size(dev->of_node, "devfreq-events",
                                                sizeof(u32));
-       if (count < 0 ) {
+       if (count < 0) {
                dev_err(dev,
                        "failed to get the count of devfreq-event in %s node\n",
                        dev->of_node->full_name);
@@ -402,7 +395,8 @@ struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev,
 {
        struct devfreq_event_dev **ptr, *edev;
 
-       ptr = devres_alloc(devm_devfreq_event_release, sizeof(*ptr), GFP_KERNEL);
+       ptr = devres_alloc(devm_devfreq_event_release, sizeof(*ptr),
+                               GFP_KERNEL);
        if (!ptr)
                return ERR_PTR(-ENOMEM);
 
index ca848cc..984c5e9 100644 (file)
@@ -84,6 +84,46 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
        return -EINVAL;
 }
 
+/**
+ * devfreq_set_freq_table() - Initialize freq_table for the frequency
+ * @devfreq:   the devfreq instance
+ */
+static void devfreq_set_freq_table(struct devfreq *devfreq)
+{
+       struct devfreq_dev_profile *profile = devfreq->profile;
+       struct dev_pm_opp *opp;
+       unsigned long freq;
+       int i, count;
+
+       /* Initialize the freq_table from OPP table */
+       count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
+       if (count <= 0)
+               return;
+
+       profile->max_state = count;
+       profile->freq_table = devm_kcalloc(devfreq->dev.parent,
+                                       profile->max_state,
+                                       sizeof(*profile->freq_table),
+                                       GFP_KERNEL);
+       if (!profile->freq_table) {
+               profile->max_state = 0;
+               return;
+       }
+
+       rcu_read_lock();
+       for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
+               opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq);
+               if (IS_ERR(opp)) {
+                       devm_kfree(devfreq->dev.parent, profile->freq_table);
+                       profile->max_state = 0;
+                       rcu_read_unlock();
+                       return;
+               }
+               profile->freq_table[i] = freq;
+       }
+       rcu_read_unlock();
+}
+
 /**
  * devfreq_update_status() - Update statistics of devfreq behavior
  * @devfreq:   the devfreq instance
@@ -478,6 +518,12 @@ struct devfreq *devfreq_add_device(struct device *dev,
        devfreq->data = data;
        devfreq->nb.notifier_call = devfreq_notifier_call;
 
+       if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
+               mutex_unlock(&devfreq->lock);
+               devfreq_set_freq_table(devfreq);
+               mutex_lock(&devfreq->lock);
+       }
+
        devfreq->trans_table =  devm_kzalloc(dev, sizeof(unsigned int) *
                                                devfreq->profile->max_state *
                                                devfreq->profile->max_state,
@@ -921,12 +967,6 @@ unlock:
        return ret;
 }
 
-static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
-                            char *buf)
-{
-       return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq);
-}
-
 static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
                              const char *buf, size_t count)
 {
@@ -953,13 +993,17 @@ unlock:
        mutex_unlock(&df->lock);
        return ret;
 }
-static DEVICE_ATTR_RW(min_freq);
 
-static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
-                            char *buf)
-{
-       return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq);
+#define show_one(name)                                         \
+static ssize_t name##_show                                     \
+(struct device *dev, struct device_attribute *attr, char *buf) \
+{                                                              \
+       return sprintf(buf, "%lu\n", to_devfreq(dev)->name);    \
 }
+show_one(min_freq);
+show_one(max_freq);
+
+static DEVICE_ATTR_RW(min_freq);
 static DEVICE_ATTR_RW(max_freq);
 
 static ssize_t available_frequencies_show(struct device *d,
@@ -1005,11 +1049,13 @@ static ssize_t trans_stat_show(struct device *dev,
        if (!devfreq->stop_polling &&
                        devfreq_update_status(devfreq, devfreq->previous_freq))
                return 0;
+       if (max_state == 0)
+               return sprintf(buf, "Not Supported.\n");
 
-       len = sprintf(buf, "   From  :   To\n");
-       len += sprintf(buf + len, "         :");
+       len = sprintf(buf, "     From  :   To\n");
+       len += sprintf(buf + len, "           :");
        for (i = 0; i < max_state; i++)
-               len += sprintf(buf + len, "%8u",
+               len += sprintf(buf + len, "%10lu",
                                devfreq->profile->freq_table[i]);
 
        len += sprintf(buf + len, "   time(ms)\n");
@@ -1021,10 +1067,10 @@ static ssize_t trans_stat_show(struct device *dev,
                } else {
                        len += sprintf(buf + len, " ");
                }
-               len += sprintf(buf + len, "%8u:",
+               len += sprintf(buf + len, "%10lu:",
                                devfreq->profile->freq_table[i]);
                for (j = 0; j < max_state; j++)
-                       len += sprintf(buf + len, "%8u",
+                       len += sprintf(buf + len, "%10u",
                                devfreq->trans_table[(i * max_state) + j]);
                len += sprintf(buf + len, "%10u\n",
                        jiffies_to_msecs(devfreq->time_in_state[i]));
index e415945..0c2f0a6 100644 (file)
@@ -56,9 +56,7 @@ static u32 find_nvram_size(void __iomem *end)
 static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
 {
        struct nvram_header __iomem *header;
-       int i;
        u32 off;
-       u32 *src, *dst;
        u32 size;
 
        if (nvram_len) {
@@ -95,10 +93,7 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
        return -ENXIO;
 
 found:
-       src = (u32 *)header;
-       dst = (u32 *)nvram_buf;
-       for (i = 0; i < sizeof(struct nvram_header); i += 4)
-               *dst++ = __raw_readl(src++);
+       __ioread32_copy(nvram_buf, header, sizeof(*header) / 4);
        header = (struct nvram_header *)nvram_buf;
        nvram_len = header->len;
        if (nvram_len > size) {
@@ -111,8 +106,8 @@ found:
                nvram_len = NVRAM_SPACE - 1;
        }
        /* proceed reading data after header */
-       for (; i < nvram_len; i += 4)
-               *dst++ = readl(src++);
+       __ioread32_copy(nvram_buf + sizeof(*header), header + 1,
+                       DIV_ROUND_UP(nvram_len, 4));
        nvram_buf[NVRAM_SPACE - 1] = '\0';
 
        return 0;
index 9c12e18..aaf9c0b 100644 (file)
@@ -22,6 +22,7 @@ KBUILD_CFLAGS                 := $(cflags-y) -DDISABLE_BRANCH_PROFILING \
 
 GCOV_PROFILE                   := n
 KASAN_SANITIZE                 := n
+UBSAN_SANITIZE                 := n
 
 lib-y                          := efi-stub-helper.o
 
index cb212eb..c88dd24 100644 (file)
@@ -344,13 +344,6 @@ config GPIO_RCAR
        help
          Say yes here to support GPIO on Renesas R-Car SoCs.
 
-config GPIO_SAMSUNG
-       bool
-       depends on PLAT_SAMSUNG
-       help
-         Legacy GPIO support. Use only for platforms without support for
-         pinctrl.
-
 config GPIO_SPEAR_SPICS
        bool "ST SPEAr13xx SPI Chip Select as GPIO support"
        depends on PLAT_SPEAR
index 548e9b5..ece7d7c 100644 (file)
@@ -80,7 +80,6 @@ obj-$(CONFIG_GPIO_PXA)                += gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)     += gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)     += gpio-rdc321x.o
 obj-$(CONFIG_GPIO_RCAR)                += gpio-rcar.o
-obj-$(CONFIG_GPIO_SAMSUNG)     += gpio-samsung.o
 obj-$(CONFIG_ARCH_SA1100)      += gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)         += gpio-sch.o
 obj-$(CONFIG_GPIO_SCH311X)     += gpio-sch311x.o
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
deleted file mode 100644 (file)
index 4cb4a31..0000000
+++ /dev/null
@@ -1,1328 +0,0 @@
-/*
- * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * SAMSUNG - GPIOlib 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/ioport.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-#include <linux/of_address.h>
-
-#include <asm/irq.h>
-
-#include <mach/map.h>
-#include <mach/regs-gpio.h>
-#include <mach/gpio-samsung.h>
-
-#include <plat/cpu.h>
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <plat/pm.h>
-
-int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
-                               unsigned int off, samsung_gpio_pull_t pull)
-{
-       void __iomem *reg = chip->base + 0x08;
-       int shift = off * 2;
-       u32 pup;
-
-       pup = __raw_readl(reg);
-       pup &= ~(3 << shift);
-       pup |= pull << shift;
-       __raw_writel(pup, reg);
-
-       return 0;
-}
-
-samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
-                                               unsigned int off)
-{
-       void __iomem *reg = chip->base + 0x08;
-       int shift = off * 2;
-       u32 pup = __raw_readl(reg);
-
-       pup >>= shift;
-       pup &= 0x3;
-
-       return (__force samsung_gpio_pull_t)pup;
-}
-
-int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
-                        unsigned int off, samsung_gpio_pull_t pull)
-{
-       switch (pull) {
-       case S3C_GPIO_PULL_NONE:
-               pull = 0x01;
-               break;
-       case S3C_GPIO_PULL_UP:
-               pull = 0x00;
-               break;
-       case S3C_GPIO_PULL_DOWN:
-               pull = 0x02;
-               break;
-       }
-       return samsung_gpio_setpull_updown(chip, off, pull);
-}
-
-samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
-                                        unsigned int off)
-{
-       samsung_gpio_pull_t pull;
-
-       pull = samsung_gpio_getpull_updown(chip, off);
-
-       switch (pull) {
-       case 0x00:
-               pull = S3C_GPIO_PULL_UP;
-               break;
-       case 0x01:
-       case 0x03:
-               pull = S3C_GPIO_PULL_NONE;
-               break;
-       case 0x02:
-               pull = S3C_GPIO_PULL_DOWN;
-               break;
-       }
-
-       return pull;
-}
-
-static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
-                                 unsigned int off, samsung_gpio_pull_t pull,
-                                 samsung_gpio_pull_t updown)
-{
-       void __iomem *reg = chip->base + 0x08;
-       u32 pup = __raw_readl(reg);
-
-       if (pull == updown)
-               pup &= ~(1 << off);
-       else if (pull == S3C_GPIO_PULL_NONE)
-               pup |= (1 << off);
-       else
-               return -EINVAL;
-
-       __raw_writel(pup, reg);
-       return 0;
-}
-
-static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
-                                                 unsigned int off,
-                                                 samsung_gpio_pull_t updown)
-{
-       void __iomem *reg = chip->base + 0x08;
-       u32 pup = __raw_readl(reg);
-
-       pup &= (1 << off);
-       return pup ? S3C_GPIO_PULL_NONE : updown;
-}
-
-samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
-                                            unsigned int off)
-{
-       return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
-}
-
-int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
-                            unsigned int off, samsung_gpio_pull_t pull)
-{
-       return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
-}
-
-samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
-                                              unsigned int off)
-{
-       return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
-}
-
-int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
-                              unsigned int off, samsung_gpio_pull_t pull)
-{
-       return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
-}
-
-/*
- * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has two bits of configuration per gpio, which have the following
- * functions:
- *     00 = input
- *     01 = output
- *     1x = special function
- */
-
-static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
-                                   unsigned int off, unsigned int cfg)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = off * 2;
-       u32 con;
-
-       if (samsung_gpio_is_cfg_special(cfg)) {
-               cfg &= 0xf;
-               if (cfg > 3)
-                       return -EINVAL;
-
-               cfg <<= shift;
-       }
-
-       con = __raw_readl(reg);
-       con &= ~(0x3 << shift);
-       con |= cfg;
-       __raw_writel(con, reg);
-
-       return 0;
-}
-
-/*
- * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- *
- * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
- * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
- * S3C_GPIO_SPECIAL() macro.
- */
-
-static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
-                                            unsigned int off)
-{
-       u32 con;
-
-       con = __raw_readl(chip->base);
-       con >>= off * 2;
-       con &= 3;
-
-       /* this conversion works for IN and OUT as well as special mode */
-       return S3C_GPIO_SPECIAL(con);
-}
-
-/*
- * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register has 4 bits
- * of control per GPIO, generally in the form of:
- *     0000 = Input
- *     0001 = Output
- *     others = Special functions (dependent on bank)
- *
- * Note, since the code to deal with the case where there are two control
- * registers instead of one, we do not have a separate set of functions for
- * each case.
- */
-
-static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
-                                   unsigned int off, unsigned int cfg)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = (off & 7) * 4;
-       u32 con;
-
-       if (off < 8 && chip->chip.ngpio > 8)
-               reg -= 4;
-
-       if (samsung_gpio_is_cfg_special(cfg)) {
-               cfg &= 0xf;
-               cfg <<= shift;
-       }
-
-       con = __raw_readl(reg);
-       con &= ~(0xf << shift);
-       con |= cfg;
-       __raw_writel(con, reg);
-
-       return 0;
-}
-
-/*
- * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- *
- * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
- * register setting into a value the software can use, such as could be passed
- * to samsung_gpio_setcfg_4bit().
- *
- * @sa samsung_gpio_getcfg_2bit
- */
-
-static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
-                                        unsigned int off)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = (off & 7) * 4;
-       u32 con;
-
-       if (off < 8 && chip->chip.ngpio > 8)
-               reg -= 4;
-
-       con = __raw_readl(reg);
-       con >>= shift;
-       con &= 0xf;
-
-       /* this conversion works for IN and OUT as well as special mode */
-       return S3C_GPIO_SPECIAL(con);
-}
-
-#ifdef CONFIG_PLAT_S3C24XX
-/*
- * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has one bit of configuration for the gpio, where setting the bit
- * means the pin is in special function mode and unset means output.
- */
-
-static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
-                                    unsigned int off, unsigned int cfg)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = off;
-       u32 con;
-
-       if (samsung_gpio_is_cfg_special(cfg)) {
-               cfg &= 0xf;
-
-               /* Map output to 0, and SFN2 to 1 */
-               cfg -= 1;
-               if (cfg > 1)
-                       return -EINVAL;
-
-               cfg <<= shift;
-       }
-
-       con = __raw_readl(reg);
-       con &= ~(0x1 << shift);
-       con |= cfg;
-       __raw_writel(con, reg);
-
-       return 0;
-}
-
-/*
- * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- *
- * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
- * GPIO configuration value.
- *
- * @sa samsung_gpio_getcfg_2bit
- * @sa samsung_gpio_getcfg_4bit
- */
-
-static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
-                                         unsigned int off)
-{
-       u32 con;
-
-       con = __raw_readl(chip->base);
-       con >>= off;
-       con &= 1;
-       con++;
-
-       return S3C_GPIO_SFN(con);
-}
-#endif
-
-static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
-                                          int nr_chips)
-{
-       for (; nr_chips > 0; nr_chips--, chipcfg++) {
-               if (!chipcfg->set_config)
-                       chipcfg->set_config = samsung_gpio_setcfg_4bit;
-               if (!chipcfg->get_config)
-                       chipcfg->get_config = samsung_gpio_getcfg_4bit;
-               if (!chipcfg->set_pull)
-                       chipcfg->set_pull = samsung_gpio_setpull_updown;
-               if (!chipcfg->get_pull)
-                       chipcfg->get_pull = samsung_gpio_getpull_updown;
-       }
-}
-
-struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
-       .set_config     = samsung_gpio_setcfg_2bit,
-       .get_config     = samsung_gpio_getcfg_2bit,
-};
-
-#ifdef CONFIG_PLAT_S3C24XX
-static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
-       .set_config     = s3c24xx_gpio_setcfg_abank,
-       .get_config     = s3c24xx_gpio_getcfg_abank,
-};
-#endif
-
-static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
-       [0] = {
-               .cfg_eint       = 0x0,
-       },
-       [1] = {
-               .cfg_eint       = 0x3,
-       },
-       [2] = {
-               .cfg_eint       = 0x7,
-       },
-       [3] = {
-               .cfg_eint       = 0xF,
-       },
-       [4] = {
-               .cfg_eint       = 0x0,
-               .set_config     = samsung_gpio_setcfg_2bit,
-               .get_config     = samsung_gpio_getcfg_2bit,
-       },
-       [5] = {
-               .cfg_eint       = 0x2,
-               .set_config     = samsung_gpio_setcfg_2bit,
-               .get_config     = samsung_gpio_getcfg_2bit,
-       },
-       [6] = {
-               .cfg_eint       = 0x3,
-               .set_config     = samsung_gpio_setcfg_2bit,
-               .get_config     = samsung_gpio_getcfg_2bit,
-       },
-       [7] = {
-               .set_config     = samsung_gpio_setcfg_2bit,
-               .get_config     = samsung_gpio_getcfg_2bit,
-       },
-};
-
-/*
- * Default routines for controlling GPIO, based on the original S3C24XX
- * GPIO functions which deal with the case where each gpio bank of the
- * chip is as following:
- *
- * base + 0x00: Control register, 2 bits per gpio
- *             gpio n: 2 bits starting at (2*n)
- *             00 = input, 01 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *             bit n: data bit n
-*/
-
-static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long con;
-
-       samsung_gpio_lock(ourchip, flags);
-
-       con = __raw_readl(base + 0x00);
-       con &= ~(3 << (offset * 2));
-
-       __raw_writel(con, base + 0x00);
-
-       samsung_gpio_unlock(ourchip, flags);
-       return 0;
-}
-
-static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
-                                      unsigned offset, int value)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long dat;
-       unsigned long con;
-
-       samsung_gpio_lock(ourchip, flags);
-
-       dat = __raw_readl(base + 0x04);
-       dat &= ~(1 << offset);
-       if (value)
-               dat |= 1 << offset;
-       __raw_writel(dat, base + 0x04);
-
-       con = __raw_readl(base + 0x00);
-       con &= ~(3 << (offset * 2));
-       con |= 1 << (offset * 2);
-
-       __raw_writel(con, base + 0x00);
-       __raw_writel(dat, base + 0x04);
-
-       samsung_gpio_unlock(ourchip, flags);
-       return 0;
-}
-
-/*
- * The samsung_gpiolib_4bit routines are to control the gpio banks where
- * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
- * following example:
- *
- * base + 0x00: Control register, 4 bits per gpio
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *             bit n: data bit n
- *
- * Note, since the data register is one bit per gpio and is at base + 0x4
- * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
- * state of the output.
- */
-
-static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
-                                     unsigned int offset)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long con;
-
-       con = __raw_readl(base + GPIOCON_OFF);
-       if (ourchip->bitmap_gpio_int & BIT(offset))
-               con |= 0xf << con_4bit_shift(offset);
-       else
-               con &= ~(0xf << con_4bit_shift(offset));
-       __raw_writel(con, base + GPIOCON_OFF);
-
-       pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
-
-       return 0;
-}
-
-static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
-                                      unsigned int offset, int value)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long con;
-       unsigned long dat;
-
-       con = __raw_readl(base + GPIOCON_OFF);
-       con &= ~(0xf << con_4bit_shift(offset));
-       con |= 0x1 << con_4bit_shift(offset);
-
-       dat = __raw_readl(base + GPIODAT_OFF);
-
-       if (value)
-               dat |= 1 << offset;
-       else
-               dat &= ~(1 << offset);
-
-       __raw_writel(dat, base + GPIODAT_OFF);
-       __raw_writel(con, base + GPIOCON_OFF);
-       __raw_writel(dat, base + GPIODAT_OFF);
-
-       pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-       return 0;
-}
-
-/*
- * The next set of routines are for the case where the GPIO configuration
- * registers are 4 bits per GPIO but there is more than one register (the
- * bank has more than 8 GPIOs.
- *
- * This case is the similar to the 4 bit case, but the registers are as
- * follows:
- *
- * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x08: Data register, 1 bit per gpio
- *             bit n: data bit n
- *
- * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
- * routines we store the 'base + 0x4' address so that these routines see
- * the data register at ourchip->base + 0x04.
- */
-
-static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
-                                      unsigned int offset)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       void __iomem *regcon = base;
-       unsigned long con;
-
-       if (offset > 7)
-               offset -= 8;
-       else
-               regcon -= 4;
-
-       con = __raw_readl(regcon);
-       con &= ~(0xf << con_4bit_shift(offset));
-       __raw_writel(con, regcon);
-
-       pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
-
-       return 0;
-}
-
-static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
-                                       unsigned int offset, int value)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       void __iomem *regcon = base;
-       unsigned long con;
-       unsigned long dat;
-       unsigned con_offset = offset;
-
-       if (con_offset > 7)
-               con_offset -= 8;
-       else
-               regcon -= 4;
-
-       con = __raw_readl(regcon);
-       con &= ~(0xf << con_4bit_shift(con_offset));
-       con |= 0x1 << con_4bit_shift(con_offset);
-
-       dat = __raw_readl(base + GPIODAT_OFF);
-
-       if (value)
-               dat |= 1 << offset;
-       else
-               dat &= ~(1 << offset);
-
-       __raw_writel(dat, base + GPIODAT_OFF);
-       __raw_writel(con, regcon);
-       __raw_writel(dat, base + GPIODAT_OFF);
-
-       pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-       return 0;
-}
-
-#ifdef CONFIG_PLAT_S3C24XX
-/* The next set of routines are for the case of s3c24xx bank a */
-
-static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
-{
-       return -EINVAL;
-}
-
-static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
-                                       unsigned offset, int value)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long dat;
-       unsigned long con;
-
-       local_irq_save(flags);
-
-       con = __raw_readl(base + 0x00);
-       dat = __raw_readl(base + 0x04);
-
-       dat &= ~(1 << offset);
-       if (value)
-               dat |= 1 << offset;
-
-       __raw_writel(dat, base + 0x04);
-
-       con &= ~(1 << offset);
-
-       __raw_writel(con, base + 0x00);
-       __raw_writel(dat, base + 0x04);
-
-       local_irq_restore(flags);
-       return 0;
-}
-#endif
-
-static void samsung_gpiolib_set(struct gpio_chip *chip,
-                               unsigned offset, int value)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long dat;
-
-       samsung_gpio_lock(ourchip, flags);
-
-       dat = __raw_readl(base + 0x04);
-       dat &= ~(1 << offset);
-       if (value)
-               dat |= 1 << offset;
-       __raw_writel(dat, base + 0x04);
-
-       samsung_gpio_unlock(ourchip, flags);
-}
-
-static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
-       unsigned long val;
-
-       val = __raw_readl(ourchip->base + 0x04);
-       val >>= offset;
-       val &= 1;
-
-       return val;
-}
-
-/*
- * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
- * for use with the configuration calls, and other parts of the s3c gpiolib
- * support code.
- *
- * Not all s3c support code will need this, as some configurations of cpu
- * may only support one or two different configuration options and have an
- * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
- * the machine support file should provide its own samsung_gpiolib_getchip()
- * and any other necessary functions.
- */
-
-#ifdef CONFIG_S3C_GPIO_TRACK
-struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
-
-static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
-{
-       unsigned int gpn;
-       int i;
-
-       gpn = chip->chip.base;
-       for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
-               BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
-               s3c_gpios[gpn] = chip;
-       }
-}
-#endif /* CONFIG_S3C_GPIO_TRACK */
-
-/*
- * samsung_gpiolib_add() - add the Samsung gpio_chip.
- * @chip: The chip to register
- *
- * This is a wrapper to gpiochip_add() that takes our specific gpio chip
- * information and makes the necessary alterations for the platform and
- * notes the information for use with the configuration systems and any
- * other parts of the system.
- */
-
-static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
-{
-       struct gpio_chip *gc = &chip->chip;
-       int ret;
-
-       BUG_ON(!chip->base);
-       BUG_ON(!gc->label);
-       BUG_ON(!gc->ngpio);
-
-       spin_lock_init(&chip->lock);
-
-       if (!gc->direction_input)
-               gc->direction_input = samsung_gpiolib_2bit_input;
-       if (!gc->direction_output)
-               gc->direction_output = samsung_gpiolib_2bit_output;
-       if (!gc->set)
-               gc->set = samsung_gpiolib_set;
-       if (!gc->get)
-               gc->get = samsung_gpiolib_get;
-
-#ifdef CONFIG_PM
-       if (chip->pm != NULL) {
-               if (!chip->pm->save || !chip->pm->resume)
-                       pr_err("gpio: %s has missing PM functions\n",
-                              gc->label);
-       } else
-               pr_err("gpio: %s has no PM function\n", gc->label);
-#endif
-
-       /* gpiochip_add() prints own failure message on error. */
-       ret = gpiochip_add_data(gc, chip);
-       if (ret >= 0)
-               s3c_gpiolib_track(chip);
-}
-
-static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
-                                            int nr_chips, void __iomem *base)
-{
-       int i;
-       struct gpio_chip *gc = &chip->chip;
-
-       for (i = 0 ; i < nr_chips; i++, chip++) {
-               /* skip banks not present on SoC */
-               if (chip->chip.base >= S3C_GPIO_END)
-                       continue;
-
-               if (!chip->config)
-                       chip->config = &s3c24xx_gpiocfg_default;
-               if (!chip->pm)
-                       chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
-               if ((base != NULL) && (chip->base == NULL))
-                       chip->base = base + ((i) * 0x10);
-
-               if (!gc->direction_input)
-                       gc->direction_input = samsung_gpiolib_2bit_input;
-               if (!gc->direction_output)
-                       gc->direction_output = samsung_gpiolib_2bit_output;
-
-               samsung_gpiolib_add(chip);
-       }
-}
-
-static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
-                                                 int nr_chips, void __iomem *base,
-                                                 unsigned int offset)
-{
-       int i;
-
-       for (i = 0 ; i < nr_chips; i++, chip++) {
-               chip->chip.direction_input = samsung_gpiolib_2bit_input;
-               chip->chip.direction_output = samsung_gpiolib_2bit_output;
-
-               if (!chip->config)
-                       chip->config = &samsung_gpio_cfgs[7];
-               if (!chip->pm)
-                       chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
-               if ((base != NULL) && (chip->base == NULL))
-                       chip->base = base + ((i) * offset);
-
-               samsung_gpiolib_add(chip);
-       }
-}
-
-/*
- * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
- * @chip: The gpio chip that is being configured.
- * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
- *
- * This helper deal with the GPIO cases where the control register has 4 bits
- * of control per GPIO, generally in the form of:
- * 0000 = Input
- * 0001 = Output
- * others = Special functions (dependent on bank)
- *
- * Note, since the code to deal with the case where there are two control
- * registers instead of one, we do not have a separate set of function
- * (samsung_gpiolib_add_4bit2_chips)for each case.
- */
-
-static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
-                                                 int nr_chips, void __iomem *base)
-{
-       int i;
-
-       for (i = 0 ; i < nr_chips; i++, chip++) {
-               chip->chip.direction_input = samsung_gpiolib_4bit_input;
-               chip->chip.direction_output = samsung_gpiolib_4bit_output;
-
-               if (!chip->config)
-                       chip->config = &samsung_gpio_cfgs[2];
-               if (!chip->pm)
-                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
-               if ((base != NULL) && (chip->base == NULL))
-                       chip->base = base + ((i) * 0x20);
-
-               chip->bitmap_gpio_int = 0;
-
-               samsung_gpiolib_add(chip);
-       }
-}
-
-static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
-                                                  int nr_chips)
-{
-       for (; nr_chips > 0; nr_chips--, chip++) {
-               chip->chip.direction_input = samsung_gpiolib_4bit2_input;
-               chip->chip.direction_output = samsung_gpiolib_4bit2_output;
-
-               if (!chip->config)
-                       chip->config = &samsung_gpio_cfgs[2];
-               if (!chip->pm)
-                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
-
-               samsung_gpiolib_add(chip);
-       }
-}
-
-int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-       struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
-
-       return samsung_chip->irq_base + offset;
-}
-
-#ifdef CONFIG_PLAT_S3C24XX
-static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-       if (offset < 4) {
-               if (soc_is_s3c2412())
-                       return IRQ_EINT0_2412 + offset;
-               else
-                       return IRQ_EINT0 + offset;
-       }
-
-       if (offset < 8)
-               return IRQ_EINT4 + offset - 4;
-
-       return -EINVAL;
-}
-#endif
-
-#ifdef CONFIG_ARCH_S3C64XX
-static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
-{
-       return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
-}
-
-static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
-{
-       return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
-}
-#endif
-
-struct samsung_gpio_chip s3c24xx_gpios[] = {
-#ifdef CONFIG_PLAT_S3C24XX
-       {
-               .config = &s3c24xx_gpiocfg_banka,
-               .chip   = {
-                       .base                   = S3C2410_GPA(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOA",
-                       .ngpio                  = 27,
-                       .direction_input        = s3c24xx_gpiolib_banka_input,
-                       .direction_output       = s3c24xx_gpiolib_banka_output,
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C2410_GPB(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOB",
-                       .ngpio  = 11,
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C2410_GPC(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOC",
-                       .ngpio  = 16,
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C2410_GPD(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOD",
-                       .ngpio  = 16,
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C2410_GPE(0),
-                       .label  = "GPIOE",
-                       .owner  = THIS_MODULE,
-                       .ngpio  = 16,
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C2410_GPF(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOF",
-                       .ngpio  = 8,
-                       .to_irq = s3c24xx_gpiolib_fbank_to_irq,
-               },
-       }, {
-               .irq_base = IRQ_EINT8,
-               .chip   = {
-                       .base   = S3C2410_GPG(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOG",
-                       .ngpio  = 16,
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C2410_GPH(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOH",
-                       .ngpio  = 15,
-               },
-       },
-               /* GPIOS for the S3C2443 and later devices. */
-       {
-               .base   = S3C2440_GPJCON,
-               .chip   = {
-                       .base   = S3C2410_GPJ(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOJ",
-                       .ngpio  = 16,
-               },
-       }, {
-               .base   = S3C2443_GPKCON,
-               .chip   = {
-                       .base   = S3C2410_GPK(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOK",
-                       .ngpio  = 16,
-               },
-       }, {
-               .base   = S3C2443_GPLCON,
-               .chip   = {
-                       .base   = S3C2410_GPL(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOL",
-                       .ngpio  = 15,
-               },
-       }, {
-               .base   = S3C2443_GPMCON,
-               .chip   = {
-                       .base   = S3C2410_GPM(0),
-                       .owner  = THIS_MODULE,
-                       .label  = "GPIOM",
-                       .ngpio  = 2,
-               },
-       },
-#endif
-};
-
-/*
- * GPIO bank summary:
- *
- * Bank        GPIOs   Style   SlpCon  ExtInt Group
- * A   8       4Bit    Yes     1
- * B   7       4Bit    Yes     1
- * C   8       4Bit    Yes     2
- * D   5       4Bit    Yes     3
- * E   5       4Bit    Yes     None
- * F   16      2Bit    Yes     4 [1]
- * G   7       4Bit    Yes     5
- * H   10      4Bit[2] Yes     6
- * I   16      2Bit    Yes     None
- * J   12      2Bit    Yes     None
- * K   16      4Bit[2] No      None
- * L   15      4Bit[2] No      None
- * M   6       4Bit    No      IRQ_EINT
- * N   16      2Bit    No      IRQ_EINT
- * O   16      2Bit    Yes     7
- * P   15      2Bit    Yes     8
- * Q   9       2Bit    Yes     9
- *
- * [1] BANKF pins 14,15 do not form part of the external interrupt sources
- * [2] BANK has two control registers, GPxCON0 and GPxCON1
- */
-
-static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
-#ifdef CONFIG_ARCH_S3C64XX
-       {
-               .chip   = {
-                       .base   = S3C64XX_GPA(0),
-                       .ngpio  = S3C64XX_GPIO_A_NR,
-                       .label  = "GPA",
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C64XX_GPB(0),
-                       .ngpio  = S3C64XX_GPIO_B_NR,
-                       .label  = "GPB",
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C64XX_GPC(0),
-                       .ngpio  = S3C64XX_GPIO_C_NR,
-                       .label  = "GPC",
-               },
-       }, {
-               .chip   = {
-                       .base   = S3C64XX_GPD(0),
-                       .ngpio  = S3C64XX_GPIO_D_NR,
-                       .label  = "GPD",
-               },
-       }, {
-               .config = &samsung_gpio_cfgs[0],
-               .chip   = {
-                       .base   = S3C64XX_GPE(0),
-                       .ngpio  = S3C64XX_GPIO_E_NR,
-                       .label  = "GPE",
-               },
-       }, {
-               .base   = S3C64XX_GPG_BASE,
-               .chip   = {
-                       .base   = S3C64XX_GPG(0),
-                       .ngpio  = S3C64XX_GPIO_G_NR,
-                       .label  = "GPG",
-               },
-       }, {
-               .base   = S3C64XX_GPM_BASE,
-               .config = &samsung_gpio_cfgs[1],
-               .chip   = {
-                       .base   = S3C64XX_GPM(0),
-                       .ngpio  = S3C64XX_GPIO_M_NR,
-                       .label  = "GPM",
-                       .to_irq = s3c64xx_gpiolib_mbank_to_irq,
-               },
-       },
-#endif
-};
-
-static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
-#ifdef CONFIG_ARCH_S3C64XX
-       {
-               .base   = S3C64XX_GPH_BASE + 0x4,
-               .chip   = {
-                       .base   = S3C64XX_GPH(0),
-                       .ngpio  = S3C64XX_GPIO_H_NR,
-                       .label  = "GPH",
-               },
-       }, {
-               .base   = S3C64XX_GPK_BASE + 0x4,
-               .config = &samsung_gpio_cfgs[0],
-               .chip   = {
-                       .base   = S3C64XX_GPK(0),
-                       .ngpio  = S3C64XX_GPIO_K_NR,
-                       .label  = "GPK",
-               },
-       }, {
-               .base   = S3C64XX_GPL_BASE + 0x4,
-               .config = &samsung_gpio_cfgs[1],
-               .chip   = {
-                       .base   = S3C64XX_GPL(0),
-                       .ngpio  = S3C64XX_GPIO_L_NR,
-                       .label  = "GPL",
-                       .to_irq = s3c64xx_gpiolib_lbank_to_irq,
-               },
-       },
-#endif
-};
-
-static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
-#ifdef CONFIG_ARCH_S3C64XX
-       {
-               .base   = S3C64XX_GPF_BASE,
-               .config = &samsung_gpio_cfgs[6],
-               .chip   = {
-                       .base   = S3C64XX_GPF(0),
-                       .ngpio  = S3C64XX_GPIO_F_NR,
-                       .label  = "GPF",
-               },
-       }, {
-               .config = &samsung_gpio_cfgs[7],
-               .chip   = {
-                       .base   = S3C64XX_GPI(0),
-                       .ngpio  = S3C64XX_GPIO_I_NR,
-                       .label  = "GPI",
-               },
-       }, {
-               .config = &samsung_gpio_cfgs[7],
-               .chip   = {
-                       .base   = S3C64XX_GPJ(0),
-                       .ngpio  = S3C64XX_GPIO_J_NR,
-                       .label  = "GPJ",
-               },
-       }, {
-               .config = &samsung_gpio_cfgs[6],
-               .chip   = {
-                       .base   = S3C64XX_GPO(0),
-                       .ngpio  = S3C64XX_GPIO_O_NR,
-                       .label  = "GPO",
-               },
-       }, {
-               .config = &samsung_gpio_cfgs[6],
-               .chip   = {
-                       .base   = S3C64XX_GPP(0),
-                       .ngpio  = S3C64XX_GPIO_P_NR,
-                       .label  = "GPP",
-               },
-       }, {
-               .config = &samsung_gpio_cfgs[6],
-               .chip   = {
-                       .base   = S3C64XX_GPQ(0),
-                       .ngpio  = S3C64XX_GPIO_Q_NR,
-                       .label  = "GPQ",
-               },
-       }, {
-               .base   = S3C64XX_GPN_BASE,
-               .irq_base = IRQ_EINT(0),
-               .config = &samsung_gpio_cfgs[5],
-               .chip   = {
-                       .base   = S3C64XX_GPN(0),
-                       .ngpio  = S3C64XX_GPIO_N_NR,
-                       .label  = "GPN",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       },
-#endif
-};
-
-/* TODO: cleanup soc_is_* */
-static __init int samsung_gpiolib_init(void)
-{
-       /*
-        * Currently there are two drivers that can provide GPIO support for
-        * Samsung SoCs. For device tree enabled platforms, the new
-        * pinctrl-samsung driver is used, providing both GPIO and pin control
-        * interfaces. For legacy (non-DT) platforms this driver is used.
-        */
-       if (of_have_populated_dt())
-               return -ENODEV;
-
-       samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
-
-       if (soc_is_s3c24xx()) {
-               s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
-                               ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
-       } else if (soc_is_s3c64xx()) {
-               samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
-                               ARRAY_SIZE(s3c64xx_gpios_2bit),
-                               S3C64XX_VA_GPIO + 0xE0, 0x20);
-               samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
-                               ARRAY_SIZE(s3c64xx_gpios_4bit),
-                               S3C64XX_VA_GPIO);
-               samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
-                               ARRAY_SIZE(s3c64xx_gpios_4bit2));
-       } else {
-               WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
-               return -ENODEV;
-       }
-
-       return 0;
-}
-core_initcall(samsung_gpiolib_init);
-
-int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
-{
-       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
-       unsigned long flags;
-       int offset;
-       int ret;
-
-       if (!chip)
-               return -EINVAL;
-
-       offset = pin - chip->chip.base;
-
-       samsung_gpio_lock(chip, flags);
-       ret = samsung_gpio_do_setcfg(chip, offset, config);
-       samsung_gpio_unlock(chip, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_cfgpin);
-
-int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
-                         unsigned int cfg)
-{
-       int ret;
-
-       for (; nr > 0; nr--, start++) {
-               ret = s3c_gpio_cfgpin(start, cfg);
-               if (ret != 0)
-                       return ret;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
-
-int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
-                         unsigned int cfg, samsung_gpio_pull_t pull)
-{
-       int ret;
-
-       for (; nr > 0; nr--, start++) {
-               s3c_gpio_setpull(start, pull);
-               ret = s3c_gpio_cfgpin(start, cfg);
-               if (ret != 0)
-                       return ret;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
-
-unsigned s3c_gpio_getcfg(unsigned int pin)
-{
-       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
-       unsigned long flags;
-       unsigned ret = 0;
-       int offset;
-
-       if (chip) {
-               offset = pin - chip->chip.base;
-
-               samsung_gpio_lock(chip, flags);
-               ret = samsung_gpio_do_getcfg(chip, offset);
-               samsung_gpio_unlock(chip, flags);
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_getcfg);
-
-int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
-{
-       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
-       unsigned long flags;
-       int offset, ret;
-
-       if (!chip)
-               return -EINVAL;
-
-       offset = pin - chip->chip.base;
-
-       samsung_gpio_lock(chip, flags);
-       ret = samsung_gpio_do_setpull(chip, offset, pull);
-       samsung_gpio_unlock(chip, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_setpull);
-
-samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
-{
-       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
-       unsigned long flags;
-       int offset;
-       u32 pup = 0;
-
-       if (chip) {
-               offset = pin - chip->chip.base;
-
-               samsung_gpio_lock(chip, flags);
-               pup = samsung_gpio_do_getpull(chip, offset);
-               samsung_gpio_unlock(chip, flags);
-       }
-
-       return (__force samsung_gpio_pull_t)pup;
-}
-EXPORT_SYMBOL(s3c_gpio_getpull);
-
-#ifdef CONFIG_PLAT_S3C24XX
-unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
-{
-       unsigned long flags;
-       unsigned long misccr;
-
-       local_irq_save(flags);
-       misccr = __raw_readl(S3C24XX_MISCCR);
-       misccr &= ~clear;
-       misccr ^= change;
-       __raw_writel(misccr, S3C24XX_MISCCR);
-       local_irq_restore(flags);
-
-       return misccr;
-}
-EXPORT_SYMBOL(s3c2410_modify_misccr);
-#endif
index 59babd5..8ae7ab6 100644 (file)
@@ -82,13 +82,13 @@ config DRM_TTM
 
 config DRM_GEM_CMA_HELPER
        bool
-       depends on DRM && HAVE_DMA_ATTRS
+       depends on DRM
        help
          Choose this if you need the GEM CMA helper functions
 
 config DRM_KMS_CMA_HELPER
        bool
-       depends on DRM && HAVE_DMA_ATTRS
+       depends on DRM
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_FB_HELPER
        select FB_SYS_FILLRECT
index c3b80fd..7b30b30 100644 (file)
@@ -198,10 +198,7 @@ EXPORT_SYMBOL(drm_ht_remove_item);
 void drm_ht_remove(struct drm_open_hash *ht)
 {
        if (ht->table) {
-               if ((PAGE_SIZE / sizeof(*ht->table)) >> ht->order)
-                       kfree(ht->table);
-               else
-                       vfree(ht->table);
+               kvfree(ht->table);
                ht->table = NULL;
        }
 }
index 35ca4f0..a1844b5 100644 (file)
@@ -5,7 +5,7 @@ config DRM_IMX
        select VIDEOMODE_HELPERS
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_CMA_HELPER
-       depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) && HAVE_DMA_ATTRS
+       depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
        depends on IMX_IPUV3_CORE
        help
          enable i.MX graphics support
index 19c18b7..dc13c48 100644 (file)
@@ -1564,7 +1564,7 @@ static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode *mode,
                                                        int bits_per_pixel)
 {
        uint32_t total_area, divisor;
-       int64_t active_area, pixels_per_second, bandwidth;
+       uint64_t active_area, pixels_per_second, bandwidth;
        uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
 
        divisor = 1024;
index 254094a..5da2aa8 100644 (file)
@@ -141,9 +141,8 @@ gk20a_pllg_calc_rate(struct gk20a_clk *clk)
 
        rate = clk->parent_rate * clk->n;
        divider = clk->m * pl_to_div[clk->pl];
-       do_div(rate, divider);
 
-       return rate / 2;
+       return rate / divider / 2;
 }
 
 static int
index d4e0a39..96dcd4a 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_RCAR_DU
        tristate "DRM Support for R-Car Display Unit"
-       depends on DRM && ARM && HAVE_DMA_ATTRS && OF
+       depends on DRM && ARM && OF
        depends on ARCH_SHMOBILE || COMPILE_TEST
        select DRM_KMS_HELPER
        select DRM_KMS_CMA_HELPER
index b9202aa..8d17d00 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_SHMOBILE
        tristate "DRM Support for SH Mobile"
-       depends on DRM && ARM && HAVE_DMA_ATTRS
+       depends on DRM && ARM
        depends on ARCH_SHMOBILE || COMPILE_TEST
        depends on FB_SH_MOBILE_MERAM || !FB_SH_MOBILE_MERAM
        select BACKLIGHT_CLASS_DEVICE
index 10c1b19..5ad43a1 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_STI
        tristate "DRM Support for STMicroelectronics SoC stiH41x Series"
-       depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM) && HAVE_DMA_ATTRS
+       depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
        select RESET_CONTROLLER
        select DRM_KMS_HELPER
        select DRM_GEM_CMA_HELPER
index 78beafb..f60a1ec 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_TILCDC
        tristate "DRM Support for TI LCDC Display Controller"
-       depends on DRM && OF && ARM && HAVE_DMA_ATTRS
+       depends on DRM && OF && ARM
        select DRM_KMS_HELPER
        select DRM_KMS_FB_HELPER
        select DRM_KMS_CMA_HELPER
index 2d7d115..5848104 100644 (file)
@@ -1,7 +1,7 @@
 config DRM_VC4
        tristate "Broadcom VC4 Graphics"
        depends on ARCH_BCM2835 || COMPILE_TEST
-       depends on DRM && HAVE_DMA_ATTRS
+       depends on DRM
        select DRM_KMS_HELPER
        select DRM_KMS_CMA_HELPER
        select DRM_GEM_CMA_HELPER
index d64d905..665ab9f 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
@@ -918,17 +919,17 @@ int vga_switcheroo_init_domain_pm_ops(struct device *dev,
                domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
                domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
 
-               dev->pm_domain = domain;
+               dev_pm_domain_set(dev, domain);
                return 0;
        }
-       dev->pm_domain = NULL;
+       dev_pm_domain_set(dev, NULL);
        return -EINVAL;
 }
 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
 
 void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
 {
-       dev->pm_domain = NULL;
+       dev_pm_domain_set(dev, NULL);
 }
 EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
 
@@ -989,10 +990,10 @@ vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
                domain->ops.runtime_resume =
                        vga_switcheroo_runtime_resume_hdmi_audio;
 
-               dev->pm_domain = domain;
+               dev_pm_domain_set(dev, domain);
                return 0;
        }
-       dev->pm_domain = NULL;
+       dev_pm_domain_set(dev, NULL);
        return -EINVAL;
 }
 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
index 58ed8f2..3d5ba5b 100644 (file)
@@ -218,7 +218,8 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
                goto done_proc;
        }
 
-       remaining_bytes = do_div(buffer_size, sizeof(__s32));
+       remaining_bytes = buffer_size % sizeof(__s32);
+       buffer_size = buffer_size / sizeof(__s32);
        if (buffer_size) {
                for (i = 0; i < buffer_size; ++i) {
                        hid_set_field(report->field[field_index], i,
index 3a2dbb3..c15756d 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/of_platform.h>
 #include <linux/err.h>
+#include <linux/input.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/machine.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
 /* S3C/EXYNOS4412/5250 ADC_V1 registers definitions */
 #define ADC_V1_CON(x)          ((x) + 0x00)
+#define ADC_V1_TSC(x)          ((x) + 0x04)
 #define ADC_V1_DLY(x)          ((x) + 0x08)
 #define ADC_V1_DATX(x)         ((x) + 0x0C)
+#define ADC_V1_DATY(x)         ((x) + 0x10)
+#define ADC_V1_UPDN(x)         ((x) + 0x14)
 #define ADC_V1_INTCLR(x)       ((x) + 0x18)
 #define ADC_V1_MUX(x)          ((x) + 0x1c)
+#define ADC_V1_CLRINTPNDNUP(x) ((x) + 0x20)
 
 /* S3C2410 ADC registers definitions */
 #define ADC_S3C2410_MUX(x)     ((x) + 0x18)
 #define ADC_S3C2410_DATX_MASK  0x3FF
 #define ADC_S3C2416_CON_RES_SEL        (1u << 3)
 
+/* touch screen always uses channel 0 */
+#define ADC_S3C2410_MUX_TS     0
+
+/* ADCTSC Register Bits */
+#define ADC_S3C2443_TSC_UD_SEN         (1u << 8)
+#define ADC_S3C2410_TSC_YM_SEN         (1u << 7)
+#define ADC_S3C2410_TSC_YP_SEN         (1u << 6)
+#define ADC_S3C2410_TSC_XM_SEN         (1u << 5)
+#define ADC_S3C2410_TSC_XP_SEN         (1u << 4)
+#define ADC_S3C2410_TSC_PULL_UP_DISABLE        (1u << 3)
+#define ADC_S3C2410_TSC_AUTO_PST       (1u << 2)
+#define ADC_S3C2410_TSC_XY_PST(x)      (((x) & 0x3) << 0)
+
+#define ADC_TSC_WAIT4INT (ADC_S3C2410_TSC_YM_SEN | \
+                        ADC_S3C2410_TSC_YP_SEN | \
+                        ADC_S3C2410_TSC_XP_SEN | \
+                        ADC_S3C2410_TSC_XY_PST(3))
+
+#define ADC_TSC_AUTOPST        (ADC_S3C2410_TSC_YM_SEN | \
+                        ADC_S3C2410_TSC_YP_SEN | \
+                        ADC_S3C2410_TSC_XP_SEN | \
+                        ADC_S3C2410_TSC_AUTO_PST | \
+                        ADC_S3C2410_TSC_XY_PST(0))
+
 /* Bit definitions for ADC_V2 */
 #define ADC_V2_CON1_SOFT_RESET (1u << 2)
 
 /* Bit definitions common for ADC_V1 and ADC_V2 */
 #define ADC_CON_EN_START       (1u << 0)
 #define ADC_CON_EN_START_MASK  (0x3 << 0)
+#define ADC_DATX_PRESSED       (1u << 15)
 #define ADC_DATX_MASK          0xFFF
+#define ADC_DATY_MASK          0xFFF
 
 #define EXYNOS_ADC_TIMEOUT     (msecs_to_jiffies(100))
 
 struct exynos_adc {
        struct exynos_adc_data  *data;
        struct device           *dev;
+       struct input_dev        *input;
        void __iomem            *regs;
        struct regmap           *pmu_map;
        struct clk              *clk;
        struct clk              *sclk;
        unsigned int            irq;
+       unsigned int            tsirq;
+       unsigned int            delay;
        struct regulator        *vdd;
 
        struct completion       completion;
 
        u32                     value;
        unsigned int            version;
+
+       bool                    read_ts;
+       u32                     ts_x;
+       u32                     ts_y;
 };
 
 struct exynos_adc_data {
@@ -197,6 +237,9 @@ static void exynos_adc_v1_init_hw(struct exynos_adc *info)
        /* Enable 12-bit ADC resolution */
        con1 |= ADC_V1_CON_RES;
        writel(con1, ADC_V1_CON(info->regs));
+
+       /* set touchscreen delay */
+       writel(info->delay, ADC_V1_DLY(info->regs));
 }
 
 static void exynos_adc_v1_exit_hw(struct exynos_adc *info)
@@ -480,8 +523,8 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
        if (info->data->start_conv)
                info->data->start_conv(info, chan->address);
 
-       timeout = wait_for_completion_timeout
-                       (&info->completion, EXYNOS_ADC_TIMEOUT);
+       timeout = wait_for_completion_timeout(&info->completion,
+                                             EXYNOS_ADC_TIMEOUT);
        if (timeout == 0) {
                dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
                if (info->data->init_hw)
@@ -498,13 +541,55 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
+static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)
+{
+       struct exynos_adc *info = iio_priv(indio_dev);
+       unsigned long timeout;
+       int ret;
+
+       mutex_lock(&indio_dev->mlock);
+       info->read_ts = true;
+
+       reinit_completion(&info->completion);
+
+       writel(ADC_S3C2410_TSC_PULL_UP_DISABLE | ADC_TSC_AUTOPST,
+              ADC_V1_TSC(info->regs));
+
+       /* Select the ts channel to be used and Trigger conversion */
+       info->data->start_conv(info, ADC_S3C2410_MUX_TS);
+
+       timeout = wait_for_completion_timeout(&info->completion,
+                                             EXYNOS_ADC_TIMEOUT);
+       if (timeout == 0) {
+               dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
+               if (info->data->init_hw)
+                       info->data->init_hw(info);
+               ret = -ETIMEDOUT;
+       } else {
+               *x = info->ts_x;
+               *y = info->ts_y;
+               ret = 0;
+       }
+
+       info->read_ts = false;
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
 static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
 {
        struct exynos_adc *info = (struct exynos_adc *)dev_id;
        u32 mask = info->data->mask;
 
        /* Read value */
-       info->value = readl(ADC_V1_DATX(info->regs)) & mask;
+       if (info->read_ts) {
+               info->ts_x = readl(ADC_V1_DATX(info->regs));
+               info->ts_y = readl(ADC_V1_DATY(info->regs));
+               writel(ADC_TSC_WAIT4INT | ADC_S3C2443_TSC_UD_SEN, ADC_V1_TSC(info->regs));
+       } else {
+               info->value = readl(ADC_V1_DATX(info->regs)) & mask;
+       }
 
        /* clear irq */
        if (info->data->clear_irq)
@@ -515,6 +600,46 @@ static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+/*
+ * Here we (ab)use a threaded interrupt handler to stay running
+ * for as long as the touchscreen remains pressed, we report
+ * a new event with the latest data and then sleep until the
+ * next timer tick. This mirrors the behavior of the old
+ * driver, with much less code.
+ */
+static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
+{
+       struct exynos_adc *info = dev_id;
+       struct iio_dev *dev = dev_get_drvdata(info->dev);
+       u32 x, y;
+       bool pressed;
+       int ret;
+
+       while (info->input->users) {
+               ret = exynos_read_s3c64xx_ts(dev, &x, &y);
+               if (ret == -ETIMEDOUT)
+                       break;
+
+               pressed = x & y & ADC_DATX_PRESSED;
+               if (!pressed) {
+                       input_report_key(info->input, BTN_TOUCH, 0);
+                       input_sync(info->input);
+                       break;
+               }
+
+               input_report_abs(info->input, ABS_X, x & ADC_DATX_MASK);
+               input_report_abs(info->input, ABS_Y, y & ADC_DATY_MASK);
+               input_report_key(info->input, BTN_TOUCH, 1);
+               input_sync(info->input);
+
+               msleep(1);
+       };
+
+       writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
+
+       return IRQ_HANDLED;
+}
+
 static int exynos_adc_reg_access(struct iio_dev *indio_dev,
                              unsigned reg, unsigned writeval,
                              unsigned *readval)
@@ -566,18 +691,72 @@ static int exynos_adc_remove_devices(struct device *dev, void *c)
        return 0;
 }
 
+static int exynos_adc_ts_open(struct input_dev *dev)
+{
+       struct exynos_adc *info = input_get_drvdata(dev);
+
+       enable_irq(info->tsirq);
+
+       return 0;
+}
+
+static void exynos_adc_ts_close(struct input_dev *dev)
+{
+       struct exynos_adc *info = input_get_drvdata(dev);
+
+       disable_irq(info->tsirq);
+}
+
+static int exynos_adc_ts_init(struct exynos_adc *info)
+{
+       int ret;
+
+       if (info->tsirq <= 0)
+               return -ENODEV;
+
+       info->input = input_allocate_device();
+       if (!info->input)
+               return -ENOMEM;
+
+       info->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       info->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+       input_set_abs_params(info->input, ABS_X, 0, 0x3FF, 0, 0);
+       input_set_abs_params(info->input, ABS_Y, 0, 0x3FF, 0, 0);
+
+       info->input->name = "S3C24xx TouchScreen";
+       info->input->id.bustype = BUS_HOST;
+       info->input->open = exynos_adc_ts_open;
+       info->input->close = exynos_adc_ts_close;
+
+       input_set_drvdata(info->input, info);
+
+       ret = input_register_device(info->input);
+       if (ret) {
+               input_free_device(info->input);
+               return ret;
+       }
+
+       disable_irq(info->tsirq);
+       ret = request_threaded_irq(info->tsirq, NULL, exynos_ts_isr,
+                                  IRQF_ONESHOT, "touchscreen", info);
+       if (ret)
+               input_unregister_device(info->input);
+
+       return ret;
+}
+
 static int exynos_adc_probe(struct platform_device *pdev)
 {
        struct exynos_adc *info = NULL;
        struct device_node *np = pdev->dev.of_node;
+       struct s3c2410_ts_mach_info *pdata = dev_get_platdata(&pdev->dev);
        struct iio_dev *indio_dev = NULL;
        struct resource *mem;
+       bool has_ts = false;
        int ret = -ENODEV;
        int irq;
 
-       if (!np)
-               return ret;
-
        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc));
        if (!indio_dev) {
                dev_err(&pdev->dev, "failed allocating iio device\n");
@@ -613,8 +792,14 @@ static int exynos_adc_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "no irq resource?\n");
                return irq;
        }
-
        info->irq = irq;
+
+       irq = platform_get_irq(pdev, 1);
+       if (irq == -EPROBE_DEFER)
+               return irq;
+
+       info->tsirq = irq;
+
        info->dev = &pdev->dev;
 
        init_completion(&info->completion);
@@ -680,6 +865,22 @@ static int exynos_adc_probe(struct platform_device *pdev)
        if (info->data->init_hw)
                info->data->init_hw(info);
 
+       /* leave out any TS related code if unreachable */
+       if (IS_REACHABLE(CONFIG_INPUT)) {
+               has_ts = of_property_read_bool(pdev->dev.of_node,
+                                              "has-touchscreen") || pdata;
+       }
+
+       if (pdata)
+               info->delay = pdata->delay;
+       else
+               info->delay = 10000;
+
+       if (has_ts)
+               ret = exynos_adc_ts_init(info);
+       if (ret)
+               goto err_iio;
+
        ret = of_platform_populate(np, exynos_adc_match, NULL, &indio_dev->dev);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed adding child nodes\n");
@@ -691,6 +892,11 @@ static int exynos_adc_probe(struct platform_device *pdev)
 err_of_populate:
        device_for_each_child(&indio_dev->dev, NULL,
                                exynos_adc_remove_devices);
+       if (has_ts) {
+               input_unregister_device(info->input);
+               free_irq(info->tsirq, info);
+       }
+err_iio:
        iio_device_unregister(indio_dev);
 err_irq:
        free_irq(info->irq, info);
@@ -710,6 +916,10 @@ static int exynos_adc_remove(struct platform_device *pdev)
        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
        struct exynos_adc *info = iio_priv(indio_dev);
 
+       if (IS_REACHABLE(CONFIG_INPUT)) {
+               free_irq(info->tsirq, info);
+               input_unregister_device(info->input);
+       }
        device_for_each_child(&indio_dev->dev, NULL,
                                exynos_adc_remove_devices);
        iio_device_unregister(indio_dev);
index 311f9fe..8d24fb1 100644 (file)
@@ -167,9 +167,7 @@ static int __init iio_sw_trigger_init(void)
                configfs_register_default_group(&iio_configfs_subsys.su_group,
                                                "triggers",
                                                &iio_triggers_group_type);
-       if (IS_ERR(iio_triggers_group))
-               return PTR_ERR(iio_triggers_group);
-       return 0;
+       return PTR_ERR_OR_ZERO(iio_triggers_group);
 }
 module_init(iio_sw_trigger_init);
 
index aa26f3c..8a8440c 100644 (file)
@@ -5,6 +5,7 @@ menuconfig INFINIBAND
        depends on NET
        depends on INET
        depends on m || IPV6 != m
+       select IRQ_POLL
        ---help---
          Core support for InfiniBand (IB).  Make sure to also select
          any protocols you wish to use as well as drivers for your
@@ -54,6 +55,15 @@ config INFINIBAND_ADDR_TRANS
        depends on INFINIBAND
        default y
 
+config INFINIBAND_ADDR_TRANS_CONFIGFS
+       bool
+       depends on INFINIBAND_ADDR_TRANS && CONFIGFS_FS && !(INFINIBAND=y && CONFIGFS_FS=m)
+       default y
+       ---help---
+         ConfigFS support for RDMA communication manager (CM).
+         This allows the user to config the default GID type that the CM
+         uses for each device, when initiaing new connections.
+
 source "drivers/infiniband/hw/mthca/Kconfig"
 source "drivers/infiniband/hw/qib/Kconfig"
 source "drivers/infiniband/hw/cxgb3/Kconfig"
index d43a899..f818538 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_INFINIBAND_USER_MAD) +=    ib_umad.o
 obj-$(CONFIG_INFINIBAND_USER_ACCESS) +=        ib_uverbs.o ib_ucm.o \
                                        $(user_access-y)
 
-ib_core-y :=                   packer.o ud_header.o verbs.o sysfs.o \
+ib_core-y :=                   packer.o ud_header.o verbs.o cq.o sysfs.o \
                                device.o fmr_pool.o cache.o netlink.o \
                                roce_gid_mgmt.o
 ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
@@ -24,6 +24,8 @@ iw_cm-y :=                    iwcm.o iwpm_util.o iwpm_msg.o
 
 rdma_cm-y :=                   cma.o
 
+rdma_cm-$(CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS) += cma_configfs.o
+
 rdma_ucm-y :=                  ucma.o
 
 ib_addr-y :=                   addr.o
index 34b1ada..337353d 100644 (file)
@@ -121,7 +121,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
 }
 EXPORT_SYMBOL(rdma_copy_addr);
 
-int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
+int rdma_translate_ip(const struct sockaddr *addr,
+                     struct rdma_dev_addr *dev_addr,
                      u16 *vlan_id)
 {
        struct net_device *dev;
@@ -139,7 +140,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
        switch (addr->sa_family) {
        case AF_INET:
                dev = ip_dev_find(dev_addr->net,
-                       ((struct sockaddr_in *) addr)->sin_addr.s_addr);
+                       ((const struct sockaddr_in *)addr)->sin_addr.s_addr);
 
                if (!dev)
                        return ret;
@@ -154,7 +155,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
                rcu_read_lock();
                for_each_netdev_rcu(dev_addr->net, dev) {
                        if (ipv6_chk_addr(dev_addr->net,
-                                         &((struct sockaddr_in6 *) addr)->sin6_addr,
+                                         &((const struct sockaddr_in6 *)addr)->sin6_addr,
                                          dev, 1)) {
                                ret = rdma_copy_addr(dev_addr, dev, NULL);
                                if (vlan_id)
@@ -198,7 +199,8 @@ static void queue_req(struct addr_req *req)
        mutex_unlock(&lock);
 }
 
-static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, void *daddr)
+static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
+                       const void *daddr)
 {
        struct neighbour *n;
        int ret;
@@ -222,8 +224,9 @@ static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, v
 }
 
 static int addr4_resolve(struct sockaddr_in *src_in,
-                        struct sockaddr_in *dst_in,
-                        struct rdma_dev_addr *addr)
+                        const struct sockaddr_in *dst_in,
+                        struct rdma_dev_addr *addr,
+                        struct rtable **prt)
 {
        __be32 src_ip = src_in->sin_addr.s_addr;
        __be32 dst_ip = dst_in->sin_addr.s_addr;
@@ -243,33 +246,29 @@ static int addr4_resolve(struct sockaddr_in *src_in,
        src_in->sin_family = AF_INET;
        src_in->sin_addr.s_addr = fl4.saddr;
 
-       if (rt->dst.dev->flags & IFF_LOOPBACK) {
-               ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
-               if (!ret)
-                       memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
-               goto put;
-       }
+       /* If there's a gateway, we're definitely in RoCE v2 (as RoCE v1 isn't
+        * routable) and we could set the network type accordingly.
+        */
+       if (rt->rt_uses_gateway)
+               addr->network = RDMA_NETWORK_IPV4;
 
-       /* If the device does ARP internally, return 'done' */
-       if (rt->dst.dev->flags & IFF_NOARP) {
-               ret = rdma_copy_addr(addr, rt->dst.dev, NULL);
-               goto put;
-       }
+       addr->hoplimit = ip4_dst_hoplimit(&rt->dst);
 
-       ret = dst_fetch_ha(&rt->dst, addr, &fl4.daddr);
-put:
-       ip_rt_put(rt);
+       *prt = rt;
+       return 0;
 out:
        return ret;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
 static int addr6_resolve(struct sockaddr_in6 *src_in,
-                        struct sockaddr_in6 *dst_in,
-                        struct rdma_dev_addr *addr)
+                        const struct sockaddr_in6 *dst_in,
+                        struct rdma_dev_addr *addr,
+                        struct dst_entry **pdst)
 {
        struct flowi6 fl6;
        struct dst_entry *dst;
+       struct rt6_info *rt;
        int ret;
 
        memset(&fl6, 0, sizeof fl6);
@@ -281,6 +280,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
        if ((ret = dst->error))
                goto put;
 
+       rt = (struct rt6_info *)dst;
        if (ipv6_addr_any(&fl6.saddr)) {
                ret = ipv6_dev_get_saddr(addr->net, ip6_dst_idev(dst)->dev,
                                         &fl6.daddr, 0, &fl6.saddr);
@@ -291,43 +291,111 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                src_in->sin6_addr = fl6.saddr;
        }
 
-       if (dst->dev->flags & IFF_LOOPBACK) {
-               ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
-               if (!ret)
-                       memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
-               goto put;
-       }
+       /* If there's a gateway, we're definitely in RoCE v2 (as RoCE v1 isn't
+        * routable) and we could set the network type accordingly.
+        */
+       if (rt->rt6i_flags & RTF_GATEWAY)
+               addr->network = RDMA_NETWORK_IPV6;
 
-       /* If the device does ARP internally, return 'done' */
-       if (dst->dev->flags & IFF_NOARP) {
-               ret = rdma_copy_addr(addr, dst->dev, NULL);
-               goto put;
-       }
+       addr->hoplimit = ip6_dst_hoplimit(dst);
 
-       ret = dst_fetch_ha(dst, addr, &fl6.daddr);
+       *pdst = dst;
+       return 0;
 put:
        dst_release(dst);
        return ret;
 }
 #else
 static int addr6_resolve(struct sockaddr_in6 *src_in,
-                        struct sockaddr_in6 *dst_in,
-                        struct rdma_dev_addr *addr)
+                        const struct sockaddr_in6 *dst_in,
+                        struct rdma_dev_addr *addr,
+                        struct dst_entry **pdst)
 {
        return -EADDRNOTAVAIL;
 }
 #endif
 
+static int addr_resolve_neigh(struct dst_entry *dst,
+                             const struct sockaddr *dst_in,
+                             struct rdma_dev_addr *addr)
+{
+       if (dst->dev->flags & IFF_LOOPBACK) {
+               int ret;
+
+               ret = rdma_translate_ip(dst_in, addr, NULL);
+               if (!ret)
+                       memcpy(addr->dst_dev_addr, addr->src_dev_addr,
+                              MAX_ADDR_LEN);
+
+               return ret;
+       }
+
+       /* If the device doesn't do ARP internally */
+       if (!(dst->dev->flags & IFF_NOARP)) {
+               const struct sockaddr_in *dst_in4 =
+                       (const struct sockaddr_in *)dst_in;
+               const struct sockaddr_in6 *dst_in6 =
+                       (const struct sockaddr_in6 *)dst_in;
+
+               return dst_fetch_ha(dst, addr,
+                                   dst_in->sa_family == AF_INET ?
+                                   (const void *)&dst_in4->sin_addr.s_addr :
+                                   (const void *)&dst_in6->sin6_addr);
+       }
+
+       return rdma_copy_addr(addr, dst->dev, NULL);
+}
+
 static int addr_resolve(struct sockaddr *src_in,
-                       struct sockaddr *dst_in,
-                       struct rdma_dev_addr *addr)
+                       const struct sockaddr *dst_in,
+                       struct rdma_dev_addr *addr,
+                       bool resolve_neigh)
 {
+       struct net_device *ndev;
+       struct dst_entry *dst;
+       int ret;
+
        if (src_in->sa_family == AF_INET) {
-               return addr4_resolve((struct sockaddr_in *) src_in,
-                       (struct sockaddr_in *) dst_in, addr);
-       } else
-               return addr6_resolve((struct sockaddr_in6 *) src_in,
-                       (struct sockaddr_in6 *) dst_in, addr);
+               struct rtable *rt = NULL;
+               const struct sockaddr_in *dst_in4 =
+                       (const struct sockaddr_in *)dst_in;
+
+               ret = addr4_resolve((struct sockaddr_in *)src_in,
+                                   dst_in4, addr, &rt);
+               if (ret)
+                       return ret;
+
+               if (resolve_neigh)
+                       ret = addr_resolve_neigh(&rt->dst, dst_in, addr);
+
+               ndev = rt->dst.dev;
+               dev_hold(ndev);
+
+               ip_rt_put(rt);
+       } else {
+               const struct sockaddr_in6 *dst_in6 =
+                       (const struct sockaddr_in6 *)dst_in;
+
+               ret = addr6_resolve((struct sockaddr_in6 *)src_in,
+                                   dst_in6, addr,
+                                   &dst);
+               if (ret)
+                       return ret;
+
+               if (resolve_neigh)
+                       ret = addr_resolve_neigh(dst, dst_in, addr);
+
+               ndev = dst->dev;
+               dev_hold(ndev);
+
+               dst_release(dst);
+       }
+
+       addr->bound_dev_if = ndev->ifindex;
+       addr->net = dev_net(ndev);
+       dev_put(ndev);
+
+       return ret;
 }
 
 static void process_req(struct work_struct *work)
@@ -343,7 +411,8 @@ static void process_req(struct work_struct *work)
                if (req->status == -ENODATA) {
                        src_in = (struct sockaddr *) &req->src_addr;
                        dst_in = (struct sockaddr *) &req->dst_addr;
-                       req->status = addr_resolve(src_in, dst_in, req->addr);
+                       req->status = addr_resolve(src_in, dst_in, req->addr,
+                                                  true);
                        if (req->status && time_after_eq(jiffies, req->timeout))
                                req->status = -ETIMEDOUT;
                        else if (req->status == -ENODATA)
@@ -403,7 +472,7 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
        req->client = client;
        atomic_inc(&client->refcount);
 
-       req->status = addr_resolve(src_in, dst_in, addr);
+       req->status = addr_resolve(src_in, dst_in, addr, true);
        switch (req->status) {
        case 0:
                req->timeout = jiffies;
@@ -425,6 +494,26 @@ err:
 }
 EXPORT_SYMBOL(rdma_resolve_ip);
 
+int rdma_resolve_ip_route(struct sockaddr *src_addr,
+                         const struct sockaddr *dst_addr,
+                         struct rdma_dev_addr *addr)
+{
+       struct sockaddr_storage ssrc_addr = {};
+       struct sockaddr *src_in = (struct sockaddr *)&ssrc_addr;
+
+       if (src_addr) {
+               if (src_addr->sa_family != dst_addr->sa_family)
+                       return -EINVAL;
+
+               memcpy(src_in, src_addr, rdma_addr_size(src_addr));
+       } else {
+               src_in->sa_family = dst_addr->sa_family;
+       }
+
+       return addr_resolve(src_in, dst_addr, addr, false);
+}
+EXPORT_SYMBOL(rdma_resolve_ip_route);
+
 void rdma_addr_cancel(struct rdma_dev_addr *addr)
 {
        struct addr_req *req, *temp_req;
@@ -456,8 +545,10 @@ static void resolve_cb(int status, struct sockaddr *src_addr,
        complete(&((struct resolve_cb_context *)context)->comp);
 }
 
-int rdma_addr_find_dmac_by_grh(const union ib_gid *sgid, const union ib_gid *dgid,
-                              u8 *dmac, u16 *vlan_id, int if_index)
+int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
+                                const union ib_gid *dgid,
+                                u8 *dmac, u16 *vlan_id, int *if_index,
+                                int *hoplimit)
 {
        int ret = 0;
        struct rdma_dev_addr dev_addr;
@@ -475,7 +566,8 @@ int rdma_addr_find_dmac_by_grh(const union ib_gid *sgid, const union ib_gid *dgi
        rdma_gid2ip(&dgid_addr._sockaddr, dgid);
 
        memset(&dev_addr, 0, sizeof(dev_addr));
-       dev_addr.bound_dev_if = if_index;
+       if (if_index)
+               dev_addr.bound_dev_if = *if_index;
        dev_addr.net = &init_net;
 
        ctx.addr = &dev_addr;
@@ -491,12 +583,16 @@ int rdma_addr_find_dmac_by_grh(const union ib_gid *sgid, const union ib_gid *dgi
        dev = dev_get_by_index(&init_net, dev_addr.bound_dev_if);
        if (!dev)
                return -ENODEV;
+       if (if_index)
+               *if_index = dev_addr.bound_dev_if;
        if (vlan_id)
                *vlan_id = rdma_vlan_dev_vlan_id(dev);
+       if (hoplimit)
+               *hoplimit = dev_addr.hoplimit;
        dev_put(dev);
        return ret;
 }
-EXPORT_SYMBOL(rdma_addr_find_dmac_by_grh);
+EXPORT_SYMBOL(rdma_addr_find_l2_eth_by_grh);
 
 int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id)
 {
index 89bebea..53343ff 100644 (file)
@@ -64,6 +64,7 @@ enum gid_attr_find_mask {
        GID_ATTR_FIND_MASK_GID          = 1UL << 0,
        GID_ATTR_FIND_MASK_NETDEV       = 1UL << 1,
        GID_ATTR_FIND_MASK_DEFAULT      = 1UL << 2,
+       GID_ATTR_FIND_MASK_GID_TYPE     = 1UL << 3,
 };
 
 enum gid_table_entry_props {
@@ -81,10 +82,6 @@ enum gid_table_write_action {
 };
 
 struct ib_gid_table_entry {
-       /* This lock protects an entry from being
-        * read and written simultaneously.
-        */
-       rwlock_t            lock;
        unsigned long       props;
        union ib_gid        gid;
        struct ib_gid_attr  attr;
@@ -109,28 +106,86 @@ struct ib_gid_table {
         * are locked by this lock.
         **/
        struct mutex         lock;
+       /* This lock protects the table entries from being
+        * read and written simultaneously.
+        */
+       rwlock_t             rwlock;
        struct ib_gid_table_entry *data_vec;
 };
 
+static void dispatch_gid_change_event(struct ib_device *ib_dev, u8 port)
+{
+       if (rdma_cap_roce_gid_table(ib_dev, port)) {
+               struct ib_event event;
+
+               event.device            = ib_dev;
+               event.element.port_num  = port;
+               event.event             = IB_EVENT_GID_CHANGE;
+
+               ib_dispatch_event(&event);
+       }
+}
+
+static const char * const gid_type_str[] = {
+       [IB_GID_TYPE_IB]        = "IB/RoCE v1",
+       [IB_GID_TYPE_ROCE_UDP_ENCAP]    = "RoCE v2",
+};
+
+const char *ib_cache_gid_type_str(enum ib_gid_type gid_type)
+{
+       if (gid_type < ARRAY_SIZE(gid_type_str) && gid_type_str[gid_type])
+               return gid_type_str[gid_type];
+
+       return "Invalid GID type";
+}
+EXPORT_SYMBOL(ib_cache_gid_type_str);
+
+int ib_cache_gid_parse_type_str(const char *buf)
+{
+       unsigned int i;
+       size_t len;
+       int err = -EINVAL;
+
+       len = strlen(buf);
+       if (len == 0)
+               return -EINVAL;
+
+       if (buf[len - 1] == '\n')
+               len--;
+
+       for (i = 0; i < ARRAY_SIZE(gid_type_str); ++i)
+               if (gid_type_str[i] && !strncmp(buf, gid_type_str[i], len) &&
+                   len == strlen(gid_type_str[i])) {
+                       err = i;
+                       break;
+               }
+
+       return err;
+}
+EXPORT_SYMBOL(ib_cache_gid_parse_type_str);
+
+/* This function expects that rwlock will be write locked in all
+ * scenarios and that lock will be locked in sleep-able (RoCE)
+ * scenarios.
+ */
 static int write_gid(struct ib_device *ib_dev, u8 port,
                     struct ib_gid_table *table, int ix,
                     const union ib_gid *gid,
                     const struct ib_gid_attr *attr,
                     enum gid_table_write_action action,
                     bool  default_gid)
+       __releases(&table->rwlock) __acquires(&table->rwlock)
 {
        int ret = 0;
        struct net_device *old_net_dev;
-       unsigned long flags;
 
        /* in rdma_cap_roce_gid_table, this funciton should be protected by a
         * sleep-able lock.
         */
-       write_lock_irqsave(&table->data_vec[ix].lock, flags);
 
        if (rdma_cap_roce_gid_table(ib_dev, port)) {
                table->data_vec[ix].props |= GID_TABLE_ENTRY_INVALID;
-               write_unlock_irqrestore(&table->data_vec[ix].lock, flags);
+               write_unlock_irq(&table->rwlock);
                /* GID_TABLE_WRITE_ACTION_MODIFY currently isn't supported by
                 * RoCE providers and thus only updates the cache.
                 */
@@ -140,7 +195,7 @@ static int write_gid(struct ib_device *ib_dev, u8 port,
                else if (action == GID_TABLE_WRITE_ACTION_DEL)
                        ret = ib_dev->del_gid(ib_dev, port, ix,
                                              &table->data_vec[ix].context);
-               write_lock_irqsave(&table->data_vec[ix].lock, flags);
+               write_lock_irq(&table->rwlock);
        }
 
        old_net_dev = table->data_vec[ix].attr.ndev;
@@ -162,17 +217,6 @@ static int write_gid(struct ib_device *ib_dev, u8 port,
 
        table->data_vec[ix].props &= ~GID_TABLE_ENTRY_INVALID;
 
-       write_unlock_irqrestore(&table->data_vec[ix].lock, flags);
-
-       if (!ret && rdma_cap_roce_gid_table(ib_dev, port)) {
-               struct ib_event event;
-
-               event.device            = ib_dev;
-               event.element.port_num  = port;
-               event.event             = IB_EVENT_GID_CHANGE;
-
-               ib_dispatch_event(&event);
-       }
        return ret;
 }
 
@@ -201,41 +245,58 @@ static int del_gid(struct ib_device *ib_dev, u8 port,
                         GID_TABLE_WRITE_ACTION_DEL, default_gid);
 }
 
+/* rwlock should be read locked */
 static int find_gid(struct ib_gid_table *table, const union ib_gid *gid,
                    const struct ib_gid_attr *val, bool default_gid,
-                   unsigned long mask)
+                   unsigned long mask, int *pempty)
 {
-       int i;
+       int i = 0;
+       int found = -1;
+       int empty = pempty ? -1 : 0;
 
-       for (i = 0; i < table->sz; i++) {
-               unsigned long flags;
-               struct ib_gid_attr *attr = &table->data_vec[i].attr;
+       while (i < table->sz && (found < 0 || empty < 0)) {
+               struct ib_gid_table_entry *data = &table->data_vec[i];
+               struct ib_gid_attr *attr = &data->attr;
+               int curr_index = i;
 
-               read_lock_irqsave(&table->data_vec[i].lock, flags);
+               i++;
 
-               if (table->data_vec[i].props & GID_TABLE_ENTRY_INVALID)
-                       goto next;
+               if (data->props & GID_TABLE_ENTRY_INVALID)
+                       continue;
+
+               if (empty < 0)
+                       if (!memcmp(&data->gid, &zgid, sizeof(*gid)) &&
+                           !memcmp(attr, &zattr, sizeof(*attr)) &&
+                           !data->props)
+                               empty = curr_index;
+
+               if (found >= 0)
+                       continue;
+
+               if (mask & GID_ATTR_FIND_MASK_GID_TYPE &&
+                   attr->gid_type != val->gid_type)
+                       continue;
 
                if (mask & GID_ATTR_FIND_MASK_GID &&
-                   memcmp(gid, &table->data_vec[i].gid, sizeof(*gid)))
-                       goto next;
+                   memcmp(gid, &data->gid, sizeof(*gid)))
+                       continue;
 
                if (mask & GID_ATTR_FIND_MASK_NETDEV &&
                    attr->ndev != val->ndev)
-                       goto next;
+                       continue;
 
                if (mask & GID_ATTR_FIND_MASK_DEFAULT &&
-                   !!(table->data_vec[i].props & GID_TABLE_ENTRY_DEFAULT) !=
+                   !!(data->props & GID_TABLE_ENTRY_DEFAULT) !=
                    default_gid)
-                       goto next;
+                       continue;
 
-               read_unlock_irqrestore(&table->data_vec[i].lock, flags);
-               return i;
-next:
-               read_unlock_irqrestore(&table->data_vec[i].lock, flags);
+               found = curr_index;
        }
 
-       return -1;
+       if (pempty)
+               *pempty = empty;
+
+       return found;
 }
 
 static void make_default_gid(struct  net_device *dev, union ib_gid *gid)
@@ -252,6 +313,7 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
        int ix;
        int ret = 0;
        struct net_device *idev;
+       int empty;
 
        table = ports_table[port - rdma_start_port(ib_dev)];
 
@@ -275,22 +337,25 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
        }
 
        mutex_lock(&table->lock);
+       write_lock_irq(&table->rwlock);
 
        ix = find_gid(table, gid, attr, false, GID_ATTR_FIND_MASK_GID |
-                     GID_ATTR_FIND_MASK_NETDEV);
+                     GID_ATTR_FIND_MASK_GID_TYPE |
+                     GID_ATTR_FIND_MASK_NETDEV, &empty);
        if (ix >= 0)
                goto out_unlock;
 
-       ix = find_gid(table, &zgid, NULL, false, GID_ATTR_FIND_MASK_GID |
-                     GID_ATTR_FIND_MASK_DEFAULT);
-       if (ix < 0) {
+       if (empty < 0) {
                ret = -ENOSPC;
                goto out_unlock;
        }
 
-       add_gid(ib_dev, port, table, ix, gid, attr, false);
+       ret = add_gid(ib_dev, port, table, empty, gid, attr, false);
+       if (!ret)
+               dispatch_gid_change_event(ib_dev, port);
 
 out_unlock:
+       write_unlock_irq(&table->rwlock);
        mutex_unlock(&table->lock);
        return ret;
 }
@@ -305,17 +370,22 @@ int ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
        table = ports_table[port - rdma_start_port(ib_dev)];
 
        mutex_lock(&table->lock);
+       write_lock_irq(&table->rwlock);
 
        ix = find_gid(table, gid, attr, false,
                      GID_ATTR_FIND_MASK_GID      |
+                     GID_ATTR_FIND_MASK_GID_TYPE |
                      GID_ATTR_FIND_MASK_NETDEV   |
-                     GID_ATTR_FIND_MASK_DEFAULT);
+                     GID_ATTR_FIND_MASK_DEFAULT,
+                     NULL);
        if (ix < 0)
                goto out_unlock;
 
-       del_gid(ib_dev, port, table, ix, false);
+       if (!del_gid(ib_dev, port, table, ix, false))
+               dispatch_gid_change_event(ib_dev, port);
 
 out_unlock:
+       write_unlock_irq(&table->rwlock);
        mutex_unlock(&table->lock);
        return 0;
 }
@@ -326,16 +396,24 @@ int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port,
        struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
        struct ib_gid_table *table;
        int ix;
+       bool deleted = false;
 
        table  = ports_table[port - rdma_start_port(ib_dev)];
 
        mutex_lock(&table->lock);
+       write_lock_irq(&table->rwlock);
 
        for (ix = 0; ix < table->sz; ix++)
                if (table->data_vec[ix].attr.ndev == ndev)
-                       del_gid(ib_dev, port, table, ix, false);
+                       if (!del_gid(ib_dev, port, table, ix, false))
+                               deleted = true;
 
+       write_unlock_irq(&table->rwlock);
        mutex_unlock(&table->lock);
+
+       if (deleted)
+               dispatch_gid_change_event(ib_dev, port);
+
        return 0;
 }
 
@@ -344,18 +422,14 @@ static int __ib_cache_gid_get(struct ib_device *ib_dev, u8 port, int index,
 {
        struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
        struct ib_gid_table *table;
-       unsigned long flags;
 
        table = ports_table[port - rdma_start_port(ib_dev)];
 
        if (index < 0 || index >= table->sz)
                return -EINVAL;
 
-       read_lock_irqsave(&table->data_vec[index].lock, flags);
-       if (table->data_vec[index].props & GID_TABLE_ENTRY_INVALID) {
-               read_unlock_irqrestore(&table->data_vec[index].lock, flags);
+       if (table->data_vec[index].props & GID_TABLE_ENTRY_INVALID)
                return -EAGAIN;
-       }
 
        memcpy(gid, &table->data_vec[index].gid, sizeof(*gid));
        if (attr) {
@@ -364,7 +438,6 @@ static int __ib_cache_gid_get(struct ib_device *ib_dev, u8 port, int index,
                        dev_hold(attr->ndev);
        }
 
-       read_unlock_irqrestore(&table->data_vec[index].lock, flags);
        return 0;
 }
 
@@ -378,17 +451,21 @@ static int _ib_cache_gid_table_find(struct ib_device *ib_dev,
        struct ib_gid_table *table;
        u8 p;
        int local_index;
+       unsigned long flags;
 
        for (p = 0; p < ib_dev->phys_port_cnt; p++) {
                table = ports_table[p];
-               local_index = find_gid(table, gid, val, false, mask);
+               read_lock_irqsave(&table->rwlock, flags);
+               local_index = find_gid(table, gid, val, false, mask, NULL);
                if (local_index >= 0) {
                        if (index)
                                *index = local_index;
                        if (port)
                                *port = p + rdma_start_port(ib_dev);
+                       read_unlock_irqrestore(&table->rwlock, flags);
                        return 0;
                }
+               read_unlock_irqrestore(&table->rwlock, flags);
        }
 
        return -ENOENT;
@@ -396,11 +473,13 @@ static int _ib_cache_gid_table_find(struct ib_device *ib_dev,
 
 static int ib_cache_gid_find(struct ib_device *ib_dev,
                             const union ib_gid *gid,
+                            enum ib_gid_type gid_type,
                             struct net_device *ndev, u8 *port,
                             u16 *index)
 {
-       unsigned long mask = GID_ATTR_FIND_MASK_GID;
-       struct ib_gid_attr gid_attr_val = {.ndev = ndev};
+       unsigned long mask = GID_ATTR_FIND_MASK_GID |
+                            GID_ATTR_FIND_MASK_GID_TYPE;
+       struct ib_gid_attr gid_attr_val = {.ndev = ndev, .gid_type = gid_type};
 
        if (ndev)
                mask |= GID_ATTR_FIND_MASK_NETDEV;
@@ -411,14 +490,17 @@ static int ib_cache_gid_find(struct ib_device *ib_dev,
 
 int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
                               const union ib_gid *gid,
+                              enum ib_gid_type gid_type,
                               u8 port, struct net_device *ndev,
                               u16 *index)
 {
        int local_index;
        struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
        struct ib_gid_table *table;
-       unsigned long mask = GID_ATTR_FIND_MASK_GID;
-       struct ib_gid_attr val = {.ndev = ndev};
+       unsigned long mask = GID_ATTR_FIND_MASK_GID |
+                            GID_ATTR_FIND_MASK_GID_TYPE;
+       struct ib_gid_attr val = {.ndev = ndev, .gid_type = gid_type};
+       unsigned long flags;
 
        if (port < rdma_start_port(ib_dev) ||
            port > rdma_end_port(ib_dev))
@@ -429,13 +511,16 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
        if (ndev)
                mask |= GID_ATTR_FIND_MASK_NETDEV;
 
-       local_index = find_gid(table, gid, &val, false, mask);
+       read_lock_irqsave(&table->rwlock, flags);
+       local_index = find_gid(table, gid, &val, false, mask, NULL);
        if (local_index >= 0) {
                if (index)
                        *index = local_index;
+               read_unlock_irqrestore(&table->rwlock, flags);
                return 0;
        }
 
+       read_unlock_irqrestore(&table->rwlock, flags);
        return -ENOENT;
 }
 EXPORT_SYMBOL(ib_find_cached_gid_by_port);
@@ -472,6 +557,7 @@ static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
        struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
        struct ib_gid_table *table;
        unsigned int i;
+       unsigned long flags;
        bool found = false;
 
        if (!ports_table)
@@ -484,11 +570,10 @@ static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
 
        table = ports_table[port - rdma_start_port(ib_dev)];
 
+       read_lock_irqsave(&table->rwlock, flags);
        for (i = 0; i < table->sz; i++) {
                struct ib_gid_attr attr;
-               unsigned long flags;
 
-               read_lock_irqsave(&table->data_vec[i].lock, flags);
                if (table->data_vec[i].props & GID_TABLE_ENTRY_INVALID)
                        goto next;
 
@@ -501,11 +586,10 @@ static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
                        found = true;
 
 next:
-               read_unlock_irqrestore(&table->data_vec[i].lock, flags);
-
                if (found)
                        break;
        }
+       read_unlock_irqrestore(&table->rwlock, flags);
 
        if (!found)
                return -ENOENT;
@@ -517,9 +601,9 @@ next:
 
 static struct ib_gid_table *alloc_gid_table(int sz)
 {
-       unsigned int i;
        struct ib_gid_table *table =
                kzalloc(sizeof(struct ib_gid_table), GFP_KERNEL);
+
        if (!table)
                return NULL;
 
@@ -530,9 +614,7 @@ static struct ib_gid_table *alloc_gid_table(int sz)
        mutex_init(&table->lock);
 
        table->sz = sz;
-
-       for (i = 0; i < sz; i++)
-               rwlock_init(&table->data_vec[i].lock);
+       rwlock_init(&table->rwlock);
 
        return table;
 
@@ -553,30 +635,37 @@ static void cleanup_gid_table_port(struct ib_device *ib_dev, u8 port,
                                   struct ib_gid_table *table)
 {
        int i;
+       bool deleted = false;
 
        if (!table)
                return;
 
+       write_lock_irq(&table->rwlock);
        for (i = 0; i < table->sz; ++i) {
                if (memcmp(&table->data_vec[i].gid, &zgid,
                           sizeof(table->data_vec[i].gid)))
-                       del_gid(ib_dev, port, table, i,
-                               table->data_vec[i].props &
-                               GID_ATTR_FIND_MASK_DEFAULT);
+                       if (!del_gid(ib_dev, port, table, i,
+                                    table->data_vec[i].props &
+                                    GID_ATTR_FIND_MASK_DEFAULT))
+                               deleted = true;
        }
+       write_unlock_irq(&table->rwlock);
+
+       if (deleted)
+               dispatch_gid_change_event(ib_dev, port);
 }
 
 void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
                                  struct net_device *ndev,
+                                 unsigned long gid_type_mask,
                                  enum ib_cache_gid_default_mode mode)
 {
        struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
        union ib_gid gid;
        struct ib_gid_attr gid_attr;
+       struct ib_gid_attr zattr_type = zattr;
        struct ib_gid_table *table;
-       int ix;
-       union ib_gid current_gid;
-       struct ib_gid_attr current_gid_attr = {};
+       unsigned int gid_type;
 
        table  = ports_table[port - rdma_start_port(ib_dev)];
 
@@ -584,46 +673,82 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
        memset(&gid_attr, 0, sizeof(gid_attr));
        gid_attr.ndev = ndev;
 
-       mutex_lock(&table->lock);
-       ix = find_gid(table, NULL, NULL, true, GID_ATTR_FIND_MASK_DEFAULT);
-
-       /* Coudn't find default GID location */
-       WARN_ON(ix < 0);
-
-       if (!__ib_cache_gid_get(ib_dev, port, ix,
-                               &current_gid, &current_gid_attr) &&
-           mode == IB_CACHE_GID_DEFAULT_MODE_SET &&
-           !memcmp(&gid, &current_gid, sizeof(gid)) &&
-           !memcmp(&gid_attr, &current_gid_attr, sizeof(gid_attr)))
-               goto unlock;
-
-       if ((memcmp(&current_gid, &zgid, sizeof(current_gid)) ||
-            memcmp(&current_gid_attr, &zattr,
-                   sizeof(current_gid_attr))) &&
-           del_gid(ib_dev, port, table, ix, true)) {
-               pr_warn("ib_cache_gid: can't delete index %d for default gid %pI6\n",
-                       ix, gid.raw);
-               goto unlock;
-       }
+       for (gid_type = 0; gid_type < IB_GID_TYPE_SIZE; ++gid_type) {
+               int ix;
+               union ib_gid current_gid;
+               struct ib_gid_attr current_gid_attr = {};
+
+               if (1UL << gid_type & ~gid_type_mask)
+                       continue;
+
+               gid_attr.gid_type = gid_type;
+
+               mutex_lock(&table->lock);
+               write_lock_irq(&table->rwlock);
+               ix = find_gid(table, NULL, &gid_attr, true,
+                             GID_ATTR_FIND_MASK_GID_TYPE |
+                             GID_ATTR_FIND_MASK_DEFAULT,
+                             NULL);
+
+               /* Coudn't find default GID location */
+               WARN_ON(ix < 0);
+
+               zattr_type.gid_type = gid_type;
+
+               if (!__ib_cache_gid_get(ib_dev, port, ix,
+                                       &current_gid, &current_gid_attr) &&
+                   mode == IB_CACHE_GID_DEFAULT_MODE_SET &&
+                   !memcmp(&gid, &current_gid, sizeof(gid)) &&
+                   !memcmp(&gid_attr, &current_gid_attr, sizeof(gid_attr)))
+                       goto release;
+
+               if (memcmp(&current_gid, &zgid, sizeof(current_gid)) ||
+                   memcmp(&current_gid_attr, &zattr_type,
+                          sizeof(current_gid_attr))) {
+                       if (del_gid(ib_dev, port, table, ix, true)) {
+                               pr_warn("ib_cache_gid: can't delete index %d for default gid %pI6\n",
+                                       ix, gid.raw);
+                               goto release;
+                       } else {
+                               dispatch_gid_change_event(ib_dev, port);
+                       }
+               }
 
-       if (mode == IB_CACHE_GID_DEFAULT_MODE_SET)
-               if (add_gid(ib_dev, port, table, ix, &gid, &gid_attr, true))
-                       pr_warn("ib_cache_gid: unable to add default gid %pI6\n",
-                               gid.raw);
+               if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) {
+                       if (add_gid(ib_dev, port, table, ix, &gid, &gid_attr, true))
+                               pr_warn("ib_cache_gid: unable to add default gid %pI6\n",
+                                       gid.raw);
+                       else
+                               dispatch_gid_change_event(ib_dev, port);
+               }
 
-unlock:
-       if (current_gid_attr.ndev)
-               dev_put(current_gid_attr.ndev);
-       mutex_unlock(&table->lock);
+release:
+               if (current_gid_attr.ndev)
+                       dev_put(current_gid_attr.ndev);
+               write_unlock_irq(&table->rwlock);
+               mutex_unlock(&table->lock);
+       }
 }
 
 static int gid_table_reserve_default(struct ib_device *ib_dev, u8 port,
                                     struct ib_gid_table *table)
 {
-       if (rdma_protocol_roce(ib_dev, port)) {
-               struct ib_gid_table_entry *entry = &table->data_vec[0];
+       unsigned int i;
+       unsigned long roce_gid_type_mask;
+       unsigned int num_default_gids;
+       unsigned int current_gid = 0;
+
+       roce_gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
+       num_default_gids = hweight_long(roce_gid_type_mask);
+       for (i = 0; i < num_default_gids && i < table->sz; i++) {
+               struct ib_gid_table_entry *entry =
+                       &table->data_vec[i];
 
                entry->props |= GID_TABLE_ENTRY_DEFAULT;
+               current_gid = find_next_bit(&roce_gid_type_mask,
+                                           BITS_PER_LONG,
+                                           current_gid);
+               entry->attr.gid_type = current_gid++;
        }
 
        return 0;
@@ -728,20 +853,30 @@ int ib_get_cached_gid(struct ib_device *device,
                      union ib_gid     *gid,
                      struct ib_gid_attr *gid_attr)
 {
+       int res;
+       unsigned long flags;
+       struct ib_gid_table **ports_table = device->cache.gid_cache;
+       struct ib_gid_table *table = ports_table[port_num - rdma_start_port(device)];
+
        if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device))
                return -EINVAL;
 
-       return __ib_cache_gid_get(device, port_num, index, gid, gid_attr);
+       read_lock_irqsave(&table->rwlock, flags);
+       res = __ib_cache_gid_get(device, port_num, index, gid, gid_attr);
+       read_unlock_irqrestore(&table->rwlock, flags);
+
+       return res;
 }
 EXPORT_SYMBOL(ib_get_cached_gid);
 
 int ib_find_cached_gid(struct ib_device *device,
                       const union ib_gid *gid,
+                      enum ib_gid_type gid_type,
                       struct net_device *ndev,
                       u8               *port_num,
                       u16              *index)
 {
-       return ib_cache_gid_find(device, gid, ndev, port_num, index);
+       return ib_cache_gid_find(device, gid, gid_type, ndev, port_num, index);
 }
 EXPORT_SYMBOL(ib_find_cached_gid);
 
@@ -956,10 +1091,12 @@ static void ib_cache_update(struct ib_device *device,
 
        device->cache.pkey_cache[port - rdma_start_port(device)] = pkey_cache;
        if (!use_roce_gid_table) {
+               write_lock(&table->rwlock);
                for (i = 0; i < gid_cache->table_len; i++) {
                        modify_gid(device, port, table, i, gid_cache->table + i,
                                   &zattr, false);
                }
+               write_unlock(&table->rwlock);
        }
 
        device->cache.lmc_cache[port - rdma_start_port(device)] = tprops->lmc;
index 0a26dd6..1d92e09 100644 (file)
@@ -364,7 +364,7 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
        read_lock_irqsave(&cm.device_lock, flags);
        list_for_each_entry(cm_dev, &cm.device_list, list) {
                if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
-                                       ndev, &p, NULL)) {
+                                       path->gid_type, ndev, &p, NULL)) {
                        port = cm_dev->port[p-1];
                        break;
                }
@@ -782,11 +782,11 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv)
        wait_time = cm_convert_to_ms(cm_id_priv->av.timeout);
 
        /* Check if the device started its remove_one */
-       spin_lock_irq(&cm.lock);
+       spin_lock_irqsave(&cm.lock, flags);
        if (!cm_dev->going_down)
                queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work,
                                   msecs_to_jiffies(wait_time));
-       spin_unlock_irq(&cm.lock);
+       spin_unlock_irqrestore(&cm.lock, flags);
 
        cm_id_priv->timewait_info = NULL;
 }
@@ -1600,6 +1600,8 @@ static int cm_req_handler(struct cm_work *work)
        struct ib_cm_id *cm_id;
        struct cm_id_private *cm_id_priv, *listen_cm_id_priv;
        struct cm_req_msg *req_msg;
+       union ib_gid gid;
+       struct ib_gid_attr gid_attr;
        int ret;
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1639,11 +1641,31 @@ static int cm_req_handler(struct cm_work *work)
        cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
 
        memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN);
-       ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
+       work->path[0].hop_limit = cm_id_priv->av.ah_attr.grh.hop_limit;
+       ret = ib_get_cached_gid(work->port->cm_dev->ib_device,
+                               work->port->port_num,
+                               cm_id_priv->av.ah_attr.grh.sgid_index,
+                               &gid, &gid_attr);
+       if (!ret) {
+               if (gid_attr.ndev) {
+                       work->path[0].ifindex = gid_attr.ndev->ifindex;
+                       work->path[0].net = dev_net(gid_attr.ndev);
+                       dev_put(gid_attr.ndev);
+               }
+               work->path[0].gid_type = gid_attr.gid_type;
+               ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
+       }
        if (ret) {
-               ib_get_cached_gid(work->port->cm_dev->ib_device,
-                                 work->port->port_num, 0, &work->path[0].sgid,
-                                 NULL);
+               int err = ib_get_cached_gid(work->port->cm_dev->ib_device,
+                                           work->port->port_num, 0,
+                                           &work->path[0].sgid,
+                                           &gid_attr);
+               if (!err && gid_attr.ndev) {
+                       work->path[0].ifindex = gid_attr.ndev->ifindex;
+                       work->path[0].net = dev_net(gid_attr.ndev);
+                       dev_put(gid_attr.ndev);
+               }
+               work->path[0].gid_type = gid_attr.gid_type;
                ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
                               &work->path[0].sgid, sizeof work->path[0].sgid,
                               NULL, 0);
@@ -3482,6 +3504,7 @@ int ib_cm_notify(struct ib_cm_id *cm_id, enum ib_event_type event)
 EXPORT_SYMBOL(ib_cm_notify);
 
 static void cm_recv_handler(struct ib_mad_agent *mad_agent,
+                           struct ib_mad_send_buf *send_buf,
                            struct ib_mad_recv_wc *mad_recv_wc)
 {
        struct cm_port *port = mad_agent->context;
@@ -3731,16 +3754,6 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
 }
 EXPORT_SYMBOL(ib_cm_init_qp_attr);
 
-static void cm_get_ack_delay(struct cm_device *cm_dev)
-{
-       struct ib_device_attr attr;
-
-       if (ib_query_device(cm_dev->ib_device, &attr))
-               cm_dev->ack_delay = 0; /* acks will rely on packet life time */
-       else
-               cm_dev->ack_delay = attr.local_ca_ack_delay;
-}
-
 static ssize_t cm_show_counter(struct kobject *obj, struct attribute *attr,
                               char *buf)
 {
@@ -3852,7 +3865,7 @@ static void cm_add_one(struct ib_device *ib_device)
                return;
 
        cm_dev->ib_device = ib_device;
-       cm_get_ack_delay(cm_dev);
+       cm_dev->ack_delay = ib_device->attrs.local_ca_ack_delay;
        cm_dev->going_down = 0;
        cm_dev->device = device_create(&cm_class, &ib_device->dev,
                                       MKDEV(0, 0), NULL,
index 2d762a2..9729639 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/in6.h>
 #include <linux/mutex.h>
 #include <linux/random.h>
+#include <linux/igmp.h>
 #include <linux/idr.h>
 #include <linux/inetdevice.h>
 #include <linux/slab.h>
@@ -60,6 +61,8 @@
 #include <rdma/ib_sa.h>
 #include <rdma/iw_cm.h>
 
+#include "core_priv.h"
+
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("Generic RDMA CM Agent");
 MODULE_LICENSE("Dual BSD/GPL");
@@ -150,6 +153,7 @@ struct cma_device {
        struct completion       comp;
        atomic_t                refcount;
        struct list_head        id_list;
+       enum ib_gid_type        *default_gid_type;
 };
 
 struct rdma_bind_list {
@@ -185,6 +189,67 @@ enum {
        CMA_OPTION_AFONLY,
 };
 
+void cma_ref_dev(struct cma_device *cma_dev)
+{
+       atomic_inc(&cma_dev->refcount);
+}
+
+struct cma_device *cma_enum_devices_by_ibdev(cma_device_filter filter,
+                                            void               *cookie)
+{
+       struct cma_device *cma_dev;
+       struct cma_device *found_cma_dev = NULL;
+
+       mutex_lock(&lock);
+
+       list_for_each_entry(cma_dev, &dev_list, list)
+               if (filter(cma_dev->device, cookie)) {
+                       found_cma_dev = cma_dev;
+                       break;
+               }
+
+       if (found_cma_dev)
+               cma_ref_dev(found_cma_dev);
+       mutex_unlock(&lock);
+       return found_cma_dev;
+}
+
+int cma_get_default_gid_type(struct cma_device *cma_dev,
+                            unsigned int port)
+{
+       if (port < rdma_start_port(cma_dev->device) ||
+           port > rdma_end_port(cma_dev->device))
+               return -EINVAL;
+
+       return cma_dev->default_gid_type[port - rdma_start_port(cma_dev->device)];
+}
+
+int cma_set_default_gid_type(struct cma_device *cma_dev,
+                            unsigned int port,
+                            enum ib_gid_type default_gid_type)
+{
+       unsigned long supported_gids;
+
+       if (port < rdma_start_port(cma_dev->device) ||
+           port > rdma_end_port(cma_dev->device))
+               return -EINVAL;
+
+       supported_gids = roce_gid_type_mask_support(cma_dev->device, port);
+
+       if (!(supported_gids & 1 << default_gid_type))
+               return -EINVAL;
+
+       cma_dev->default_gid_type[port - rdma_start_port(cma_dev->device)] =
+               default_gid_type;
+
+       return 0;
+}
+
+struct ib_device *cma_get_ib_dev(struct cma_device *cma_dev)
+{
+       return cma_dev->device;
+}
+
 /*
  * Device removal can occur at anytime, so we need extra handling to
  * serialize notifying the user of device removal with other callbacks.
@@ -228,6 +293,7 @@ struct rdma_id_private {
        u8                      tos;
        u8                      reuseaddr;
        u8                      afonly;
+       enum ib_gid_type        gid_type;
 };
 
 struct cma_multicast {
@@ -239,6 +305,7 @@ struct cma_multicast {
        void                    *context;
        struct sockaddr_storage addr;
        struct kref             mcref;
+       bool                    igmp_joined;
 };
 
 struct cma_work {
@@ -335,18 +402,48 @@ static inline void cma_set_ip_ver(struct cma_hdr *hdr, u8 ip_ver)
        hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF);
 }
 
-static void cma_attach_to_dev(struct rdma_id_private *id_priv,
-                             struct cma_device *cma_dev)
+static int cma_igmp_send(struct net_device *ndev, union ib_gid *mgid, bool join)
 {
-       atomic_inc(&cma_dev->refcount);
+       struct in_device *in_dev = NULL;
+
+       if (ndev) {
+               rtnl_lock();
+               in_dev = __in_dev_get_rtnl(ndev);
+               if (in_dev) {
+                       if (join)
+                               ip_mc_inc_group(in_dev,
+                                               *(__be32 *)(mgid->raw + 12));
+                       else
+                               ip_mc_dec_group(in_dev,
+                                               *(__be32 *)(mgid->raw + 12));
+               }
+               rtnl_unlock();
+       }
+       return (in_dev) ? 0 : -ENODEV;
+}
+
+static void _cma_attach_to_dev(struct rdma_id_private *id_priv,
+                              struct cma_device *cma_dev)
+{
+       cma_ref_dev(cma_dev);
        id_priv->cma_dev = cma_dev;
+       id_priv->gid_type = 0;
        id_priv->id.device = cma_dev->device;
        id_priv->id.route.addr.dev_addr.transport =
                rdma_node_get_transport(cma_dev->device->node_type);
        list_add_tail(&id_priv->list, &cma_dev->id_list);
 }
 
-static inline void cma_deref_dev(struct cma_device *cma_dev)
+static void cma_attach_to_dev(struct rdma_id_private *id_priv,
+                             struct cma_device *cma_dev)
+{
+       _cma_attach_to_dev(id_priv, cma_dev);
+       id_priv->gid_type =
+               cma_dev->default_gid_type[id_priv->id.port_num -
+                                         rdma_start_port(cma_dev->device)];
+}
+
+void cma_deref_dev(struct cma_device *cma_dev)
 {
        if (atomic_dec_and_test(&cma_dev->refcount))
                complete(&cma_dev->comp);
@@ -441,6 +538,7 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a
 }
 
 static inline int cma_validate_port(struct ib_device *device, u8 port,
+                                   enum ib_gid_type gid_type,
                                      union ib_gid *gid, int dev_type,
                                      int bound_if_index)
 {
@@ -453,10 +551,25 @@ static inline int cma_validate_port(struct ib_device *device, u8 port,
        if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
                return ret;
 
-       if (dev_type == ARPHRD_ETHER)
+       if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) {
                ndev = dev_get_by_index(&init_net, bound_if_index);
+               if (ndev && ndev->flags & IFF_LOOPBACK) {
+                       pr_info("detected loopback device\n");
+                       dev_put(ndev);
 
-       ret = ib_find_cached_gid_by_port(device, gid, port, ndev, NULL);
+                       if (!device->get_netdev)
+                               return -EOPNOTSUPP;
+
+                       ndev = device->get_netdev(device, port);
+                       if (!ndev)
+                               return -ENODEV;
+               }
+       } else {
+               gid_type = IB_GID_TYPE_IB;
+       }
+
+       ret = ib_find_cached_gid_by_port(device, gid, gid_type, port,
+                                        ndev, NULL);
 
        if (ndev)
                dev_put(ndev);
@@ -490,7 +603,10 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
                gidp = rdma_protocol_roce(cma_dev->device, port) ?
                       &iboe_gid : &gid;
 
-               ret = cma_validate_port(cma_dev->device, port, gidp,
+               ret = cma_validate_port(cma_dev->device, port,
+                                       rdma_protocol_ib(cma_dev->device, port) ?
+                                       IB_GID_TYPE_IB :
+                                       listen_id_priv->gid_type, gidp,
                                        dev_addr->dev_type,
                                        dev_addr->bound_dev_if);
                if (!ret) {
@@ -509,8 +625,11 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
                        gidp = rdma_protocol_roce(cma_dev->device, port) ?
                               &iboe_gid : &gid;
 
-                       ret = cma_validate_port(cma_dev->device, port, gidp,
-                                               dev_addr->dev_type,
+                       ret = cma_validate_port(cma_dev->device, port,
+                                               rdma_protocol_ib(cma_dev->device, port) ?
+                                               IB_GID_TYPE_IB :
+                                               cma_dev->default_gid_type[port - 1],
+                                               gidp, dev_addr->dev_type,
                                                dev_addr->bound_dev_if);
                        if (!ret) {
                                id_priv->id.port_num = port;
@@ -1437,8 +1556,24 @@ static void cma_leave_mc_groups(struct rdma_id_private *id_priv)
                                      id_priv->id.port_num)) {
                        ib_sa_free_multicast(mc->multicast.ib);
                        kfree(mc);
-               } else
+               } else {
+                       if (mc->igmp_joined) {
+                               struct rdma_dev_addr *dev_addr =
+                                       &id_priv->id.route.addr.dev_addr;
+                               struct net_device *ndev = NULL;
+
+                               if (dev_addr->bound_dev_if)
+                                       ndev = dev_get_by_index(&init_net,
+                                                               dev_addr->bound_dev_if);
+                               if (ndev) {
+                                       cma_igmp_send(ndev,
+                                                     &mc->multicast.ib->rec.mgid,
+                                                     false);
+                                       dev_put(ndev);
+                               }
+                       }
                        kref_put(&mc->mcref, release_mc);
+               }
        }
 }
 
@@ -1896,7 +2031,6 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
        struct rdma_id_private *listen_id, *conn_id;
        struct rdma_cm_event event;
        int ret;
-       struct ib_device_attr attr;
        struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr;
        struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr;
 
@@ -1938,13 +2072,6 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
        memcpy(cma_src_addr(conn_id), laddr, rdma_addr_size(laddr));
        memcpy(cma_dst_addr(conn_id), raddr, rdma_addr_size(raddr));
 
-       ret = ib_query_device(conn_id->id.device, &attr);
-       if (ret) {
-               mutex_unlock(&conn_id->handler_mutex);
-               rdma_destroy_id(new_cm_id);
-               goto out;
-       }
-
        memset(&event, 0, sizeof event);
        event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
        event.param.conn.private_data = iw_event->private_data;
@@ -2051,7 +2178,7 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
        memcpy(cma_src_addr(dev_id_priv), cma_src_addr(id_priv),
               rdma_addr_size(cma_src_addr(id_priv)));
 
-       cma_attach_to_dev(dev_id_priv, cma_dev);
+       _cma_attach_to_dev(dev_id_priv, cma_dev);
        list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
        atomic_inc(&id_priv->refcount);
        dev_id_priv->internal_id = 1;
@@ -2321,8 +2448,23 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
 
        if (addr->dev_addr.bound_dev_if) {
                ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if);
+               if (!ndev)
+                       return -ENODEV;
+
+               if (ndev->flags & IFF_LOOPBACK) {
+                       dev_put(ndev);
+                       if (!id_priv->id.device->get_netdev)
+                               return -EOPNOTSUPP;
+
+                       ndev = id_priv->id.device->get_netdev(id_priv->id.device,
+                                                             id_priv->id.port_num);
+                       if (!ndev)
+                               return -ENODEV;
+               }
+
                route->path_rec->net = &init_net;
-               route->path_rec->ifindex = addr->dev_addr.bound_dev_if;
+               route->path_rec->ifindex = ndev->ifindex;
+               route->path_rec->gid_type = id_priv->gid_type;
        }
        if (!ndev) {
                ret = -ENODEV;
@@ -2336,7 +2478,14 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
        rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.dst_addr,
                    &route->path_rec->dgid);
 
-       route->path_rec->hop_limit = 1;
+       /* Use the hint from IP Stack to select GID Type */
+       if (route->path_rec->gid_type < ib_network_to_gid_type(addr->dev_addr.network))
+               route->path_rec->gid_type = ib_network_to_gid_type(addr->dev_addr.network);
+       if (((struct sockaddr *)&id_priv->id.route.addr.dst_addr)->sa_family != AF_IB)
+               /* TODO: get the hoplimit from the inet/inet6 device */
+               route->path_rec->hop_limit = addr->dev_addr.hoplimit;
+       else
+               route->path_rec->hop_limit = 1;
        route->path_rec->reversible = 1;
        route->path_rec->pkey = cpu_to_be16(0xffff);
        route->path_rec->mtu_selector = IB_SA_EQ;
@@ -3534,12 +3683,23 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
        event.status = status;
        event.param.ud.private_data = mc->context;
        if (!status) {
+               struct rdma_dev_addr *dev_addr =
+                       &id_priv->id.route.addr.dev_addr;
+               struct net_device *ndev =
+                       dev_get_by_index(&init_net, dev_addr->bound_dev_if);
+               enum ib_gid_type gid_type =
+                       id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
+                       rdma_start_port(id_priv->cma_dev->device)];
+
                event.event = RDMA_CM_EVENT_MULTICAST_JOIN;
                ib_init_ah_from_mcmember(id_priv->id.device,
                                         id_priv->id.port_num, &multicast->rec,
+                                        ndev, gid_type,
                                         &event.param.ud.ah_attr);
                event.param.ud.qp_num = 0xFFFFFF;
                event.param.ud.qkey = be32_to_cpu(multicast->rec.qkey);
+               if (ndev)
+                       dev_put(ndev);
        } else
                event.event = RDMA_CM_EVENT_MULTICAST_ERROR;
 
@@ -3672,9 +3832,10 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
 {
        struct iboe_mcast_work *work;
        struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
-       int err;
+       int err = 0;
        struct sockaddr *addr = (struct sockaddr *)&mc->addr;
        struct net_device *ndev = NULL;
+       enum ib_gid_type gid_type;
 
        if (cma_zero_addr((struct sockaddr *)&mc->addr))
                return -EINVAL;
@@ -3704,9 +3865,25 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
        mc->multicast.ib->rec.rate = iboe_get_rate(ndev);
        mc->multicast.ib->rec.hop_limit = 1;
        mc->multicast.ib->rec.mtu = iboe_get_mtu(ndev->mtu);
+
+       gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
+                  rdma_start_port(id_priv->cma_dev->device)];
+       if (addr->sa_family == AF_INET) {
+               if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
+                       err = cma_igmp_send(ndev, &mc->multicast.ib->rec.mgid,
+                                           true);
+               if (!err) {
+                       mc->igmp_joined = true;
+                       mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
+               }
+       } else {
+               if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
+                       err = -ENOTSUPP;
+       }
        dev_put(ndev);
-       if (!mc->multicast.ib->rec.mtu) {
-               err = -EINVAL;
+       if (err || !mc->multicast.ib->rec.mtu) {
+               if (!err)
+                       err = -EINVAL;
                goto out2;
        }
        rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
@@ -3745,7 +3922,7 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
        memcpy(&mc->addr, addr, rdma_addr_size(addr));
        mc->context = context;
        mc->id_priv = id_priv;
-
+       mc->igmp_joined = false;
        spin_lock(&id_priv->lock);
        list_add(&mc->list, &id_priv->mc_list);
        spin_unlock(&id_priv->lock);
@@ -3790,9 +3967,25 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
                        if (rdma_cap_ib_mcast(id->device, id->port_num)) {
                                ib_sa_free_multicast(mc->multicast.ib);
                                kfree(mc);
-                       } else if (rdma_protocol_roce(id->device, id->port_num))
+                       } else if (rdma_protocol_roce(id->device, id->port_num)) {
+                               if (mc->igmp_joined) {
+                                       struct rdma_dev_addr *dev_addr =
+                                               &id->route.addr.dev_addr;
+                                       struct net_device *ndev = NULL;
+
+                                       if (dev_addr->bound_dev_if)
+                                               ndev = dev_get_by_index(&init_net,
+                                                                       dev_addr->bound_dev_if);
+                                       if (ndev) {
+                                               cma_igmp_send(ndev,
+                                                             &mc->multicast.ib->rec.mgid,
+                                                             false);
+                                               dev_put(ndev);
+                                       }
+                                       mc->igmp_joined = false;
+                               }
                                kref_put(&mc->mcref, release_mc);
-
+                       }
                        return;
                }
        }
@@ -3861,12 +4054,27 @@ static void cma_add_one(struct ib_device *device)
 {
        struct cma_device *cma_dev;
        struct rdma_id_private *id_priv;
+       unsigned int i;
+       unsigned long supported_gids = 0;
 
        cma_dev = kmalloc(sizeof *cma_dev, GFP_KERNEL);
        if (!cma_dev)
                return;
 
        cma_dev->device = device;
+       cma_dev->default_gid_type = kcalloc(device->phys_port_cnt,
+                                           sizeof(*cma_dev->default_gid_type),
+                                           GFP_KERNEL);
+       if (!cma_dev->default_gid_type) {
+               kfree(cma_dev);
+               return;
+       }
+       for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) {
+               supported_gids = roce_gid_type_mask_support(device, i);
+               WARN_ON(!supported_gids);
+               cma_dev->default_gid_type[i - rdma_start_port(device)] =
+                       find_first_bit(&supported_gids, BITS_PER_LONG);
+       }
 
        init_completion(&cma_dev->comp);
        atomic_set(&cma_dev->refcount, 1);
@@ -3946,6 +4154,7 @@ static void cma_remove_one(struct ib_device *device, void *client_data)
        mutex_unlock(&lock);
 
        cma_process_remove(cma_dev);
+       kfree(cma_dev->default_gid_type);
        kfree(cma_dev);
 }
 
@@ -4079,6 +4288,7 @@ static int __init cma_init(void)
 
        if (ibnl_add_client(RDMA_NL_RDMA_CM, RDMA_NL_RDMA_CM_NUM_OPS, cma_cb_table))
                printk(KERN_WARNING "RDMA CMA: failed to add netlink callback\n");
+       cma_configfs_init();
 
        return 0;
 
@@ -4093,6 +4303,7 @@ err_wq:
 
 static void __exit cma_cleanup(void)
 {
+       cma_configfs_exit();
        ibnl_remove_client(RDMA_NL_RDMA_CM);
        ib_unregister_client(&cma_client);
        unregister_netdevice_notifier(&cma_nb);
diff --git a/drivers/infiniband/core/cma_configfs.c b/drivers/infiniband/core/cma_configfs.c
new file mode 100644 (file)
index 0000000..18b112a
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2015, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/configfs.h>
+#include <rdma/ib_verbs.h>
+#include "core_priv.h"
+
+struct cma_device;
+
+struct cma_dev_group;
+
+struct cma_dev_port_group {
+       unsigned int            port_num;
+       struct cma_dev_group    *cma_dev_group;
+       struct config_group     group;
+};
+
+struct cma_dev_group {
+       char                            name[IB_DEVICE_NAME_MAX];
+       struct config_group             device_group;
+       struct config_group             ports_group;
+       struct config_group             *default_dev_group[2];
+       struct config_group             **default_ports_group;
+       struct cma_dev_port_group       *ports;
+};
+
+static struct cma_dev_port_group *to_dev_port_group(struct config_item *item)
+{
+       struct config_group *group;
+
+       if (!item)
+               return NULL;
+
+       group = container_of(item, struct config_group, cg_item);
+       return container_of(group, struct cma_dev_port_group, group);
+}
+
+static bool filter_by_name(struct ib_device *ib_dev, void *cookie)
+{
+       return !strcmp(ib_dev->name, cookie);
+}
+
+static int cma_configfs_params_get(struct config_item *item,
+                                  struct cma_device **pcma_dev,
+                                  struct cma_dev_port_group **pgroup)
+{
+       struct cma_dev_port_group *group = to_dev_port_group(item);
+       struct cma_device *cma_dev;
+
+       if (!group)
+               return -ENODEV;
+
+       cma_dev = cma_enum_devices_by_ibdev(filter_by_name,
+                                           group->cma_dev_group->name);
+       if (!cma_dev)
+               return -ENODEV;
+
+       *pcma_dev = cma_dev;
+       *pgroup = group;
+
+       return 0;
+}
+
+static void cma_configfs_params_put(struct cma_device *cma_dev)
+{
+       cma_deref_dev(cma_dev);
+}
+
+static ssize_t default_roce_mode_show(struct config_item *item,
+                                     char *buf)
+{
+       struct cma_device *cma_dev;
+       struct cma_dev_port_group *group;
+       int gid_type;
+       ssize_t ret;
+
+       ret = cma_configfs_params_get(item, &cma_dev, &group);
+       if (ret)
+               return ret;
+
+       gid_type = cma_get_default_gid_type(cma_dev, group->port_num);
+       cma_configfs_params_put(cma_dev);
+
+       if (gid_type < 0)
+               return gid_type;
+
+       return sprintf(buf, "%s\n", ib_cache_gid_type_str(gid_type));
+}
+
+static ssize_t default_roce_mode_store(struct config_item *item,
+                                      const char *buf, size_t count)
+{
+       struct cma_device *cma_dev;
+       struct cma_dev_port_group *group;
+       int gid_type = ib_cache_gid_parse_type_str(buf);
+       ssize_t ret;
+
+       if (gid_type < 0)
+               return -EINVAL;
+
+       ret = cma_configfs_params_get(item, &cma_dev, &group);
+       if (ret)
+               return ret;
+
+       ret = cma_set_default_gid_type(cma_dev, group->port_num, gid_type);
+
+       cma_configfs_params_put(cma_dev);
+
+       return !ret ? strnlen(buf, count) : ret;
+}
+
+CONFIGFS_ATTR(, default_roce_mode);
+
+static struct configfs_attribute *cma_configfs_attributes[] = {
+       &attr_default_roce_mode,
+       NULL,
+};
+
+static struct config_item_type cma_port_group_type = {
+       .ct_attrs       = cma_configfs_attributes,
+       .ct_owner       = THIS_MODULE
+};
+
+static int make_cma_ports(struct cma_dev_group *cma_dev_group,
+                         struct cma_device *cma_dev)
+{
+       struct ib_device *ibdev;
+       unsigned int i;
+       unsigned int ports_num;
+       struct cma_dev_port_group *ports;
+       struct config_group **ports_group;
+       int err;
+
+       ibdev = cma_get_ib_dev(cma_dev);
+
+       if (!ibdev)
+               return -ENODEV;
+
+       ports_num = ibdev->phys_port_cnt;
+       ports = kcalloc(ports_num, sizeof(*cma_dev_group->ports),
+                       GFP_KERNEL);
+       ports_group = kcalloc(ports_num + 1, sizeof(*ports_group), GFP_KERNEL);
+
+       if (!ports || !ports_group) {
+               err = -ENOMEM;
+               goto free;
+       }
+
+       for (i = 0; i < ports_num; i++) {
+               char port_str[10];
+
+               ports[i].port_num = i + 1;
+               snprintf(port_str, sizeof(port_str), "%u", i + 1);
+               ports[i].cma_dev_group = cma_dev_group;
+               config_group_init_type_name(&ports[i].group,
+                                           port_str,
+                                           &cma_port_group_type);
+               ports_group[i] = &ports[i].group;
+       }
+       ports_group[i] = NULL;
+       cma_dev_group->default_ports_group = ports_group;
+       cma_dev_group->ports = ports;
+
+       return 0;
+free:
+       kfree(ports);
+       kfree(ports_group);
+       cma_dev_group->ports = NULL;
+       cma_dev_group->default_ports_group = NULL;
+       return err;
+}
+
+static void release_cma_dev(struct config_item  *item)
+{
+       struct config_group *group = container_of(item, struct config_group,
+                                                 cg_item);
+       struct cma_dev_group *cma_dev_group = container_of(group,
+                                                          struct cma_dev_group,
+                                                          device_group);
+
+       kfree(cma_dev_group);
+};
+
+static void release_cma_ports_group(struct config_item  *item)
+{
+       struct config_group *group = container_of(item, struct config_group,
+                                                 cg_item);
+       struct cma_dev_group *cma_dev_group = container_of(group,
+                                                          struct cma_dev_group,
+                                                          ports_group);
+
+       kfree(cma_dev_group->ports);
+       kfree(cma_dev_group->default_ports_group);
+       cma_dev_group->ports = NULL;
+       cma_dev_group->default_ports_group = NULL;
+};
+
+static struct configfs_item_operations cma_ports_item_ops = {
+       .release = release_cma_ports_group
+};
+
+static struct config_item_type cma_ports_group_type = {
+       .ct_item_ops    = &cma_ports_item_ops,
+       .ct_owner       = THIS_MODULE
+};
+
+static struct configfs_item_operations cma_device_item_ops = {
+       .release = release_cma_dev
+};
+
+static struct config_item_type cma_device_group_type = {
+       .ct_item_ops    = &cma_device_item_ops,
+       .ct_owner       = THIS_MODULE
+};
+
+static struct config_group *make_cma_dev(struct config_group *group,
+                                        const char *name)
+{
+       int err = -ENODEV;
+       struct cma_device *cma_dev = cma_enum_devices_by_ibdev(filter_by_name,
+                                                              (void *)name);
+       struct cma_dev_group *cma_dev_group = NULL;
+
+       if (!cma_dev)
+               goto fail;
+
+       cma_dev_group = kzalloc(sizeof(*cma_dev_group), GFP_KERNEL);
+
+       if (!cma_dev_group) {
+               err = -ENOMEM;
+               goto fail;
+       }
+
+       strncpy(cma_dev_group->name, name, sizeof(cma_dev_group->name));
+
+       err = make_cma_ports(cma_dev_group, cma_dev);
+       if (err)
+               goto fail;
+
+       cma_dev_group->ports_group.default_groups =
+               cma_dev_group->default_ports_group;
+       config_group_init_type_name(&cma_dev_group->ports_group, "ports",
+                                   &cma_ports_group_type);
+
+       cma_dev_group->device_group.default_groups
+               = cma_dev_group->default_dev_group;
+       cma_dev_group->default_dev_group[0] = &cma_dev_group->ports_group;
+       cma_dev_group->default_dev_group[1] = NULL;
+
+       config_group_init_type_name(&cma_dev_group->device_group, name,
+                                   &cma_device_group_type);
+
+       cma_deref_dev(cma_dev);
+       return &cma_dev_group->device_group;
+
+fail:
+       if (cma_dev)
+               cma_deref_dev(cma_dev);
+       kfree(cma_dev_group);
+       return ERR_PTR(err);
+}
+
+static struct configfs_group_operations cma_subsys_group_ops = {
+       .make_group     = make_cma_dev,
+};
+
+static struct config_item_type cma_subsys_type = {
+       .ct_group_ops   = &cma_subsys_group_ops,
+       .ct_owner       = THIS_MODULE,
+};
+
+static struct configfs_subsystem cma_subsys = {
+       .su_group       = {
+               .cg_item        = {
+                       .ci_namebuf     = "rdma_cm",
+                       .ci_type        = &cma_subsys_type,
+               },
+       },
+};
+
+int __init cma_configfs_init(void)
+{
+       config_group_init(&cma_subsys.su_group);
+       mutex_init(&cma_subsys.su_mutex);
+       return configfs_register_subsystem(&cma_subsys);
+}
+
+void __exit cma_configfs_exit(void)
+{
+       configfs_unregister_subsystem(&cma_subsys);
+}
index 5cf6eb7..eab3221 100644 (file)
 
 #include <rdma/ib_verbs.h>
 
+#if IS_ENABLED(CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS)
+int cma_configfs_init(void);
+void cma_configfs_exit(void);
+#else
+static inline int cma_configfs_init(void)
+{
+       return 0;
+}
+
+static inline void cma_configfs_exit(void)
+{
+}
+#endif
+struct cma_device;
+void cma_ref_dev(struct cma_device *cma_dev);
+void cma_deref_dev(struct cma_device *cma_dev);
+typedef bool (*cma_device_filter)(struct ib_device *, void *);
+struct cma_device *cma_enum_devices_by_ibdev(cma_device_filter filter,
+                                            void               *cookie);
+int cma_get_default_gid_type(struct cma_device *cma_dev,
+                            unsigned int port);
+int cma_set_default_gid_type(struct cma_device *cma_dev,
+                            unsigned int port,
+                            enum ib_gid_type default_gid_type);
+struct ib_device *cma_get_ib_dev(struct cma_device *cma_dev);
+
 int  ib_device_register_sysfs(struct ib_device *device,
                              int (*port_callback)(struct ib_device *,
                                                   u8, struct kobject *));
@@ -70,8 +96,13 @@ enum ib_cache_gid_default_mode {
        IB_CACHE_GID_DEFAULT_MODE_DELETE
 };
 
+int ib_cache_gid_parse_type_str(const char *buf);
+
+const char *ib_cache_gid_type_str(enum ib_gid_type gid_type);
+
 void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
                                  struct net_device *ndev,
+                                 unsigned long gid_type_mask,
                                  enum ib_cache_gid_default_mode mode);
 
 int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
@@ -87,9 +118,23 @@ int roce_gid_mgmt_init(void);
 void roce_gid_mgmt_cleanup(void);
 
 int roce_rescan_device(struct ib_device *ib_dev);
+unsigned long roce_gid_type_mask_support(struct ib_device *ib_dev, u8 port);
 
 int ib_cache_setup_one(struct ib_device *device);
 void ib_cache_cleanup_one(struct ib_device *device);
 void ib_cache_release_one(struct ib_device *device);
 
+static inline bool rdma_is_upper_dev_rcu(struct net_device *dev,
+                                        struct net_device *upper)
+{
+       struct net_device *_upper = NULL;
+       struct list_head *iter;
+
+       netdev_for_each_all_upper_dev_rcu(dev, _upper, iter)
+               if (_upper == upper)
+                       break;
+
+       return _upper == upper;
+}
+
 #endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c
new file mode 100644 (file)
index 0000000..a754fc7
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015 HGST, a Western Digital Company.
+ *
+ * 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/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <rdma/ib_verbs.h>
+
+/* # of WCs to poll for with a single call to ib_poll_cq */
+#define IB_POLL_BATCH                  16
+
+/* # of WCs to iterate over before yielding */
+#define IB_POLL_BUDGET_IRQ             256
+#define IB_POLL_BUDGET_WORKQUEUE       65536
+
+#define IB_POLL_FLAGS \
+       (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS)
+
+static int __ib_process_cq(struct ib_cq *cq, int budget)
+{
+       int i, n, completed = 0;
+
+       while ((n = ib_poll_cq(cq, IB_POLL_BATCH, cq->wc)) > 0) {
+               for (i = 0; i < n; i++) {
+                       struct ib_wc *wc = &cq->wc[i];
+
+                       if (wc->wr_cqe)
+                               wc->wr_cqe->done(cq, wc);
+                       else
+                               WARN_ON_ONCE(wc->status == IB_WC_SUCCESS);
+               }
+
+               completed += n;
+
+               if (n != IB_POLL_BATCH ||
+                   (budget != -1 && completed >= budget))
+                       break;
+       }
+
+       return completed;
+}
+
+/**
+ * ib_process_direct_cq - process a CQ in caller context
+ * @cq:                CQ to process
+ * @budget:    number of CQEs to poll for
+ *
+ * This function is used to process all outstanding CQ entries on a
+ * %IB_POLL_DIRECT CQ.  It does not offload CQ processing to a different
+ * context and does not ask for completion interrupts from the HCA.
+ *
+ * Note: for compatibility reasons -1 can be passed in %budget for unlimited
+ * polling.  Do not use this feature in new code, it will be removed soon.
+ */
+int ib_process_cq_direct(struct ib_cq *cq, int budget)
+{
+       WARN_ON_ONCE(cq->poll_ctx != IB_POLL_DIRECT);
+
+       return __ib_process_cq(cq, budget);
+}
+EXPORT_SYMBOL(ib_process_cq_direct);
+
+static void ib_cq_completion_direct(struct ib_cq *cq, void *private)
+{
+       WARN_ONCE(1, "got unsolicited completion for CQ 0x%p\n", cq);
+}
+
+static int ib_poll_handler(struct irq_poll *iop, int budget)
+{
+       struct ib_cq *cq = container_of(iop, struct ib_cq, iop);
+       int completed;
+
+       completed = __ib_process_cq(cq, budget);
+       if (completed < budget) {
+               irq_poll_complete(&cq->iop);
+               if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
+                       irq_poll_sched(&cq->iop);
+       }
+
+       return completed;
+}
+
+static void ib_cq_completion_softirq(struct ib_cq *cq, void *private)
+{
+       irq_poll_sched(&cq->iop);
+}
+
+static void ib_cq_poll_work(struct work_struct *work)
+{
+       struct ib_cq *cq = container_of(work, struct ib_cq, work);
+       int completed;
+
+       completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE);
+       if (completed >= IB_POLL_BUDGET_WORKQUEUE ||
+           ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
+               queue_work(ib_comp_wq, &cq->work);
+}
+
+static void ib_cq_completion_workqueue(struct ib_cq *cq, void *private)
+{
+       queue_work(ib_comp_wq, &cq->work);
+}
+
+/**
+ * ib_alloc_cq - allocate a completion queue
+ * @dev:               device to allocate the CQ for
+ * @private:           driver private data, accessible from cq->cq_context
+ * @nr_cqe:            number of CQEs to allocate
+ * @comp_vector:       HCA completion vectors for this CQ
+ * @poll_ctx:          context to poll the CQ from.
+ *
+ * This is the proper interface to allocate a CQ for in-kernel users. A
+ * CQ allocated with this interface will automatically be polled from the
+ * specified context.  The ULP needs must use wr->wr_cqe instead of wr->wr_id
+ * to use this CQ abstraction.
+ */
+struct ib_cq *ib_alloc_cq(struct ib_device *dev, void *private,
+               int nr_cqe, int comp_vector, enum ib_poll_context poll_ctx)
+{
+       struct ib_cq_init_attr cq_attr = {
+               .cqe            = nr_cqe,
+               .comp_vector    = comp_vector,
+       };
+       struct ib_cq *cq;
+       int ret = -ENOMEM;
+
+       cq = dev->create_cq(dev, &cq_attr, NULL, NULL);
+       if (IS_ERR(cq))
+               return cq;
+
+       cq->device = dev;
+       cq->uobject = NULL;
+       cq->event_handler = NULL;
+       cq->cq_context = private;
+       cq->poll_ctx = poll_ctx;
+       atomic_set(&cq->usecnt, 0);
+
+       cq->wc = kmalloc_array(IB_POLL_BATCH, sizeof(*cq->wc), GFP_KERNEL);
+       if (!cq->wc)
+               goto out_destroy_cq;
+
+       switch (cq->poll_ctx) {
+       case IB_POLL_DIRECT:
+               cq->comp_handler = ib_cq_completion_direct;
+               break;
+       case IB_POLL_SOFTIRQ:
+               cq->comp_handler = ib_cq_completion_softirq;
+
+               irq_poll_init(&cq->iop, IB_POLL_BUDGET_IRQ, ib_poll_handler);
+               ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+               break;
+       case IB_POLL_WORKQUEUE:
+               cq->comp_handler = ib_cq_completion_workqueue;
+               INIT_WORK(&cq->work, ib_cq_poll_work);
+               ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+               break;
+       default:
+               ret = -EINVAL;
+               goto out_free_wc;
+       }
+
+       return cq;
+
+out_free_wc:
+       kfree(cq->wc);
+out_destroy_cq:
+       cq->device->destroy_cq(cq);
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(ib_alloc_cq);
+
+/**
+ * ib_free_cq - free a completion queue
+ * @cq:                completion queue to free.
+ */
+void ib_free_cq(struct ib_cq *cq)
+{
+       int ret;
+
+       if (WARN_ON_ONCE(atomic_read(&cq->usecnt)))
+               return;
+
+       switch (cq->poll_ctx) {
+       case IB_POLL_DIRECT:
+               break;
+       case IB_POLL_SOFTIRQ:
+               irq_poll_disable(&cq->iop);
+               break;
+       case IB_POLL_WORKQUEUE:
+               flush_work(&cq->work);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+       }
+
+       kfree(cq->wc);
+       ret = cq->device->destroy_cq(cq);
+       WARN_ON_ONCE(ret);
+}
+EXPORT_SYMBOL(ib_free_cq);
index 179e813..00da80e 100644 (file)
@@ -58,6 +58,7 @@ struct ib_client_data {
        bool              going_down;
 };
 
+struct workqueue_struct *ib_comp_wq;
 struct workqueue_struct *ib_wq;
 EXPORT_SYMBOL_GPL(ib_wq);
 
@@ -325,6 +326,7 @@ int ib_register_device(struct ib_device *device,
 {
        int ret;
        struct ib_client *client;
+       struct ib_udata uhw = {.outlen = 0, .inlen = 0};
 
        mutex_lock(&device_mutex);
 
@@ -352,6 +354,13 @@ int ib_register_device(struct ib_device *device,
                goto out;
        }
 
+       memset(&device->attrs, 0, sizeof(device->attrs));
+       ret = device->query_device(device, &device->attrs, &uhw);
+       if (ret) {
+               printk(KERN_WARNING "Couldn't query the device attributes\n");
+               goto out;
+       }
+
        ret = ib_device_register_sysfs(device, port_callback);
        if (ret) {
                printk(KERN_WARNING "Couldn't register device %s with driver model\n",
@@ -627,25 +636,6 @@ void ib_dispatch_event(struct ib_event *event)
 }
 EXPORT_SYMBOL(ib_dispatch_event);
 
-/**
- * ib_query_device - Query IB device attributes
- * @device:Device to query
- * @device_attr:Device attributes
- *
- * ib_query_device() returns the attributes of a device through the
- * @device_attr pointer.
- */
-int ib_query_device(struct ib_device *device,
-                   struct ib_device_attr *device_attr)
-{
-       struct ib_udata uhw = {.outlen = 0, .inlen = 0};
-
-       memset(device_attr, 0, sizeof(*device_attr));
-
-       return device->query_device(device, device_attr, &uhw);
-}
-EXPORT_SYMBOL(ib_query_device);
-
 /**
  * ib_query_port - Query IB port attributes
  * @device:Device to query
@@ -825,26 +815,31 @@ EXPORT_SYMBOL(ib_modify_port);
  *   a specified GID value occurs.
  * @device: The device to query.
  * @gid: The GID value to search for.
+ * @gid_type: Type of GID.
  * @ndev: The ndev related to the GID to search for.
  * @port_num: The port number of the device where the GID value was found.
  * @index: The index into the GID table where the GID was found.  This
  *   parameter may be NULL.
  */
 int ib_find_gid(struct ib_device *device, union ib_gid *gid,
-               struct net_device *ndev, u8 *port_num, u16 *index)
+               enum ib_gid_type gid_type, struct net_device *ndev,
+               u8 *port_num, u16 *index)
 {
        union ib_gid tmp_gid;
        int ret, port, i;
 
        for (port = rdma_start_port(device); port <= rdma_end_port(device); ++port) {
                if (rdma_cap_roce_gid_table(device, port)) {
-                       if (!ib_find_cached_gid_by_port(device, gid, port,
+                       if (!ib_find_cached_gid_by_port(device, gid, gid_type, port,
                                                        ndev, index)) {
                                *port_num = port;
                                return 0;
                        }
                }
 
+               if (gid_type != IB_GID_TYPE_IB)
+                       continue;
+
                for (i = 0; i < device->port_immutable[port].gid_tbl_len; ++i) {
                        ret = ib_query_gid(device, port, i, &tmp_gid, NULL);
                        if (ret)
@@ -954,10 +949,18 @@ static int __init ib_core_init(void)
        if (!ib_wq)
                return -ENOMEM;
 
+       ib_comp_wq = alloc_workqueue("ib-comp-wq",
+                       WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM,
+                       WQ_UNBOUND_MAX_ACTIVE);
+       if (!ib_comp_wq) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
        ret = class_register(&ib_class);
        if (ret) {
                printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
-               goto err;
+               goto err_comp;
        }
 
        ret = ibnl_init();
@@ -972,7 +975,8 @@ static int __init ib_core_init(void)
 
 err_sysfs:
        class_unregister(&ib_class);
-
+err_comp:
+       destroy_workqueue(ib_comp_wq);
 err:
        destroy_workqueue(ib_wq);
        return ret;
@@ -983,6 +987,7 @@ static void __exit ib_core_cleanup(void)
        ib_cache_cleanup();
        ibnl_cleanup();
        class_unregister(&ib_class);
+       destroy_workqueue(ib_comp_wq);
        /* Make sure that any pending umem accounting work is done. */
        destroy_workqueue(ib_wq);
 }
index 9f5ad7c..6ac3683 100644 (file)
@@ -212,7 +212,6 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd             *pd,
 {
        struct ib_device   *device;
        struct ib_fmr_pool *pool;
-       struct ib_device_attr *attr;
        int i;
        int ret;
        int max_remaps;
@@ -228,25 +227,10 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd             *pd,
                return ERR_PTR(-ENOSYS);
        }
 
-       attr = kmalloc(sizeof *attr, GFP_KERNEL);
-       if (!attr) {
-               printk(KERN_WARNING PFX "couldn't allocate device attr struct\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       ret = ib_query_device(device, attr);
-       if (ret) {
-               printk(KERN_WARNING PFX "couldn't query device: %d\n", ret);
-               kfree(attr);
-               return ERR_PTR(ret);
-       }
-
-       if (!attr->max_map_per_fmr)
+       if (!device->attrs.max_map_per_fmr)
                max_remaps = IB_FMR_MAX_REMAPS;
        else
-               max_remaps = attr->max_map_per_fmr;
-
-       kfree(attr);
+               max_remaps = device->attrs.max_map_per_fmr;
 
        pool = kmalloc(sizeof *pool, GFP_KERNEL);
        if (!pool) {
index 2281de1..9fa5bf3 100644 (file)
@@ -84,6 +84,9 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
                              u8 mgmt_class);
 static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
                           struct ib_mad_agent_private *agent_priv);
+static bool ib_mad_send_error(struct ib_mad_port_private *port_priv,
+                             struct ib_wc *wc);
+static void ib_mad_send_done(struct ib_cq *cq, struct ib_wc *wc);
 
 /*
  * Returns a ib_mad_port_private structure or NULL for a device/port
@@ -681,7 +684,7 @@ static void snoop_recv(struct ib_mad_qp_info *qp_info,
 
                atomic_inc(&mad_snoop_priv->refcount);
                spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
-               mad_snoop_priv->agent.recv_handler(&mad_snoop_priv->agent,
+               mad_snoop_priv->agent.recv_handler(&mad_snoop_priv->agent, NULL,
                                                   mad_recv_wc);
                deref_snoop_agent(mad_snoop_priv);
                spin_lock_irqsave(&qp_info->snoop_lock, flags);
@@ -689,12 +692,11 @@ static void snoop_recv(struct ib_mad_qp_info *qp_info,
        spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
 }
 
-static void build_smp_wc(struct ib_qp *qp,
-                        u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
-                        struct ib_wc *wc)
+static void build_smp_wc(struct ib_qp *qp, struct ib_cqe *cqe, u16 slid,
+               u16 pkey_index, u8 port_num, struct ib_wc *wc)
 {
        memset(wc, 0, sizeof *wc);
-       wc->wr_id = wr_id;
+       wc->wr_cqe = cqe;
        wc->status = IB_WC_SUCCESS;
        wc->opcode = IB_WC_RECV;
        wc->pkey_index = pkey_index;
@@ -832,7 +834,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
        }
 
        build_smp_wc(mad_agent_priv->agent.qp,
-                    send_wr->wr.wr_id, drslid,
+                    send_wr->wr.wr_cqe, drslid,
                     send_wr->pkey_index,
                     send_wr->port_num, &mad_wc);
 
@@ -1039,7 +1041,9 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 
        mad_send_wr->sg_list[1].lkey = mad_agent->qp->pd->local_dma_lkey;
 
-       mad_send_wr->send_wr.wr.wr_id = (unsigned long) mad_send_wr;
+       mad_send_wr->mad_list.cqe.done = ib_mad_send_done;
+
+       mad_send_wr->send_wr.wr.wr_cqe = &mad_send_wr->mad_list.cqe;
        mad_send_wr->send_wr.wr.sg_list = mad_send_wr->sg_list;
        mad_send_wr->send_wr.wr.num_sge = 2;
        mad_send_wr->send_wr.wr.opcode = IB_WR_SEND;
@@ -1151,8 +1155,9 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
 
        /* Set WR ID to find mad_send_wr upon completion */
        qp_info = mad_send_wr->mad_agent_priv->qp_info;
-       mad_send_wr->send_wr.wr.wr_id = (unsigned long)&mad_send_wr->mad_list;
        mad_send_wr->mad_list.mad_queue = &qp_info->send_queue;
+       mad_send_wr->mad_list.cqe.done = ib_mad_send_done;
+       mad_send_wr->send_wr.wr.wr_cqe = &mad_send_wr->mad_list.cqe;
 
        mad_agent = mad_send_wr->send_buf.mad_agent;
        sge = mad_send_wr->sg_list;
@@ -1982,9 +1987,9 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
                                /* user rmpp is in effect
                                 * and this is an active RMPP MAD
                                 */
-                               mad_recv_wc->wc->wr_id = 0;
-                               mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
-                                                                  mad_recv_wc);
+                               mad_agent_priv->agent.recv_handler(
+                                               &mad_agent_priv->agent, NULL,
+                                               mad_recv_wc);
                                atomic_dec(&mad_agent_priv->refcount);
                        } else {
                                /* not user rmpp, revert to normal behavior and
@@ -1998,9 +2003,10 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
                        spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
                        /* Defined behavior is to complete response before request */
-                       mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf;
-                       mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
-                                                          mad_recv_wc);
+                       mad_agent_priv->agent.recv_handler(
+                                       &mad_agent_priv->agent,
+                                       &mad_send_wr->send_buf,
+                                       mad_recv_wc);
                        atomic_dec(&mad_agent_priv->refcount);
 
                        mad_send_wc.status = IB_WC_SUCCESS;
@@ -2009,7 +2015,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
                        ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
                }
        } else {
-               mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+               mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, NULL,
                                                   mad_recv_wc);
                deref_mad_agent(mad_agent_priv);
        }
@@ -2172,13 +2178,14 @@ handle_smi(struct ib_mad_port_private *port_priv,
        return handle_ib_smi(port_priv, qp_info, wc, port_num, recv, response);
 }
 
-static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
-                                    struct ib_wc *wc)
+static void ib_mad_recv_done(struct ib_cq *cq, struct ib_wc *wc)
 {
+       struct ib_mad_port_private *port_priv = cq->cq_context;
+       struct ib_mad_list_head *mad_list =
+               container_of(wc->wr_cqe, struct ib_mad_list_head, cqe);
        struct ib_mad_qp_info *qp_info;
        struct ib_mad_private_header *mad_priv_hdr;
        struct ib_mad_private *recv, *response = NULL;
-       struct ib_mad_list_head *mad_list;
        struct ib_mad_agent_private *mad_agent;
        int port_num;
        int ret = IB_MAD_RESULT_SUCCESS;
@@ -2186,7 +2193,17 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        u16 resp_mad_pkey_index = 0;
        bool opa;
 
-       mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
+       if (list_empty_careful(&port_priv->port_list))
+               return;
+
+       if (wc->status != IB_WC_SUCCESS) {
+               /*
+                * Receive errors indicate that the QP has entered the error
+                * state - error handling/shutdown code will cleanup
+                */
+               return;
+       }
+
        qp_info = mad_list->mad_queue->qp_info;
        dequeue_mad(mad_list);
 
@@ -2227,7 +2244,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        response = alloc_mad_private(mad_size, GFP_KERNEL);
        if (!response) {
                dev_err(&port_priv->device->dev,
-                       "ib_mad_recv_done_handler no memory for response buffer\n");
+                       "%s: no memory for response buffer\n", __func__);
                goto out;
        }
 
@@ -2413,11 +2430,12 @@ done:
        spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 }
 
-static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
-                                    struct ib_wc *wc)
+static void ib_mad_send_done(struct ib_cq *cq, struct ib_wc *wc)
 {
+       struct ib_mad_port_private *port_priv = cq->cq_context;
+       struct ib_mad_list_head *mad_list =
+               container_of(wc->wr_cqe, struct ib_mad_list_head, cqe);
        struct ib_mad_send_wr_private   *mad_send_wr, *queued_send_wr;
-       struct ib_mad_list_head         *mad_list;
        struct ib_mad_qp_info           *qp_info;
        struct ib_mad_queue             *send_queue;
        struct ib_send_wr               *bad_send_wr;
@@ -2425,7 +2443,14 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
        unsigned long flags;
        int ret;
 
-       mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
+       if (list_empty_careful(&port_priv->port_list))
+               return;
+
+       if (wc->status != IB_WC_SUCCESS) {
+               if (!ib_mad_send_error(port_priv, wc))
+                       return;
+       }
+
        mad_send_wr = container_of(mad_list, struct ib_mad_send_wr_private,
                                   mad_list);
        send_queue = mad_list->mad_queue;
@@ -2490,24 +2515,15 @@ static void mark_sends_for_retry(struct ib_mad_qp_info *qp_info)
        spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
 }
 
-static void mad_error_handler(struct ib_mad_port_private *port_priv,
-                             struct ib_wc *wc)
+static bool ib_mad_send_error(struct ib_mad_port_private *port_priv,
+               struct ib_wc *wc)
 {
-       struct ib_mad_list_head *mad_list;
-       struct ib_mad_qp_info *qp_info;
+       struct ib_mad_list_head *mad_list =
+               container_of(wc->wr_cqe, struct ib_mad_list_head, cqe);
+       struct ib_mad_qp_info *qp_info = mad_list->mad_queue->qp_info;
        struct ib_mad_send_wr_private *mad_send_wr;
        int ret;
 
-       /* Determine if failure was a send or receive */
-       mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
-       qp_info = mad_list->mad_queue->qp_info;
-       if (mad_list->mad_queue == &qp_info->recv_queue)
-               /*
-                * Receive errors indicate that the QP has entered the error
-                * state - error handling/shutdown code will cleanup
-                */
-               return;
-
        /*
         * Send errors will transition the QP to SQE - move
         * QP to RTS and repost flushed work requests
@@ -2522,10 +2538,9 @@ static void mad_error_handler(struct ib_mad_port_private *port_priv,
                        mad_send_wr->retry = 0;
                        ret = ib_post_send(qp_info->qp, &mad_send_wr->send_wr.wr,
                                        &bad_send_wr);
-                       if (ret)
-                               ib_mad_send_done_handler(port_priv, wc);
-               } else
-                       ib_mad_send_done_handler(port_priv, wc);
+                       if (!ret)
+                               return false;
+               }
        } else {
                struct ib_qp_attr *attr;
 
@@ -2539,42 +2554,14 @@ static void mad_error_handler(struct ib_mad_port_private *port_priv,
                        kfree(attr);
                        if (ret)
                                dev_err(&port_priv->device->dev,
-                                       "mad_error_handler - ib_modify_qp to RTS : %d\n",
-                                       ret);
+                                       "%s - ib_modify_qp to RTS: %d\n",
+                                       __func__, ret);
                        else
                                mark_sends_for_retry(qp_info);
                }
-               ib_mad_send_done_handler(port_priv, wc);
        }
-}
 
-/*
- * IB MAD completion callback
- */
-static void ib_mad_completion_handler(struct work_struct *work)
-{
-       struct ib_mad_port_private *port_priv;
-       struct ib_wc wc;
-
-       port_priv = container_of(work, struct ib_mad_port_private, work);
-       ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
-
-       while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) {
-               if (wc.status == IB_WC_SUCCESS) {
-                       switch (wc.opcode) {
-                       case IB_WC_SEND:
-                               ib_mad_send_done_handler(port_priv, &wc);
-                               break;
-                       case IB_WC_RECV:
-                               ib_mad_recv_done_handler(port_priv, &wc);
-                               break;
-                       default:
-                               BUG_ON(1);
-                               break;
-                       }
-               } else
-                       mad_error_handler(port_priv, &wc);
-       }
+       return true;
 }
 
 static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
@@ -2716,7 +2703,7 @@ static void local_completions(struct work_struct *work)
                         * before request
                         */
                        build_smp_wc(recv_mad_agent->agent.qp,
-                                    (unsigned long) local->mad_send_wr,
+                                    local->mad_send_wr->send_wr.wr.wr_cqe,
                                     be16_to_cpu(IB_LID_PERMISSIVE),
                                     local->mad_send_wr->send_wr.pkey_index,
                                     recv_mad_agent->agent.port_num, &wc);
@@ -2744,6 +2731,7 @@ static void local_completions(struct work_struct *work)
                                           IB_MAD_SNOOP_RECVS);
                        recv_mad_agent->agent.recv_handler(
                                                &recv_mad_agent->agent,
+                                               &local->mad_send_wr->send_buf,
                                                &local->mad_priv->header.recv_wc);
                        spin_lock_irqsave(&recv_mad_agent->lock, flags);
                        atomic_dec(&recv_mad_agent->refcount);
@@ -2855,17 +2843,6 @@ static void timeout_sends(struct work_struct *work)
        spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 }
 
-static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg)
-{
-       struct ib_mad_port_private *port_priv = cq->cq_context;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ib_mad_port_list_lock, flags);
-       if (!list_empty(&port_priv->port_list))
-               queue_work(port_priv->wq, &port_priv->work);
-       spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
-}
-
 /*
  * Allocate receive MADs and post receive WRs for them
  */
@@ -2913,8 +2890,9 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
                        break;
                }
                mad_priv->header.mapping = sg_list.addr;
-               recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list;
                mad_priv->header.mad_list.mad_queue = recv_queue;
+               mad_priv->header.mad_list.cqe.done = ib_mad_recv_done;
+               recv_wr.wr_cqe = &mad_priv->header.mad_list.cqe;
 
                /* Post receive WR */
                spin_lock_irqsave(&recv_queue->lock, flags);
@@ -3151,7 +3129,6 @@ static int ib_mad_port_open(struct ib_device *device,
        unsigned long flags;
        char name[sizeof "ib_mad123"];
        int has_smi;
-       struct ib_cq_init_attr cq_attr = {};
 
        if (WARN_ON(rdma_max_mad_size(device, port_num) < IB_MGMT_MAD_SIZE))
                return -EFAULT;
@@ -3179,10 +3156,8 @@ static int ib_mad_port_open(struct ib_device *device,
        if (has_smi)
                cq_size *= 2;
 
-       cq_attr.cqe = cq_size;
-       port_priv->cq = ib_create_cq(port_priv->device,
-                                    ib_mad_thread_completion_handler,
-                                    NULL, port_priv, &cq_attr);
+       port_priv->cq = ib_alloc_cq(port_priv->device, port_priv, cq_size, 0,
+                       IB_POLL_WORKQUEUE);
        if (IS_ERR(port_priv->cq)) {
                dev_err(&device->dev, "Couldn't create ib_mad CQ\n");
                ret = PTR_ERR(port_priv->cq);
@@ -3211,7 +3186,6 @@ static int ib_mad_port_open(struct ib_device *device,
                ret = -ENOMEM;
                goto error8;
        }
-       INIT_WORK(&port_priv->work, ib_mad_completion_handler);
 
        spin_lock_irqsave(&ib_mad_port_list_lock, flags);
        list_add_tail(&port_priv->port_list, &ib_mad_port_list);
@@ -3238,7 +3212,7 @@ error7:
 error6:
        ib_dealloc_pd(port_priv->pd);
 error4:
-       ib_destroy_cq(port_priv->cq);
+       ib_free_cq(port_priv->cq);
        cleanup_recv_queue(&port_priv->qp_info[1]);
        cleanup_recv_queue(&port_priv->qp_info[0]);
 error3:
@@ -3271,7 +3245,7 @@ static int ib_mad_port_close(struct ib_device *device, int port_num)
        destroy_mad_qp(&port_priv->qp_info[1]);
        destroy_mad_qp(&port_priv->qp_info[0]);
        ib_dealloc_pd(port_priv->pd);
-       ib_destroy_cq(port_priv->cq);
+       ib_free_cq(port_priv->cq);
        cleanup_recv_queue(&port_priv->qp_info[1]);
        cleanup_recv_queue(&port_priv->qp_info[0]);
        /* XXX: Handle deallocation of MAD registration tables */
index 990698a..28669f6 100644 (file)
@@ -64,6 +64,7 @@
 
 struct ib_mad_list_head {
        struct list_head list;
+       struct ib_cqe cqe;
        struct ib_mad_queue *mad_queue;
 };
 
@@ -204,7 +205,6 @@ struct ib_mad_port_private {
        struct ib_mad_mgmt_version_table version[MAX_MGMT_VERSION];
        struct list_head agent_list;
        struct workqueue_struct *wq;
-       struct work_struct work;
        struct ib_mad_qp_info qp_info[IB_MAD_QPS_CORE];
 };
 
index bb6685f..250937c 100644 (file)
@@ -723,14 +723,27 @@ EXPORT_SYMBOL(ib_sa_get_mcmember_rec);
 
 int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
                             struct ib_sa_mcmember_rec *rec,
+                            struct net_device *ndev,
+                            enum ib_gid_type gid_type,
                             struct ib_ah_attr *ah_attr)
 {
        int ret;
        u16 gid_index;
        u8 p;
 
-       ret = ib_find_cached_gid(device, &rec->port_gid,
-                                NULL, &p, &gid_index);
+       if (rdma_protocol_roce(device, port_num)) {
+               ret = ib_find_cached_gid_by_port(device, &rec->port_gid,
+                                                gid_type, port_num,
+                                                ndev,
+                                                &gid_index);
+       } else if (rdma_protocol_ib(device, port_num)) {
+               ret = ib_find_cached_gid(device, &rec->port_gid,
+                                        IB_GID_TYPE_IB, NULL, &p,
+                                        &gid_index);
+       } else {
+               ret = -EINVAL;
+       }
+
        if (ret)
                return ret;
 
index 178f984..06556c3 100644 (file)
@@ -67,17 +67,53 @@ struct netdev_event_work {
        struct netdev_event_work_cmd    cmds[ROCE_NETDEV_CALLBACK_SZ];
 };
 
+static const struct {
+       bool (*is_supported)(const struct ib_device *device, u8 port_num);
+       enum ib_gid_type gid_type;
+} PORT_CAP_TO_GID_TYPE[] = {
+       {rdma_protocol_roce_eth_encap, IB_GID_TYPE_ROCE},
+       {rdma_protocol_roce_udp_encap, IB_GID_TYPE_ROCE_UDP_ENCAP},
+};
+
+#define CAP_TO_GID_TABLE_SIZE  ARRAY_SIZE(PORT_CAP_TO_GID_TYPE)
+
+unsigned long roce_gid_type_mask_support(struct ib_device *ib_dev, u8 port)
+{
+       int i;
+       unsigned int ret_flags = 0;
+
+       if (!rdma_protocol_roce(ib_dev, port))
+               return 1UL << IB_GID_TYPE_IB;
+
+       for (i = 0; i < CAP_TO_GID_TABLE_SIZE; i++)
+               if (PORT_CAP_TO_GID_TYPE[i].is_supported(ib_dev, port))
+                       ret_flags |= 1UL << PORT_CAP_TO_GID_TYPE[i].gid_type;
+
+       return ret_flags;
+}
+EXPORT_SYMBOL(roce_gid_type_mask_support);
+
 static void update_gid(enum gid_op_type gid_op, struct ib_device *ib_dev,
                       u8 port, union ib_gid *gid,
                       struct ib_gid_attr *gid_attr)
 {
-       switch (gid_op) {
-       case GID_ADD:
-               ib_cache_gid_add(ib_dev, port, gid, gid_attr);
-               break;
-       case GID_DEL:
-               ib_cache_gid_del(ib_dev, port, gid, gid_attr);
-               break;
+       int i;
+       unsigned long gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
+
+       for (i = 0; i < IB_GID_TYPE_SIZE; i++) {
+               if ((1UL << i) & gid_type_mask) {
+                       gid_attr->gid_type = i;
+                       switch (gid_op) {
+                       case GID_ADD:
+                               ib_cache_gid_add(ib_dev, port,
+                                                gid, gid_attr);
+                               break;
+                       case GID_DEL:
+                               ib_cache_gid_del(ib_dev, port,
+                                                gid, gid_attr);
+                               break;
+                       }
+               }
        }
 }
 
@@ -103,18 +139,6 @@ static enum bonding_slave_state is_eth_active_slave_of_bonding_rcu(struct net_de
        return BONDING_SLAVE_STATE_NA;
 }
 
-static bool is_upper_dev_rcu(struct net_device *dev, struct net_device *upper)
-{
-       struct net_device *_upper = NULL;
-       struct list_head *iter;
-
-       netdev_for_each_all_upper_dev_rcu(dev, _upper, iter)
-               if (_upper == upper)
-                       break;
-
-       return _upper == upper;
-}
-
 #define REQUIRED_BOND_STATES           (BONDING_SLAVE_STATE_ACTIVE |   \
                                         BONDING_SLAVE_STATE_NA)
 static int is_eth_port_of_netdev(struct ib_device *ib_dev, u8 port,
@@ -132,7 +156,7 @@ static int is_eth_port_of_netdev(struct ib_device *ib_dev, u8 port,
        if (!real_dev)
                real_dev = event_ndev;
 
-       res = ((is_upper_dev_rcu(rdma_ndev, event_ndev) &&
+       res = ((rdma_is_upper_dev_rcu(rdma_ndev, event_ndev) &&
               (is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) &
                REQUIRED_BOND_STATES)) ||
               real_dev == rdma_ndev);
@@ -178,7 +202,7 @@ static int upper_device_filter(struct ib_device *ib_dev, u8 port,
                return 1;
 
        rcu_read_lock();
-       res = is_upper_dev_rcu(rdma_ndev, event_ndev);
+       res = rdma_is_upper_dev_rcu(rdma_ndev, event_ndev);
        rcu_read_unlock();
 
        return res;
@@ -203,10 +227,12 @@ static void enum_netdev_default_gids(struct ib_device *ib_dev,
                                     u8 port, struct net_device *event_ndev,
                                     struct net_device *rdma_ndev)
 {
+       unsigned long gid_type_mask;
+
        rcu_read_lock();
        if (!rdma_ndev ||
            ((rdma_ndev != event_ndev &&
-             !is_upper_dev_rcu(rdma_ndev, event_ndev)) ||
+             !rdma_is_upper_dev_rcu(rdma_ndev, event_ndev)) ||
             is_eth_active_slave_of_bonding_rcu(rdma_ndev,
                                                netdev_master_upper_dev_get_rcu(rdma_ndev)) ==
             BONDING_SLAVE_STATE_INACTIVE)) {
@@ -215,7 +241,9 @@ static void enum_netdev_default_gids(struct ib_device *ib_dev,
        }
        rcu_read_unlock();
 
-       ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
+       gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
+
+       ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev, gid_type_mask,
                                     IB_CACHE_GID_DEFAULT_MODE_SET);
 }
 
@@ -234,12 +262,17 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev,
 
        rcu_read_lock();
 
-       if (is_upper_dev_rcu(rdma_ndev, event_ndev) &&
+       if (rdma_is_upper_dev_rcu(rdma_ndev, event_ndev) &&
            is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) ==
            BONDING_SLAVE_STATE_INACTIVE) {
+               unsigned long gid_type_mask;
+
                rcu_read_unlock();
 
+               gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
+
                ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
+                                            gid_type_mask,
                                             IB_CACHE_GID_DEFAULT_MODE_DELETE);
        } else {
                rcu_read_unlock();
index a95a32b..f334090 100644 (file)
@@ -49,7 +49,9 @@
 #include <net/netlink.h>
 #include <uapi/rdma/ib_user_sa.h>
 #include <rdma/ib_marshall.h>
+#include <rdma/ib_addr.h>
 #include "sa.h"
+#include "core_priv.h"
 
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
@@ -715,7 +717,9 @@ static int ib_nl_handle_set_timeout(struct sk_buff *skb,
        struct nlattr *tb[LS_NLA_TYPE_MAX];
        int ret;
 
-       if (!netlink_capable(skb, CAP_NET_ADMIN))
+       if (!(nlh->nlmsg_flags & NLM_F_REQUEST) ||
+           !(NETLINK_CB(skb).sk) ||
+           !netlink_capable(skb, CAP_NET_ADMIN))
                return -EPERM;
 
        ret = nla_parse(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh),
@@ -789,7 +793,9 @@ static int ib_nl_handle_resolve_resp(struct sk_buff *skb,
        int found = 0;
        int ret;
 
-       if (!netlink_capable(skb, CAP_NET_ADMIN))
+       if ((nlh->nlmsg_flags & NLM_F_REQUEST) ||
+           !(NETLINK_CB(skb).sk) ||
+           !netlink_capable(skb, CAP_NET_ADMIN))
                return -EPERM;
 
        spin_lock_irqsave(&ib_nl_request_lock, flags);
@@ -996,7 +1002,8 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
 {
        int ret;
        u16 gid_index;
-       int force_grh;
+       int use_roce;
+       struct net_device *ndev = NULL;
 
        memset(ah_attr, 0, sizeof *ah_attr);
        ah_attr->dlid = be16_to_cpu(rec->dlid);
@@ -1006,16 +1013,71 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
        ah_attr->port_num = port_num;
        ah_attr->static_rate = rec->rate;
 
-       force_grh = rdma_cap_eth_ah(device, port_num);
+       use_roce = rdma_cap_eth_ah(device, port_num);
+
+       if (use_roce) {
+               struct net_device *idev;
+               struct net_device *resolved_dev;
+               struct rdma_dev_addr dev_addr = {.bound_dev_if = rec->ifindex,
+                                                .net = rec->net ? rec->net :
+                                                        &init_net};
+               union {
+                       struct sockaddr     _sockaddr;
+                       struct sockaddr_in  _sockaddr_in;
+                       struct sockaddr_in6 _sockaddr_in6;
+               } sgid_addr, dgid_addr;
+
+               if (!device->get_netdev)
+                       return -EOPNOTSUPP;
+
+               rdma_gid2ip(&sgid_addr._sockaddr, &rec->sgid);
+               rdma_gid2ip(&dgid_addr._sockaddr, &rec->dgid);
+
+               /* validate the route */
+               ret = rdma_resolve_ip_route(&sgid_addr._sockaddr,
+                                           &dgid_addr._sockaddr, &dev_addr);
+               if (ret)
+                       return ret;
 
-       if (rec->hop_limit > 1 || force_grh) {
-               struct net_device *ndev = ib_get_ndev_from_path(rec);
+               if ((dev_addr.network == RDMA_NETWORK_IPV4 ||
+                    dev_addr.network == RDMA_NETWORK_IPV6) &&
+                   rec->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
+                       return -EINVAL;
+
+               idev = device->get_netdev(device, port_num);
+               if (!idev)
+                       return -ENODEV;
+
+               resolved_dev = dev_get_by_index(dev_addr.net,
+                                               dev_addr.bound_dev_if);
+               if (resolved_dev->flags & IFF_LOOPBACK) {
+                       dev_put(resolved_dev);
+                       resolved_dev = idev;
+                       dev_hold(resolved_dev);
+               }
+               ndev = ib_get_ndev_from_path(rec);
+               rcu_read_lock();
+               if ((ndev && ndev != resolved_dev) ||
+                   (resolved_dev != idev &&
+                    !rdma_is_upper_dev_rcu(idev, resolved_dev)))
+                       ret = -EHOSTUNREACH;
+               rcu_read_unlock();
+               dev_put(idev);
+               dev_put(resolved_dev);
+               if (ret) {
+                       if (ndev)
+                               dev_put(ndev);
+                       return ret;
+               }
+       }
 
+       if (rec->hop_limit > 1 || use_roce) {
                ah_attr->ah_flags = IB_AH_GRH;
                ah_attr->grh.dgid = rec->dgid;
 
-               ret = ib_find_cached_gid(device, &rec->sgid, ndev, &port_num,
-                                        &gid_index);
+               ret = ib_find_cached_gid_by_port(device, &rec->sgid,
+                                                rec->gid_type, port_num, ndev,
+                                                &gid_index);
                if (ret) {
                        if (ndev)
                                dev_put(ndev);
@@ -1029,9 +1091,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
                if (ndev)
                        dev_put(ndev);
        }
-       if (force_grh) {
+
+       if (use_roce)
                memcpy(ah_attr->dmac, rec->dmac, ETH_ALEN);
-       }
+
        return 0;
 }
 EXPORT_SYMBOL(ib_init_ah_from_path);
@@ -1157,6 +1220,7 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
                          mad->data, &rec);
                rec.net = NULL;
                rec.ifindex = 0;
+               rec.gid_type = IB_GID_TYPE_IB;
                memset(rec.dmac, 0, ETH_ALEN);
                query->callback(status, &rec, query->context);
        } else
@@ -1609,14 +1673,15 @@ static void send_handler(struct ib_mad_agent *agent,
 }
 
 static void recv_handler(struct ib_mad_agent *mad_agent,
+                        struct ib_mad_send_buf *send_buf,
                         struct ib_mad_recv_wc *mad_recv_wc)
 {
        struct ib_sa_query *query;
-       struct ib_mad_send_buf *mad_buf;
 
-       mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
-       query = mad_buf->context[0];
+       if (!send_buf)
+               return;
 
+       query = send_buf->context[0];
        if (query->callback) {
                if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
                        query->callback(query,
index b1f37d4..3de9351 100644 (file)
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/netdevice.h>
 
 #include <rdma/ib_mad.h>
+#include <rdma/ib_pma.h>
 
+struct ib_port;
+
+struct gid_attr_group {
+       struct ib_port          *port;
+       struct kobject          kobj;
+       struct attribute_group  ndev;
+       struct attribute_group  type;
+};
 struct ib_port {
        struct kobject         kobj;
        struct ib_device      *ibdev;
+       struct gid_attr_group *gid_attr_group;
        struct attribute_group gid_group;
        struct attribute_group pkey_group;
        u8                     port_num;
+       struct attribute_group *pma_table;
 };
 
 struct port_attribute {
@@ -65,6 +77,7 @@ struct port_table_attribute {
        struct port_attribute   attr;
        char                    name[8];
        int                     index;
+       __be16                  attr_id;
 };
 
 static ssize_t port_attr_show(struct kobject *kobj,
@@ -84,6 +97,24 @@ static const struct sysfs_ops port_sysfs_ops = {
        .show = port_attr_show
 };
 
+static ssize_t gid_attr_show(struct kobject *kobj,
+                            struct attribute *attr, char *buf)
+{
+       struct port_attribute *port_attr =
+               container_of(attr, struct port_attribute, attr);
+       struct ib_port *p = container_of(kobj, struct gid_attr_group,
+                                        kobj)->port;
+
+       if (!port_attr->show)
+               return -EIO;
+
+       return port_attr->show(p, port_attr, buf);
+}
+
+static const struct sysfs_ops gid_attr_sysfs_ops = {
+       .show = gid_attr_show
+};
+
 static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
                          char *buf)
 {
@@ -281,6 +312,46 @@ static struct attribute *port_default_attrs[] = {
        NULL
 };
 
+static size_t print_ndev(struct ib_gid_attr *gid_attr, char *buf)
+{
+       if (!gid_attr->ndev)
+               return -EINVAL;
+
+       return sprintf(buf, "%s\n", gid_attr->ndev->name);
+}
+
+static size_t print_gid_type(struct ib_gid_attr *gid_attr, char *buf)
+{
+       return sprintf(buf, "%s\n", ib_cache_gid_type_str(gid_attr->gid_type));
+}
+
+static ssize_t _show_port_gid_attr(struct ib_port *p,
+                                  struct port_attribute *attr,
+                                  char *buf,
+                                  size_t (*print)(struct ib_gid_attr *gid_attr,
+                                                  char *buf))
+{
+       struct port_table_attribute *tab_attr =
+               container_of(attr, struct port_table_attribute, attr);
+       union ib_gid gid;
+       struct ib_gid_attr gid_attr = {};
+       ssize_t ret;
+       va_list args;
+
+       ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid,
+                          &gid_attr);
+       if (ret)
+               goto err;
+
+       ret = print(&gid_attr, buf);
+
+err:
+       if (gid_attr.ndev)
+               dev_put(gid_attr.ndev);
+       va_end(args);
+       return ret;
+}
+
 static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
                             char *buf)
 {
@@ -296,6 +367,19 @@ static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
        return sprintf(buf, "%pI6\n", gid.raw);
 }
 
+static ssize_t show_port_gid_attr_ndev(struct ib_port *p,
+                                      struct port_attribute *attr, char *buf)
+{
+       return _show_port_gid_attr(p, attr, buf, print_ndev);
+}
+
+static ssize_t show_port_gid_attr_gid_type(struct ib_port *p,
+                                          struct port_attribute *attr,
+                                          char *buf)
+{
+       return _show_port_gid_attr(p, attr, buf, print_gid_type);
+}
+
 static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
                              char *buf)
 {
@@ -314,24 +398,32 @@ static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
 #define PORT_PMA_ATTR(_name, _counter, _width, _offset)                        \
 struct port_table_attribute port_pma_attr_##_name = {                  \
        .attr  = __ATTR(_name, S_IRUGO, show_pma_counter, NULL),        \
-       .index = (_offset) | ((_width) << 16) | ((_counter) << 24)      \
+       .index = (_offset) | ((_width) << 16) | ((_counter) << 24),     \
+       .attr_id = IB_PMA_PORT_COUNTERS ,                               \
 }
 
-static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
-                               char *buf)
+#define PORT_PMA_ATTR_EXT(_name, _width, _offset)                      \
+struct port_table_attribute port_pma_attr_ext_##_name = {              \
+       .attr  = __ATTR(_name, S_IRUGO, show_pma_counter, NULL),        \
+       .index = (_offset) | ((_width) << 16),                          \
+       .attr_id = IB_PMA_PORT_COUNTERS_EXT ,                           \
+}
+
+/*
+ * Get a Perfmgmt MAD block of data.
+ * Returns error code or the number of bytes retrieved.
+ */
+static int get_perf_mad(struct ib_device *dev, int port_num, __be16 attr,
+               void *data, int offset, size_t size)
 {
-       struct port_table_attribute *tab_attr =
-               container_of(attr, struct port_table_attribute, attr);
-       int offset = tab_attr->index & 0xffff;
-       int width  = (tab_attr->index >> 16) & 0xff;
-       struct ib_mad *in_mad  = NULL;
-       struct ib_mad *out_mad = NULL;
+       struct ib_mad *in_mad;
+       struct ib_mad *out_mad;
        size_t mad_size = sizeof(*out_mad);
        u16 out_mad_pkey_index = 0;
        ssize_t ret;
 
-       if (!p->ibdev->process_mad)
-               return sprintf(buf, "N/A (no PMA)\n");
+       if (!dev->process_mad)
+               return -ENOSYS;
 
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
        out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
@@ -344,12 +436,13 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
        in_mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_PERF_MGMT;
        in_mad->mad_hdr.class_version = 1;
        in_mad->mad_hdr.method        = IB_MGMT_METHOD_GET;
-       in_mad->mad_hdr.attr_id       = cpu_to_be16(0x12); /* PortCounters */
+       in_mad->mad_hdr.attr_id       = attr;
 
-       in_mad->data[41] = p->port_num; /* PortSelect field */
+       if (attr != IB_PMA_CLASS_PORT_INFO)
+               in_mad->data[41] = port_num;    /* PortSelect field */
 
-       if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY,
-                p->port_num, NULL, NULL,
+       if ((dev->process_mad(dev, IB_MAD_IGNORE_MKEY,
+                port_num, NULL, NULL,
                 (const struct ib_mad_hdr *)in_mad, mad_size,
                 (struct ib_mad_hdr *)out_mad, &mad_size,
                 &out_mad_pkey_index) &
@@ -358,31 +451,54 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
                ret = -EINVAL;
                goto out;
        }
+       memcpy(data, out_mad->data + offset, size);
+       ret = size;
+out:
+       kfree(in_mad);
+       kfree(out_mad);
+       return ret;
+}
+
+static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
+                               char *buf)
+{
+       struct port_table_attribute *tab_attr =
+               container_of(attr, struct port_table_attribute, attr);
+       int offset = tab_attr->index & 0xffff;
+       int width  = (tab_attr->index >> 16) & 0xff;
+       ssize_t ret;
+       u8 data[8];
+
+       ret = get_perf_mad(p->ibdev, p->port_num, tab_attr->attr_id, &data,
+                       40 + offset / 8, sizeof(data));
+       if (ret < 0)
+               return sprintf(buf, "N/A (no PMA)\n");
 
        switch (width) {
        case 4:
-               ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >>
+               ret = sprintf(buf, "%u\n", (*data >>
                                            (4 - (offset % 8))) & 0xf);
                break;
        case 8:
-               ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]);
+               ret = sprintf(buf, "%u\n", *data);
                break;
        case 16:
                ret = sprintf(buf, "%u\n",
-                             be16_to_cpup((__be16 *)(out_mad->data + 40 + offset / 8)));
+                             be16_to_cpup((__be16 *)data));
                break;
        case 32:
                ret = sprintf(buf, "%u\n",
-                             be32_to_cpup((__be32 *)(out_mad->data + 40 + offset / 8)));
+                             be32_to_cpup((__be32 *)data));
+               break;
+       case 64:
+               ret = sprintf(buf, "%llu\n",
+                               be64_to_cpup((__be64 *)data));
                break;
+
        default:
                ret = 0;
        }
 
-out:
-       kfree(in_mad);
-       kfree(out_mad);
-
        return ret;
 }
 
@@ -403,6 +519,18 @@ static PORT_PMA_ATTR(port_rcv_data             , 13, 32, 224);
 static PORT_PMA_ATTR(port_xmit_packets             , 14, 32, 256);
 static PORT_PMA_ATTR(port_rcv_packets              , 15, 32, 288);
 
+/*
+ * Counters added by extended set
+ */
+static PORT_PMA_ATTR_EXT(port_xmit_data                    , 64,  64);
+static PORT_PMA_ATTR_EXT(port_rcv_data             , 64, 128);
+static PORT_PMA_ATTR_EXT(port_xmit_packets         , 64, 192);
+static PORT_PMA_ATTR_EXT(port_rcv_packets          , 64, 256);
+static PORT_PMA_ATTR_EXT(unicast_xmit_packets      , 64, 320);
+static PORT_PMA_ATTR_EXT(unicast_rcv_packets       , 64, 384);
+static PORT_PMA_ATTR_EXT(multicast_xmit_packets            , 64, 448);
+static PORT_PMA_ATTR_EXT(multicast_rcv_packets     , 64, 512);
+
 static struct attribute *pma_attrs[] = {
        &port_pma_attr_symbol_error.attr.attr,
        &port_pma_attr_link_error_recovery.attr.attr,
@@ -423,11 +551,65 @@ static struct attribute *pma_attrs[] = {
        NULL
 };
 
+static struct attribute *pma_attrs_ext[] = {
+       &port_pma_attr_symbol_error.attr.attr,
+       &port_pma_attr_link_error_recovery.attr.attr,
+       &port_pma_attr_link_downed.attr.attr,
+       &port_pma_attr_port_rcv_errors.attr.attr,
+       &port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
+       &port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
+       &port_pma_attr_port_xmit_discards.attr.attr,
+       &port_pma_attr_port_xmit_constraint_errors.attr.attr,
+       &port_pma_attr_port_rcv_constraint_errors.attr.attr,
+       &port_pma_attr_local_link_integrity_errors.attr.attr,
+       &port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
+       &port_pma_attr_VL15_dropped.attr.attr,
+       &port_pma_attr_ext_port_xmit_data.attr.attr,
+       &port_pma_attr_ext_port_rcv_data.attr.attr,
+       &port_pma_attr_ext_port_xmit_packets.attr.attr,
+       &port_pma_attr_ext_port_rcv_packets.attr.attr,
+       &port_pma_attr_ext_unicast_rcv_packets.attr.attr,
+       &port_pma_attr_ext_unicast_xmit_packets.attr.attr,
+       &port_pma_attr_ext_multicast_rcv_packets.attr.attr,
+       &port_pma_attr_ext_multicast_xmit_packets.attr.attr,
+       NULL
+};
+
+static struct attribute *pma_attrs_noietf[] = {
+       &port_pma_attr_symbol_error.attr.attr,
+       &port_pma_attr_link_error_recovery.attr.attr,
+       &port_pma_attr_link_downed.attr.attr,
+       &port_pma_attr_port_rcv_errors.attr.attr,
+       &port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
+       &port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
+       &port_pma_attr_port_xmit_discards.attr.attr,
+       &port_pma_attr_port_xmit_constraint_errors.attr.attr,
+       &port_pma_attr_port_rcv_constraint_errors.attr.attr,
+       &port_pma_attr_local_link_integrity_errors.attr.attr,
+       &port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
+       &port_pma_attr_VL15_dropped.attr.attr,
+       &port_pma_attr_ext_port_xmit_data.attr.attr,
+       &port_pma_attr_ext_port_rcv_data.attr.attr,
+       &port_pma_attr_ext_port_xmit_packets.attr.attr,
+       &port_pma_attr_ext_port_rcv_packets.attr.attr,
+       NULL
+};
+
 static struct attribute_group pma_group = {
        .name  = "counters",
        .attrs  = pma_attrs
 };
 
+static struct attribute_group pma_group_ext = {
+       .name  = "counters",
+       .attrs  = pma_attrs_ext
+};
+
+static struct attribute_group pma_group_noietf = {
+       .name  = "counters",
+       .attrs  = pma_attrs_noietf
+};
+
 static void ib_port_release(struct kobject *kobj)
 {
        struct ib_port *p = container_of(kobj, struct ib_port, kobj);
@@ -451,12 +633,41 @@ static void ib_port_release(struct kobject *kobj)
        kfree(p);
 }
 
+static void ib_port_gid_attr_release(struct kobject *kobj)
+{
+       struct gid_attr_group *g = container_of(kobj, struct gid_attr_group,
+                                               kobj);
+       struct attribute *a;
+       int i;
+
+       if (g->ndev.attrs) {
+               for (i = 0; (a = g->ndev.attrs[i]); ++i)
+                       kfree(a);
+
+               kfree(g->ndev.attrs);
+       }
+
+       if (g->type.attrs) {
+               for (i = 0; (a = g->type.attrs[i]); ++i)
+                       kfree(a);
+
+               kfree(g->type.attrs);
+       }
+
+       kfree(g);
+}
+
 static struct kobj_type port_type = {
        .release       = ib_port_release,
        .sysfs_ops     = &port_sysfs_ops,
        .default_attrs = port_default_attrs
 };
 
+static struct kobj_type gid_attr_type = {
+       .sysfs_ops      = &gid_attr_sysfs_ops,
+       .release        = ib_port_gid_attr_release
+};
+
 static struct attribute **
 alloc_group_attrs(ssize_t (*show)(struct ib_port *,
                                  struct port_attribute *, char *buf),
@@ -500,6 +711,31 @@ err:
        return NULL;
 }
 
+/*
+ * Figure out which counter table to use depending on
+ * the device capabilities.
+ */
+static struct attribute_group *get_counter_table(struct ib_device *dev,
+                                                int port_num)
+{
+       struct ib_class_port_info cpi;
+
+       if (get_perf_mad(dev, port_num, IB_PMA_CLASS_PORT_INFO,
+                               &cpi, 40, sizeof(cpi)) >= 0) {
+
+               if (cpi.capability_mask && IB_PMA_CLASS_CAP_EXT_WIDTH)
+                       /* We have extended counters */
+                       return &pma_group_ext;
+
+               if (cpi.capability_mask && IB_PMA_CLASS_CAP_EXT_WIDTH_NOIETF)
+                       /* But not the IETF ones */
+                       return &pma_group_noietf;
+       }
+
+       /* Fall back to normal counters */
+       return &pma_group;
+}
+
 static int add_port(struct ib_device *device, int port_num,
                    int (*port_callback)(struct ib_device *,
                                         u8, struct kobject *))
@@ -528,9 +764,24 @@ static int add_port(struct ib_device *device, int port_num,
                return ret;
        }
 
-       ret = sysfs_create_group(&p->kobj, &pma_group);
-       if (ret)
+       p->gid_attr_group = kzalloc(sizeof(*p->gid_attr_group), GFP_KERNEL);
+       if (!p->gid_attr_group) {
+               ret = -ENOMEM;
                goto err_put;
+       }
+
+       p->gid_attr_group->port = p;
+       ret = kobject_init_and_add(&p->gid_attr_group->kobj, &gid_attr_type,
+                                  &p->kobj, "gid_attrs");
+       if (ret) {
+               kfree(p->gid_attr_group);
+               goto err_put;
+       }
+
+       p->pma_table = get_counter_table(device, port_num);
+       ret = sysfs_create_group(&p->kobj, p->pma_table);
+       if (ret)
+               goto err_put_gid_attrs;
 
        p->gid_group.name  = "gids";
        p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
@@ -543,12 +794,38 @@ static int add_port(struct ib_device *device, int port_num,
        if (ret)
                goto err_free_gid;
 
+       p->gid_attr_group->ndev.name = "ndevs";
+       p->gid_attr_group->ndev.attrs = alloc_group_attrs(show_port_gid_attr_ndev,
+                                                         attr.gid_tbl_len);
+       if (!p->gid_attr_group->ndev.attrs) {
+               ret = -ENOMEM;
+               goto err_remove_gid;
+       }
+
+       ret = sysfs_create_group(&p->gid_attr_group->kobj,
+                                &p->gid_attr_group->ndev);
+       if (ret)
+               goto err_free_gid_ndev;
+
+       p->gid_attr_group->type.name = "types";
+       p->gid_attr_group->type.attrs = alloc_group_attrs(show_port_gid_attr_gid_type,
+                                                         attr.gid_tbl_len);
+       if (!p->gid_attr_group->type.attrs) {
+               ret = -ENOMEM;
+               goto err_remove_gid_ndev;
+       }
+
+       ret = sysfs_create_group(&p->gid_attr_group->kobj,
+                                &p->gid_attr_group->type);
+       if (ret)
+               goto err_free_gid_type;
+
        p->pkey_group.name  = "pkeys";
        p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,
                                                attr.pkey_tbl_len);
        if (!p->pkey_group.attrs) {
                ret = -ENOMEM;
-               goto err_remove_gid;
+               goto err_remove_gid_type;
        }
 
        ret = sysfs_create_group(&p->kobj, &p->pkey_group);
@@ -576,6 +853,28 @@ err_free_pkey:
        kfree(p->pkey_group.attrs);
        p->pkey_group.attrs = NULL;
 
+err_remove_gid_type:
+       sysfs_remove_group(&p->gid_attr_group->kobj,
+                          &p->gid_attr_group->type);
+
+err_free_gid_type:
+       for (i = 0; i < attr.gid_tbl_len; ++i)
+               kfree(p->gid_attr_group->type.attrs[i]);
+
+       kfree(p->gid_attr_group->type.attrs);
+       p->gid_attr_group->type.attrs = NULL;
+
+err_remove_gid_ndev:
+       sysfs_remove_group(&p->gid_attr_group->kobj,
+                          &p->gid_attr_group->ndev);
+
+err_free_gid_ndev:
+       for (i = 0; i < attr.gid_tbl_len; ++i)
+               kfree(p->gid_attr_group->ndev.attrs[i]);
+
+       kfree(p->gid_attr_group->ndev.attrs);
+       p->gid_attr_group->ndev.attrs = NULL;
+
 err_remove_gid:
        sysfs_remove_group(&p->kobj, &p->gid_group);
 
@@ -587,7 +886,10 @@ err_free_gid:
        p->gid_group.attrs = NULL;
 
 err_remove_pma:
-       sysfs_remove_group(&p->kobj, &pma_group);
+       sysfs_remove_group(&p->kobj, p->pma_table);
+
+err_put_gid_attrs:
+       kobject_put(&p->gid_attr_group->kobj);
 
 err_put:
        kobject_put(&p->kobj);
@@ -614,18 +916,12 @@ static ssize_t show_sys_image_guid(struct device *device,
                                   struct device_attribute *dev_attr, char *buf)
 {
        struct ib_device *dev = container_of(device, struct ib_device, dev);
-       struct ib_device_attr attr;
-       ssize_t ret;
-
-       ret = ib_query_device(dev, &attr);
-       if (ret)
-               return ret;
 
        return sprintf(buf, "%04x:%04x:%04x:%04x\n",
-                      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
-                      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
-                      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
-                      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
+                      be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[0]),
+                      be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[1]),
+                      be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[2]),
+                      be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[3]));
 }
 
 static ssize_t show_node_guid(struct device *device,
@@ -800,9 +1096,14 @@ static void free_port_list_attributes(struct ib_device *device)
        list_for_each_entry_safe(p, t, &device->port_list, entry) {
                struct ib_port *port = container_of(p, struct ib_port, kobj);
                list_del(&p->entry);
-               sysfs_remove_group(p, &pma_group);
+               sysfs_remove_group(p, port->pma_table);
                sysfs_remove_group(p, &port->pkey_group);
                sysfs_remove_group(p, &port->gid_group);
+               sysfs_remove_group(&port->gid_attr_group->kobj,
+                                  &port->gid_attr_group->ndev);
+               sysfs_remove_group(&port->gid_attr_group->kobj,
+                                  &port->gid_attr_group->type);
+               kobject_put(&port->gid_attr_group->kobj);
                kobject_put(p);
        }
 
index 72feee6..19837d2 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/string.h>
 #include <linux/export.h>
 #include <linux/if_ether.h>
+#include <linux/ip.h>
 
 #include <rdma/ib_pack.h>
 
@@ -116,6 +117,72 @@ static const struct ib_field vlan_table[]  = {
          .size_bits    = 16 }
 };
 
+static const struct ib_field ip4_table[]  = {
+       { STRUCT_FIELD(ip4, ver),
+         .offset_words = 0,
+         .offset_bits  = 0,
+         .size_bits    = 4 },
+       { STRUCT_FIELD(ip4, hdr_len),
+         .offset_words = 0,
+         .offset_bits  = 4,
+         .size_bits    = 4 },
+       { STRUCT_FIELD(ip4, tos),
+         .offset_words = 0,
+         .offset_bits  = 8,
+         .size_bits    = 8 },
+       { STRUCT_FIELD(ip4, tot_len),
+         .offset_words = 0,
+         .offset_bits  = 16,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(ip4, id),
+         .offset_words = 1,
+         .offset_bits  = 0,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(ip4, frag_off),
+         .offset_words = 1,
+         .offset_bits  = 16,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(ip4, ttl),
+         .offset_words = 2,
+         .offset_bits  = 0,
+         .size_bits    = 8 },
+       { STRUCT_FIELD(ip4, protocol),
+         .offset_words = 2,
+         .offset_bits  = 8,
+         .size_bits    = 8 },
+       { STRUCT_FIELD(ip4, check),
+         .offset_words = 2,
+         .offset_bits  = 16,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(ip4, saddr),
+         .offset_words = 3,
+         .offset_bits  = 0,
+         .size_bits    = 32 },
+       { STRUCT_FIELD(ip4, daddr),
+         .offset_words = 4,
+         .offset_bits  = 0,
+         .size_bits    = 32 }
+};
+
+static const struct ib_field udp_table[]  = {
+       { STRUCT_FIELD(udp, sport),
+         .offset_words = 0,
+         .offset_bits  = 0,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(udp, dport),
+         .offset_words = 0,
+         .offset_bits  = 16,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(udp, length),
+         .offset_words = 1,
+         .offset_bits  = 0,
+         .size_bits    = 16 },
+       { STRUCT_FIELD(udp, csum),
+         .offset_words = 1,
+         .offset_bits  = 16,
+         .size_bits    = 16 }
+};
+
 static const struct ib_field grh_table[]  = {
        { STRUCT_FIELD(grh, ip_version),
          .offset_words = 0,
@@ -213,26 +280,57 @@ static const struct ib_field deth_table[] = {
          .size_bits    = 24 }
 };
 
+__sum16 ib_ud_ip4_csum(struct ib_ud_header *header)
+{
+       struct iphdr iph;
+
+       iph.ihl         = 5;
+       iph.version     = 4;
+       iph.tos         = header->ip4.tos;
+       iph.tot_len     = header->ip4.tot_len;
+       iph.id          = header->ip4.id;
+       iph.frag_off    = header->ip4.frag_off;
+       iph.ttl         = header->ip4.ttl;
+       iph.protocol    = header->ip4.protocol;
+       iph.check       = 0;
+       iph.saddr       = header->ip4.saddr;
+       iph.daddr       = header->ip4.daddr;
+
+       return ip_fast_csum((u8 *)&iph, iph.ihl);
+}
+EXPORT_SYMBOL(ib_ud_ip4_csum);
+
 /**
  * ib_ud_header_init - Initialize UD header structure
  * @payload_bytes:Length of packet payload
  * @lrh_present: specify if LRH is present
  * @eth_present: specify if Eth header is present
  * @vlan_present: packet is tagged vlan
- * @grh_present:GRH flag (if non-zero, GRH will be included)
+ * @grh_present: GRH flag (if non-zero, GRH will be included)
+ * @ip_version: if non-zero, IP header, V4 or V6, will be included
+ * @udp_present :if non-zero, UDP header will be included
  * @immediate_present: specify if immediate data is present
  * @header:Structure to initialize
  */
-void ib_ud_header_init(int                         payload_bytes,
-                      int                  lrh_present,
-                      int                  eth_present,
-                      int                  vlan_present,
-                      int                  grh_present,
-                      int                  immediate_present,
-                      struct ib_ud_header *header)
+int ib_ud_header_init(int     payload_bytes,
+                     int    lrh_present,
+                     int    eth_present,
+                     int    vlan_present,
+                     int    grh_present,
+                     int    ip_version,
+                     int    udp_present,
+                     int    immediate_present,
+                     struct ib_ud_header *header)
 {
+       grh_present = grh_present && !ip_version;
        memset(header, 0, sizeof *header);
 
+       /*
+        * UDP header without IP header doesn't make sense
+        */
+       if (udp_present && ip_version != 4 && ip_version != 6)
+               return -EINVAL;
+
        if (lrh_present) {
                u16 packet_length;
 
@@ -252,7 +350,7 @@ void ib_ud_header_init(int                      payload_bytes,
        if (vlan_present)
                header->eth.type = cpu_to_be16(ETH_P_8021Q);
 
-       if (grh_present) {
+       if (ip_version == 6 || grh_present) {
                header->grh.ip_version      = 6;
                header->grh.payload_length  =
                        cpu_to_be16((IB_BTH_BYTES     +
@@ -260,8 +358,30 @@ void ib_ud_header_init(int                     payload_bytes,
                                     payload_bytes    +
                                     4                + /* ICRC     */
                                     3) & ~3);          /* round up */
-               header->grh.next_header     = 0x1b;
+               header->grh.next_header     = udp_present ? IPPROTO_UDP : 0x1b;
+       }
+
+       if (ip_version == 4) {
+               int udp_bytes = udp_present ? IB_UDP_BYTES : 0;
+
+               header->ip4.ver = 4; /* version 4 */
+               header->ip4.hdr_len = 5; /* 5 words */
+               header->ip4.tot_len =
+                       cpu_to_be16(IB_IP4_BYTES   +
+                                    udp_bytes     +
+                                    IB_BTH_BYTES  +
+                                    IB_DETH_BYTES +
+                                    payload_bytes +
+                                    4);     /* ICRC     */
+               header->ip4.protocol = IPPROTO_UDP;
        }
+       if (udp_present && ip_version)
+               header->udp.length =
+                       cpu_to_be16(IB_UDP_BYTES   +
+                                    IB_BTH_BYTES  +
+                                    IB_DETH_BYTES +
+                                    payload_bytes +
+                                    4);     /* ICRC     */
 
        if (immediate_present)
                header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
@@ -273,8 +393,11 @@ void ib_ud_header_init(int                     payload_bytes,
        header->lrh_present = lrh_present;
        header->eth_present = eth_present;
        header->vlan_present = vlan_present;
-       header->grh_present = grh_present;
+       header->grh_present = grh_present || (ip_version == 6);
+       header->ipv4_present = ip_version == 4;
+       header->udp_present = udp_present;
        header->immediate_present = immediate_present;
+       return 0;
 }
 EXPORT_SYMBOL(ib_ud_header_init);
 
@@ -311,6 +434,16 @@ int ib_ud_header_pack(struct ib_ud_header *header,
                        &header->grh, buf + len);
                len += IB_GRH_BYTES;
        }
+       if (header->ipv4_present) {
+               ib_pack(ip4_table, ARRAY_SIZE(ip4_table),
+                       &header->ip4, buf + len);
+               len += IB_IP4_BYTES;
+       }
+       if (header->udp_present) {
+               ib_pack(udp_table, ARRAY_SIZE(udp_table),
+                       &header->udp, buf + len);
+               len += IB_UDP_BYTES;
+       }
 
        ib_pack(bth_table, ARRAY_SIZE(bth_table),
                &header->bth, buf + len);
index 40becdb..e69bf26 100644 (file)
@@ -232,7 +232,7 @@ static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn,
        ib_ucontext_notifier_end_account(context);
 }
 
-static struct mmu_notifier_ops ib_umem_notifiers = {
+static const struct mmu_notifier_ops ib_umem_notifiers = {
        .release                    = ib_umem_notifier_release,
        .invalidate_page            = ib_umem_notifier_invalidate_page,
        .invalidate_range_start     = ib_umem_notifier_invalidate_range_start,
index 57f281f..415a318 100644 (file)
@@ -210,6 +210,7 @@ static void send_handler(struct ib_mad_agent *agent,
 }
 
 static void recv_handler(struct ib_mad_agent *agent,
+                        struct ib_mad_send_buf *send_buf,
                         struct ib_mad_recv_wc *mad_recv_wc)
 {
        struct ib_umad_file *file = agent->context;
index 94bbd8c..612ccfd 100644 (file)
@@ -204,6 +204,8 @@ void ib_uverbs_event_handler(struct ib_event_handler *handler,
                             struct ib_event *event);
 void ib_uverbs_dealloc_xrcd(struct ib_uverbs_device *dev, struct ib_xrcd *xrcd);
 
+int uverbs_dealloc_mw(struct ib_mw *mw);
+
 struct ib_uverbs_flow_spec {
        union {
                union {
index 1c02dea..6ffc9c4 100644 (file)
@@ -291,9 +291,6 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
        struct ib_uverbs_get_context      cmd;
        struct ib_uverbs_get_context_resp resp;
        struct ib_udata                   udata;
-#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
-       struct ib_device_attr             dev_attr;
-#endif
        struct ib_ucontext               *ucontext;
        struct file                      *filp;
        int ret;
@@ -342,10 +339,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
        ucontext->odp_mrs_count = 0;
        INIT_LIST_HEAD(&ucontext->no_private_counters);
 
-       ret = ib_query_device(ib_dev, &dev_attr);
-       if (ret)
-               goto err_free;
-       if (!(dev_attr.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
+       if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
                ucontext->invalidate_range = NULL;
 
 #endif
@@ -447,8 +441,6 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
 {
        struct ib_uverbs_query_device      cmd;
        struct ib_uverbs_query_device_resp resp;
-       struct ib_device_attr              attr;
-       int                                ret;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -456,12 +448,8 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
 
-       ret = ib_query_device(ib_dev, &attr);
-       if (ret)
-               return ret;
-
        memset(&resp, 0, sizeof resp);
-       copy_query_dev_fields(file, ib_dev, &resp, &attr);
+       copy_query_dev_fields(file, ib_dev, &resp, &ib_dev->attrs);
 
        if (copy_to_user((void __user *) (unsigned long) cmd.response,
                         &resp, sizeof resp))
@@ -986,11 +974,8 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
        }
 
        if (cmd.access_flags & IB_ACCESS_ON_DEMAND) {
-               struct ib_device_attr attr;
-
-               ret = ib_query_device(pd->device, &attr);
-               if (ret || !(attr.device_cap_flags &
-                               IB_DEVICE_ON_DEMAND_PAGING)) {
+               if (!(pd->device->attrs.device_cap_flags &
+                     IB_DEVICE_ON_DEMAND_PAGING)) {
                        pr_debug("ODP support not available\n");
                        ret = -EINVAL;
                        goto err_put;
@@ -1008,7 +993,6 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
        mr->pd      = pd;
        mr->uobject = uobj;
        atomic_inc(&pd->usecnt);
-       atomic_set(&mr->usecnt, 0);
 
        uobj->object = mr;
        ret = idr_add_uobj(&ib_uverbs_mr_idr, uobj);
@@ -1106,11 +1090,6 @@ ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file,
                }
        }
 
-       if (atomic_read(&mr->usecnt)) {
-               ret = -EBUSY;
-               goto put_uobj_pd;
-       }
-
        old_pd = mr->pd;
        ret = mr->device->rereg_user_mr(mr, cmd.flags, cmd.start,
                                        cmd.length, cmd.hca_va,
@@ -1258,7 +1237,7 @@ err_copy:
        idr_remove_uobj(&ib_uverbs_mw_idr, uobj);
 
 err_unalloc:
-       ib_dealloc_mw(mw);
+       uverbs_dealloc_mw(mw);
 
 err_put:
        put_pd_read(pd);
@@ -1287,7 +1266,7 @@ ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file,
 
        mw = uobj->object;
 
-       ret = ib_dealloc_mw(mw);
+       ret = uverbs_dealloc_mw(mw);
        if (!ret)
                uobj->live = 0;
 
@@ -1845,7 +1824,10 @@ static int create_qp(struct ib_uverbs_file *file,
                      sizeof(cmd->create_flags))
                attr.create_flags = cmd->create_flags;
 
-       if (attr.create_flags & ~IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
+       if (attr.create_flags & ~(IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK |
+                               IB_QP_CREATE_CROSS_CHANNEL |
+                               IB_QP_CREATE_MANAGED_SEND |
+                               IB_QP_CREATE_MANAGED_RECV)) {
                ret = -EINVAL;
                goto err_put;
        }
index e3ef288..39680ae 100644 (file)
@@ -133,6 +133,17 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
 static void ib_uverbs_add_one(struct ib_device *device);
 static void ib_uverbs_remove_one(struct ib_device *device, void *client_data);
 
+int uverbs_dealloc_mw(struct ib_mw *mw)
+{
+       struct ib_pd *pd = mw->pd;
+       int ret;
+
+       ret = mw->device->dealloc_mw(mw);
+       if (!ret)
+               atomic_dec(&pd->usecnt);
+       return ret;
+}
+
 static void ib_uverbs_release_dev(struct kobject *kobj)
 {
        struct ib_uverbs_device *dev =
@@ -224,7 +235,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
                struct ib_mw *mw = uobj->object;
 
                idr_remove_uobj(&ib_uverbs_mw_idr, uobj);
-               ib_dealloc_mw(mw);
+               uverbs_dealloc_mw(mw);
                kfree(uobj);
        }
 
index 7d2f14c..af020f8 100644 (file)
@@ -144,5 +144,6 @@ void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst,
        memset(dst->dmac, 0, sizeof(dst->dmac));
        dst->net = NULL;
        dst->ifindex = 0;
+       dst->gid_type = IB_GID_TYPE_IB;
 }
 EXPORT_SYMBOL(ib_copy_path_rec_from_user);
index 545906d..5af6d02 100644 (file)
@@ -229,12 +229,6 @@ EXPORT_SYMBOL(rdma_port_get_link_layer);
 struct ib_pd *ib_alloc_pd(struct ib_device *device)
 {
        struct ib_pd *pd;
-       struct ib_device_attr devattr;
-       int rc;
-
-       rc = ib_query_device(device, &devattr);
-       if (rc)
-               return ERR_PTR(rc);
 
        pd = device->alloc_pd(device, NULL, NULL);
        if (IS_ERR(pd))
@@ -245,7 +239,7 @@ struct ib_pd *ib_alloc_pd(struct ib_device *device)
        pd->local_mr = NULL;
        atomic_set(&pd->usecnt, 0);
 
-       if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
+       if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
                pd->local_dma_lkey = device->local_dma_lkey;
        else {
                struct ib_mr *mr;
@@ -311,8 +305,61 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
 }
 EXPORT_SYMBOL(ib_create_ah);
 
+static int ib_get_header_version(const union rdma_network_hdr *hdr)
+{
+       const struct iphdr *ip4h = (struct iphdr *)&hdr->roce4grh;
+       struct iphdr ip4h_checked;
+       const struct ipv6hdr *ip6h = (struct ipv6hdr *)&hdr->ibgrh;
+
+       /* If it's IPv6, the version must be 6, otherwise, the first
+        * 20 bytes (before the IPv4 header) are garbled.
+        */
+       if (ip6h->version != 6)
+               return (ip4h->version == 4) ? 4 : 0;
+       /* version may be 6 or 4 because the first 20 bytes could be garbled */
+
+       /* RoCE v2 requires no options, thus header length
+        * must be 5 words
+        */
+       if (ip4h->ihl != 5)
+               return 6;
+
+       /* Verify checksum.
+        * We can't write on scattered buffers so we need to copy to
+        * temp buffer.
+        */
+       memcpy(&ip4h_checked, ip4h, sizeof(ip4h_checked));
+       ip4h_checked.check = 0;
+       ip4h_checked.check = ip_fast_csum((u8 *)&ip4h_checked, 5);
+       /* if IPv4 header checksum is OK, believe it */
+       if (ip4h->check == ip4h_checked.check)
+               return 4;
+       return 6;
+}
+
+static enum rdma_network_type ib_get_net_type_by_grh(struct ib_device *device,
+                                                    u8 port_num,
+                                                    const struct ib_grh *grh)
+{
+       int grh_version;
+
+       if (rdma_protocol_ib(device, port_num))
+               return RDMA_NETWORK_IB;
+
+       grh_version = ib_get_header_version((union rdma_network_hdr *)grh);
+
+       if (grh_version == 4)
+               return RDMA_NETWORK_IPV4;
+
+       if (grh->next_hdr == IPPROTO_UDP)
+               return RDMA_NETWORK_IPV6;
+
+       return RDMA_NETWORK_ROCE_V1;
+}
+
 struct find_gid_index_context {
        u16 vlan_id;
+       enum ib_gid_type gid_type;
 };
 
 static bool find_gid_index(const union ib_gid *gid,
@@ -322,6 +369,9 @@ static bool find_gid_index(const union ib_gid *gid,
        struct find_gid_index_context *ctx =
                (struct find_gid_index_context *)context;
 
+       if (ctx->gid_type != gid_attr->gid_type)
+               return false;
+
        if ((!!(ctx->vlan_id != 0xffff) == !is_vlan_dev(gid_attr->ndev)) ||
            (is_vlan_dev(gid_attr->ndev) &&
             vlan_dev_vlan_id(gid_attr->ndev) != ctx->vlan_id))
@@ -332,14 +382,49 @@ static bool find_gid_index(const union ib_gid *gid,
 
 static int get_sgid_index_from_eth(struct ib_device *device, u8 port_num,
                                   u16 vlan_id, const union ib_gid *sgid,
+                                  enum ib_gid_type gid_type,
                                   u16 *gid_index)
 {
-       struct find_gid_index_context context = {.vlan_id = vlan_id};
+       struct find_gid_index_context context = {.vlan_id = vlan_id,
+                                                .gid_type = gid_type};
 
        return ib_find_gid_by_filter(device, sgid, port_num, find_gid_index,
                                     &context, gid_index);
 }
 
+static int get_gids_from_rdma_hdr(union rdma_network_hdr *hdr,
+                                 enum rdma_network_type net_type,
+                                 union ib_gid *sgid, union ib_gid *dgid)
+{
+       struct sockaddr_in  src_in;
+       struct sockaddr_in  dst_in;
+       __be32 src_saddr, dst_saddr;
+
+       if (!sgid || !dgid)
+               return -EINVAL;
+
+       if (net_type == RDMA_NETWORK_IPV4) {
+               memcpy(&src_in.sin_addr.s_addr,
+                      &hdr->roce4grh.saddr, 4);
+               memcpy(&dst_in.sin_addr.s_addr,
+                      &hdr->roce4grh.daddr, 4);
+               src_saddr = src_in.sin_addr.s_addr;
+               dst_saddr = dst_in.sin_addr.s_addr;
+               ipv6_addr_set_v4mapped(src_saddr,
+                                      (struct in6_addr *)sgid);
+               ipv6_addr_set_v4mapped(dst_saddr,
+                                      (struct in6_addr *)dgid);
+               return 0;
+       } else if (net_type == RDMA_NETWORK_IPV6 ||
+                  net_type == RDMA_NETWORK_IB) {
+               *dgid = hdr->ibgrh.dgid;
+               *sgid = hdr->ibgrh.sgid;
+               return 0;
+       } else {
+               return -EINVAL;
+       }
+}
+
 int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
                       const struct ib_wc *wc, const struct ib_grh *grh,
                       struct ib_ah_attr *ah_attr)
@@ -347,33 +432,72 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
        u32 flow_class;
        u16 gid_index;
        int ret;
+       enum rdma_network_type net_type = RDMA_NETWORK_IB;
+       enum ib_gid_type gid_type = IB_GID_TYPE_IB;
+       int hoplimit = 0xff;
+       union ib_gid dgid;
+       union ib_gid sgid;
 
        memset(ah_attr, 0, sizeof *ah_attr);
        if (rdma_cap_eth_ah(device, port_num)) {
+               if (wc->wc_flags & IB_WC_WITH_NETWORK_HDR_TYPE)
+                       net_type = wc->network_hdr_type;
+               else
+                       net_type = ib_get_net_type_by_grh(device, port_num, grh);
+               gid_type = ib_network_to_gid_type(net_type);
+       }
+       ret = get_gids_from_rdma_hdr((union rdma_network_hdr *)grh, net_type,
+                                    &sgid, &dgid);
+       if (ret)
+               return ret;
+
+       if (rdma_protocol_roce(device, port_num)) {
+               int if_index = 0;
                u16 vlan_id = wc->wc_flags & IB_WC_WITH_VLAN ?
                                wc->vlan_id : 0xffff;
+               struct net_device *idev;
+               struct net_device *resolved_dev;
 
                if (!(wc->wc_flags & IB_WC_GRH))
                        return -EPROTOTYPE;
 
-               if (!(wc->wc_flags & IB_WC_WITH_SMAC) ||
-                   !(wc->wc_flags & IB_WC_WITH_VLAN)) {
-                       ret = rdma_addr_find_dmac_by_grh(&grh->dgid, &grh->sgid,
-                                                        ah_attr->dmac,
-                                                        wc->wc_flags & IB_WC_WITH_VLAN ?
-                                                        NULL : &vlan_id,
-                                                        0);
-                       if (ret)
-                               return ret;
+               if (!device->get_netdev)
+                       return -EOPNOTSUPP;
+
+               idev = device->get_netdev(device, port_num);
+               if (!idev)
+                       return -ENODEV;
+
+               ret = rdma_addr_find_l2_eth_by_grh(&dgid, &sgid,
+                                                  ah_attr->dmac,
+                                                  wc->wc_flags & IB_WC_WITH_VLAN ?
+                                                  NULL : &vlan_id,
+                                                  &if_index, &hoplimit);
+               if (ret) {
+                       dev_put(idev);
+                       return ret;
                }
 
-               ret = get_sgid_index_from_eth(device, port_num, vlan_id,
-                                             &grh->dgid, &gid_index);
+               resolved_dev = dev_get_by_index(&init_net, if_index);
+               if (resolved_dev->flags & IFF_LOOPBACK) {
+                       dev_put(resolved_dev);
+                       resolved_dev = idev;
+                       dev_hold(resolved_dev);
+               }
+               rcu_read_lock();
+               if (resolved_dev != idev && !rdma_is_upper_dev_rcu(idev,
+                                                                  resolved_dev))
+                       ret = -EHOSTUNREACH;
+               rcu_read_unlock();
+               dev_put(idev);
+               dev_put(resolved_dev);
                if (ret)
                        return ret;
 
-               if (wc->wc_flags & IB_WC_WITH_SMAC)
-                       memcpy(ah_attr->dmac, wc->smac, ETH_ALEN);
+               ret = get_sgid_index_from_eth(device, port_num, vlan_id,
+                                             &dgid, gid_type, &gid_index);
+               if (ret)
+                       return ret;
        }
 
        ah_attr->dlid = wc->slid;
@@ -383,10 +507,11 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
 
        if (wc->wc_flags & IB_WC_GRH) {
                ah_attr->ah_flags = IB_AH_GRH;
-               ah_attr->grh.dgid = grh->sgid;
+               ah_attr->grh.dgid = sgid;
 
                if (!rdma_cap_eth_ah(device, port_num)) {
-                       ret = ib_find_cached_gid_by_port(device, &grh->dgid,
+                       ret = ib_find_cached_gid_by_port(device, &dgid,
+                                                        IB_GID_TYPE_IB,
                                                         port_num, NULL,
                                                         &gid_index);
                        if (ret)
@@ -396,7 +521,7 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
                ah_attr->grh.sgid_index = (u8) gid_index;
                flow_class = be32_to_cpu(grh->version_tclass_flow);
                ah_attr->grh.flow_label = flow_class & 0xFFFFF;
-               ah_attr->grh.hop_limit = 0xFF;
+               ah_attr->grh.hop_limit = hoplimit;
                ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
        }
        return 0;
@@ -1014,6 +1139,7 @@ int ib_resolve_eth_dmac(struct ib_qp *qp,
                        union ib_gid            sgid;
                        struct ib_gid_attr      sgid_attr;
                        int                     ifindex;
+                       int                     hop_limit;
 
                        ret = ib_query_gid(qp->device,
                                           qp_attr->ah_attr.port_num,
@@ -1028,12 +1154,14 @@ int ib_resolve_eth_dmac(struct ib_qp *qp,
 
                        ifindex = sgid_attr.ndev->ifindex;
 
-                       ret = rdma_addr_find_dmac_by_grh(&sgid,
-                                                        &qp_attr->ah_attr.grh.dgid,
-                                                        qp_attr->ah_attr.dmac,
-                                                        NULL, ifindex);
+                       ret = rdma_addr_find_l2_eth_by_grh(&sgid,
+                                                          &qp_attr->ah_attr.grh.dgid,
+                                                          qp_attr->ah_attr.dmac,
+                                                          NULL, &ifindex, &hop_limit);
 
                        dev_put(sgid_attr.ndev);
+
+                       qp_attr->ah_attr.grh.hop_limit = hop_limit;
                }
        }
 out:
@@ -1215,29 +1343,17 @@ struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
                mr->pd      = pd;
                mr->uobject = NULL;
                atomic_inc(&pd->usecnt);
-               atomic_set(&mr->usecnt, 0);
        }
 
        return mr;
 }
 EXPORT_SYMBOL(ib_get_dma_mr);
 
-int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
-{
-       return mr->device->query_mr ?
-               mr->device->query_mr(mr, mr_attr) : -ENOSYS;
-}
-EXPORT_SYMBOL(ib_query_mr);
-
 int ib_dereg_mr(struct ib_mr *mr)
 {
-       struct ib_pd *pd;
+       struct ib_pd *pd = mr->pd;
        int ret;
 
-       if (atomic_read(&mr->usecnt))
-               return -EBUSY;
-
-       pd = mr->pd;
        ret = mr->device->dereg_mr(mr);
        if (!ret)
                atomic_dec(&pd->usecnt);
@@ -1273,49 +1389,12 @@ struct ib_mr *ib_alloc_mr(struct ib_pd *pd,
                mr->pd      = pd;
                mr->uobject = NULL;
                atomic_inc(&pd->usecnt);
-               atomic_set(&mr->usecnt, 0);
        }
 
        return mr;
 }
 EXPORT_SYMBOL(ib_alloc_mr);
 
-/* Memory windows */
-
-struct ib_mw *ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type)
-{
-       struct ib_mw *mw;
-
-       if (!pd->device->alloc_mw)
-               return ERR_PTR(-ENOSYS);
-
-       mw = pd->device->alloc_mw(pd, type);
-       if (!IS_ERR(mw)) {
-               mw->device  = pd->device;
-               mw->pd      = pd;
-               mw->uobject = NULL;
-               mw->type    = type;
-               atomic_inc(&pd->usecnt);
-       }
-
-       return mw;
-}
-EXPORT_SYMBOL(ib_alloc_mw);
-
-int ib_dealloc_mw(struct ib_mw *mw)
-{
-       struct ib_pd *pd;
-       int ret;
-
-       pd = mw->pd;
-       ret = mw->device->dealloc_mw(mw);
-       if (!ret)
-               atomic_dec(&pd->usecnt);
-
-       return ret;
-}
-EXPORT_SYMBOL(ib_dealloc_mw);
-
 /* "Fast" memory regions */
 
 struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
@@ -1530,7 +1609,7 @@ int ib_sg_to_pages(struct ib_mr *mr,
                   int (*set_page)(struct ib_mr *, u64))
 {
        struct scatterlist *sg;
-       u64 last_end_dma_addr = 0, last_page_addr = 0;
+       u64 last_end_dma_addr = 0;
        unsigned int last_page_off = 0;
        u64 page_mask = ~((u64)mr->page_size - 1);
        int i, ret;
@@ -1572,7 +1651,6 @@ next_page:
 
                mr->length += dma_len;
                last_end_dma_addr = end_dma_addr;
-               last_page_addr = end_dma_addr & page_mask;
                last_page_off = end_dma_addr & ~page_mask;
        }
 
index cb78b1e..f504ba7 100644 (file)
@@ -149,7 +149,7 @@ static int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_en
        error = l2t_send(tdev, skb, l2e);
        if (error < 0)
                kfree_skb(skb);
-       return error;
+       return error < 0 ? error : 0;
 }
 
 int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
@@ -165,7 +165,7 @@ int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
        error = cxgb3_ofld_send(tdev, skb);
        if (error < 0)
                kfree_skb(skb);
-       return error;
+       return error < 0 ? error : 0;
 }
 
 static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
index cfe4049..97fbfd2 100644 (file)
@@ -115,10 +115,6 @@ static int iwch_poll_cq_one(struct iwch_dev *rhp, struct iwch_cq *chp,
                case T3_SEND_WITH_SE_INV:
                        wc->opcode = IB_WC_SEND;
                        break;
-               case T3_BIND_MW:
-                       wc->opcode = IB_WC_BIND_MW;
-                       break;
-
                case T3_LOCAL_INV:
                        wc->opcode = IB_WC_LOCAL_INV;
                        break;
index 5c36ee2..1d04c87 100644 (file)
@@ -75,37 +75,6 @@ int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
        return ret;
 }
 
-int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
-                                       struct iwch_mr *mhp,
-                                       int shift,
-                                       int npages)
-{
-       u32 stag;
-       int ret;
-
-       /* We could support this... */
-       if (npages > mhp->attr.pbl_size)
-               return -ENOMEM;
-
-       stag = mhp->attr.stag;
-       if (cxio_reregister_phys_mem(&rhp->rdev,
-                                  &stag, mhp->attr.pdid,
-                                  mhp->attr.perms,
-                                  mhp->attr.zbva,
-                                  mhp->attr.va_fbo,
-                                  mhp->attr.len,
-                                  shift - 12,
-                                  mhp->attr.pbl_size, mhp->attr.pbl_addr))
-               return -ENOMEM;
-
-       ret = iwch_finish_mem_reg(mhp, stag);
-       if (ret)
-               cxio_dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
-                      mhp->attr.pbl_addr);
-
-       return ret;
-}
-
 int iwch_alloc_pbl(struct iwch_mr *mhp, int npages)
 {
        mhp->attr.pbl_addr = cxio_hal_pblpool_alloc(&mhp->rhp->rdev,
@@ -130,74 +99,3 @@ int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset)
        return cxio_write_pbl(&mhp->rhp->rdev, pages,
                              mhp->attr.pbl_addr + (offset << 3), npages);
 }
-
-int build_phys_page_list(struct ib_phys_buf *buffer_list,
-                                       int num_phys_buf,
-                                       u64 *iova_start,
-                                       u64 *total_size,
-                                       int *npages,
-                                       int *shift,
-                                       __be64 **page_list)
-{
-       u64 mask;
-       int i, j, n;
-
-       mask = 0;
-       *total_size = 0;
-       for (i = 0; i < num_phys_buf; ++i) {
-               if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
-                       return -EINVAL;
-               if (i != 0 && i != num_phys_buf - 1 &&
-                   (buffer_list[i].size & ~PAGE_MASK))
-                       return -EINVAL;
-               *total_size += buffer_list[i].size;
-               if (i > 0)
-                       mask |= buffer_list[i].addr;
-               else
-                       mask |= buffer_list[i].addr & PAGE_MASK;
-               if (i != num_phys_buf - 1)
-                       mask |= buffer_list[i].addr + buffer_list[i].size;
-               else
-                       mask |= (buffer_list[i].addr + buffer_list[i].size +
-                               PAGE_SIZE - 1) & PAGE_MASK;
-       }
-
-       if (*total_size > 0xFFFFFFFFULL)
-               return -ENOMEM;
-
-       /* Find largest page shift we can use to cover buffers */
-       for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift))
-               if ((1ULL << *shift) & mask)
-                       break;
-
-       buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1);
-       buffer_list[0].addr &= ~0ull << *shift;
-
-       *npages = 0;
-       for (i = 0; i < num_phys_buf; ++i)
-               *npages += (buffer_list[i].size +
-                       (1ULL << *shift) - 1) >> *shift;
-
-       if (!*npages)
-               return -EINVAL;
-
-       *page_list = kmalloc(sizeof(u64) * *npages, GFP_KERNEL);
-       if (!*page_list)
-               return -ENOMEM;
-
-       n = 0;
-       for (i = 0; i < num_phys_buf; ++i)
-               for (j = 0;
-                    j < (buffer_list[i].size + (1ULL << *shift) - 1) >> *shift;
-                    ++j)
-                       (*page_list)[n++] = cpu_to_be64(buffer_list[i].addr +
-                           ((u64) j << *shift));
-
-       PDBG("%s va 0x%llx mask 0x%llx shift %d len %lld pbl_size %d\n",
-            __func__, (unsigned long long) *iova_start,
-            (unsigned long long) mask, *shift, (unsigned long long) *total_size,
-            *npages);
-
-       return 0;
-
-}
index c34725c..2734820 100644 (file)
@@ -458,9 +458,6 @@ static int iwch_dereg_mr(struct ib_mr *ib_mr)
        u32 mmid;
 
        PDBG("%s ib_mr %p\n", __func__, ib_mr);
-       /* There can be no memory windows */
-       if (atomic_read(&ib_mr->usecnt))
-               return -EINVAL;
 
        mhp = to_iwch_mr(ib_mr);
        kfree(mhp->pages);
@@ -479,24 +476,25 @@ static int iwch_dereg_mr(struct ib_mr *ib_mr)
        return 0;
 }
 
-static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
-                                       struct ib_phys_buf *buffer_list,
-                                       int num_phys_buf,
-                                       int acc,
-                                       u64 *iova_start)
+static struct ib_mr *iwch_get_dma_mr(struct ib_pd *pd, int acc)
 {
-       __be64 *page_list;
-       int shift;
-       u64 total_size;
-       int npages;
-       struct iwch_dev *rhp;
-       struct iwch_pd *php;
+       const u64 total_size = 0xffffffff;
+       const u64 mask = (total_size + PAGE_SIZE - 1) & PAGE_MASK;
+       struct iwch_pd *php = to_iwch_pd(pd);
+       struct iwch_dev *rhp = php->rhp;
        struct iwch_mr *mhp;
-       int ret;
+       __be64 *page_list;
+       int shift = 26, npages, ret, i;
 
        PDBG("%s ib_pd %p\n", __func__, pd);
-       php = to_iwch_pd(pd);
-       rhp = php->rhp;
+
+       /*
+        * T3 only supports 32 bits of size.
+        */
+       if (sizeof(phys_addr_t) > 4) {
+               pr_warn_once(MOD "Cannot support dma_mrs on this platform.\n");
+               return ERR_PTR(-ENOTSUPP);
+       }
 
        mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
        if (!mhp)
@@ -504,22 +502,23 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
 
        mhp->rhp = rhp;
 
-       /* First check that we have enough alignment */
-       if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) {
+       npages = (total_size + (1ULL << shift) - 1) >> shift;
+       if (!npages) {
                ret = -EINVAL;
                goto err;
        }
 
-       if (num_phys_buf > 1 &&
-           ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK)) {
-               ret = -EINVAL;
+       page_list = kmalloc_array(npages, sizeof(u64), GFP_KERNEL);
+       if (!page_list) {
+               ret = -ENOMEM;
                goto err;
        }
 
-       ret = build_phys_page_list(buffer_list, num_phys_buf, iova_start,
-                                  &total_size, &npages, &shift, &page_list);
-       if (ret)
-               goto err;
+       for (i = 0; i < npages; i++)
+               page_list[i] = cpu_to_be64((u64)i << shift);
+
+       PDBG("%s mask 0x%llx shift %d len %lld pbl_size %d\n",
+               __func__, mask, shift, total_size, npages);
 
        ret = iwch_alloc_pbl(mhp, npages);
        if (ret) {
@@ -536,7 +535,7 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
        mhp->attr.zbva = 0;
 
        mhp->attr.perms = iwch_ib_to_tpt_access(acc);
-       mhp->attr.va_fbo = *iova_start;
+       mhp->attr.va_fbo = 0;
        mhp->attr.page_size = shift - 12;
 
        mhp->attr.len = (u32) total_size;
@@ -553,76 +552,8 @@ err_pbl:
 err:
        kfree(mhp);
        return ERR_PTR(ret);
-
-}
-
-static int iwch_reregister_phys_mem(struct ib_mr *mr,
-                                    int mr_rereg_mask,
-                                    struct ib_pd *pd,
-                                    struct ib_phys_buf *buffer_list,
-                                    int num_phys_buf,
-                                    int acc, u64 * iova_start)
-{
-
-       struct iwch_mr mh, *mhp;
-       struct iwch_pd *php;
-       struct iwch_dev *rhp;
-       __be64 *page_list = NULL;
-       int shift = 0;
-       u64 total_size;
-       int npages = 0;
-       int ret;
-
-       PDBG("%s ib_mr %p ib_pd %p\n", __func__, mr, pd);
-
-       /* There can be no memory windows */
-       if (atomic_read(&mr->usecnt))
-               return -EINVAL;
-
-       mhp = to_iwch_mr(mr);
-       rhp = mhp->rhp;
-       php = to_iwch_pd(mr->pd);
-
-       /* make sure we are on the same adapter */
-       if (rhp != php->rhp)
-               return -EINVAL;
-
-       memcpy(&mh, mhp, sizeof *mhp);
-
-       if (mr_rereg_mask & IB_MR_REREG_PD)
-               php = to_iwch_pd(pd);
-       if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-               mh.attr.perms = iwch_ib_to_tpt_access(acc);
-       if (mr_rereg_mask & IB_MR_REREG_TRANS) {
-               ret = build_phys_page_list(buffer_list, num_phys_buf,
-                                          iova_start,
-                                          &total_size, &npages,
-                                          &shift, &page_list);
-               if (ret)
-                       return ret;
-       }
-
-       ret = iwch_reregister_mem(rhp, php, &mh, shift, npages);
-       kfree(page_list);
-       if (ret) {
-               return ret;
-       }
-       if (mr_rereg_mask & IB_MR_REREG_PD)
-               mhp->attr.pdid = php->pdid;
-       if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-               mhp->attr.perms = iwch_ib_to_tpt_access(acc);
-       if (mr_rereg_mask & IB_MR_REREG_TRANS) {
-               mhp->attr.zbva = 0;
-               mhp->attr.va_fbo = *iova_start;
-               mhp->attr.page_size = shift - 12;
-               mhp->attr.len = (u32) total_size;
-               mhp->attr.pbl_size = npages;
-       }
-
-       return 0;
 }
 
-
 static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                      u64 virt, int acc, struct ib_udata *udata)
 {
@@ -726,28 +657,6 @@ err:
        return ERR_PTR(err);
 }
 
-static struct ib_mr *iwch_get_dma_mr(struct ib_pd *pd, int acc)
-{
-       struct ib_phys_buf bl;
-       u64 kva;
-       struct ib_mr *ibmr;
-
-       PDBG("%s ib_pd %p\n", __func__, pd);
-
-       /*
-        * T3 only supports 32 bits of size.
-        */
-       if (sizeof(phys_addr_t) > 4) {
-               pr_warn_once(MOD "Cannot support dma_mrs on this platform.\n");
-               return ERR_PTR(-ENOTSUPP);
-       }
-       bl.size = 0xffffffff;
-       bl.addr = 0;
-       kva = 0;
-       ibmr = iwch_register_phys_mem(pd, &bl, 1, acc, &kva);
-       return ibmr;
-}
-
 static struct ib_mw *iwch_alloc_mw(struct ib_pd *pd, enum ib_mw_type type)
 {
        struct iwch_dev *rhp;
@@ -1452,12 +1361,9 @@ int iwch_register_device(struct iwch_dev *dev)
        dev->ibdev.resize_cq = iwch_resize_cq;
        dev->ibdev.poll_cq = iwch_poll_cq;
        dev->ibdev.get_dma_mr = iwch_get_dma_mr;
-       dev->ibdev.reg_phys_mr = iwch_register_phys_mem;
-       dev->ibdev.rereg_phys_mr = iwch_reregister_phys_mem;
        dev->ibdev.reg_user_mr = iwch_reg_user_mr;
        dev->ibdev.dereg_mr = iwch_dereg_mr;
        dev->ibdev.alloc_mw = iwch_alloc_mw;
-       dev->ibdev.bind_mw = iwch_bind_mw;
        dev->ibdev.dealloc_mw = iwch_dealloc_mw;
        dev->ibdev.alloc_mr = iwch_alloc_mr;
        dev->ibdev.map_mr_sg = iwch_map_mr_sg;
index 2ac85b8..252c464 100644 (file)
@@ -330,9 +330,6 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                      struct ib_send_wr **bad_wr);
 int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                      struct ib_recv_wr **bad_wr);
-int iwch_bind_mw(struct ib_qp *qp,
-                            struct ib_mw *mw,
-                            struct ib_mw_bind *mw_bind);
 int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
 int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg);
 int iwch_post_zb_read(struct iwch_ep *ep);
@@ -341,21 +338,9 @@ void iwch_unregister_device(struct iwch_dev *dev);
 void stop_read_rep_timer(struct iwch_qp *qhp);
 int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
                      struct iwch_mr *mhp, int shift);
-int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
-                                       struct iwch_mr *mhp,
-                                       int shift,
-                                       int npages);
 int iwch_alloc_pbl(struct iwch_mr *mhp, int npages);
 void iwch_free_pbl(struct iwch_mr *mhp);
 int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset);
-int build_phys_page_list(struct ib_phys_buf *buffer_list,
-                                       int num_phys_buf,
-                                       u64 *iova_start,
-                                       u64 *total_size,
-                                       int *npages,
-                                       int *shift,
-                                       __be64 **page_list);
-
 
 #define IWCH_NODE_DESC "cxgb3 Chelsio Communications"
 
index d0548fc..d939980 100644 (file)
@@ -526,88 +526,6 @@ out:
        return err;
 }
 
-int iwch_bind_mw(struct ib_qp *qp,
-                            struct ib_mw *mw,
-                            struct ib_mw_bind *mw_bind)
-{
-       struct iwch_dev *rhp;
-       struct iwch_mw *mhp;
-       struct iwch_qp *qhp;
-       union t3_wr *wqe;
-       u32 pbl_addr;
-       u8 page_size;
-       u32 num_wrs;
-       unsigned long flag;
-       struct ib_sge sgl;
-       int err=0;
-       enum t3_wr_flags t3_wr_flags;
-       u32 idx;
-       struct t3_swsq *sqp;
-
-       qhp = to_iwch_qp(qp);
-       mhp = to_iwch_mw(mw);
-       rhp = qhp->rhp;
-
-       spin_lock_irqsave(&qhp->lock, flag);
-       if (qhp->attr.state > IWCH_QP_STATE_RTS) {
-               spin_unlock_irqrestore(&qhp->lock, flag);
-               return -EINVAL;
-       }
-       num_wrs = Q_FREECNT(qhp->wq.sq_rptr, qhp->wq.sq_wptr,
-                           qhp->wq.sq_size_log2);
-       if (num_wrs == 0) {
-               spin_unlock_irqrestore(&qhp->lock, flag);
-               return -ENOMEM;
-       }
-       idx = Q_PTR2IDX(qhp->wq.wptr, qhp->wq.size_log2);
-       PDBG("%s: idx 0x%0x, mw 0x%p, mw_bind 0x%p\n", __func__, idx,
-            mw, mw_bind);
-       wqe = (union t3_wr *) (qhp->wq.queue + idx);
-
-       t3_wr_flags = 0;
-       if (mw_bind->send_flags & IB_SEND_SIGNALED)
-               t3_wr_flags = T3_COMPLETION_FLAG;
-
-       sgl.addr = mw_bind->bind_info.addr;
-       sgl.lkey = mw_bind->bind_info.mr->lkey;
-       sgl.length = mw_bind->bind_info.length;
-       wqe->bind.reserved = 0;
-       wqe->bind.type = TPT_VATO;
-
-       /* TBD: check perms */
-       wqe->bind.perms = iwch_ib_to_tpt_bind_access(
-               mw_bind->bind_info.mw_access_flags);
-       wqe->bind.mr_stag = cpu_to_be32(mw_bind->bind_info.mr->lkey);
-       wqe->bind.mw_stag = cpu_to_be32(mw->rkey);
-       wqe->bind.mw_len = cpu_to_be32(mw_bind->bind_info.length);
-       wqe->bind.mw_va = cpu_to_be64(mw_bind->bind_info.addr);
-       err = iwch_sgl2pbl_map(rhp, &sgl, 1, &pbl_addr, &page_size);
-       if (err) {
-               spin_unlock_irqrestore(&qhp->lock, flag);
-               return err;
-       }
-       wqe->send.wrid.id0.hi = qhp->wq.sq_wptr;
-       sqp = qhp->wq.sq + Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2);
-       sqp->wr_id = mw_bind->wr_id;
-       sqp->opcode = T3_BIND_MW;
-       sqp->sq_wptr = qhp->wq.sq_wptr;
-       sqp->complete = 0;
-       sqp->signaled = (mw_bind->send_flags & IB_SEND_SIGNALED);
-       wqe->bind.mr_pbl_addr = cpu_to_be32(pbl_addr);
-       wqe->bind.mr_pagesz = page_size;
-       build_fw_riwrh((void *)wqe, T3_WR_BIND, t3_wr_flags,
-                      Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 0,
-                      sizeof(struct t3_bind_mw_wr) >> 3, T3_SOPEOP);
-       ++(qhp->wq.wptr);
-       ++(qhp->wq.sq_wptr);
-       spin_unlock_irqrestore(&qhp->lock, flag);
-
-       if (cxio_wq_db_enabled(&qhp->wq))
-               ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
-
-       return err;
-}
-
 static inline void build_term_codes(struct respQ_msg_t *rsp_msg,
                                    u8 *layer_type, u8 *ecode)
 {
index 326d07d..cd2ff5f 100644 (file)
@@ -3271,6 +3271,12 @@ static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)
                                    &ep->com.mapped_local_addr;
 
+       if (ipv6_addr_type(&sin6->sin6_addr) != IPV6_ADDR_ANY) {
+               err = cxgb4_clip_get(ep->com.dev->rdev.lldi.ports[0],
+                                    (const u32 *)&sin6->sin6_addr.s6_addr, 1);
+               if (err)
+                       return err;
+       }
        c4iw_init_wr_wait(&ep->com.wr_wait);
        err = cxgb4_create_server6(ep->com.dev->rdev.lldi.ports[0],
                                   ep->stid, &sin6->sin6_addr,
@@ -3282,13 +3288,13 @@ static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
                                          0, 0, __func__);
        else if (err > 0)
                err = net_xmit_errno(err);
-       if (err)
+       if (err) {
+               cxgb4_clip_release(ep->com.dev->rdev.lldi.ports[0],
+                                  (const u32 *)&sin6->sin6_addr.s6_addr, 1);
                pr_err("cxgb4_create_server6/filter failed err %d stid %d laddr %pI6 lport %d\n",
                       err, ep->stid,
                       sin6->sin6_addr.s6_addr, ntohs(sin6->sin6_port));
-       else
-               cxgb4_clip_get(ep->com.dev->rdev.lldi.ports[0],
-                              (const u32 *)&sin6->sin6_addr.s6_addr, 1);
+       }
        return err;
 }
 
index de9cd69..cf21df4 100644 (file)
@@ -744,9 +744,6 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)
                case FW_RI_SEND_WITH_SE:
                        wc->opcode = IB_WC_SEND;
                        break;
-               case FW_RI_BIND_MW:
-                       wc->opcode = IB_WC_BIND_MW;
-                       break;
 
                case FW_RI_LOCAL_INV:
                        wc->opcode = IB_WC_LOCAL_INV;
index 58fce17..8024ea4 100644 (file)
@@ -315,14 +315,12 @@ static int qp_release(struct inode *inode, struct file *file)
 static int qp_open(struct inode *inode, struct file *file)
 {
        struct c4iw_debugfs_data *qpd;
-       int ret = 0;
        int count = 1;
 
        qpd = kmalloc(sizeof *qpd, GFP_KERNEL);
-       if (!qpd) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!qpd)
+               return -ENOMEM;
+
        qpd->devp = inode->i_private;
        qpd->pos = 0;
 
@@ -333,8 +331,8 @@ static int qp_open(struct inode *inode, struct file *file)
        qpd->bufsize = count * 128;
        qpd->buf = vmalloc(qpd->bufsize);
        if (!qpd->buf) {
-               ret = -ENOMEM;
-               goto err1;
+               kfree(qpd);
+               return -ENOMEM;
        }
 
        spin_lock_irq(&qpd->devp->lock);
@@ -343,11 +341,7 @@ static int qp_open(struct inode *inode, struct file *file)
 
        qpd->buf[qpd->pos++] = 0;
        file->private_data = qpd;
-       goto out;
-err1:
-       kfree(qpd);
-out:
-       return ret;
+       return 0;
 }
 
 static const struct file_operations qp_debugfs_fops = {
@@ -781,8 +775,7 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
                pr_err(MOD "%s: unsupported udb/ucq densities %u/%u\n",
                       pci_name(rdev->lldi.pdev), rdev->lldi.udb_density,
                       rdev->lldi.ucq_density);
-               err = -EINVAL;
-               goto err1;
+               return -EINVAL;
        }
        if (rdev->lldi.vr->qp.start != rdev->lldi.vr->cq.start ||
            rdev->lldi.vr->qp.size != rdev->lldi.vr->cq.size) {
@@ -791,8 +784,7 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
                       pci_name(rdev->lldi.pdev), rdev->lldi.vr->qp.start,
                       rdev->lldi.vr->qp.size, rdev->lldi.vr->cq.size,
                       rdev->lldi.vr->cq.size);
-               err = -EINVAL;
-               goto err1;
+               return -EINVAL;
        }
 
        rdev->qpmask = rdev->lldi.udb_density - 1;
@@ -816,10 +808,8 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
             rdev->lldi.db_reg, rdev->lldi.gts_reg,
             rdev->qpmask, rdev->cqmask);
 
-       if (c4iw_num_stags(rdev) == 0) {
-               err = -EINVAL;
-               goto err1;
-       }
+       if (c4iw_num_stags(rdev) == 0)
+               return -EINVAL;
 
        rdev->stats.pd.total = T4_MAX_NUM_PD;
        rdev->stats.stag.total = rdev->lldi.vr->stag.size;
@@ -831,29 +821,31 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
        err = c4iw_init_resource(rdev, c4iw_num_stags(rdev), T4_MAX_NUM_PD);
        if (err) {
                printk(KERN_ERR MOD "error %d initializing resources\n", err);
-               goto err1;
+               return err;
        }
        err = c4iw_pblpool_create(rdev);
        if (err) {
                printk(KERN_ERR MOD "error %d initializing pbl pool\n", err);
-               goto err2;
+               goto destroy_resource;
        }
        err = c4iw_rqtpool_create(rdev);
        if (err) {
                printk(KERN_ERR MOD "error %d initializing rqt pool\n", err);
-               goto err3;
+               goto destroy_pblpool;
        }
        err = c4iw_ocqp_pool_create(rdev);
        if (err) {
                printk(KERN_ERR MOD "error %d initializing ocqp pool\n", err);
-               goto err4;
+               goto destroy_rqtpool;
        }
        rdev->status_page = (struct t4_dev_status_page *)
                            __get_free_page(GFP_KERNEL);
-       if (!rdev->status_page) {
-               pr_err(MOD "error allocating status page\n");
-               goto err4;
-       }
+       if (!rdev->status_page)
+               goto destroy_ocqp_pool;
+       rdev->status_page->qp_start = rdev->lldi.vr->qp.start;
+       rdev->status_page->qp_size = rdev->lldi.vr->qp.size;
+       rdev->status_page->cq_start = rdev->lldi.vr->cq.start;
+       rdev->status_page->cq_size = rdev->lldi.vr->cq.size;
 
        if (c4iw_wr_log) {
                rdev->wr_log = kzalloc((1 << c4iw_wr_log_size_order) *
@@ -869,13 +861,14 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
        rdev->status_page->db_off = 0;
 
        return 0;
-err4:
+destroy_ocqp_pool:
+       c4iw_ocqp_pool_destroy(rdev);
+destroy_rqtpool:
        c4iw_rqtpool_destroy(rdev);
-err3:
+destroy_pblpool:
        c4iw_pblpool_destroy(rdev);
-err2:
+destroy_resource:
        c4iw_destroy_resource(&rdev->resource);
-err1:
        return err;
 }
 
index 00e55fa..fb2de75 100644 (file)
@@ -947,8 +947,6 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                      struct ib_send_wr **bad_wr);
 int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                      struct ib_recv_wr **bad_wr);
-int c4iw_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
-                struct ib_mw_bind *mw_bind);
 int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
 int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog);
 int c4iw_destroy_listen(struct iw_cm_id *cm_id);
@@ -968,17 +966,6 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start,
                                           u64 length, u64 virt, int acc,
                                           struct ib_udata *udata);
 struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
-struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd,
-                                       struct ib_phys_buf *buffer_list,
-                                       int num_phys_buf,
-                                       int acc,
-                                       u64 *iova_start);
-int c4iw_reregister_phys_mem(struct ib_mr *mr,
-                                    int mr_rereg_mask,
-                                    struct ib_pd *pd,
-                                    struct ib_phys_buf *buffer_list,
-                                    int num_phys_buf,
-                                    int acc, u64 *iova_start);
 int c4iw_dereg_mr(struct ib_mr *ib_mr);
 int c4iw_destroy_cq(struct ib_cq *ib_cq);
 struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
index e1629ab..7849890 100644 (file)
@@ -392,32 +392,6 @@ static int register_mem(struct c4iw_dev *rhp, struct c4iw_pd *php,
        return ret;
 }
 
-static int reregister_mem(struct c4iw_dev *rhp, struct c4iw_pd *php,
-                         struct c4iw_mr *mhp, int shift, int npages)
-{
-       u32 stag;
-       int ret;
-
-       if (npages > mhp->attr.pbl_size)
-               return -ENOMEM;
-
-       stag = mhp->attr.stag;
-       ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid,
-                             FW_RI_STAG_NSMR, mhp->attr.perms,
-                             mhp->attr.mw_bind_enable, mhp->attr.zbva,
-                             mhp->attr.va_fbo, mhp->attr.len, shift - 12,
-                             mhp->attr.pbl_size, mhp->attr.pbl_addr);
-       if (ret)
-               return ret;
-
-       ret = finish_mem_reg(mhp, stag);
-       if (ret)
-               dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
-                      mhp->attr.pbl_addr);
-
-       return ret;
-}
-
 static int alloc_pbl(struct c4iw_mr *mhp, int npages)
 {
        mhp->attr.pbl_addr = c4iw_pblpool_alloc(&mhp->rhp->rdev,
@@ -431,228 +405,6 @@ static int alloc_pbl(struct c4iw_mr *mhp, int npages)
        return 0;
 }
 
-static int build_phys_page_list(struct ib_phys_buf *buffer_list,
-                               int num_phys_buf, u64 *iova_start,
-                               u64 *total_size, int *npages,
-                               int *shift, __be64 **page_list)
-{
-       u64 mask;
-       int i, j, n;
-
-       mask = 0;
-       *total_size = 0;
-       for (i = 0; i < num_phys_buf; ++i) {
-               if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
-                       return -EINVAL;
-               if (i != 0 && i != num_phys_buf - 1 &&
-                   (buffer_list[i].size & ~PAGE_MASK))
-                       return -EINVAL;
-               *total_size += buffer_list[i].size;
-               if (i > 0)
-                       mask |= buffer_list[i].addr;
-               else
-                       mask |= buffer_list[i].addr & PAGE_MASK;
-               if (i != num_phys_buf - 1)
-                       mask |= buffer_list[i].addr + buffer_list[i].size;
-               else
-                       mask |= (buffer_list[i].addr + buffer_list[i].size +
-                               PAGE_SIZE - 1) & PAGE_MASK;
-       }
-
-       if (*total_size > 0xFFFFFFFFULL)
-               return -ENOMEM;
-
-       /* Find largest page shift we can use to cover buffers */
-       for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift))
-               if ((1ULL << *shift) & mask)
-                       break;
-
-       buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1);
-       buffer_list[0].addr &= ~0ull << *shift;
-
-       *npages = 0;
-       for (i = 0; i < num_phys_buf; ++i)
-               *npages += (buffer_list[i].size +
-                       (1ULL << *shift) - 1) >> *shift;
-
-       if (!*npages)
-               return -EINVAL;
-
-       *page_list = kmalloc(sizeof(u64) * *npages, GFP_KERNEL);
-       if (!*page_list)
-               return -ENOMEM;
-
-       n = 0;
-       for (i = 0; i < num_phys_buf; ++i)
-               for (j = 0;
-                    j < (buffer_list[i].size + (1ULL << *shift) - 1) >> *shift;
-                    ++j)
-                       (*page_list)[n++] = cpu_to_be64(buffer_list[i].addr +
-                           ((u64) j << *shift));
-
-       PDBG("%s va 0x%llx mask 0x%llx shift %d len %lld pbl_size %d\n",
-            __func__, (unsigned long long)*iova_start,
-            (unsigned long long)mask, *shift, (unsigned long long)*total_size,
-            *npages);
-
-       return 0;
-
-}
-
-int c4iw_reregister_phys_mem(struct ib_mr *mr, int mr_rereg_mask,
-                            struct ib_pd *pd, struct ib_phys_buf *buffer_list,
-                            int num_phys_buf, int acc, u64 *iova_start)
-{
-
-       struct c4iw_mr mh, *mhp;
-       struct c4iw_pd *php;
-       struct c4iw_dev *rhp;
-       __be64 *page_list = NULL;
-       int shift = 0;
-       u64 total_size;
-       int npages;
-       int ret;
-
-       PDBG("%s ib_mr %p ib_pd %p\n", __func__, mr, pd);
-
-       /* There can be no memory windows */
-       if (atomic_read(&mr->usecnt))
-               return -EINVAL;
-
-       mhp = to_c4iw_mr(mr);
-       rhp = mhp->rhp;
-       php = to_c4iw_pd(mr->pd);
-
-       /* make sure we are on the same adapter */
-       if (rhp != php->rhp)
-               return -EINVAL;
-
-       memcpy(&mh, mhp, sizeof *mhp);
-
-       if (mr_rereg_mask & IB_MR_REREG_PD)
-               php = to_c4iw_pd(pd);
-       if (mr_rereg_mask & IB_MR_REREG_ACCESS) {
-               mh.attr.perms = c4iw_ib_to_tpt_access(acc);
-               mh.attr.mw_bind_enable = (acc & IB_ACCESS_MW_BIND) ==
-                                        IB_ACCESS_MW_BIND;
-       }
-       if (mr_rereg_mask & IB_MR_REREG_TRANS) {
-               ret = build_phys_page_list(buffer_list, num_phys_buf,
-                                               iova_start,
-                                               &total_size, &npages,
-                                               &shift, &page_list);
-               if (ret)
-                       return ret;
-       }
-
-       if (mr_exceeds_hw_limits(rhp, total_size)) {
-               kfree(page_list);
-               return -EINVAL;
-       }
-
-       ret = reregister_mem(rhp, php, &mh, shift, npages);
-       kfree(page_list);
-       if (ret)
-               return ret;
-       if (mr_rereg_mask & IB_MR_REREG_PD)
-               mhp->attr.pdid = php->pdid;
-       if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-               mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
-       if (mr_rereg_mask & IB_MR_REREG_TRANS) {
-               mhp->attr.zbva = 0;
-               mhp->attr.va_fbo = *iova_start;
-               mhp->attr.page_size = shift - 12;
-               mhp->attr.len = (u32) total_size;
-               mhp->attr.pbl_size = npages;
-       }
-
-       return 0;
-}
-
-struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd,
-                                    struct ib_phys_buf *buffer_list,
-                                    int num_phys_buf, int acc, u64 *iova_start)
-{
-       __be64 *page_list;
-       int shift;
-       u64 total_size;
-       int npages;
-       struct c4iw_dev *rhp;
-       struct c4iw_pd *php;
-       struct c4iw_mr *mhp;
-       int ret;
-
-       PDBG("%s ib_pd %p\n", __func__, pd);
-       php = to_c4iw_pd(pd);
-       rhp = php->rhp;
-
-       mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
-       if (!mhp)
-               return ERR_PTR(-ENOMEM);
-
-       mhp->rhp = rhp;
-
-       /* First check that we have enough alignment */
-       if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) {
-               ret = -EINVAL;
-               goto err;
-       }
-
-       if (num_phys_buf > 1 &&
-           ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK)) {
-               ret = -EINVAL;
-               goto err;
-       }
-
-       ret = build_phys_page_list(buffer_list, num_phys_buf, iova_start,
-                                       &total_size, &npages, &shift,
-                                       &page_list);
-       if (ret)
-               goto err;
-
-       if (mr_exceeds_hw_limits(rhp, total_size)) {
-               kfree(page_list);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       ret = alloc_pbl(mhp, npages);
-       if (ret) {
-               kfree(page_list);
-               goto err;
-       }
-
-       ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr,
-                            npages);
-       kfree(page_list);
-       if (ret)
-               goto err_pbl;
-
-       mhp->attr.pdid = php->pdid;
-       mhp->attr.zbva = 0;
-
-       mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
-       mhp->attr.va_fbo = *iova_start;
-       mhp->attr.page_size = shift - 12;
-
-       mhp->attr.len = (u32) total_size;
-       mhp->attr.pbl_size = npages;
-       ret = register_mem(rhp, php, mhp, shift);
-       if (ret)
-               goto err_pbl;
-
-       return &mhp->ibmr;
-
-err_pbl:
-       c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
-                             mhp->attr.pbl_size << 3);
-
-err:
-       kfree(mhp);
-       return ERR_PTR(ret);
-
-}
-
 struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc)
 {
        struct c4iw_dev *rhp;
@@ -952,9 +704,6 @@ int c4iw_dereg_mr(struct ib_mr *ib_mr)
        u32 mmid;
 
        PDBG("%s ib_mr %p\n", __func__, ib_mr);
-       /* There can be no memory windows */
-       if (atomic_read(&ib_mr->usecnt))
-               return -EINVAL;
 
        mhp = to_c4iw_mr(ib_mr);
        rhp = mhp->rhp;
index 0a7d998..ec04272 100644 (file)
@@ -549,12 +549,9 @@ int c4iw_register_device(struct c4iw_dev *dev)
        dev->ibdev.resize_cq = c4iw_resize_cq;
        dev->ibdev.poll_cq = c4iw_poll_cq;
        dev->ibdev.get_dma_mr = c4iw_get_dma_mr;
-       dev->ibdev.reg_phys_mr = c4iw_register_phys_mem;
-       dev->ibdev.rereg_phys_mr = c4iw_reregister_phys_mem;
        dev->ibdev.reg_user_mr = c4iw_reg_user_mr;
        dev->ibdev.dereg_mr = c4iw_dereg_mr;
        dev->ibdev.alloc_mw = c4iw_alloc_mw;
-       dev->ibdev.bind_mw = c4iw_bind_mw;
        dev->ibdev.dealloc_mw = c4iw_dealloc_mw;
        dev->ibdev.alloc_mr = c4iw_alloc_mr;
        dev->ibdev.map_mr_sg = c4iw_map_mr_sg;
index aa515af..e99345e 100644 (file)
@@ -933,11 +933,6 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
        return err;
 }
 
-int c4iw_bind_mw(struct ib_qp *qp, struct ib_mw *mw, struct ib_mw_bind *mw_bind)
-{
-       return -ENOSYS;
-}
-
 static inline void build_term_codes(struct t4_cqe *err_cqe, u8 *layer_type,
                                    u8 *ecode)
 {
index 1092a2d..6126bbe 100644 (file)
@@ -699,4 +699,11 @@ static inline void t4_set_cq_in_error(struct t4_cq *cq)
 
 struct t4_dev_status_page {
        u8 db_off;
+       u8 pad1;
+       u16 pad2;
+       u32 pad3;
+       u64 qp_start;
+       u64 qp_size;
+       u64 cq_start;
+       u64 cq_size;
 };
index cbd0ce1..295f422 100644 (file)
@@ -32,7 +32,7 @@
 #ifndef __C4IW_USER_H__
 #define __C4IW_USER_H__
 
-#define C4IW_UVERBS_ABI_VERSION        2
+#define C4IW_UVERBS_ABI_VERSION        3
 
 /*
  * Make sure that all structs defined in this file remain laid out so
index 86af713..105246f 100644 (file)
@@ -92,7 +92,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
                                ah_attr->grh.sgid_index, &sgid, &gid_attr);
        if (ret)
                return ERR_PTR(ret);
-       memset(ah->av.eth.s_mac, 0, ETH_ALEN);
+       eth_zero_addr(ah->av.eth.s_mac);
        if (gid_attr.ndev) {
                if (is_vlan_dev(gid_attr.ndev))
                        vlan_tag = vlan_dev_vlan_id(gid_attr.ndev);
@@ -104,6 +104,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
        ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
        ah->av.eth.gid_index = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
        ah->av.eth.vlan = cpu_to_be16(vlan_tag);
+       ah->av.eth.hop_limit = ah_attr->grh.hop_limit;
        if (ah_attr->static_rate) {
                ah->av.eth.stat_rate = ah_attr->static_rate + MLX4_STAT_RATE_OFFSET;
                while (ah->av.eth.stat_rate > IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET &&
index b88fc8f..9f8b516 100644 (file)
@@ -811,9 +811,6 @@ repoll:
                        wc->opcode    = IB_WC_MASKED_FETCH_ADD;
                        wc->byte_len  = 8;
                        break;
-               case MLX4_OPCODE_BIND_MW:
-                       wc->opcode    = IB_WC_BIND_MW;
-                       break;
                case MLX4_OPCODE_LSO:
                        wc->opcode    = IB_WC_LSO;
                        break;
index 97d6878..1c7ab6c 100644 (file)
@@ -154,9 +154,9 @@ static struct net_device *mlx4_ib_get_netdev(struct ib_device *device, u8 port_n
        return dev;
 }
 
-static int mlx4_ib_update_gids(struct gid_entry *gids,
-                              struct mlx4_ib_dev *ibdev,
-                              u8 port_num)
+static int mlx4_ib_update_gids_v1(struct gid_entry *gids,
+                                 struct mlx4_ib_dev *ibdev,
+                                 u8 port_num)
 {
        struct mlx4_cmd_mailbox *mailbox;
        int err;
@@ -187,6 +187,63 @@ static int mlx4_ib_update_gids(struct gid_entry *gids,
        return err;
 }
 
+static int mlx4_ib_update_gids_v1_v2(struct gid_entry *gids,
+                                    struct mlx4_ib_dev *ibdev,
+                                    u8 port_num)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       int err;
+       struct mlx4_dev *dev = ibdev->dev;
+       int i;
+       struct {
+               union ib_gid    gid;
+               __be32          rsrvd1[2];
+               __be16          rsrvd2;
+               u8              type;
+               u8              version;
+               __be32          rsrvd3;
+       } *gid_tbl;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return -ENOMEM;
+
+       gid_tbl = mailbox->buf;
+       for (i = 0; i < MLX4_MAX_PORT_GIDS; ++i) {
+               memcpy(&gid_tbl[i].gid, &gids[i].gid, sizeof(union ib_gid));
+               if (gids[i].gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
+                       gid_tbl[i].version = 2;
+                       if (!ipv6_addr_v4mapped((struct in6_addr *)&gids[i].gid))
+                               gid_tbl[i].type = 1;
+                       else
+                               memset(&gid_tbl[i].gid, 0, 12);
+               }
+       }
+
+       err = mlx4_cmd(dev, mailbox->dma,
+                      MLX4_SET_PORT_ROCE_ADDR << 8 | port_num,
+                      1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
+                      MLX4_CMD_WRAPPED);
+       if (mlx4_is_bonded(dev))
+               err += mlx4_cmd(dev, mailbox->dma,
+                               MLX4_SET_PORT_ROCE_ADDR << 8 | 2,
+                               1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
+                               MLX4_CMD_WRAPPED);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
+static int mlx4_ib_update_gids(struct gid_entry *gids,
+                              struct mlx4_ib_dev *ibdev,
+                              u8 port_num)
+{
+       if (ibdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2)
+               return mlx4_ib_update_gids_v1_v2(gids, ibdev, port_num);
+
+       return mlx4_ib_update_gids_v1(gids, ibdev, port_num);
+}
+
 static int mlx4_ib_add_gid(struct ib_device *device,
                           u8 port_num,
                           unsigned int index,
@@ -215,7 +272,8 @@ static int mlx4_ib_add_gid(struct ib_device *device,
        port_gid_table = &iboe->gids[port_num - 1];
        spin_lock_bh(&iboe->lock);
        for (i = 0; i < MLX4_MAX_PORT_GIDS; ++i) {
-               if (!memcmp(&port_gid_table->gids[i].gid, gid, sizeof(*gid))) {
+               if (!memcmp(&port_gid_table->gids[i].gid, gid, sizeof(*gid)) &&
+                   (port_gid_table->gids[i].gid_type == attr->gid_type))  {
                        found = i;
                        break;
                }
@@ -233,6 +291,7 @@ static int mlx4_ib_add_gid(struct ib_device *device,
                        } else {
                                *context = port_gid_table->gids[free].ctx;
                                memcpy(&port_gid_table->gids[free].gid, gid, sizeof(*gid));
+                               port_gid_table->gids[free].gid_type = attr->gid_type;
                                port_gid_table->gids[free].ctx->real_index = free;
                                port_gid_table->gids[free].ctx->refcount = 1;
                                hw_update = 1;
@@ -248,8 +307,10 @@ static int mlx4_ib_add_gid(struct ib_device *device,
                if (!gids) {
                        ret = -ENOMEM;
                } else {
-                       for (i = 0; i < MLX4_MAX_PORT_GIDS; i++)
+                       for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) {
                                memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid));
+                               gids[i].gid_type = port_gid_table->gids[i].gid_type;
+                       }
                }
        }
        spin_unlock_bh(&iboe->lock);
@@ -325,6 +386,7 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
        int i;
        int ret;
        unsigned long flags;
+       struct ib_gid_attr attr;
 
        if (port_num > MLX4_MAX_PORTS)
                return -EINVAL;
@@ -335,10 +397,13 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
        if (!rdma_cap_roce_gid_table(&ibdev->ib_dev, port_num))
                return index;
 
-       ret = ib_get_cached_gid(&ibdev->ib_dev, port_num, index, &gid, NULL);
+       ret = ib_get_cached_gid(&ibdev->ib_dev, port_num, index, &gid, &attr);
        if (ret)
                return ret;
 
+       if (attr.ndev)
+               dev_put(attr.ndev);
+
        if (!memcmp(&gid, &zgid, sizeof(gid)))
                return -EINVAL;
 
@@ -346,7 +411,8 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
        port_gid_table = &iboe->gids[port_num - 1];
 
        for (i = 0; i < MLX4_MAX_PORT_GIDS; ++i)
-               if (!memcmp(&port_gid_table->gids[i].gid, &gid, sizeof(gid))) {
+               if (!memcmp(&port_gid_table->gids[i].gid, &gid, sizeof(gid)) &&
+                   attr.gid_type == port_gid_table->gids[i].gid_type) {
                        ctx = port_gid_table->gids[i].ctx;
                        break;
                }
@@ -2119,6 +2185,7 @@ static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num,
                               struct ib_port_immutable *immutable)
 {
        struct ib_port_attr attr;
+       struct mlx4_ib_dev *mdev = to_mdev(ibdev);
        int err;
 
        err = mlx4_ib_query_port(ibdev, port_num, &attr);
@@ -2128,10 +2195,15 @@ static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num,
        immutable->pkey_tbl_len = attr.pkey_tbl_len;
        immutable->gid_tbl_len = attr.gid_tbl_len;
 
-       if (mlx4_ib_port_link_layer(ibdev, port_num) == IB_LINK_LAYER_INFINIBAND)
+       if (mlx4_ib_port_link_layer(ibdev, port_num) == IB_LINK_LAYER_INFINIBAND) {
                immutable->core_cap_flags = RDMA_CORE_PORT_IBA_IB;
-       else
-               immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE;
+       } else {
+               if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE)
+                       immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE;
+               if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2)
+                       immutable->core_cap_flags = RDMA_CORE_PORT_IBA_ROCE |
+                               RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP;
+       }
 
        immutable->max_mad_size = IB_MGMT_MAD_SIZE;
 
@@ -2283,7 +2355,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
            dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN) {
                ibdev->ib_dev.alloc_mw = mlx4_ib_alloc_mw;
-               ibdev->ib_dev.bind_mw = mlx4_ib_bind_mw;
                ibdev->ib_dev.dealloc_mw = mlx4_ib_dealloc_mw;
 
                ibdev->ib_dev.uverbs_cmd_mask |=
@@ -2423,7 +2494,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        if (mlx4_ib_init_sriov(ibdev))
                goto err_mad;
 
-       if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE) {
+       if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE ||
+           dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2) {
                if (!iboe->nb.notifier_call) {
                        iboe->nb.notifier_call = mlx4_ib_netdev_event;
                        err = register_netdevice_notifier(&iboe->nb);
@@ -2432,6 +2504,12 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
                                goto err_notif;
                        }
                }
+               if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2) {
+                       err = mlx4_config_roce_v2_port(dev, ROCE_V2_UDP_DPORT);
+                       if (err) {
+                               goto err_notif;
+                       }
+               }
        }
 
        for (j = 0; j < ARRAY_SIZE(mlx4_class_attributes); ++j) {
index 1caa11e..52ce7b0 100644 (file)
@@ -177,11 +177,18 @@ struct mlx4_ib_wq {
        unsigned                tail;
 };
 
+enum {
+       MLX4_IB_QP_CREATE_ROCE_V2_GSI = IB_QP_CREATE_RESERVED_START
+};
+
 enum mlx4_ib_qp_flags {
        MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
        MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
        MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP,
        MLX4_IB_QP_CREATE_USE_GFP_NOIO = IB_QP_CREATE_USE_GFP_NOIO,
+
+       /* Mellanox specific flags start from IB_QP_CREATE_RESERVED_START */
+       MLX4_IB_ROCE_V2_GSI_QP = MLX4_IB_QP_CREATE_ROCE_V2_GSI,
        MLX4_IB_SRIOV_TUNNEL_QP = 1 << 30,
        MLX4_IB_SRIOV_SQP = 1 << 31,
 };
@@ -478,6 +485,7 @@ struct gid_cache_context {
 
 struct gid_entry {
        union ib_gid    gid;
+       enum ib_gid_type gid_type;
        struct gid_cache_context *ctx;
 };
 
@@ -704,8 +712,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                  struct ib_udata *udata);
 int mlx4_ib_dereg_mr(struct ib_mr *mr);
 struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type);
-int mlx4_ib_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
-                   struct ib_mw_bind *mw_bind);
 int mlx4_ib_dealloc_mw(struct ib_mw *mw);
 struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
                               enum ib_mr_type mr_type,
index 4d1e1c6..242b94e 100644 (file)
@@ -366,28 +366,6 @@ err_free:
        return ERR_PTR(err);
 }
 
-int mlx4_ib_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
-                   struct ib_mw_bind *mw_bind)
-{
-       struct ib_bind_mw_wr  wr;
-       struct ib_send_wr *bad_wr;
-       int ret;
-
-       memset(&wr, 0, sizeof(wr));
-       wr.wr.opcode            = IB_WR_BIND_MW;
-       wr.wr.wr_id             = mw_bind->wr_id;
-       wr.wr.send_flags        = mw_bind->send_flags;
-       wr.mw                   = mw;
-       wr.bind_info            = mw_bind->bind_info;
-       wr.rkey                 = ib_inc_rkey(mw->rkey);
-
-       ret = mlx4_ib_post_send(qp, &wr.wr, &bad_wr);
-       if (!ret)
-               mw->rkey = wr.rkey;
-
-       return ret;
-}
-
 int mlx4_ib_dealloc_mw(struct ib_mw *ibmw)
 {
        struct mlx4_ib_mw *mw = to_mmw(ibmw);
index 13eaaf4..bc5536f 100644 (file)
@@ -32,6 +32,8 @@
  */
 
 #include <linux/log2.h>
+#include <linux/etherdevice.h>
+#include <net/ip.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -85,6 +87,7 @@ struct mlx4_ib_sqp {
        u32                     send_psn;
        struct ib_ud_header     ud_header;
        u8                      header_buf[MLX4_IB_UD_HEADER_SIZE];
+       struct ib_qp            *roce_v2_gsi;
 };
 
 enum {
@@ -115,7 +118,6 @@ static const __be32 mlx4_ib_opcode[] = {
        [IB_WR_REG_MR]                          = cpu_to_be32(MLX4_OPCODE_FMR),
        [IB_WR_MASKED_ATOMIC_CMP_AND_SWP]       = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_CS),
        [IB_WR_MASKED_ATOMIC_FETCH_AND_ADD]     = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_FA),
-       [IB_WR_BIND_MW]                         = cpu_to_be32(MLX4_OPCODE_BIND_MW),
 };
 
 static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp)
@@ -154,7 +156,10 @@ static int is_sqp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
                        }
                }
        }
-       return proxy_sqp;
+       if (proxy_sqp)
+               return 1;
+
+       return !!(qp->flags & MLX4_IB_ROCE_V2_GSI_QP);
 }
 
 /* used for INIT/CLOSE port logic */
@@ -796,11 +801,13 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        goto err_mtt;
 
-               qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(u64), gfp);
+               qp->sq.wrid = kmalloc_array(qp->sq.wqe_cnt, sizeof(u64),
+                                       gfp | __GFP_NOWARN);
                if (!qp->sq.wrid)
                        qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
                                                gfp, PAGE_KERNEL);
-               qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(u64), gfp);
+               qp->rq.wrid = kmalloc_array(qp->rq.wqe_cnt, sizeof(u64),
+                                       gfp | __GFP_NOWARN);
                if (!qp->rq.wrid)
                        qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
                                                gfp, PAGE_KERNEL);
@@ -1099,9 +1106,9 @@ static u32 get_sqp_num(struct mlx4_ib_dev *dev, struct ib_qp_init_attr *attr)
                return dev->dev->caps.qp1_proxy[attr->port_num - 1];
 }
 
-struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
-                               struct ib_qp_init_attr *init_attr,
-                               struct ib_udata *udata)
+static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
+                                       struct ib_qp_init_attr *init_attr,
+                                       struct ib_udata *udata)
 {
        struct mlx4_ib_qp *qp = NULL;
        int err;
@@ -1120,6 +1127,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
                                        MLX4_IB_SRIOV_TUNNEL_QP |
                                        MLX4_IB_SRIOV_SQP |
                                        MLX4_IB_QP_NETIF |
+                                       MLX4_IB_QP_CREATE_ROCE_V2_GSI |
                                        MLX4_IB_QP_CREATE_USE_GFP_NOIO))
                return ERR_PTR(-EINVAL);
 
@@ -1128,15 +1136,21 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
                        return ERR_PTR(-EINVAL);
        }
 
-       if (init_attr->create_flags &&
-           ((udata && init_attr->create_flags & ~(sup_u_create_flags)) ||
-            ((init_attr->create_flags & ~(MLX4_IB_SRIOV_SQP |
-                                          MLX4_IB_QP_CREATE_USE_GFP_NOIO |
-                                          MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)) &&
-             init_attr->qp_type != IB_QPT_UD) ||
-            ((init_attr->create_flags & MLX4_IB_SRIOV_SQP) &&
-             init_attr->qp_type > IB_QPT_GSI)))
-               return ERR_PTR(-EINVAL);
+       if (init_attr->create_flags) {
+               if (udata && init_attr->create_flags & ~(sup_u_create_flags))
+                       return ERR_PTR(-EINVAL);
+
+               if ((init_attr->create_flags & ~(MLX4_IB_SRIOV_SQP |
+                                                MLX4_IB_QP_CREATE_USE_GFP_NOIO |
+                                                MLX4_IB_QP_CREATE_ROCE_V2_GSI  |
+                                                MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK) &&
+                    init_attr->qp_type != IB_QPT_UD) ||
+                   (init_attr->create_flags & MLX4_IB_SRIOV_SQP &&
+                    init_attr->qp_type > IB_QPT_GSI) ||
+                   (init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI &&
+                    init_attr->qp_type != IB_QPT_GSI))
+                       return ERR_PTR(-EINVAL);
+       }
 
        switch (init_attr->qp_type) {
        case IB_QPT_XRC_TGT:
@@ -1173,19 +1187,29 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
        case IB_QPT_SMI:
        case IB_QPT_GSI:
        {
+               int sqpn;
+
                /* Userspace is not allowed to create special QPs: */
                if (udata)
                        return ERR_PTR(-EINVAL);
+               if (init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI) {
+                       int res = mlx4_qp_reserve_range(to_mdev(pd->device)->dev, 1, 1, &sqpn, 0);
+
+                       if (res)
+                               return ERR_PTR(res);
+               } else {
+                       sqpn = get_sqp_num(to_mdev(pd->device), init_attr);
+               }
 
                err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata,
-                                      get_sqp_num(to_mdev(pd->device), init_attr),
+                                      sqpn,
                                       &qp, gfp);
                if (err)
                        return ERR_PTR(err);
 
                qp->port        = init_attr->port_num;
-               qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
-
+               qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 :
+                       init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI ? sqpn : 1;
                break;
        }
        default:
@@ -1196,7 +1220,41 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
        return &qp->ibqp;
 }
 
-int mlx4_ib_destroy_qp(struct ib_qp *qp)
+struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
+                               struct ib_qp_init_attr *init_attr,
+                               struct ib_udata *udata) {
+       struct ib_device *device = pd ? pd->device : init_attr->xrcd->device;
+       struct ib_qp *ibqp;
+       struct mlx4_ib_dev *dev = to_mdev(device);
+
+       ibqp = _mlx4_ib_create_qp(pd, init_attr, udata);
+
+       if (!IS_ERR(ibqp) &&
+           (init_attr->qp_type == IB_QPT_GSI) &&
+           !(init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI)) {
+               struct mlx4_ib_sqp *sqp = to_msqp((to_mqp(ibqp)));
+               int is_eth = rdma_cap_eth_ah(&dev->ib_dev, init_attr->port_num);
+
+               if (is_eth &&
+                   dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2) {
+                       init_attr->create_flags |= MLX4_IB_QP_CREATE_ROCE_V2_GSI;
+                       sqp->roce_v2_gsi = ib_create_qp(pd, init_attr);
+
+                       if (IS_ERR(sqp->roce_v2_gsi)) {
+                               pr_err("Failed to create GSI QP for RoCEv2 (%ld)\n", PTR_ERR(sqp->roce_v2_gsi));
+                               sqp->roce_v2_gsi = NULL;
+                       } else {
+                               sqp = to_msqp(to_mqp(sqp->roce_v2_gsi));
+                               sqp->qp.flags |= MLX4_IB_ROCE_V2_GSI_QP;
+                       }
+
+                       init_attr->create_flags &= ~MLX4_IB_QP_CREATE_ROCE_V2_GSI;
+               }
+       }
+       return ibqp;
+}
+
+static int _mlx4_ib_destroy_qp(struct ib_qp *qp)
 {
        struct mlx4_ib_dev *dev = to_mdev(qp->device);
        struct mlx4_ib_qp *mqp = to_mqp(qp);
@@ -1225,6 +1283,20 @@ int mlx4_ib_destroy_qp(struct ib_qp *qp)
        return 0;
 }
 
+int mlx4_ib_destroy_qp(struct ib_qp *qp)
+{
+       struct mlx4_ib_qp *mqp = to_mqp(qp);
+
+       if (mqp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) {
+               struct mlx4_ib_sqp *sqp = to_msqp(mqp);
+
+               if (sqp->roce_v2_gsi)
+                       ib_destroy_qp(sqp->roce_v2_gsi);
+       }
+
+       return _mlx4_ib_destroy_qp(qp);
+}
+
 static int to_mlx4_st(struct mlx4_ib_dev *dev, enum mlx4_ib_qp_type type)
 {
        switch (type) {
@@ -1507,6 +1579,24 @@ static int create_qp_lb_counter(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
        return 0;
 }
 
+enum {
+       MLX4_QPC_ROCE_MODE_1 = 0,
+       MLX4_QPC_ROCE_MODE_2 = 2,
+       MLX4_QPC_ROCE_MODE_UNDEFINED = 0xff
+};
+
+static u8 gid_type_to_qpc(enum ib_gid_type gid_type)
+{
+       switch (gid_type) {
+       case IB_GID_TYPE_ROCE:
+               return MLX4_QPC_ROCE_MODE_1;
+       case IB_GID_TYPE_ROCE_UDP_ENCAP:
+               return MLX4_QPC_ROCE_MODE_2;
+       default:
+               return MLX4_QPC_ROCE_MODE_UNDEFINED;
+       }
+}
+
 static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                               const struct ib_qp_attr *attr, int attr_mask,
                               enum ib_qp_state cur_state, enum ib_qp_state new_state)
@@ -1633,6 +1723,14 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                        mlx4_ib_steer_qp_reg(dev, qp, 1);
                        steer_qp = 1;
                }
+
+               if (ibqp->qp_type == IB_QPT_GSI) {
+                       enum ib_gid_type gid_type = qp->flags & MLX4_IB_ROCE_V2_GSI_QP ?
+                               IB_GID_TYPE_ROCE_UDP_ENCAP : IB_GID_TYPE_ROCE;
+                       u8 qpc_roce_mode = gid_type_to_qpc(gid_type);
+
+                       context->rlkey_roce_mode |= (qpc_roce_mode << 6);
+               }
        }
 
        if (attr_mask & IB_QP_PKEY_INDEX) {
@@ -1650,9 +1748,10 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                u16 vlan = 0xffff;
                u8 smac[ETH_ALEN];
                int status = 0;
+               int is_eth = rdma_cap_eth_ah(&dev->ib_dev, port_num) &&
+                       attr->ah_attr.ah_flags & IB_AH_GRH;
 
-               if (rdma_cap_eth_ah(&dev->ib_dev, port_num) &&
-                   attr->ah_attr.ah_flags & IB_AH_GRH) {
+               if (is_eth) {
                        int index = attr->ah_attr.grh.sgid_index;
 
                        status = ib_get_cached_gid(ibqp->device, port_num,
@@ -1674,6 +1773,18 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
 
                optpar |= (MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH |
                           MLX4_QP_OPTPAR_SCHED_QUEUE);
+
+               if (is_eth &&
+                   (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR)) {
+                       u8 qpc_roce_mode = gid_type_to_qpc(gid_attr.gid_type);
+
+                       if (qpc_roce_mode == MLX4_QPC_ROCE_MODE_UNDEFINED) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+                       context->rlkey_roce_mode |= (qpc_roce_mode << 6);
+               }
+
        }
 
        if (attr_mask & IB_QP_TIMEOUT) {
@@ -1845,7 +1956,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                sqd_event = 0;
 
        if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
-               context->rlkey |= (1 << 4);
+               context->rlkey_roce_mode |= (1 << 4);
 
        /*
         * Before passing a kernel QP to the HW, make sure that the
@@ -2022,8 +2133,8 @@ out:
        return err;
 }
 
-int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-                     int attr_mask, struct ib_udata *udata)
+static int _mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+                             int attr_mask, struct ib_udata *udata)
 {
        struct mlx4_ib_dev *dev = to_mdev(ibqp->device);
        struct mlx4_ib_qp *qp = to_mqp(ibqp);
@@ -2126,6 +2237,27 @@ out:
        return err;
 }
 
+int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+                     int attr_mask, struct ib_udata *udata)
+{
+       struct mlx4_ib_qp *mqp = to_mqp(ibqp);
+       int ret;
+
+       ret = _mlx4_ib_modify_qp(ibqp, attr, attr_mask, udata);
+
+       if (mqp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) {
+               struct mlx4_ib_sqp *sqp = to_msqp(mqp);
+               int err = 0;
+
+               if (sqp->roce_v2_gsi)
+                       err = ib_modify_qp(sqp->roce_v2_gsi, attr, attr_mask);
+               if (err)
+                       pr_err("Failed to modify GSI QP for RoCEv2 (%d)\n",
+                              err);
+       }
+       return ret;
+}
+
 static int vf_get_qp0_qkey(struct mlx4_dev *dev, int qpn, u32 *qkey)
 {
        int i;
@@ -2168,7 +2300,7 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp,
        if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_SMI_OWNER)
                send_size += sizeof (struct mlx4_ib_tunnel_header);
 
-       ib_ud_header_init(send_size, 1, 0, 0, 0, 0, &sqp->ud_header);
+       ib_ud_header_init(send_size, 1, 0, 0, 0, 0, 0, 0, &sqp->ud_header);
 
        if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_SMI_OWNER) {
                sqp->ud_header.lrh.service_level =
@@ -2252,16 +2384,7 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp,
        return 0;
 }
 
-static void mlx4_u64_to_smac(u8 *dst_mac, u64 src_mac)
-{
-       int i;
-
-       for (i = ETH_ALEN; i; i--) {
-               dst_mac[i - 1] = src_mac & 0xff;
-               src_mac >>= 8;
-       }
-}
-
+#define MLX4_ROCEV2_QP1_SPORT 0xC000
 static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
                            void *wqe, unsigned *mlx_seg_len)
 {
@@ -2281,6 +2404,8 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
        bool is_eth;
        bool is_vlan = false;
        bool is_grh;
+       bool is_udp = false;
+       int ip_version = 0;
 
        send_size = 0;
        for (i = 0; i < wr->wr.num_sge; ++i)
@@ -2289,6 +2414,8 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
        is_eth = rdma_port_get_link_layer(sqp->qp.ibqp.device, sqp->qp.port) == IB_LINK_LAYER_ETHERNET;
        is_grh = mlx4_ib_ah_grh_present(ah);
        if (is_eth) {
+               struct ib_gid_attr gid_attr;
+
                if (mlx4_is_mfunc(to_mdev(ib_dev)->dev)) {
                        /* When multi-function is enabled, the ib_core gid
                         * indexes don't necessarily match the hw ones, so
@@ -2302,19 +2429,35 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
                        err = ib_get_cached_gid(ib_dev,
                                                be32_to_cpu(ah->av.ib.port_pd) >> 24,
                                                ah->av.ib.gid_index, &sgid,
-                                               NULL);
-                       if (!err && !memcmp(&sgid, &zgid, sizeof(sgid)))
-                               err = -ENOENT;
-                       if (err)
+                                               &gid_attr);
+                       if (!err) {
+                               if (gid_attr.ndev)
+                                       dev_put(gid_attr.ndev);
+                               if (!memcmp(&sgid, &zgid, sizeof(sgid)))
+                                       err = -ENOENT;
+                       }
+                       if (!err) {
+                               is_udp = gid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP;
+                               if (is_udp) {
+                                       if (ipv6_addr_v4mapped((struct in6_addr *)&sgid))
+                                               ip_version = 4;
+                                       else
+                                               ip_version = 6;
+                                       is_grh = false;
+                               }
+                       } else {
                                return err;
+                       }
                }
-
                if (ah->av.eth.vlan != cpu_to_be16(0xffff)) {
                        vlan = be16_to_cpu(ah->av.eth.vlan) & 0x0fff;
                        is_vlan = 1;
                }
        }
-       ib_ud_header_init(send_size, !is_eth, is_eth, is_vlan, is_grh, 0, &sqp->ud_header);
+       err = ib_ud_header_init(send_size, !is_eth, is_eth, is_vlan, is_grh,
+                         ip_version, is_udp, 0, &sqp->ud_header);
+       if (err)
+               return err;
 
        if (!is_eth) {
                sqp->ud_header.lrh.service_level =
@@ -2323,7 +2466,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
                sqp->ud_header.lrh.source_lid = cpu_to_be16(ah->av.ib.g_slid & 0x7f);
        }
 
-       if (is_grh) {
+       if (is_grh || (ip_version == 6)) {
                sqp->ud_header.grh.traffic_class =
                        (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 20) & 0xff;
                sqp->ud_header.grh.flow_label    =
@@ -2352,6 +2495,25 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
                       ah->av.ib.dgid, 16);
        }
 
+       if (ip_version == 4) {
+               sqp->ud_header.ip4.tos =
+                       (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 20) & 0xff;
+               sqp->ud_header.ip4.id = 0;
+               sqp->ud_header.ip4.frag_off = htons(IP_DF);
+               sqp->ud_header.ip4.ttl = ah->av.eth.hop_limit;
+
+               memcpy(&sqp->ud_header.ip4.saddr,
+                      sgid.raw + 12, 4);
+               memcpy(&sqp->ud_header.ip4.daddr, ah->av.ib.dgid + 12, 4);
+               sqp->ud_header.ip4.check = ib_ud_ip4_csum(&sqp->ud_header);
+       }
+
+       if (is_udp) {
+               sqp->ud_header.udp.dport = htons(ROCE_V2_UDP_DPORT);
+               sqp->ud_header.udp.sport = htons(MLX4_ROCEV2_QP1_SPORT);
+               sqp->ud_header.udp.csum = 0;
+       }
+
        mlx->flags &= cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE);
 
        if (!is_eth) {
@@ -2380,34 +2542,27 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr,
 
        if (is_eth) {
                struct in6_addr in6;
-
+               u16 ether_type;
                u16 pcp = (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 29) << 13;
 
+               ether_type = (!is_udp) ? MLX4_IB_IBOE_ETHERTYPE :
+                       (ip_version == 4 ? ETH_P_IP : ETH_P_IPV6);
+
                mlx->sched_prio = cpu_to_be16(pcp);
 
+               ether_addr_copy(sqp->ud_header.eth.smac_h, ah->av.eth.s_mac);
                memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6);
-               /* FIXME: cache smac value? */
                memcpy(&ctrl->srcrb_flags16[0], ah->av.eth.mac, 2);
                memcpy(&ctrl->imm, ah->av.eth.mac + 2, 4);
                memcpy(&in6, sgid.raw, sizeof(in6));
 
-               if (!mlx4_is_mfunc(to_mdev(ib_dev)->dev)) {
-                       u64 mac = atomic64_read(&to_mdev(ib_dev)->iboe.mac[sqp->qp.port - 1]);
-                       u8 smac[ETH_ALEN];
-
-                       mlx4_u64_to_smac(smac, mac);
-                       memcpy(sqp->ud_header.eth.smac_h, smac, ETH_ALEN);
-               } else {
-                       /* use the src mac of the tunnel */
-                       memcpy(sqp->ud_header.eth.smac_h, ah->av.eth.s_mac, ETH_ALEN);
-               }
 
                if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6))
                        mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK);
                if (!is_vlan) {
-                       sqp->ud_header.eth.type = cpu_to_be16(MLX4_IB_IBOE_ETHERTYPE);
+                       sqp->ud_header.eth.type = cpu_to_be16(ether_type);
                } else {
-                       sqp->ud_header.vlan.type = cpu_to_be16(MLX4_IB_IBOE_ETHERTYPE);
+                       sqp->ud_header.vlan.type = cpu_to_be16(ether_type);
                        sqp->ud_header.vlan.tag = cpu_to_be16(vlan | pcp);
                }
        } else {
@@ -2528,25 +2683,6 @@ static void set_reg_seg(struct mlx4_wqe_fmr_seg *fseg,
        fseg->reserved[1]       = 0;
 }
 
-static void set_bind_seg(struct mlx4_wqe_bind_seg *bseg,
-               struct ib_bind_mw_wr *wr)
-{
-       bseg->flags1 =
-               convert_access(wr->bind_info.mw_access_flags) &
-               cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_READ  |
-                           MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_WRITE |
-                           MLX4_WQE_FMR_AND_BIND_PERM_ATOMIC);
-       bseg->flags2 = 0;
-       if (wr->mw->type == IB_MW_TYPE_2)
-               bseg->flags2 |= cpu_to_be32(MLX4_WQE_BIND_TYPE_2);
-       if (wr->bind_info.mw_access_flags & IB_ZERO_BASED)
-               bseg->flags2 |= cpu_to_be32(MLX4_WQE_BIND_ZERO_BASED);
-       bseg->new_rkey = cpu_to_be32(wr->rkey);
-       bseg->lkey = cpu_to_be32(wr->bind_info.mr->lkey);
-       bseg->addr = cpu_to_be64(wr->bind_info.addr);
-       bseg->length = cpu_to_be64(wr->bind_info.length);
-}
-
 static void set_local_inv_seg(struct mlx4_wqe_local_inval_seg *iseg, u32 rkey)
 {
        memset(iseg, 0, sizeof(*iseg));
@@ -2766,6 +2902,29 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        int i;
        struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
 
+       if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_GSI) {
+               struct mlx4_ib_sqp *sqp = to_msqp(qp);
+
+               if (sqp->roce_v2_gsi) {
+                       struct mlx4_ib_ah *ah = to_mah(ud_wr(wr)->ah);
+                       struct ib_gid_attr gid_attr;
+                       union ib_gid gid;
+
+                       if (!ib_get_cached_gid(ibqp->device,
+                                              be32_to_cpu(ah->av.ib.port_pd) >> 24,
+                                              ah->av.ib.gid_index, &gid,
+                                              &gid_attr)) {
+                               if (gid_attr.ndev)
+                                       dev_put(gid_attr.ndev);
+                               qp = (gid_attr.gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ?
+                                       to_mqp(sqp->roce_v2_gsi) : qp;
+                       } else {
+                               pr_err("Failed to get gid at index %d. RoCEv2 will not work properly\n",
+                                      ah->av.ib.gid_index);
+                       }
+               }
+       }
+
        spin_lock_irqsave(&qp->sq.lock, flags);
        if (mdev->dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR) {
                err = -EIO;
@@ -2867,13 +3026,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                size += sizeof(struct mlx4_wqe_fmr_seg) / 16;
                                break;
 
-                       case IB_WR_BIND_MW:
-                               ctrl->srcrb_flags |=
-                                       cpu_to_be32(MLX4_WQE_CTRL_STRONG_ORDER);
-                               set_bind_seg(wqe, bind_mw_wr(wr));
-                               wqe  += sizeof(struct mlx4_wqe_bind_seg);
-                               size += sizeof(struct mlx4_wqe_bind_seg) / 16;
-                               break;
                        default:
                                /* No extra segments required for sends */
                                break;
index c394376..0597f3e 100644 (file)
@@ -171,7 +171,8 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
                if (err)
                        goto err_mtt;
 
-               srq->wrid = kmalloc(srq->msrq.max * sizeof (u64), GFP_KERNEL);
+               srq->wrid = kmalloc_array(srq->msrq.max, sizeof(u64),
+                                       GFP_KERNEL | __GFP_NOWARN);
                if (!srq->wrid) {
                        srq->wrid = __vmalloc(srq->msrq.max * sizeof(u64),
                                              GFP_KERNEL, PAGE_KERNEL);
index 6608058..745efa4 100644 (file)
 
 #include "mlx5_ib.h"
 
-struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
-                          struct mlx5_ib_ah *ah)
+static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev,
+                                 struct mlx5_ib_ah *ah,
+                                 struct ib_ah_attr *ah_attr,
+                                 enum rdma_link_layer ll)
 {
        if (ah_attr->ah_flags & IB_AH_GRH) {
                memcpy(ah->av.rgid, &ah_attr->grh.dgid, 16);
@@ -44,9 +46,20 @@ struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
                ah->av.tclass = ah_attr->grh.traffic_class;
        }
 
-       ah->av.rlid = cpu_to_be16(ah_attr->dlid);
-       ah->av.fl_mlid = ah_attr->src_path_bits & 0x7f;
-       ah->av.stat_rate_sl = (ah_attr->static_rate << 4) | (ah_attr->sl & 0xf);
+       ah->av.stat_rate_sl = (ah_attr->static_rate << 4);
+
+       if (ll == IB_LINK_LAYER_ETHERNET) {
+               memcpy(ah->av.rmac, ah_attr->dmac, sizeof(ah_attr->dmac));
+               ah->av.udp_sport =
+                       mlx5_get_roce_udp_sport(dev,
+                                               ah_attr->port_num,
+                                               ah_attr->grh.sgid_index);
+               ah->av.stat_rate_sl |= (ah_attr->sl & 0x7) << 1;
+       } else {
+               ah->av.rlid = cpu_to_be16(ah_attr->dlid);
+               ah->av.fl_mlid = ah_attr->src_path_bits & 0x7f;
+               ah->av.stat_rate_sl |= (ah_attr->sl & 0xf);
+       }
 
        return &ah->ibah;
 }
@@ -54,12 +67,19 @@ struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
 struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
 {
        struct mlx5_ib_ah *ah;
+       struct mlx5_ib_dev *dev = to_mdev(pd->device);
+       enum rdma_link_layer ll;
+
+       ll = pd->device->get_link_layer(pd->device, ah_attr->port_num);
+
+       if (ll == IB_LINK_LAYER_ETHERNET && !(ah_attr->ah_flags & IB_AH_GRH))
+               return ERR_PTR(-EINVAL);
 
        ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
        if (!ah)
                return ERR_PTR(-ENOMEM);
 
-       return create_ib_ah(ah_attr, ah); /* never fails */
+       return create_ib_ah(dev, ah, ah_attr, ll); /* never fails */
 }
 
 int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
index 92ddae1..fd1de31 100644 (file)
@@ -154,9 +154,6 @@ static void handle_good_req(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
                wc->opcode    = IB_WC_MASKED_FETCH_ADD;
                wc->byte_len  = 8;
                break;
-       case MLX5_OPCODE_BIND_MW:
-               wc->opcode    = IB_WC_BIND_MW;
-               break;
        case MLX5_OPCODE_UMR:
                wc->opcode = get_umr_comp(wq, idx);
                break;
@@ -171,6 +168,7 @@ enum {
 static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
                             struct mlx5_ib_qp *qp)
 {
+       enum rdma_link_layer ll = rdma_port_get_link_layer(qp->ibqp.device, 1);
        struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device);
        struct mlx5_ib_srq *srq;
        struct mlx5_ib_wq *wq;
@@ -236,6 +234,22 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
        } else {
                wc->pkey_index = 0;
        }
+
+       if (ll != IB_LINK_LAYER_ETHERNET)
+               return;
+
+       switch (wc->sl & 0x3) {
+       case MLX5_CQE_ROCE_L3_HEADER_TYPE_GRH:
+               wc->network_hdr_type = RDMA_NETWORK_IB;
+               break;
+       case MLX5_CQE_ROCE_L3_HEADER_TYPE_IPV6:
+               wc->network_hdr_type = RDMA_NETWORK_IPV6;
+               break;
+       case MLX5_CQE_ROCE_L3_HEADER_TYPE_IPV4:
+               wc->network_hdr_type = RDMA_NETWORK_IPV4;
+               break;
+       }
+       wc->wc_flags |= IB_WC_WITH_NETWORK_HDR_TYPE;
 }
 
 static void dump_cqe(struct mlx5_ib_dev *dev, struct mlx5_err_cqe *cqe)
@@ -760,12 +774,12 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
        int eqn;
        int err;
 
-       if (attr->flags)
-               return ERR_PTR(-EINVAL);
-
        if (entries < 0)
                return ERR_PTR(-EINVAL);
 
+       if (check_cq_create_flags(attr->flags))
+               return ERR_PTR(-EOPNOTSUPP);
+
        entries = roundup_pow_of_two(entries + 1);
        if (entries > (1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz)))
                return ERR_PTR(-EINVAL);
@@ -779,6 +793,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
        spin_lock_init(&cq->lock);
        cq->resize_buf = NULL;
        cq->resize_umem = NULL;
+       cq->create_flags = attr->flags;
 
        if (context) {
                err = create_cq_user(dev, udata, context, cq, entries,
@@ -796,6 +811,10 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
 
        cq->cqe_size = cqe_size;
        cqb->ctx.cqe_sz_flags = cqe_sz_to_mlx_sz(cqe_size) << 5;
+
+       if (cq->create_flags & IB_CQ_FLAGS_IGNORE_OVERRUN)
+               cqb->ctx.cqe_sz_flags |= (1 << 1);
+
        cqb->ctx.log_sz_usr_page = cpu_to_be32((ilog2(entries) << 24) | index);
        err = mlx5_vector2eqn(dev->mdev, vector, &eqn, &irqn);
        if (err)
index b0ec175..ec737e2 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/io-mapping.h>
 #include <linux/sched.h>
 #include <rdma/ib_user_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
 #include <linux/mlx5/vport.h>
 #include <rdma/ib_smi.h>
 #include <rdma/ib_umem.h>
@@ -66,12 +68,14 @@ static char mlx5_version[] =
        DRIVER_NAME ": Mellanox Connect-IB Infiniband driver v"
        DRIVER_VERSION " (" DRIVER_RELDATE ")\n";
 
+enum {
+       MLX5_ATOMIC_SIZE_QP_8BYTES = 1 << 3,
+};
+
 static enum rdma_link_layer
-mlx5_ib_port_link_layer(struct ib_device *device)
+mlx5_port_type_cap_to_rdma_ll(int port_type_cap)
 {
-       struct mlx5_ib_dev *dev = to_mdev(device);
-
-       switch (MLX5_CAP_GEN(dev->mdev, port_type)) {
+       switch (port_type_cap) {
        case MLX5_CAP_PORT_TYPE_IB:
                return IB_LINK_LAYER_INFINIBAND;
        case MLX5_CAP_PORT_TYPE_ETH:
@@ -81,6 +85,202 @@ mlx5_ib_port_link_layer(struct ib_device *device)
        }
 }
 
+static enum rdma_link_layer
+mlx5_ib_port_link_layer(struct ib_device *device, u8 port_num)
+{
+       struct mlx5_ib_dev *dev = to_mdev(device);
+       int port_type_cap = MLX5_CAP_GEN(dev->mdev, port_type);
+
+       return mlx5_port_type_cap_to_rdma_ll(port_type_cap);
+}
+
+static int mlx5_netdev_event(struct notifier_block *this,
+                            unsigned long event, void *ptr)
+{
+       struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
+       struct mlx5_ib_dev *ibdev = container_of(this, struct mlx5_ib_dev,
+                                                roce.nb);
+
+       if ((event != NETDEV_UNREGISTER) && (event != NETDEV_REGISTER))
+               return NOTIFY_DONE;
+
+       write_lock(&ibdev->roce.netdev_lock);
+       if (ndev->dev.parent == &ibdev->mdev->pdev->dev)
+               ibdev->roce.netdev = (event == NETDEV_UNREGISTER) ? NULL : ndev;
+       write_unlock(&ibdev->roce.netdev_lock);
+
+       return NOTIFY_DONE;
+}
+
+static struct net_device *mlx5_ib_get_netdev(struct ib_device *device,
+                                            u8 port_num)
+{
+       struct mlx5_ib_dev *ibdev = to_mdev(device);
+       struct net_device *ndev;
+
+       /* Ensure ndev does not disappear before we invoke dev_hold()
+        */
+       read_lock(&ibdev->roce.netdev_lock);
+       ndev = ibdev->roce.netdev;
+       if (ndev)
+               dev_hold(ndev);
+       read_unlock(&ibdev->roce.netdev_lock);
+
+       return ndev;
+}
+
+static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
+                               struct ib_port_attr *props)
+{
+       struct mlx5_ib_dev *dev = to_mdev(device);
+       struct net_device *ndev;
+       enum ib_mtu ndev_ib_mtu;
+       u16 qkey_viol_cntr;
+
+       memset(props, 0, sizeof(*props));
+
+       props->port_cap_flags  |= IB_PORT_CM_SUP;
+       props->port_cap_flags  |= IB_PORT_IP_BASED_GIDS;
+
+       props->gid_tbl_len      = MLX5_CAP_ROCE(dev->mdev,
+                                               roce_address_table_size);
+       props->max_mtu          = IB_MTU_4096;
+       props->max_msg_sz       = 1 << MLX5_CAP_GEN(dev->mdev, log_max_msg);
+       props->pkey_tbl_len     = 1;
+       props->state            = IB_PORT_DOWN;
+       props->phys_state       = 3;
+
+       mlx5_query_nic_vport_qkey_viol_cntr(dev->mdev, &qkey_viol_cntr);
+       props->qkey_viol_cntr = qkey_viol_cntr;
+
+       ndev = mlx5_ib_get_netdev(device, port_num);
+       if (!ndev)
+               return 0;
+
+       if (netif_running(ndev) && netif_carrier_ok(ndev)) {
+               props->state      = IB_PORT_ACTIVE;
+               props->phys_state = 5;
+       }
+
+       ndev_ib_mtu = iboe_get_mtu(ndev->mtu);
+
+       dev_put(ndev);
+
+       props->active_mtu       = min(props->max_mtu, ndev_ib_mtu);
+
+       props->active_width     = IB_WIDTH_4X;  /* TODO */
+       props->active_speed     = IB_SPEED_QDR; /* TODO */
+
+       return 0;
+}
+
+static void ib_gid_to_mlx5_roce_addr(const union ib_gid *gid,
+                                    const struct ib_gid_attr *attr,
+                                    void *mlx5_addr)
+{
+#define MLX5_SET_RA(p, f, v) MLX5_SET(roce_addr_layout, p, f, v)
+       char *mlx5_addr_l3_addr = MLX5_ADDR_OF(roce_addr_layout, mlx5_addr,
+                                              source_l3_address);
+       void *mlx5_addr_mac     = MLX5_ADDR_OF(roce_addr_layout, mlx5_addr,
+                                              source_mac_47_32);
+
+       if (!gid)
+               return;
+
+       ether_addr_copy(mlx5_addr_mac, attr->ndev->dev_addr);
+
+       if (is_vlan_dev(attr->ndev)) {
+               MLX5_SET_RA(mlx5_addr, vlan_valid, 1);
+               MLX5_SET_RA(mlx5_addr, vlan_id, vlan_dev_vlan_id(attr->ndev));
+       }
+
+       switch (attr->gid_type) {
+       case IB_GID_TYPE_IB:
+               MLX5_SET_RA(mlx5_addr, roce_version, MLX5_ROCE_VERSION_1);
+               break;
+       case IB_GID_TYPE_ROCE_UDP_ENCAP:
+               MLX5_SET_RA(mlx5_addr, roce_version, MLX5_ROCE_VERSION_2);
+               break;
+
+       default:
+               WARN_ON(true);
+       }
+
+       if (attr->gid_type != IB_GID_TYPE_IB) {
+               if (ipv6_addr_v4mapped((void *)gid))
+                       MLX5_SET_RA(mlx5_addr, roce_l3_type,
+                                   MLX5_ROCE_L3_TYPE_IPV4);
+               else
+                       MLX5_SET_RA(mlx5_addr, roce_l3_type,
+                                   MLX5_ROCE_L3_TYPE_IPV6);
+       }
+
+       if ((attr->gid_type == IB_GID_TYPE_IB) ||
+           !ipv6_addr_v4mapped((void *)gid))
+               memcpy(mlx5_addr_l3_addr, gid, sizeof(*gid));
+       else
+               memcpy(&mlx5_addr_l3_addr[12], &gid->raw[12], 4);
+}
+
+static int set_roce_addr(struct ib_device *device, u8 port_num,
+                        unsigned int index,
+                        const union ib_gid *gid,
+                        const struct ib_gid_attr *attr)
+{
+       struct mlx5_ib_dev *dev = to_mdev(device);
+       u32  in[MLX5_ST_SZ_DW(set_roce_address_in)];
+       u32 out[MLX5_ST_SZ_DW(set_roce_address_out)];
+       void *in_addr = MLX5_ADDR_OF(set_roce_address_in, in, roce_address);
+       enum rdma_link_layer ll = mlx5_ib_port_link_layer(device, port_num);
+
+       if (ll != IB_LINK_LAYER_ETHERNET)
+               return -EINVAL;
+
+       memset(in, 0, sizeof(in));
+
+       ib_gid_to_mlx5_roce_addr(gid, attr, in_addr);
+
+       MLX5_SET(set_roce_address_in, in, roce_address_index, index);
+       MLX5_SET(set_roce_address_in, in, opcode, MLX5_CMD_OP_SET_ROCE_ADDRESS);
+
+       memset(out, 0, sizeof(out));
+       return mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
+}
+
+static int mlx5_ib_add_gid(struct ib_device *device, u8 port_num,
+                          unsigned int index, const union ib_gid *gid,
+                          const struct ib_gid_attr *attr,
+                          __always_unused void **context)
+{
+       return set_roce_addr(device, port_num, index, gid, attr);
+}
+
+static int mlx5_ib_del_gid(struct ib_device *device, u8 port_num,
+                          unsigned int index, __always_unused void **context)
+{
+       return set_roce_addr(device, port_num, index, NULL, NULL);
+}
+
+__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
+                              int index)
+{
+       struct ib_gid_attr attr;
+       union ib_gid gid;
+
+       if (ib_get_cached_gid(&dev->ib_dev, port_num, index, &gid, &attr))
+               return 0;
+
+       if (!attr.ndev)
+               return 0;
+
+       dev_put(attr.ndev);
+
+       if (attr.gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
+               return 0;
+
+       return cpu_to_be16(MLX5_CAP_ROCE(dev->mdev, r_roce_min_src_udp_port));
+}
+
 static int mlx5_use_mad_ifc(struct mlx5_ib_dev *dev)
 {
        return !dev->mdev->issi;
@@ -97,13 +297,35 @@ static int mlx5_get_vport_access_method(struct ib_device *ibdev)
        if (mlx5_use_mad_ifc(to_mdev(ibdev)))
                return MLX5_VPORT_ACCESS_METHOD_MAD;
 
-       if (mlx5_ib_port_link_layer(ibdev) ==
+       if (mlx5_ib_port_link_layer(ibdev, 1) ==
            IB_LINK_LAYER_ETHERNET)
                return MLX5_VPORT_ACCESS_METHOD_NIC;
 
        return MLX5_VPORT_ACCESS_METHOD_HCA;
 }
 
+static void get_atomic_caps(struct mlx5_ib_dev *dev,
+                           struct ib_device_attr *props)
+{
+       u8 tmp;
+       u8 atomic_operations = MLX5_CAP_ATOMIC(dev->mdev, atomic_operations);
+       u8 atomic_size_qp = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_qp);
+       u8 atomic_req_8B_endianness_mode =
+               MLX5_CAP_ATOMIC(dev->mdev, atomic_req_8B_endianess_mode);
+
+       /* Check if HW supports 8 bytes standard atomic operations and capable
+        * of host endianness respond
+        */
+       tmp = MLX5_ATOMIC_OPS_CMP_SWAP | MLX5_ATOMIC_OPS_FETCH_ADD;
+       if (((atomic_operations & tmp) == tmp) &&
+           (atomic_size_qp & MLX5_ATOMIC_SIZE_QP_8BYTES) &&
+           (atomic_req_8B_endianness_mode)) {
+               props->atomic_cap = IB_ATOMIC_HCA;
+       } else {
+               props->atomic_cap = IB_ATOMIC_NONE;
+       }
+}
+
 static int mlx5_query_system_image_guid(struct ib_device *ibdev,
                                        __be64 *sys_image_guid)
 {
@@ -119,13 +341,21 @@ static int mlx5_query_system_image_guid(struct ib_device *ibdev,
 
        case MLX5_VPORT_ACCESS_METHOD_HCA:
                err = mlx5_query_hca_vport_system_image_guid(mdev, &tmp);
-               if (!err)
-                       *sys_image_guid = cpu_to_be64(tmp);
-               return err;
+               break;
+
+       case MLX5_VPORT_ACCESS_METHOD_NIC:
+               err = mlx5_query_nic_vport_system_image_guid(mdev, &tmp);
+               break;
 
        default:
                return -EINVAL;
        }
+
+       if (!err)
+               *sys_image_guid = cpu_to_be64(tmp);
+
+       return err;
+
 }
 
 static int mlx5_query_max_pkeys(struct ib_device *ibdev,
@@ -179,13 +409,20 @@ static int mlx5_query_node_guid(struct mlx5_ib_dev *dev,
 
        case MLX5_VPORT_ACCESS_METHOD_HCA:
                err = mlx5_query_hca_vport_node_guid(dev->mdev, &tmp);
-               if (!err)
-                       *node_guid = cpu_to_be64(tmp);
-               return err;
+               break;
+
+       case MLX5_VPORT_ACCESS_METHOD_NIC:
+               err = mlx5_query_nic_vport_node_guid(dev->mdev, &tmp);
+               break;
 
        default:
                return -EINVAL;
        }
+
+       if (!err)
+               *node_guid = cpu_to_be64(tmp);
+
+       return err;
 }
 
 struct mlx5_reg_node_desc {
@@ -263,6 +500,10 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
        if (MLX5_CAP_GEN(mdev, block_lb_mc))
                props->device_cap_flags |= IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
 
+       if (MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&
+           (MLX5_CAP_ETH(dev->mdev, csum_cap)))
+                       props->device_cap_flags |= IB_DEVICE_RAW_IP_CSUM;
+
        props->vendor_part_id      = mdev->pdev->device;
        props->hw_ver              = mdev->pdev->revision;
 
@@ -278,7 +519,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
        props->max_sge = min(max_rq_sg, max_sq_sg);
        props->max_sge_rd = props->max_sge;
        props->max_cq              = 1 << MLX5_CAP_GEN(mdev, log_max_cq);
-       props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_eq_sz)) - 1;
+       props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1;
        props->max_mr              = 1 << MLX5_CAP_GEN(mdev, log_max_mkey);
        props->max_pd              = 1 << MLX5_CAP_GEN(mdev, log_max_pd);
        props->max_qp_rd_atom      = 1 << MLX5_CAP_GEN(mdev, log_max_ra_req_qp);
@@ -289,13 +530,15 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
        props->max_res_rd_atom     = props->max_qp_rd_atom * props->max_qp;
        props->max_srq_sge         = max_rq_sg - 1;
        props->max_fast_reg_page_list_len = (unsigned int)-1;
-       props->atomic_cap          = IB_ATOMIC_NONE;
+       get_atomic_caps(dev, props);
        props->masked_atomic_cap   = IB_ATOMIC_NONE;
        props->max_mcast_grp       = 1 << MLX5_CAP_GEN(mdev, log_max_mcg);
        props->max_mcast_qp_attach = MLX5_CAP_GEN(mdev, max_qp_mcg);
        props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
                                           props->max_mcast_grp;
        props->max_map_per_fmr = INT_MAX; /* no limit in ConnectIB */
+       props->hca_core_clock = MLX5_CAP_GEN(mdev, device_frequency_khz);
+       props->timestamp_mask = 0x7FFFFFFFFFFFFFFFULL;
 
 #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
        if (MLX5_CAP_GEN(mdev, pg))
@@ -303,6 +546,9 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
        props->odp_caps = dev->odp_caps;
 #endif
 
+       if (MLX5_CAP_GEN(mdev, cd))
+               props->device_cap_flags |= IB_DEVICE_CROSS_CHANNEL;
+
        return 0;
 }
 
@@ -483,6 +729,9 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
        case MLX5_VPORT_ACCESS_METHOD_HCA:
                return mlx5_query_hca_port(ibdev, port, props);
 
+       case MLX5_VPORT_ACCESS_METHOD_NIC:
+               return mlx5_query_port_roce(ibdev, port, props);
+
        default:
                return -EINVAL;
        }
@@ -583,8 +832,8 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
                                                  struct ib_udata *udata)
 {
        struct mlx5_ib_dev *dev = to_mdev(ibdev);
-       struct mlx5_ib_alloc_ucontext_req_v2 req;
-       struct mlx5_ib_alloc_ucontext_resp resp;
+       struct mlx5_ib_alloc_ucontext_req_v2 req = {};
+       struct mlx5_ib_alloc_ucontext_resp resp = {};
        struct mlx5_ib_ucontext *context;
        struct mlx5_uuar_info *uuari;
        struct mlx5_uar *uars;
@@ -599,20 +848,22 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        if (!dev->ib_active)
                return ERR_PTR(-EAGAIN);
 
-       memset(&req, 0, sizeof(req));
+       if (udata->inlen < sizeof(struct ib_uverbs_cmd_hdr))
+               return ERR_PTR(-EINVAL);
+
        reqlen = udata->inlen - sizeof(struct ib_uverbs_cmd_hdr);
        if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req))
                ver = 0;
-       else if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req_v2))
+       else if (reqlen >= sizeof(struct mlx5_ib_alloc_ucontext_req_v2))
                ver = 2;
        else
                return ERR_PTR(-EINVAL);
 
-       err = ib_copy_from_udata(&req, udata, reqlen);
+       err = ib_copy_from_udata(&req, udata, min(reqlen, sizeof(req)));
        if (err)
                return ERR_PTR(err);
 
-       if (req.flags || req.reserved)
+       if (req.flags)
                return ERR_PTR(-EINVAL);
 
        if (req.total_num_uuars > MLX5_MAX_UUARS)
@@ -621,6 +872,14 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        if (req.total_num_uuars == 0)
                return ERR_PTR(-EINVAL);
 
+       if (req.comp_mask || req.reserved0 || req.reserved1 || req.reserved2)
+               return ERR_PTR(-EOPNOTSUPP);
+
+       if (reqlen > sizeof(req) &&
+           !ib_is_udata_cleared(udata, sizeof(req),
+                                reqlen - sizeof(req)))
+               return ERR_PTR(-EOPNOTSUPP);
+
        req.total_num_uuars = ALIGN(req.total_num_uuars,
                                    MLX5_NON_FP_BF_REGS_PER_PAGE);
        if (req.num_low_latency_uuars > req.total_num_uuars - 1)
@@ -636,6 +895,11 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        resp.max_send_wqebb = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
        resp.max_recv_wr = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
        resp.max_srq_recv_wr = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
+       resp.cqe_version = min_t(__u8,
+                                (__u8)MLX5_CAP_GEN(dev->mdev, cqe_version),
+                                req.max_cqe_version);
+       resp.response_length = min(offsetof(typeof(resp), response_length) +
+                                  sizeof(resp.response_length), udata->outlen);
 
        context = kzalloc(sizeof(*context), GFP_KERNEL);
        if (!context)
@@ -681,22 +945,49 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        context->ibucontext.invalidate_range = &mlx5_ib_invalidate_range;
 #endif
 
+       if (MLX5_CAP_GEN(dev->mdev, log_max_transport_domain)) {
+               err = mlx5_core_alloc_transport_domain(dev->mdev,
+                                                      &context->tdn);
+               if (err)
+                       goto out_uars;
+       }
+
        INIT_LIST_HEAD(&context->db_page_list);
        mutex_init(&context->db_page_mutex);
 
        resp.tot_uuars = req.total_num_uuars;
        resp.num_ports = MLX5_CAP_GEN(dev->mdev, num_ports);
-       err = ib_copy_to_udata(udata, &resp,
-                              sizeof(resp) - sizeof(resp.reserved));
+
+       if (field_avail(typeof(resp), cqe_version, udata->outlen))
+               resp.response_length += sizeof(resp.cqe_version);
+
+       if (field_avail(typeof(resp), hca_core_clock_offset, udata->outlen)) {
+               resp.comp_mask |=
+                       MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET;
+               resp.hca_core_clock_offset =
+                       offsetof(struct mlx5_init_seg, internal_timer_h) %
+                       PAGE_SIZE;
+               resp.response_length += sizeof(resp.hca_core_clock_offset) +
+                                       sizeof(resp.reserved2) +
+                                       sizeof(resp.reserved3);
+       }
+
+       err = ib_copy_to_udata(udata, &resp, resp.response_length);
        if (err)
-               goto out_uars;
+               goto out_td;
 
        uuari->ver = ver;
        uuari->num_low_latency_uuars = req.num_low_latency_uuars;
        uuari->uars = uars;
        uuari->num_uars = num_uars;
+       context->cqe_version = resp.cqe_version;
+
        return &context->ibucontext;
 
+out_td:
+       if (MLX5_CAP_GEN(dev->mdev, log_max_transport_domain))
+               mlx5_core_dealloc_transport_domain(dev->mdev, context->tdn);
+
 out_uars:
        for (i--; i >= 0; i--)
                mlx5_cmd_free_uar(dev->mdev, uars[i].index);
@@ -721,6 +1012,9 @@ static int mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
        struct mlx5_uuar_info *uuari = &context->uuari;
        int i;
 
+       if (MLX5_CAP_GEN(dev->mdev, log_max_transport_domain))
+               mlx5_core_dealloc_transport_domain(dev->mdev, context->tdn);
+
        for (i = 0; i < uuari->num_uars; i++) {
                if (mlx5_cmd_free_uar(dev->mdev, uuari->uars[i].index))
                        mlx5_ib_warn(dev, "failed to free UAR 0x%x\n", uuari->uars[i].index);
@@ -790,6 +1084,30 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
        case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES:
                return -ENOSYS;
 
+       case MLX5_IB_MMAP_CORE_CLOCK:
+               if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+                       return -EINVAL;
+
+               if (vma->vm_flags & (VM_WRITE | VM_EXEC))
+                       return -EPERM;
+
+               /* Don't expose to user-space information it shouldn't have */
+               if (PAGE_SIZE > 4096)
+                       return -EOPNOTSUPP;
+
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               pfn = (dev->mdev->iseg_base +
+                      offsetof(struct mlx5_init_seg, internal_timer_h)) >>
+                       PAGE_SHIFT;
+               if (io_remap_pfn_range(vma, vma->vm_start, pfn,
+                                      PAGE_SIZE, vma->vm_page_prot))
+                       return -EAGAIN;
+
+               mlx5_ib_dbg(dev, "mapped internal timer at 0x%lx, PA 0x%llx\n",
+                           vma->vm_start,
+                           (unsigned long long)pfn << PAGE_SHIFT);
+               break;
+
        default:
                return -EINVAL;
        }
@@ -1758,6 +2076,32 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
        mlx5_ib_dealloc_pd(devr->p0);
 }
 
+static u32 get_core_cap_flags(struct ib_device *ibdev)
+{
+       struct mlx5_ib_dev *dev = to_mdev(ibdev);
+       enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, 1);
+       u8 l3_type_cap = MLX5_CAP_ROCE(dev->mdev, l3_type);
+       u8 roce_version_cap = MLX5_CAP_ROCE(dev->mdev, roce_version);
+       u32 ret = 0;
+
+       if (ll == IB_LINK_LAYER_INFINIBAND)
+               return RDMA_CORE_PORT_IBA_IB;
+
+       if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV4_CAP))
+               return 0;
+
+       if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV6_CAP))
+               return 0;
+
+       if (roce_version_cap & MLX5_ROCE_VERSION_1_CAP)
+               ret |= RDMA_CORE_PORT_IBA_ROCE;
+
+       if (roce_version_cap & MLX5_ROCE_VERSION_2_CAP)
+               ret |= RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP;
+
+       return ret;
+}
+
 static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
                               struct ib_port_immutable *immutable)
 {
@@ -1770,20 +2114,50 @@ static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
 
        immutable->pkey_tbl_len = attr.pkey_tbl_len;
        immutable->gid_tbl_len = attr.gid_tbl_len;
-       immutable->core_cap_flags = RDMA_CORE_PORT_IBA_IB;
+       immutable->core_cap_flags = get_core_cap_flags(ibdev);
        immutable->max_mad_size = IB_MGMT_MAD_SIZE;
 
        return 0;
 }
 
+static int mlx5_enable_roce(struct mlx5_ib_dev *dev)
+{
+       int err;
+
+       dev->roce.nb.notifier_call = mlx5_netdev_event;
+       err = register_netdevice_notifier(&dev->roce.nb);
+       if (err)
+               return err;
+
+       err = mlx5_nic_vport_enable_roce(dev->mdev);
+       if (err)
+               goto err_unregister_netdevice_notifier;
+
+       return 0;
+
+err_unregister_netdevice_notifier:
+       unregister_netdevice_notifier(&dev->roce.nb);
+       return err;
+}
+
+static void mlx5_disable_roce(struct mlx5_ib_dev *dev)
+{
+       mlx5_nic_vport_disable_roce(dev->mdev);
+       unregister_netdevice_notifier(&dev->roce.nb);
+}
+
 static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
 {
        struct mlx5_ib_dev *dev;
+       enum rdma_link_layer ll;
+       int port_type_cap;
        int err;
        int i;
 
-       /* don't create IB instance over Eth ports, no RoCE yet! */
-       if (MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH)
+       port_type_cap = MLX5_CAP_GEN(mdev, port_type);
+       ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
+
+       if ((ll == IB_LINK_LAYER_ETHERNET) && !MLX5_CAP_GEN(mdev, roce))
                return NULL;
 
        printk_once(KERN_INFO "%s", mlx5_version);
@@ -1794,6 +2168,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
 
        dev->mdev = mdev;
 
+       rwlock_init(&dev->roce.netdev_lock);
        err = get_port_caps(dev);
        if (err)
                goto err_dealloc;
@@ -1843,7 +2218,12 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
 
        dev->ib_dev.query_device        = mlx5_ib_query_device;
        dev->ib_dev.query_port          = mlx5_ib_query_port;
+       dev->ib_dev.get_link_layer      = mlx5_ib_port_link_layer;
+       if (ll == IB_LINK_LAYER_ETHERNET)
+               dev->ib_dev.get_netdev  = mlx5_ib_get_netdev;
        dev->ib_dev.query_gid           = mlx5_ib_query_gid;
+       dev->ib_dev.add_gid             = mlx5_ib_add_gid;
+       dev->ib_dev.del_gid             = mlx5_ib_del_gid;
        dev->ib_dev.query_pkey          = mlx5_ib_query_pkey;
        dev->ib_dev.modify_device       = mlx5_ib_modify_device;
        dev->ib_dev.modify_port         = mlx5_ib_modify_port;
@@ -1893,7 +2273,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
                        (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
        }
 
-       if (mlx5_ib_port_link_layer(&dev->ib_dev) ==
+       if (mlx5_ib_port_link_layer(&dev->ib_dev, 1) ==
            IB_LINK_LAYER_ETHERNET) {
                dev->ib_dev.create_flow = mlx5_ib_create_flow;
                dev->ib_dev.destroy_flow = mlx5_ib_destroy_flow;
@@ -1908,9 +2288,15 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
        mutex_init(&dev->flow_db.lock);
        mutex_init(&dev->cap_mask_mutex);
 
+       if (ll == IB_LINK_LAYER_ETHERNET) {
+               err = mlx5_enable_roce(dev);
+               if (err)
+                       goto err_dealloc;
+       }
+
        err = create_dev_resources(&dev->devr);
        if (err)
-               goto err_dealloc;
+               goto err_disable_roce;
 
        err = mlx5_ib_odp_init_one(dev);
        if (err)
@@ -1947,6 +2333,10 @@ err_odp:
 err_rsrc:
        destroy_dev_resources(&dev->devr);
 
+err_disable_roce:
+       if (ll == IB_LINK_LAYER_ETHERNET)
+               mlx5_disable_roce(dev);
+
 err_dealloc:
        ib_dealloc_device((struct ib_device *)dev);
 
@@ -1956,11 +2346,14 @@ err_dealloc:
 static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
 {
        struct mlx5_ib_dev *dev = context;
+       enum rdma_link_layer ll = mlx5_ib_port_link_layer(&dev->ib_dev, 1);
 
        ib_unregister_device(&dev->ib_dev);
        destroy_umrc_res(dev);
        mlx5_ib_odp_remove_one(dev);
        destroy_dev_resources(&dev->devr);
+       if (ll == IB_LINK_LAYER_ETHERNET)
+               mlx5_disable_roce(dev);
        ib_dealloc_device(&dev->ib_dev);
 }
 
index 1474ccc..d2b9737 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/mlx5/qp.h>
 #include <linux/mlx5/srq.h>
 #include <linux/types.h>
+#include <linux/mlx5/transobj.h>
 
 #define mlx5_ib_dbg(dev, format, arg...)                               \
 pr_debug("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,   \
@@ -55,6 +56,11 @@ pr_err("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,   \
 pr_warn("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,    \
        __LINE__, current->pid, ##arg)
 
+#define field_avail(type, fld, sz) (offsetof(type, fld) +              \
+                                   sizeof(((type *)0)->fld) <= (sz))
+#define MLX5_IB_DEFAULT_UIDX 0xffffff
+#define MLX5_USER_ASSIGNED_UIDX_MASK __mlx5_mask(qpc, user_index)
+
 enum {
        MLX5_IB_MMAP_CMD_SHIFT  = 8,
        MLX5_IB_MMAP_CMD_MASK   = 0xff,
@@ -62,7 +68,9 @@ enum {
 
 enum mlx5_ib_mmap_cmd {
        MLX5_IB_MMAP_REGULAR_PAGE               = 0,
-       MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES       = 1, /* always last */
+       MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES       = 1,
+       /* 5 is chosen in order to be compatible with old versions of libmlx5 */
+       MLX5_IB_MMAP_CORE_CLOCK                 = 5,
 };
 
 enum {
@@ -85,6 +93,15 @@ enum mlx5_ib_mad_ifc_flags {
        MLX5_MAD_IFC_NET_VIEW           = 4,
 };
 
+enum {
+       MLX5_CROSS_CHANNEL_UUAR         = 0,
+};
+
+enum {
+       MLX5_CQE_VERSION_V0,
+       MLX5_CQE_VERSION_V1,
+};
+
 struct mlx5_ib_ucontext {
        struct ib_ucontext      ibucontext;
        struct list_head        db_page_list;
@@ -93,6 +110,9 @@ struct mlx5_ib_ucontext {
         */
        struct mutex            db_page_mutex;
        struct mlx5_uuar_info   uuari;
+       u8                      cqe_version;
+       /* Transport Domain number */
+       u32                     tdn;
 };
 
 static inline struct mlx5_ib_ucontext *to_mucontext(struct ib_ucontext *ibucontext)
@@ -201,47 +221,70 @@ struct mlx5_ib_pfault {
        struct mlx5_pagefault   mpfault;
 };
 
+struct mlx5_ib_ubuffer {
+       struct ib_umem         *umem;
+       int                     buf_size;
+       u64                     buf_addr;
+};
+
+struct mlx5_ib_qp_base {
+       struct mlx5_ib_qp       *container_mibqp;
+       struct mlx5_core_qp     mqp;
+       struct mlx5_ib_ubuffer  ubuffer;
+};
+
+struct mlx5_ib_qp_trans {
+       struct mlx5_ib_qp_base  base;
+       u16                     xrcdn;
+       u8                      alt_port;
+       u8                      atomic_rd_en;
+       u8                      resp_depth;
+};
+
 struct mlx5_ib_rq {
+       struct mlx5_ib_qp_base base;
+       struct mlx5_ib_wq       *rq;
+       struct mlx5_ib_ubuffer  ubuffer;
+       struct mlx5_db          *doorbell;
        u32                     tirn;
+       u8                      state;
+};
+
+struct mlx5_ib_sq {
+       struct mlx5_ib_qp_base base;
+       struct mlx5_ib_wq       *sq;
+       struct mlx5_ib_ubuffer  ubuffer;
+       struct mlx5_db          *doorbell;
+       u32                     tisn;
+       u8                      state;
 };
 
 struct mlx5_ib_raw_packet_qp {
+       struct mlx5_ib_sq sq;
        struct mlx5_ib_rq rq;
 };
 
 struct mlx5_ib_qp {
        struct ib_qp            ibqp;
        union {
-               struct mlx5_core_qp             mqp;
-               struct mlx5_ib_raw_packet_qp    raw_packet_qp;
+               struct mlx5_ib_qp_trans trans_qp;
+               struct mlx5_ib_raw_packet_qp raw_packet_qp;
        };
-
        struct mlx5_buf         buf;
 
        struct mlx5_db          db;
        struct mlx5_ib_wq       rq;
 
-       u32                     doorbell_qpn;
        u8                      sq_signal_bits;
        u8                      fm_cache;
-       int                     sq_max_wqes_per_wr;
-       int                     sq_spare_wqes;
        struct mlx5_ib_wq       sq;
 
-       struct ib_umem         *umem;
-       int                     buf_size;
-
        /* serialize qp state modifications
         */
        struct mutex            mutex;
-       u16                     xrcdn;
        u32                     flags;
        u8                      port;
-       u8                      alt_port;
-       u8                      atomic_rd_en;
-       u8                      resp_depth;
        u8                      state;
-       int                     mlx_type;
        int                     wq_sig;
        int                     scat_cqe;
        int                     max_inline_data;
@@ -284,6 +327,9 @@ struct mlx5_ib_cq_buf {
 enum mlx5_ib_qp_flags {
        MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK     = 1 << 0,
        MLX5_IB_QP_SIGNATURE_HANDLING           = 1 << 1,
+       MLX5_IB_QP_CROSS_CHANNEL                = 1 << 2,
+       MLX5_IB_QP_MANAGED_SEND                 = 1 << 3,
+       MLX5_IB_QP_MANAGED_RECV                 = 1 << 4,
 };
 
 struct mlx5_umr_wr {
@@ -326,6 +372,7 @@ struct mlx5_ib_cq {
        struct mlx5_ib_cq_buf  *resize_buf;
        struct ib_umem         *resize_umem;
        int                     cqe_size;
+       u32                     create_flags;
 };
 
 struct mlx5_ib_srq {
@@ -449,9 +496,19 @@ struct mlx5_ib_resources {
        struct ib_srq   *s1;
 };
 
+struct mlx5_roce {
+       /* Protect mlx5_ib_get_netdev from invoking dev_hold() with a NULL
+        * netdev pointer
+        */
+       rwlock_t                netdev_lock;
+       struct net_device       *netdev;
+       struct notifier_block   nb;
+};
+
 struct mlx5_ib_dev {
        struct ib_device                ib_dev;
        struct mlx5_core_dev            *mdev;
+       struct mlx5_roce                roce;
        MLX5_DECLARE_DOORBELL_LOCK(uar_lock);
        int                             num_ports;
        /* serialize update of capability mask
@@ -498,7 +555,7 @@ static inline struct mlx5_ib_cq *to_mcq(struct ib_cq *ibcq)
 
 static inline struct mlx5_ib_qp *to_mibqp(struct mlx5_core_qp *mqp)
 {
-       return container_of(mqp, struct mlx5_ib_qp, mqp);
+       return container_of(mqp, struct mlx5_ib_qp_base, mqp)->container_mibqp;
 }
 
 static inline struct mlx5_ib_mr *to_mibmr(struct mlx5_core_mr *mmr)
@@ -550,8 +607,6 @@ void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
 int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
                 u8 port, const struct ib_wc *in_wc, const struct ib_grh *in_grh,
                 const void *in_mad, void *response_mad);
-struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
-                          struct mlx5_ib_ah *ah);
 struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
 int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
 int mlx5_ib_destroy_ah(struct ib_ah *ah);
@@ -578,7 +633,8 @@ int mlx5_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                      struct ib_recv_wr **bad_wr);
 void *mlx5_get_send_wqe(struct mlx5_ib_qp *qp, int n);
 int mlx5_ib_read_user_wqe(struct mlx5_ib_qp *qp, int send, int wqe_index,
-                         void *buffer, u32 length);
+                         void *buffer, u32 length,
+                         struct mlx5_ib_qp_base *base);
 struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
                                const struct ib_cq_init_attr *attr,
                                struct ib_ucontext *context,
@@ -680,6 +736,9 @@ static inline void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp)  {}
 
 #endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
 
+__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
+                              int index);
+
 static inline void init_query_mad(struct ib_smp *mad)
 {
        mad->base_version  = 1;
@@ -705,4 +764,28 @@ static inline int is_qp1(enum ib_qp_type qp_type)
 #define MLX5_MAX_UMR_SHIFT 16
 #define MLX5_MAX_UMR_PAGES (1 << MLX5_MAX_UMR_SHIFT)
 
+static inline u32 check_cq_create_flags(u32 flags)
+{
+       /*
+        * It returns non-zero value for unsupported CQ
+        * create flags, otherwise it returns zero.
+        */
+       return (flags & ~(IB_CQ_FLAGS_IGNORE_OVERRUN |
+                         IB_CQ_FLAGS_TIMESTAMP_COMPLETION));
+}
+
+static inline int verify_assign_uidx(u8 cqe_version, u32 cmd_uidx,
+                                    u32 *user_index)
+{
+       if (cqe_version) {
+               if ((cmd_uidx == MLX5_IB_DEFAULT_UIDX) ||
+                   (cmd_uidx & ~MLX5_USER_ASSIGNED_UIDX_MASK))
+                       return -EINVAL;
+               *user_index = cmd_uidx;
+       } else {
+               *user_index = MLX5_IB_DEFAULT_UIDX;
+       }
+
+       return 0;
+}
 #endif /* MLX5_IB_H */
index aa8391e..b8d7636 100644 (file)
@@ -153,14 +153,16 @@ static struct mlx5_ib_mr *mlx5_ib_odp_find_mr_lkey(struct mlx5_ib_dev *dev,
 
 static void mlx5_ib_page_fault_resume(struct mlx5_ib_qp *qp,
                                      struct mlx5_ib_pfault *pfault,
-                                     int error) {
+                                     int error)
+{
        struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.pd->device);
-       int ret = mlx5_core_page_fault_resume(dev->mdev, qp->mqp.qpn,
+       u32 qpn = qp->trans_qp.base.mqp.qpn;
+       int ret = mlx5_core_page_fault_resume(dev->mdev,
+                                             qpn,
                                              pfault->mpfault.flags,
                                              error);
        if (ret)
-               pr_err("Failed to resolve the page fault on QP 0x%x\n",
-                      qp->mqp.qpn);
+               pr_err("Failed to resolve the page fault on QP 0x%x\n", qpn);
 }
 
 /*
@@ -391,6 +393,7 @@ static int mlx5_ib_mr_initiator_pfault_handler(
 #if defined(DEBUG)
        u32 ctrl_wqe_index, ctrl_qpn;
 #endif
+       u32 qpn = qp->trans_qp.base.mqp.qpn;
 
        ds = be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_DS_MASK;
        if (ds * MLX5_WQE_DS_UNITS > wqe_length) {
@@ -401,7 +404,7 @@ static int mlx5_ib_mr_initiator_pfault_handler(
 
        if (ds == 0) {
                mlx5_ib_err(dev, "Got WQE with zero DS. wqe_index=%x, qpn=%x\n",
-                           wqe_index, qp->mqp.qpn);
+                           wqe_index, qpn);
                return -EFAULT;
        }
 
@@ -411,16 +414,16 @@ static int mlx5_ib_mr_initiator_pfault_handler(
                        MLX5_WQE_CTRL_WQE_INDEX_SHIFT;
        if (wqe_index != ctrl_wqe_index) {
                mlx5_ib_err(dev, "Got WQE with invalid wqe_index. wqe_index=0x%x, qpn=0x%x ctrl->wqe_index=0x%x\n",
-                           wqe_index, qp->mqp.qpn,
+                           wqe_index, qpn,
                            ctrl_wqe_index);
                return -EFAULT;
        }
 
        ctrl_qpn = (be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_QPN_MASK) >>
                MLX5_WQE_CTRL_QPN_SHIFT;
-       if (qp->mqp.qpn != ctrl_qpn) {
+       if (qpn != ctrl_qpn) {
                mlx5_ib_err(dev, "Got WQE with incorrect QP number. wqe_index=0x%x, qpn=0x%x ctrl->qpn=0x%x\n",
-                           wqe_index, qp->mqp.qpn,
+                           wqe_index, qpn,
                            ctrl_qpn);
                return -EFAULT;
        }
@@ -537,6 +540,7 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_qp *qp,
        int resume_with_error = 0;
        u16 wqe_index = pfault->mpfault.wqe.wqe_index;
        int requestor = pfault->mpfault.flags & MLX5_PFAULT_REQUESTOR;
+       u32 qpn = qp->trans_qp.base.mqp.qpn;
 
        buffer = (char *)__get_free_page(GFP_KERNEL);
        if (!buffer) {
@@ -546,10 +550,10 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_qp *qp,
        }
 
        ret = mlx5_ib_read_user_wqe(qp, requestor, wqe_index, buffer,
-                                   PAGE_SIZE);
+                                   PAGE_SIZE, &qp->trans_qp.base);
        if (ret < 0) {
                mlx5_ib_err(dev, "Failed reading a WQE following page fault, error=%x, wqe_index=%x, qpn=%x\n",
-                           -ret, wqe_index, qp->mqp.qpn);
+                           -ret, wqe_index, qpn);
                resume_with_error = 1;
                goto resolve_page_fault;
        }
@@ -586,7 +590,8 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_qp *qp,
 resolve_page_fault:
        mlx5_ib_page_fault_resume(qp, pfault, resume_with_error);
        mlx5_ib_dbg(dev, "PAGE FAULT completed. QP 0x%x resume_with_error=%d, flags: 0x%x\n",
-                   qp->mqp.qpn, resume_with_error, pfault->mpfault.flags);
+                   qpn, resume_with_error,
+                   pfault->mpfault.flags);
 
        free_page((unsigned long)buffer);
 }
@@ -753,7 +758,7 @@ void mlx5_ib_odp_create_qp(struct mlx5_ib_qp *qp)
        qp->disable_page_faults = 1;
        spin_lock_init(&qp->disable_page_faults_lock);
 
-       qp->mqp.pfault_handler  = mlx5_ib_pfault_handler;
+       qp->trans_qp.base.mqp.pfault_handler = mlx5_ib_pfault_handler;
 
        for (i = 0; i < MLX5_IB_PAGEFAULT_CONTEXTS; ++i)
                INIT_WORK(&qp->pagefaults[i].work, mlx5_ib_qp_pfault_action);
index 307bdbc..8fb9c27 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <linux/module.h>
 #include <rdma/ib_umem.h>
+#include <rdma/ib_cache.h>
+#include <rdma/ib_user_verbs.h>
 #include "mlx5_ib.h"
 #include "user.h"
 
@@ -114,14 +116,15 @@ void *mlx5_get_send_wqe(struct mlx5_ib_qp *qp, int n)
  * Return: the number of bytes copied, or an error code.
  */
 int mlx5_ib_read_user_wqe(struct mlx5_ib_qp *qp, int send, int wqe_index,
-                         void *buffer, u32 length)
+                         void *buffer, u32 length,
+                         struct mlx5_ib_qp_base *base)
 {
        struct ib_device *ibdev = qp->ibqp.device;
        struct mlx5_ib_dev *dev = to_mdev(ibdev);
        struct mlx5_ib_wq *wq = send ? &qp->sq : &qp->rq;
        size_t offset;
        size_t wq_end;
-       struct ib_umem *umem = qp->umem;
+       struct ib_umem *umem = base->ubuffer.umem;
        u32 first_copy_length;
        int wqe_length;
        int ret;
@@ -172,8 +175,10 @@ static void mlx5_ib_qp_event(struct mlx5_core_qp *qp, int type)
        struct ib_qp *ibqp = &to_mibqp(qp)->ibqp;
        struct ib_event event;
 
-       if (type == MLX5_EVENT_TYPE_PATH_MIG)
-               to_mibqp(qp)->port = to_mibqp(qp)->alt_port;
+       if (type == MLX5_EVENT_TYPE_PATH_MIG) {
+               /* This event is only valid for trans_qps */
+               to_mibqp(qp)->port = to_mibqp(qp)->trans_qp.alt_port;
+       }
 
        if (ibqp->event_handler) {
                event.device     = ibqp->device;
@@ -366,7 +371,9 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
 
 static int set_user_buf_size(struct mlx5_ib_dev *dev,
                            struct mlx5_ib_qp *qp,
-                           struct mlx5_ib_create_qp *ucmd)
+                           struct mlx5_ib_create_qp *ucmd,
+                           struct mlx5_ib_qp_base *base,
+                           struct ib_qp_init_attr *attr)
 {
        int desc_sz = 1 << qp->sq.wqe_shift;
 
@@ -391,8 +398,13 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
                return -EINVAL;
        }
 
-       qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
-               (qp->sq.wqe_cnt << 6);
+       if (attr->qp_type == IB_QPT_RAW_PACKET) {
+               base->ubuffer.buf_size = qp->rq.wqe_cnt << qp->rq.wqe_shift;
+               qp->raw_packet_qp.sq.ubuffer.buf_size = qp->sq.wqe_cnt << 6;
+       } else {
+               base->ubuffer.buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
+                                        (qp->sq.wqe_cnt << 6);
+       }
 
        return 0;
 }
@@ -578,8 +590,8 @@ static int to_mlx5_st(enum ib_qp_type type)
        case IB_QPT_SMI:                return MLX5_QP_ST_QP0;
        case IB_QPT_GSI:                return MLX5_QP_ST_QP1;
        case IB_QPT_RAW_IPV6:           return MLX5_QP_ST_RAW_IPV6;
-       case IB_QPT_RAW_ETHERTYPE:      return MLX5_QP_ST_RAW_ETHERTYPE;
        case IB_QPT_RAW_PACKET:
+       case IB_QPT_RAW_ETHERTYPE:      return MLX5_QP_ST_RAW_ETHERTYPE;
        case IB_QPT_MAX:
        default:                return -EINVAL;
        }
@@ -590,13 +602,51 @@ static int uuarn_to_uar_index(struct mlx5_uuar_info *uuari, int uuarn)
        return uuari->uars[uuarn / MLX5_BF_REGS_PER_PAGE].index;
 }
 
+static int mlx5_ib_umem_get(struct mlx5_ib_dev *dev,
+                           struct ib_pd *pd,
+                           unsigned long addr, size_t size,
+                           struct ib_umem **umem,
+                           int *npages, int *page_shift, int *ncont,
+                           u32 *offset)
+{
+       int err;
+
+       *umem = ib_umem_get(pd->uobject->context, addr, size, 0, 0);
+       if (IS_ERR(*umem)) {
+               mlx5_ib_dbg(dev, "umem_get failed\n");
+               return PTR_ERR(*umem);
+       }
+
+       mlx5_ib_cont_pages(*umem, addr, npages, page_shift, ncont, NULL);
+
+       err = mlx5_ib_get_buf_offset(addr, *page_shift, offset);
+       if (err) {
+               mlx5_ib_warn(dev, "bad offset\n");
+               goto err_umem;
+       }
+
+       mlx5_ib_dbg(dev, "addr 0x%lx, size %zu, npages %d, page_shift %d, ncont %d, offset %d\n",
+                   addr, size, *npages, *page_shift, *ncont, *offset);
+
+       return 0;
+
+err_umem:
+       ib_umem_release(*umem);
+       *umem = NULL;
+
+       return err;
+}
+
 static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                          struct mlx5_ib_qp *qp, struct ib_udata *udata,
+                         struct ib_qp_init_attr *attr,
                          struct mlx5_create_qp_mbox_in **in,
-                         struct mlx5_ib_create_qp_resp *resp, int *inlen)
+                         struct mlx5_ib_create_qp_resp *resp, int *inlen,
+                         struct mlx5_ib_qp_base *base)
 {
        struct mlx5_ib_ucontext *context;
        struct mlx5_ib_create_qp ucmd;
+       struct mlx5_ib_ubuffer *ubuffer = &base->ubuffer;
        int page_shift = 0;
        int uar_index;
        int npages;
@@ -615,18 +665,23 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        /*
         * TBD: should come from the verbs when we have the API
         */
-       uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH);
-       if (uuarn < 0) {
-               mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n");
-               mlx5_ib_dbg(dev, "reverting to medium latency\n");
-               uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_MEDIUM);
+       if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL)
+               /* In CROSS_CHANNEL CQ and QP must use the same UAR */
+               uuarn = MLX5_CROSS_CHANNEL_UUAR;
+       else {
+               uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH);
                if (uuarn < 0) {
-                       mlx5_ib_dbg(dev, "failed to allocate medium latency UUAR\n");
-                       mlx5_ib_dbg(dev, "reverting to high latency\n");
-                       uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
+                       mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n");
+                       mlx5_ib_dbg(dev, "reverting to medium latency\n");
+                       uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_MEDIUM);
                        if (uuarn < 0) {
-                               mlx5_ib_warn(dev, "uuar allocation failed\n");
-                               return uuarn;
+                               mlx5_ib_dbg(dev, "failed to allocate medium latency UUAR\n");
+                               mlx5_ib_dbg(dev, "reverting to high latency\n");
+                               uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
+                               if (uuarn < 0) {
+                                       mlx5_ib_warn(dev, "uuar allocation failed\n");
+                                       return uuarn;
+                               }
                        }
                }
        }
@@ -638,32 +693,20 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
        qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
 
-       err = set_user_buf_size(dev, qp, &ucmd);
+       err = set_user_buf_size(dev, qp, &ucmd, base, attr);
        if (err)
                goto err_uuar;
 
-       if (ucmd.buf_addr && qp->buf_size) {
-               qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
-                                      qp->buf_size, 0, 0);
-               if (IS_ERR(qp->umem)) {
-                       mlx5_ib_dbg(dev, "umem_get failed\n");
-                       err = PTR_ERR(qp->umem);
+       if (ucmd.buf_addr && ubuffer->buf_size) {
+               ubuffer->buf_addr = ucmd.buf_addr;
+               err = mlx5_ib_umem_get(dev, pd, ubuffer->buf_addr,
+                                      ubuffer->buf_size,
+                                      &ubuffer->umem, &npages, &page_shift,
+                                      &ncont, &offset);
+               if (err)
                        goto err_uuar;
-               }
        } else {
-               qp->umem = NULL;
-       }
-
-       if (qp->umem) {
-               mlx5_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift,
-                                  &ncont, NULL);
-               err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift, &offset);
-               if (err) {
-                       mlx5_ib_warn(dev, "bad offset\n");
-                       goto err_umem;
-               }
-               mlx5_ib_dbg(dev, "addr 0x%llx, size %d, npages %d, page_shift %d, ncont %d, offset %d\n",
-                           ucmd.buf_addr, qp->buf_size, npages, page_shift, ncont, offset);
+               ubuffer->umem = NULL;
        }
 
        *inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
@@ -672,8 +715,9 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                err = -ENOMEM;
                goto err_umem;
        }
-       if (qp->umem)
-               mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0);
+       if (ubuffer->umem)
+               mlx5_ib_populate_pas(dev, ubuffer->umem, page_shift,
+                                    (*in)->pas, 0);
        (*in)->ctx.log_pg_sz_remote_qpn =
                cpu_to_be32((page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24);
        (*in)->ctx.params2 = cpu_to_be32(offset << 6);
@@ -704,29 +748,31 @@ err_free:
        kvfree(*in);
 
 err_umem:
-       if (qp->umem)
-               ib_umem_release(qp->umem);
+       if (ubuffer->umem)
+               ib_umem_release(ubuffer->umem);
 
 err_uuar:
        free_uuar(&context->uuari, uuarn);
        return err;
 }
 
-static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp)
+static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp,
+                           struct mlx5_ib_qp_base *base)
 {
        struct mlx5_ib_ucontext *context;
 
        context = to_mucontext(pd->uobject->context);
        mlx5_ib_db_unmap_user(context, &qp->db);
-       if (qp->umem)
-               ib_umem_release(qp->umem);
+       if (base->ubuffer.umem)
+               ib_umem_release(base->ubuffer.umem);
        free_uuar(&context->uuari, qp->uuarn);
 }
 
 static int create_kernel_qp(struct mlx5_ib_dev *dev,
                            struct ib_qp_init_attr *init_attr,
                            struct mlx5_ib_qp *qp,
-                           struct mlx5_create_qp_mbox_in **in, int *inlen)
+                           struct mlx5_create_qp_mbox_in **in, int *inlen,
+                           struct mlx5_ib_qp_base *base)
 {
        enum mlx5_ib_latency_class lc = MLX5_IB_LATENCY_CLASS_LOW;
        struct mlx5_uuar_info *uuari;
@@ -758,9 +804,9 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
 
        qp->rq.offset = 0;
        qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
-       qp->buf_size = err + (qp->rq.wqe_cnt << qp->rq.wqe_shift);
+       base->ubuffer.buf_size = err + (qp->rq.wqe_cnt << qp->rq.wqe_shift);
 
-       err = mlx5_buf_alloc(dev->mdev, qp->buf_size, &qp->buf);
+       err = mlx5_buf_alloc(dev->mdev, base->ubuffer.buf_size, &qp->buf);
        if (err) {
                mlx5_ib_dbg(dev, "err %d\n", err);
                goto err_uuar;
@@ -853,19 +899,304 @@ static int is_connected(enum ib_qp_type qp_type)
        return 0;
 }
 
+static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
+                                   struct mlx5_ib_sq *sq, u32 tdn)
+{
+       u32 in[MLX5_ST_SZ_DW(create_tis_in)];
+       void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
+
+       memset(in, 0, sizeof(in));
+
+       MLX5_SET(tisc, tisc, transport_domain, tdn);
+
+       return mlx5_core_create_tis(dev->mdev, in, sizeof(in), &sq->tisn);
+}
+
+static void destroy_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
+                                     struct mlx5_ib_sq *sq)
+{
+       mlx5_core_destroy_tis(dev->mdev, sq->tisn);
+}
+
+static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
+                                  struct mlx5_ib_sq *sq, void *qpin,
+                                  struct ib_pd *pd)
+{
+       struct mlx5_ib_ubuffer *ubuffer = &sq->ubuffer;
+       __be64 *pas;
+       void *in;
+       void *sqc;
+       void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
+       void *wq;
+       int inlen;
+       int err;
+       int page_shift = 0;
+       int npages;
+       int ncont = 0;
+       u32 offset = 0;
+
+       err = mlx5_ib_umem_get(dev, pd, ubuffer->buf_addr, ubuffer->buf_size,
+                              &sq->ubuffer.umem, &npages, &page_shift,
+                              &ncont, &offset);
+       if (err)
+               return err;
+
+       inlen = MLX5_ST_SZ_BYTES(create_sq_in) + sizeof(u64) * ncont;
+       in = mlx5_vzalloc(inlen);
+       if (!in) {
+               err = -ENOMEM;
+               goto err_umem;
+       }
+
+       sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
+       MLX5_SET(sqc, sqc, flush_in_error_en, 1);
+       MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
+       MLX5_SET(sqc, sqc, user_index, MLX5_GET(qpc, qpc, user_index));
+       MLX5_SET(sqc, sqc, cqn, MLX5_GET(qpc, qpc, cqn_snd));
+       MLX5_SET(sqc, sqc, tis_lst_sz, 1);
+       MLX5_SET(sqc, sqc, tis_num_0, sq->tisn);
+
+       wq = MLX5_ADDR_OF(sqc, sqc, wq);
+       MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
+       MLX5_SET(wq, wq, pd, MLX5_GET(qpc, qpc, pd));
+       MLX5_SET(wq, wq, uar_page, MLX5_GET(qpc, qpc, uar_page));
+       MLX5_SET64(wq, wq, dbr_addr, MLX5_GET64(qpc, qpc, dbr_addr));
+       MLX5_SET(wq, wq, log_wq_stride, ilog2(MLX5_SEND_WQE_BB));
+       MLX5_SET(wq, wq, log_wq_sz, MLX5_GET(qpc, qpc, log_sq_size));
+       MLX5_SET(wq, wq, log_wq_pg_sz,  page_shift - MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET(wq, wq, page_offset, offset);
+
+       pas = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);
+       mlx5_ib_populate_pas(dev, sq->ubuffer.umem, page_shift, pas, 0);
+
+       err = mlx5_core_create_sq_tracked(dev->mdev, in, inlen, &sq->base.mqp);
+
+       kvfree(in);
+
+       if (err)
+               goto err_umem;
+
+       return 0;
+
+err_umem:
+       ib_umem_release(sq->ubuffer.umem);
+       sq->ubuffer.umem = NULL;
+
+       return err;
+}
+
+static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
+                                    struct mlx5_ib_sq *sq)
+{
+       mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
+       ib_umem_release(sq->ubuffer.umem);
+}
+
+static int get_rq_pas_size(void *qpc)
+{
+       u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12;
+       u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride);
+       u32 log_rq_size   = MLX5_GET(qpc, qpc, log_rq_size);
+       u32 page_offset   = MLX5_GET(qpc, qpc, page_offset);
+       u32 po_quanta     = 1 << (log_page_size - 6);
+       u32 rq_sz         = 1 << (log_rq_size + 4 + log_rq_stride);
+       u32 page_size     = 1 << log_page_size;
+       u32 rq_sz_po      = rq_sz + (page_offset * po_quanta);
+       u32 rq_num_pas    = (rq_sz_po + page_size - 1) / page_size;
+
+       return rq_num_pas * sizeof(u64);
+}
+
+static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
+                                  struct mlx5_ib_rq *rq, void *qpin)
+{
+       __be64 *pas;
+       __be64 *qp_pas;
+       void *in;
+       void *rqc;
+       void *wq;
+       void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
+       int inlen;
+       int err;
+       u32 rq_pas_size = get_rq_pas_size(qpc);
+
+       inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size;
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
+       MLX5_SET(rqc, rqc, vsd, 1);
+       MLX5_SET(rqc, rqc, mem_rq_type, MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE);
+       MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);
+       MLX5_SET(rqc, rqc, flush_in_error_en, 1);
+       MLX5_SET(rqc, rqc, user_index, MLX5_GET(qpc, qpc, user_index));
+       MLX5_SET(rqc, rqc, cqn, MLX5_GET(qpc, qpc, cqn_rcv));
+
+       wq = MLX5_ADDR_OF(rqc, rqc, wq);
+       MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
+       MLX5_SET(wq, wq, end_padding_mode,
+                MLX5_GET64(qpc, qpc, end_padding_mode));
+       MLX5_SET(wq, wq, page_offset, MLX5_GET(qpc, qpc, page_offset));
+       MLX5_SET(wq, wq, pd, MLX5_GET(qpc, qpc, pd));
+       MLX5_SET64(wq, wq, dbr_addr, MLX5_GET64(qpc, qpc, dbr_addr));
+       MLX5_SET(wq, wq, log_wq_stride, MLX5_GET(qpc, qpc, log_rq_stride) + 4);
+       MLX5_SET(wq, wq, log_wq_pg_sz, MLX5_GET(qpc, qpc, log_page_size));
+       MLX5_SET(wq, wq, log_wq_sz, MLX5_GET(qpc, qpc, log_rq_size));
+
+       pas = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);
+       qp_pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, qpin, pas);
+       memcpy(pas, qp_pas, rq_pas_size);
+
+       err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rq->base.mqp);
+
+       kvfree(in);
+
+       return err;
+}
+
+static void destroy_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
+                                    struct mlx5_ib_rq *rq)
+{
+       mlx5_core_destroy_rq_tracked(dev->mdev, &rq->base.mqp);
+}
+
+static int create_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
+                                   struct mlx5_ib_rq *rq, u32 tdn)
+{
+       u32 *in;
+       void *tirc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(create_tir_in);
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
+       MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_DIRECT);
+       MLX5_SET(tirc, tirc, inline_rqn, rq->base.mqp.qpn);
+       MLX5_SET(tirc, tirc, transport_domain, tdn);
+
+       err = mlx5_core_create_tir(dev->mdev, in, inlen, &rq->tirn);
+
+       kvfree(in);
+
+       return err;
+}
+
+static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
+                                     struct mlx5_ib_rq *rq)
+{
+       mlx5_core_destroy_tir(dev->mdev, rq->tirn);
+}
+
+static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+                               struct mlx5_create_qp_mbox_in *in,
+                               struct ib_pd *pd)
+{
+       struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
+       struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
+       struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
+       struct ib_uobject *uobj = pd->uobject;
+       struct ib_ucontext *ucontext = uobj->context;
+       struct mlx5_ib_ucontext *mucontext = to_mucontext(ucontext);
+       int err;
+       u32 tdn = mucontext->tdn;
+
+       if (qp->sq.wqe_cnt) {
+               err = create_raw_packet_qp_tis(dev, sq, tdn);
+               if (err)
+                       return err;
+
+               err = create_raw_packet_qp_sq(dev, sq, in, pd);
+               if (err)
+                       goto err_destroy_tis;
+
+               sq->base.container_mibqp = qp;
+       }
+
+       if (qp->rq.wqe_cnt) {
+               err = create_raw_packet_qp_rq(dev, rq, in);
+               if (err)
+                       goto err_destroy_sq;
+
+               rq->base.container_mibqp = qp;
+
+               err = create_raw_packet_qp_tir(dev, rq, tdn);
+               if (err)
+                       goto err_destroy_rq;
+       }
+
+       qp->trans_qp.base.mqp.qpn = qp->sq.wqe_cnt ? sq->base.mqp.qpn :
+                                                    rq->base.mqp.qpn;
+
+       return 0;
+
+err_destroy_rq:
+       destroy_raw_packet_qp_rq(dev, rq);
+err_destroy_sq:
+       if (!qp->sq.wqe_cnt)
+               return err;
+       destroy_raw_packet_qp_sq(dev, sq);
+err_destroy_tis:
+       destroy_raw_packet_qp_tis(dev, sq);
+
+       return err;
+}
+
+static void destroy_raw_packet_qp(struct mlx5_ib_dev *dev,
+                                 struct mlx5_ib_qp *qp)
+{
+       struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
+       struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
+       struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
+
+       if (qp->rq.wqe_cnt) {
+               destroy_raw_packet_qp_tir(dev, rq);
+               destroy_raw_packet_qp_rq(dev, rq);
+       }
+
+       if (qp->sq.wqe_cnt) {
+               destroy_raw_packet_qp_sq(dev, sq);
+               destroy_raw_packet_qp_tis(dev, sq);
+       }
+}
+
+static void raw_packet_qp_copy_info(struct mlx5_ib_qp *qp,
+                                   struct mlx5_ib_raw_packet_qp *raw_packet_qp)
+{
+       struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
+       struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
+
+       sq->sq = &qp->sq;
+       rq->rq = &qp->rq;
+       sq->doorbell = &qp->db;
+       rq->doorbell = &qp->db;
+}
+
 static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                            struct ib_qp_init_attr *init_attr,
                            struct ib_udata *udata, struct mlx5_ib_qp *qp)
 {
        struct mlx5_ib_resources *devr = &dev->devr;
        struct mlx5_core_dev *mdev = dev->mdev;
+       struct mlx5_ib_qp_base *base;
        struct mlx5_ib_create_qp_resp resp;
        struct mlx5_create_qp_mbox_in *in;
        struct mlx5_ib_create_qp ucmd;
        int inlen = sizeof(*in);
        int err;
+       u32 uidx = MLX5_IB_DEFAULT_UIDX;
+       void *qpc;
+
+       base = init_attr->qp_type == IB_QPT_RAW_PACKET ?
+              &qp->raw_packet_qp.rq.base :
+              &qp->trans_qp.base;
 
-       mlx5_ib_odp_create_qp(qp);
+       if (init_attr->qp_type != IB_QPT_RAW_PACKET)
+               mlx5_ib_odp_create_qp(qp);
 
        mutex_init(&qp->mutex);
        spin_lock_init(&qp->sq.lock);
@@ -880,6 +1211,21 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                }
        }
 
+       if (init_attr->create_flags &
+                       (IB_QP_CREATE_CROSS_CHANNEL |
+                        IB_QP_CREATE_MANAGED_SEND |
+                        IB_QP_CREATE_MANAGED_RECV)) {
+               if (!MLX5_CAP_GEN(mdev, cd)) {
+                       mlx5_ib_dbg(dev, "cross-channel isn't supported\n");
+                       return -EINVAL;
+               }
+               if (init_attr->create_flags & IB_QP_CREATE_CROSS_CHANNEL)
+                       qp->flags |= MLX5_IB_QP_CROSS_CHANNEL;
+               if (init_attr->create_flags & IB_QP_CREATE_MANAGED_SEND)
+                       qp->flags |= MLX5_IB_QP_MANAGED_SEND;
+               if (init_attr->create_flags & IB_QP_CREATE_MANAGED_RECV)
+                       qp->flags |= MLX5_IB_QP_MANAGED_RECV;
+       }
        if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
                qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
 
@@ -889,6 +1235,11 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                        return -EFAULT;
                }
 
+               err = get_qp_user_index(to_mucontext(pd->uobject->context),
+                                       &ucmd, udata->inlen, &uidx);
+               if (err)
+                       return err;
+
                qp->wq_sig = !!(ucmd.flags & MLX5_QP_FLAG_SIGNATURE);
                qp->scat_cqe = !!(ucmd.flags & MLX5_QP_FLAG_SCATTER_CQE);
        } else {
@@ -918,11 +1269,13 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                                            ucmd.sq_wqe_count, max_wqes);
                                return -EINVAL;
                        }
-                       err = create_user_qp(dev, pd, qp, udata, &in, &resp, &inlen);
+                       err = create_user_qp(dev, pd, qp, udata, init_attr, &in,
+                                            &resp, &inlen, base);
                        if (err)
                                mlx5_ib_dbg(dev, "err %d\n", err);
                } else {
-                       err = create_kernel_qp(dev, init_attr, qp, &in, &inlen);
+                       err = create_kernel_qp(dev, init_attr, qp, &in, &inlen,
+                                              base);
                        if (err)
                                mlx5_ib_dbg(dev, "err %d\n", err);
                }
@@ -954,6 +1307,13 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
                in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_BLOCK_MCAST);
 
+       if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL)
+               in->ctx.params2 |= cpu_to_be32(MLX5_QP_BIT_CC_MASTER);
+       if (qp->flags & MLX5_IB_QP_MANAGED_SEND)
+               in->ctx.params2 |= cpu_to_be32(MLX5_QP_BIT_CC_SLAVE_SEND);
+       if (qp->flags & MLX5_IB_QP_MANAGED_RECV)
+               in->ctx.params2 |= cpu_to_be32(MLX5_QP_BIT_CC_SLAVE_RECV);
+
        if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
                int rcqe_sz;
                int scqe_sz;
@@ -1018,26 +1378,35 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
 
        in->ctx.db_rec_addr = cpu_to_be64(qp->db.dma);
 
-       err = mlx5_core_create_qp(dev->mdev, &qp->mqp, in, inlen);
+       if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1) {
+               qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
+               /* 0xffffff means we ask to work with cqe version 0 */
+               MLX5_SET(qpc, qpc, user_index, uidx);
+       }
+
+       if (init_attr->qp_type == IB_QPT_RAW_PACKET) {
+               qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
+               raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
+               err = create_raw_packet_qp(dev, qp, in, pd);
+       } else {
+               err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
+       }
+
        if (err) {
                mlx5_ib_dbg(dev, "create qp failed\n");
                goto err_create;
        }
 
        kvfree(in);
-       /* Hardware wants QPN written in big-endian order (after
-        * shifting) for send doorbell.  Precompute this value to save
-        * a little bit when posting sends.
-        */
-       qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
 
-       qp->mqp.event = mlx5_ib_qp_event;
+       base->container_mibqp = qp;
+       base->mqp.event = mlx5_ib_qp_event;
 
        return 0;
 
 err_create:
        if (qp->create_type == MLX5_QP_USER)
-               destroy_qp_user(pd, qp);
+               destroy_qp_user(pd, qp, base);
        else if (qp->create_type == MLX5_QP_KERNEL)
                destroy_qp_kernel(dev, qp);
 
@@ -1129,11 +1498,11 @@ static void get_cqs(struct mlx5_ib_qp *qp,
        case IB_QPT_UD:
        case IB_QPT_RAW_IPV6:
        case IB_QPT_RAW_ETHERTYPE:
+       case IB_QPT_RAW_PACKET:
                *send_cq = to_mcq(qp->ibqp.send_cq);
                *recv_cq = to_mcq(qp->ibqp.recv_cq);
                break;
 
-       case IB_QPT_RAW_PACKET:
        case IB_QPT_MAX:
        default:
                *send_cq = NULL;
@@ -1142,45 +1511,66 @@ static void get_cqs(struct mlx5_ib_qp *qp,
        }
 }
 
+static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+                               u16 operation);
+
 static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 {
        struct mlx5_ib_cq *send_cq, *recv_cq;
+       struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
        struct mlx5_modify_qp_mbox_in *in;
        int err;
 
+       base = qp->ibqp.qp_type == IB_QPT_RAW_PACKET ?
+              &qp->raw_packet_qp.rq.base :
+              &qp->trans_qp.base;
+
        in = kzalloc(sizeof(*in), GFP_KERNEL);
        if (!in)
                return;
 
        if (qp->state != IB_QPS_RESET) {
-               mlx5_ib_qp_disable_pagefaults(qp);
-               if (mlx5_core_qp_modify(dev->mdev, to_mlx5_state(qp->state),
-                                       MLX5_QP_STATE_RST, in, 0, &qp->mqp))
-                       mlx5_ib_warn(dev, "mlx5_ib: modify QP %06x to RESET failed\n",
-                                    qp->mqp.qpn);
+               if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET) {
+                       mlx5_ib_qp_disable_pagefaults(qp);
+                       err = mlx5_core_qp_modify(dev->mdev,
+                                                 MLX5_CMD_OP_2RST_QP, in, 0,
+                                                 &base->mqp);
+               } else {
+                       err = modify_raw_packet_qp(dev, qp,
+                                                  MLX5_CMD_OP_2RST_QP);
+               }
+               if (err)
+                       mlx5_ib_warn(dev, "mlx5_ib: modify QP 0x%06x to RESET failed\n",
+                                    base->mqp.qpn);
        }
 
        get_cqs(qp, &send_cq, &recv_cq);
 
        if (qp->create_type == MLX5_QP_KERNEL) {
                mlx5_ib_lock_cqs(send_cq, recv_cq);
-               __mlx5_ib_cq_clean(recv_cq, qp->mqp.qpn,
+               __mlx5_ib_cq_clean(recv_cq, base->mqp.qpn,
                                   qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
                if (send_cq != recv_cq)
-                       __mlx5_ib_cq_clean(send_cq, qp->mqp.qpn, NULL);
+                       __mlx5_ib_cq_clean(send_cq, base->mqp.qpn,
+                                          NULL);
                mlx5_ib_unlock_cqs(send_cq, recv_cq);
        }
 
-       err = mlx5_core_destroy_qp(dev->mdev, &qp->mqp);
-       if (err)
-               mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n", qp->mqp.qpn);
-       kfree(in);
+       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+               destroy_raw_packet_qp(dev, qp);
+       } else {
+               err = mlx5_core_destroy_qp(dev->mdev, &base->mqp);
+               if (err)
+                       mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n",
+                                    base->mqp.qpn);
+       }
 
+       kfree(in);
 
        if (qp->create_type == MLX5_QP_KERNEL)
                destroy_qp_kernel(dev, qp);
        else if (qp->create_type == MLX5_QP_USER)
-               destroy_qp_user(&get_pd(qp)->ibpd, qp);
+               destroy_qp_user(&get_pd(qp)->ibpd, qp, base);
 }
 
 static const char *ib_qp_type_str(enum ib_qp_type type)
@@ -1234,6 +1624,16 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
                        return ERR_PTR(-EINVAL);
                }
                dev = to_mdev(to_mxrcd(init_attr->xrcd)->ibxrcd.device);
+
+               if (init_attr->qp_type == IB_QPT_RAW_PACKET) {
+                       if (!pd->uobject) {
+                               mlx5_ib_dbg(dev, "Raw Packet QP is not supported for kernel consumers\n");
+                               return ERR_PTR(-EINVAL);
+                       } else if (!to_mucontext(pd->uobject->context)->cqe_version) {
+                               mlx5_ib_dbg(dev, "Raw Packet QP is only supported for CQE version > 0\n");
+                               return ERR_PTR(-EINVAL);
+                       }
+               }
        }
 
        switch (init_attr->qp_type) {
@@ -1250,6 +1650,7 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
                }
 
                /* fall through */
+       case IB_QPT_RAW_PACKET:
        case IB_QPT_RC:
        case IB_QPT_UC:
        case IB_QPT_UD:
@@ -1272,19 +1673,19 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
                else if (is_qp1(init_attr->qp_type))
                        qp->ibqp.qp_num = 1;
                else
-                       qp->ibqp.qp_num = qp->mqp.qpn;
+                       qp->ibqp.qp_num = qp->trans_qp.base.mqp.qpn;
 
                mlx5_ib_dbg(dev, "ib qpnum 0x%x, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x\n",
-                           qp->ibqp.qp_num, qp->mqp.qpn, to_mcq(init_attr->recv_cq)->mcq.cqn,
+                           qp->ibqp.qp_num, qp->trans_qp.base.mqp.qpn,
+                           to_mcq(init_attr->recv_cq)->mcq.cqn,
                            to_mcq(init_attr->send_cq)->mcq.cqn);
 
-               qp->xrcdn = xrcdn;
+               qp->trans_qp.xrcdn = xrcdn;
 
                break;
 
        case IB_QPT_RAW_IPV6:
        case IB_QPT_RAW_ETHERTYPE:
-       case IB_QPT_RAW_PACKET:
        case IB_QPT_MAX:
        default:
                mlx5_ib_dbg(dev, "unsupported qp type %d\n",
@@ -1318,12 +1719,12 @@ static __be32 to_mlx5_access_flags(struct mlx5_ib_qp *qp, const struct ib_qp_att
        if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
                dest_rd_atomic = attr->max_dest_rd_atomic;
        else
-               dest_rd_atomic = qp->resp_depth;
+               dest_rd_atomic = qp->trans_qp.resp_depth;
 
        if (attr_mask & IB_QP_ACCESS_FLAGS)
                access_flags = attr->qp_access_flags;
        else
-               access_flags = qp->atomic_rd_en;
+               access_flags = qp->trans_qp.atomic_rd_en;
 
        if (!dest_rd_atomic)
                access_flags &= IB_ACCESS_REMOTE_WRITE;
@@ -1360,21 +1761,42 @@ static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
        return rate + MLX5_STAT_RATE_OFFSET;
 }
 
-static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
+static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev,
+                                     struct mlx5_ib_sq *sq, u8 sl)
+{
+       void *in;
+       void *tisc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(modify_tis_in);
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(modify_tis_in, in, bitmask.prio, 1);
+
+       tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx);
+       MLX5_SET(tisc, tisc, prio, ((sl & 0x7) << 1));
+
+       err = mlx5_core_modify_tis(dev, sq->tisn, in, inlen);
+
+       kvfree(in);
+
+       return err;
+}
+
+static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+                        const struct ib_ah_attr *ah,
                         struct mlx5_qp_path *path, u8 port, int attr_mask,
                         u32 path_flags, const struct ib_qp_attr *attr)
 {
+       enum rdma_link_layer ll = rdma_port_get_link_layer(&dev->ib_dev, port);
        int err;
 
-       path->fl = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
-       path->free_ar = (path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x80 : 0;
-
        if (attr_mask & IB_QP_PKEY_INDEX)
                path->pkey_index = attr->pkey_index;
 
-       path->grh_mlid  = ah->src_path_bits & 0x7f;
-       path->rlid      = cpu_to_be16(ah->dlid);
-
        if (ah->ah_flags & IB_AH_GRH) {
                if (ah->grh.sgid_index >=
                    dev->mdev->port_caps[port - 1].gid_table_len) {
@@ -1383,7 +1805,27 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
                               dev->mdev->port_caps[port - 1].gid_table_len);
                        return -EINVAL;
                }
-               path->grh_mlid |= 1 << 7;
+       }
+
+       if (ll == IB_LINK_LAYER_ETHERNET) {
+               if (!(ah->ah_flags & IB_AH_GRH))
+                       return -EINVAL;
+               memcpy(path->rmac, ah->dmac, sizeof(ah->dmac));
+               path->udp_sport = mlx5_get_roce_udp_sport(dev, port,
+                                                         ah->grh.sgid_index);
+               path->dci_cfi_prio_sl = (ah->sl & 0x7) << 4;
+       } else {
+               path->fl = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
+               path->free_ar = (path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x80 :
+                                                                       0;
+               path->rlid = cpu_to_be16(ah->dlid);
+               path->grh_mlid = ah->src_path_bits & 0x7f;
+               if (ah->ah_flags & IB_AH_GRH)
+                       path->grh_mlid  |= 1 << 7;
+               path->dci_cfi_prio_sl = ah->sl & 0xf;
+       }
+
+       if (ah->ah_flags & IB_AH_GRH) {
                path->mgid_index = ah->grh.sgid_index;
                path->hop_limit  = ah->grh.hop_limit;
                path->tclass_flowlabel =
@@ -1401,7 +1843,10 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
        if (attr_mask & IB_QP_TIMEOUT)
                path->ackto_lt = attr->timeout << 3;
 
-       path->sl = ah->sl & 0xf;
+       if ((qp->ibqp.qp_type == IB_QPT_RAW_PACKET) && qp->sq.wqe_cnt)
+               return modify_raw_packet_eth_prio(dev->mdev,
+                                                 &qp->raw_packet_qp.sq,
+                                                 ah->sl & 0xf);
 
        return 0;
 }
@@ -1549,12 +1994,154 @@ static int ib_mask_to_mlx5_opt(int ib_mask)
        return result;
 }
 
+static int modify_raw_packet_qp_rq(struct mlx5_core_dev *dev,
+                                  struct mlx5_ib_rq *rq, int new_state)
+{
+       void *in;
+       void *rqc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(modify_rq_in, in, rq_state, rq->state);
+
+       rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
+       MLX5_SET(rqc, rqc, state, new_state);
+
+       err = mlx5_core_modify_rq(dev, rq->base.mqp.qpn, in, inlen);
+       if (err)
+               goto out;
+
+       rq->state = new_state;
+
+out:
+       kvfree(in);
+       return err;
+}
+
+static int modify_raw_packet_qp_sq(struct mlx5_core_dev *dev,
+                                  struct mlx5_ib_sq *sq, int new_state)
+{
+       void *in;
+       void *sqc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(modify_sq_in);
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(modify_sq_in, in, sq_state, sq->state);
+
+       sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
+       MLX5_SET(sqc, sqc, state, new_state);
+
+       err = mlx5_core_modify_sq(dev, sq->base.mqp.qpn, in, inlen);
+       if (err)
+               goto out;
+
+       sq->state = new_state;
+
+out:
+       kvfree(in);
+       return err;
+}
+
+static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+                               u16 operation)
+{
+       struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
+       struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
+       struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
+       int rq_state;
+       int sq_state;
+       int err;
+
+       switch (operation) {
+       case MLX5_CMD_OP_RST2INIT_QP:
+               rq_state = MLX5_RQC_STATE_RDY;
+               sq_state = MLX5_SQC_STATE_RDY;
+               break;
+       case MLX5_CMD_OP_2ERR_QP:
+               rq_state = MLX5_RQC_STATE_ERR;
+               sq_state = MLX5_SQC_STATE_ERR;
+               break;
+       case MLX5_CMD_OP_2RST_QP:
+               rq_state = MLX5_RQC_STATE_RST;
+               sq_state = MLX5_SQC_STATE_RST;
+               break;
+       case MLX5_CMD_OP_INIT2INIT_QP:
+       case MLX5_CMD_OP_INIT2RTR_QP:
+       case MLX5_CMD_OP_RTR2RTS_QP:
+       case MLX5_CMD_OP_RTS2RTS_QP:
+               /* Nothing to do here... */
+               return 0;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       if (qp->rq.wqe_cnt) {
+               err =  modify_raw_packet_qp_rq(dev->mdev, rq, rq_state);
+               if (err)
+                       return err;
+       }
+
+       if (qp->sq.wqe_cnt)
+               return modify_raw_packet_qp_sq(dev->mdev, sq, sq_state);
+
+       return 0;
+}
+
 static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                               const struct ib_qp_attr *attr, int attr_mask,
                               enum ib_qp_state cur_state, enum ib_qp_state new_state)
 {
+       static const u16 optab[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE] = {
+               [MLX5_QP_STATE_RST] = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+                       [MLX5_QP_STATE_INIT]    = MLX5_CMD_OP_RST2INIT_QP,
+               },
+               [MLX5_QP_STATE_INIT]  = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+                       [MLX5_QP_STATE_INIT]    = MLX5_CMD_OP_INIT2INIT_QP,
+                       [MLX5_QP_STATE_RTR]     = MLX5_CMD_OP_INIT2RTR_QP,
+               },
+               [MLX5_QP_STATE_RTR]   = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+                       [MLX5_QP_STATE_RTS]     = MLX5_CMD_OP_RTR2RTS_QP,
+               },
+               [MLX5_QP_STATE_RTS]   = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+                       [MLX5_QP_STATE_RTS]     = MLX5_CMD_OP_RTS2RTS_QP,
+               },
+               [MLX5_QP_STATE_SQD] = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+               },
+               [MLX5_QP_STATE_SQER] = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+                       [MLX5_QP_STATE_RTS]     = MLX5_CMD_OP_SQERR2RTS_QP,
+               },
+               [MLX5_QP_STATE_ERR] = {
+                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
+                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
+               }
+       };
+
        struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
        struct mlx5_ib_qp *qp = to_mqp(ibqp);
+       struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
        struct mlx5_ib_cq *send_cq, *recv_cq;
        struct mlx5_qp_context *context;
        struct mlx5_modify_qp_mbox_in *in;
@@ -1564,6 +2151,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        int sqd_event;
        int mlx5_st;
        int err;
+       u16 op;
 
        in = kzalloc(sizeof(*in), GFP_KERNEL);
        if (!in)
@@ -1623,7 +2211,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                context->pri_path.port = attr->port_num;
 
        if (attr_mask & IB_QP_AV) {
-               err = mlx5_set_path(dev, &attr->ah_attr, &context->pri_path,
+               err = mlx5_set_path(dev, qp, &attr->ah_attr, &context->pri_path,
                                    attr_mask & IB_QP_PORT ? attr->port_num : qp->port,
                                    attr_mask, 0, attr);
                if (err)
@@ -1634,7 +2222,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                context->pri_path.ackto_lt |= attr->timeout << 3;
 
        if (attr_mask & IB_QP_ALT_PATH) {
-               err = mlx5_set_path(dev, &attr->alt_ah_attr, &context->alt_path,
+               err = mlx5_set_path(dev, qp, &attr->alt_ah_attr,
+                                   &context->alt_path,
                                    attr->alt_port_num, attr_mask, 0, attr);
                if (err)
                        goto out;
@@ -1706,41 +2295,51 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
         * again to RTS, and may cause the driver and the device to get out of
         * sync. */
        if (cur_state != IB_QPS_RESET && cur_state != IB_QPS_ERR &&
-           (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR))
+           (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR) &&
+           (qp->ibqp.qp_type != IB_QPT_RAW_PACKET))
                mlx5_ib_qp_disable_pagefaults(qp);
 
+       if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||
+           !optab[mlx5_cur][mlx5_new])
+               goto out;
+
+       op = optab[mlx5_cur][mlx5_new];
        optpar = ib_mask_to_mlx5_opt(attr_mask);
        optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st];
        in->optparam = cpu_to_be32(optpar);
-       err = mlx5_core_qp_modify(dev->mdev, to_mlx5_state(cur_state),
-                                 to_mlx5_state(new_state), in, sqd_event,
-                                 &qp->mqp);
+
+       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET)
+               err = modify_raw_packet_qp(dev, qp, op);
+       else
+               err = mlx5_core_qp_modify(dev->mdev, op, in, sqd_event,
+                                         &base->mqp);
        if (err)
                goto out;
 
-       if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+       if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT &&
+           (qp->ibqp.qp_type != IB_QPT_RAW_PACKET))
                mlx5_ib_qp_enable_pagefaults(qp);
 
        qp->state = new_state;
 
        if (attr_mask & IB_QP_ACCESS_FLAGS)
-               qp->atomic_rd_en = attr->qp_access_flags;
+               qp->trans_qp.atomic_rd_en = attr->qp_access_flags;
        if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
-               qp->resp_depth = attr->max_dest_rd_atomic;
+               qp->trans_qp.resp_depth = attr->max_dest_rd_atomic;
        if (attr_mask & IB_QP_PORT)
                qp->port = attr->port_num;
        if (attr_mask & IB_QP_ALT_PATH)
-               qp->alt_port = attr->alt_port_num;
+               qp->trans_qp.alt_port = attr->alt_port_num;
 
        /*
         * If we moved a kernel QP to RESET, clean up all old CQ
         * entries and reinitialize the QP.
         */
        if (new_state == IB_QPS_RESET && !ibqp->uobject) {
-               mlx5_ib_cq_clean(recv_cq, qp->mqp.qpn,
+               mlx5_ib_cq_clean(recv_cq, base->mqp.qpn,
                                 ibqp->srq ? to_msrq(ibqp->srq) : NULL);
                if (send_cq != recv_cq)
-                       mlx5_ib_cq_clean(send_cq, qp->mqp.qpn, NULL);
+                       mlx5_ib_cq_clean(send_cq, base->mqp.qpn, NULL);
 
                qp->rq.head = 0;
                qp->rq.tail = 0;
@@ -1765,15 +2364,21 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        enum ib_qp_state cur_state, new_state;
        int err = -EINVAL;
        int port;
+       enum rdma_link_layer ll = IB_LINK_LAYER_UNSPECIFIED;
 
        mutex_lock(&qp->mutex);
 
        cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
        new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
 
+       if (!(cur_state == new_state && cur_state == IB_QPS_RESET)) {
+               port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
+               ll = dev->ib_dev.get_link_layer(&dev->ib_dev, port);
+       }
+
        if (ibqp->qp_type != MLX5_IB_QPT_REG_UMR &&
            !ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask,
-                               IB_LINK_LAYER_UNSPECIFIED))
+                               ll))
                goto out;
 
        if ((attr_mask & IB_QP_PORT) &&
@@ -2570,7 +3175,7 @@ static void finish_wqe(struct mlx5_ib_qp *qp,
 
        ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8) |
                                             mlx5_opcode | ((u32)opmod << 24));
-       ctrl->qpn_ds = cpu_to_be32(size | (qp->mqp.qpn << 8));
+       ctrl->qpn_ds = cpu_to_be32(size | (qp->trans_qp.base.mqp.qpn << 8));
        ctrl->fm_ce_se |= fence;
        qp->fm_cache = next_fence;
        if (unlikely(qp->wq_sig))
@@ -3003,7 +3608,7 @@ static void to_ib_ah_attr(struct mlx5_ib_dev *ibdev, struct ib_ah_attr *ib_ah_at
            ib_ah_attr->port_num > MLX5_CAP_GEN(dev, num_ports))
                return;
 
-       ib_ah_attr->sl = path->sl & 0xf;
+       ib_ah_attr->sl = path->dci_cfi_prio_sl & 0xf;
 
        ib_ah_attr->dlid          = be16_to_cpu(path->rlid);
        ib_ah_attr->src_path_bits = path->grh_mlid & 0x7f;
@@ -3021,39 +3626,153 @@ static void to_ib_ah_attr(struct mlx5_ib_dev *ibdev, struct ib_ah_attr *ib_ah_at
        }
 }
 
-int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
-                    struct ib_qp_init_attr *qp_init_attr)
+static int query_raw_packet_qp_sq_state(struct mlx5_ib_dev *dev,
+                                       struct mlx5_ib_sq *sq,
+                                       u8 *sq_state)
+{
+       void *out;
+       void *sqc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(query_sq_out);
+       out = mlx5_vzalloc(inlen);
+       if (!out)
+               return -ENOMEM;
+
+       err = mlx5_core_query_sq(dev->mdev, sq->base.mqp.qpn, out);
+       if (err)
+               goto out;
+
+       sqc = MLX5_ADDR_OF(query_sq_out, out, sq_context);
+       *sq_state = MLX5_GET(sqc, sqc, state);
+       sq->state = *sq_state;
+
+out:
+       kvfree(out);
+       return err;
+}
+
+static int query_raw_packet_qp_rq_state(struct mlx5_ib_dev *dev,
+                                       struct mlx5_ib_rq *rq,
+                                       u8 *rq_state)
+{
+       void *out;
+       void *rqc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(query_rq_out);
+       out = mlx5_vzalloc(inlen);
+       if (!out)
+               return -ENOMEM;
+
+       err = mlx5_core_query_rq(dev->mdev, rq->base.mqp.qpn, out);
+       if (err)
+               goto out;
+
+       rqc = MLX5_ADDR_OF(query_rq_out, out, rq_context);
+       *rq_state = MLX5_GET(rqc, rqc, state);
+       rq->state = *rq_state;
+
+out:
+       kvfree(out);
+       return err;
+}
+
+static int sqrq_state_to_qp_state(u8 sq_state, u8 rq_state,
+                                 struct mlx5_ib_qp *qp, u8 *qp_state)
+{
+       static const u8 sqrq_trans[MLX5_RQ_NUM_STATE][MLX5_SQ_NUM_STATE] = {
+               [MLX5_RQC_STATE_RST] = {
+                       [MLX5_SQC_STATE_RST]    = IB_QPS_RESET,
+                       [MLX5_SQC_STATE_RDY]    = MLX5_QP_STATE_BAD,
+                       [MLX5_SQC_STATE_ERR]    = MLX5_QP_STATE_BAD,
+                       [MLX5_SQ_STATE_NA]      = IB_QPS_RESET,
+               },
+               [MLX5_RQC_STATE_RDY] = {
+                       [MLX5_SQC_STATE_RST]    = MLX5_QP_STATE_BAD,
+                       [MLX5_SQC_STATE_RDY]    = MLX5_QP_STATE,
+                       [MLX5_SQC_STATE_ERR]    = IB_QPS_SQE,
+                       [MLX5_SQ_STATE_NA]      = MLX5_QP_STATE,
+               },
+               [MLX5_RQC_STATE_ERR] = {
+                       [MLX5_SQC_STATE_RST]    = MLX5_QP_STATE_BAD,
+                       [MLX5_SQC_STATE_RDY]    = MLX5_QP_STATE_BAD,
+                       [MLX5_SQC_STATE_ERR]    = IB_QPS_ERR,
+                       [MLX5_SQ_STATE_NA]      = IB_QPS_ERR,
+               },
+               [MLX5_RQ_STATE_NA] = {
+                       [MLX5_SQC_STATE_RST]    = IB_QPS_RESET,
+                       [MLX5_SQC_STATE_RDY]    = MLX5_QP_STATE,
+                       [MLX5_SQC_STATE_ERR]    = MLX5_QP_STATE,
+                       [MLX5_SQ_STATE_NA]      = MLX5_QP_STATE_BAD,
+               },
+       };
+
+       *qp_state = sqrq_trans[rq_state][sq_state];
+
+       if (*qp_state == MLX5_QP_STATE_BAD) {
+               WARN(1, "Buggy Raw Packet QP state, SQ 0x%x state: 0x%x, RQ 0x%x state: 0x%x",
+                    qp->raw_packet_qp.sq.base.mqp.qpn, sq_state,
+                    qp->raw_packet_qp.rq.base.mqp.qpn, rq_state);
+               return -EINVAL;
+       }
+
+       if (*qp_state == MLX5_QP_STATE)
+               *qp_state = qp->state;
+
+       return 0;
+}
+
+static int query_raw_packet_qp_state(struct mlx5_ib_dev *dev,
+                                    struct mlx5_ib_qp *qp,
+                                    u8 *raw_packet_qp_state)
+{
+       struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
+       struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
+       struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
+       int err;
+       u8 sq_state = MLX5_SQ_STATE_NA;
+       u8 rq_state = MLX5_RQ_STATE_NA;
+
+       if (qp->sq.wqe_cnt) {
+               err = query_raw_packet_qp_sq_state(dev, sq, &sq_state);
+               if (err)
+                       return err;
+       }
+
+       if (qp->rq.wqe_cnt) {
+               err = query_raw_packet_qp_rq_state(dev, rq, &rq_state);
+               if (err)
+                       return err;
+       }
+
+       return sqrq_state_to_qp_state(sq_state, rq_state, qp,
+                                     raw_packet_qp_state);
+}
+
+static int query_qp_attr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+                        struct ib_qp_attr *qp_attr)
 {
-       struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
-       struct mlx5_ib_qp *qp = to_mqp(ibqp);
        struct mlx5_query_qp_mbox_out *outb;
        struct mlx5_qp_context *context;
        int mlx5_state;
        int err = 0;
 
-#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
-       /*
-        * Wait for any outstanding page faults, in case the user frees memory
-        * based upon this query's result.
-        */
-       flush_workqueue(mlx5_ib_page_fault_wq);
-#endif
-
-       mutex_lock(&qp->mutex);
        outb = kzalloc(sizeof(*outb), GFP_KERNEL);
-       if (!outb) {
-               err = -ENOMEM;
-               goto out;
-       }
+       if (!outb)
+               return -ENOMEM;
+
        context = &outb->ctx;
-       err = mlx5_core_qp_query(dev->mdev, &qp->mqp, outb, sizeof(*outb));
+       err = mlx5_core_qp_query(dev->mdev, &qp->trans_qp.base.mqp, outb,
+                                sizeof(*outb));
        if (err)
-               goto out_free;
+               goto out;
 
        mlx5_state = be32_to_cpu(context->flags) >> 28;
 
        qp->state                    = to_ib_qp_state(mlx5_state);
-       qp_attr->qp_state            = qp->state;
        qp_attr->path_mtu            = context->mtu_msgmax >> 5;
        qp_attr->path_mig_state      =
                to_ib_mig_state((be32_to_cpu(context->flags) >> 11) & 0x3);
@@ -3087,6 +3806,43 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
        qp_attr->retry_cnt          = (be32_to_cpu(context->params1) >> 16) & 0x7;
        qp_attr->rnr_retry          = (be32_to_cpu(context->params1) >> 13) & 0x7;
        qp_attr->alt_timeout        = context->alt_path.ackto_lt >> 3;
+
+out:
+       kfree(outb);
+       return err;
+}
+
+int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+                    int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
+{
+       struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+       struct mlx5_ib_qp *qp = to_mqp(ibqp);
+       int err = 0;
+       u8 raw_packet_qp_state;
+
+#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
+       /*
+        * Wait for any outstanding page faults, in case the user frees memory
+        * based upon this query's result.
+        */
+       flush_workqueue(mlx5_ib_page_fault_wq);
+#endif
+
+       mutex_lock(&qp->mutex);
+
+       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+               err = query_raw_packet_qp_state(dev, qp, &raw_packet_qp_state);
+               if (err)
+                       goto out;
+               qp->state = raw_packet_qp_state;
+               qp_attr->port_num = 1;
+       } else {
+               err = query_qp_attr(dev, qp, qp_attr);
+               if (err)
+                       goto out;
+       }
+
+       qp_attr->qp_state            = qp->state;
        qp_attr->cur_qp_state        = qp_attr->qp_state;
        qp_attr->cap.max_recv_wr     = qp->rq.wqe_cnt;
        qp_attr->cap.max_recv_sge    = qp->rq.max_gs;
@@ -3110,12 +3866,16 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
        if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
                qp_init_attr->create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK;
 
+       if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL)
+               qp_init_attr->create_flags |= IB_QP_CREATE_CROSS_CHANNEL;
+       if (qp->flags & MLX5_IB_QP_MANAGED_SEND)
+               qp_init_attr->create_flags |= IB_QP_CREATE_MANAGED_SEND;
+       if (qp->flags & MLX5_IB_QP_MANAGED_RECV)
+               qp_init_attr->create_flags |= IB_QP_CREATE_MANAGED_RECV;
+
        qp_init_attr->sq_sig_type = qp->sq_signal_bits & MLX5_WQE_CTRL_CQ_UPDATE ?
                IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
 
-out_free:
-       kfree(outb);
-
 out:
        mutex_unlock(&qp->mutex);
        return err;
index e008505..4659256 100644 (file)
@@ -78,28 +78,41 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
                           struct ib_udata *udata, int buf_size, int *inlen)
 {
        struct mlx5_ib_dev *dev = to_mdev(pd->device);
-       struct mlx5_ib_create_srq ucmd;
+       struct mlx5_ib_create_srq ucmd = {};
        size_t ucmdlen;
+       void *xsrqc;
        int err;
        int npages;
        int page_shift;
        int ncont;
        u32 offset;
+       u32 uidx = MLX5_IB_DEFAULT_UIDX;
+       int drv_data = udata->inlen - sizeof(struct ib_uverbs_cmd_hdr);
 
-       ucmdlen =
-               (udata->inlen - sizeof(struct ib_uverbs_cmd_hdr) <
-                sizeof(ucmd)) ? (sizeof(ucmd) -
-                                 sizeof(ucmd.reserved)) : sizeof(ucmd);
+       if (drv_data < 0)
+               return -EINVAL;
+
+       ucmdlen = (drv_data < sizeof(ucmd)) ?
+                 drv_data : sizeof(ucmd);
 
        if (ib_copy_from_udata(&ucmd, udata, ucmdlen)) {
                mlx5_ib_dbg(dev, "failed copy udata\n");
                return -EFAULT;
        }
 
-       if (ucmdlen == sizeof(ucmd) &&
-           ucmd.reserved != 0)
+       if (ucmd.reserved0 || ucmd.reserved1)
                return -EINVAL;
 
+       if (drv_data > sizeof(ucmd) &&
+           !ib_is_udata_cleared(udata, sizeof(ucmd),
+                                drv_data - sizeof(ucmd)))
+               return -EINVAL;
+
+       err = get_srq_user_index(to_mucontext(pd->uobject->context),
+                                &ucmd, udata->inlen, &uidx);
+       if (err)
+               return err;
+
        srq->wq_sig = !!(ucmd.flags & MLX5_SRQ_FLAG_SIGNATURE);
 
        srq->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, buf_size,
@@ -138,6 +151,12 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
        (*in)->ctx.log_pg_sz = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
        (*in)->ctx.pgoff_cqn = cpu_to_be32(offset << 26);
 
+       if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1) {
+               xsrqc = MLX5_ADDR_OF(create_xrc_srq_in, *in,
+                                    xrc_srq_context_entry);
+               MLX5_SET(xrc_srqc, xsrqc, user_index, uidx);
+       }
+
        return 0;
 
 err_in:
@@ -158,6 +177,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
        struct mlx5_wqe_srq_next_seg *next;
        int page_shift;
        int npages;
+       void *xsrqc;
 
        err = mlx5_db_alloc(dev->mdev, &srq->db);
        if (err) {
@@ -204,6 +224,13 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
 
        (*in)->ctx.log_pg_sz = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
 
+       if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1) {
+               xsrqc = MLX5_ADDR_OF(create_xrc_srq_in, *in,
+                                    xrc_srq_context_entry);
+               /* 0xffffff means we ask to work with cqe version 0 */
+               MLX5_SET(xrc_srqc, xsrqc, user_index, MLX5_IB_DEFAULT_UIDX);
+       }
+
        return 0;
 
 err_in:
index 76fb7b9..b94a554 100644 (file)
@@ -35,6 +35,8 @@
 
 #include <linux/types.h>
 
+#include "mlx5_ib.h"
+
 enum {
        MLX5_QP_FLAG_SIGNATURE          = 1 << 0,
        MLX5_QP_FLAG_SCATTER_CQE        = 1 << 1,
@@ -66,7 +68,15 @@ struct mlx5_ib_alloc_ucontext_req_v2 {
        __u32   total_num_uuars;
        __u32   num_low_latency_uuars;
        __u32   flags;
-       __u32   reserved;
+       __u32   comp_mask;
+       __u8    max_cqe_version;
+       __u8    reserved0;
+       __u16   reserved1;
+       __u32   reserved2;
+};
+
+enum mlx5_ib_alloc_ucontext_resp_mask {
+       MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0,
 };
 
 struct mlx5_ib_alloc_ucontext_resp {
@@ -80,7 +90,13 @@ struct mlx5_ib_alloc_ucontext_resp {
        __u32   max_recv_wr;
        __u32   max_srq_recv_wr;
        __u16   num_ports;
-       __u16   reserved;
+       __u16   reserved1;
+       __u32   comp_mask;
+       __u32   response_length;
+       __u8    cqe_version;
+       __u8    reserved2;
+       __u16   reserved3;
+       __u64   hca_core_clock_offset;
 };
 
 struct mlx5_ib_alloc_pd_resp {
@@ -110,7 +126,9 @@ struct mlx5_ib_create_srq {
        __u64   buf_addr;
        __u64   db_addr;
        __u32   flags;
-       __u32   reserved; /* explicit padding (optional on i386) */
+       __u32   reserved0; /* explicit padding (optional on i386) */
+       __u32   uidx;
+       __u32   reserved1;
 };
 
 struct mlx5_ib_create_srq_resp {
@@ -125,9 +143,48 @@ struct mlx5_ib_create_qp {
        __u32   rq_wqe_count;
        __u32   rq_wqe_shift;
        __u32   flags;
+       __u32   uidx;
+       __u32   reserved0;
+       __u64   sq_buf_addr;
 };
 
 struct mlx5_ib_create_qp_resp {
        __u32   uuar_index;
 };
+
+static inline int get_qp_user_index(struct mlx5_ib_ucontext *ucontext,
+                                   struct mlx5_ib_create_qp *ucmd,
+                                   int inlen,
+                                   u32 *user_index)
+{
+       u8 cqe_version = ucontext->cqe_version;
+
+       if (field_avail(struct mlx5_ib_create_qp, uidx, inlen) &&
+           !cqe_version && (ucmd->uidx == MLX5_IB_DEFAULT_UIDX))
+               return 0;
+
+       if (!!(field_avail(struct mlx5_ib_create_qp, uidx, inlen) !=
+              !!cqe_version))
+               return -EINVAL;
+
+       return verify_assign_uidx(cqe_version, ucmd->uidx, user_index);
+}
+
+static inline int get_srq_user_index(struct mlx5_ib_ucontext *ucontext,
+                                    struct mlx5_ib_create_srq *ucmd,
+                                    int inlen,
+                                    u32 *user_index)
+{
+       u8 cqe_version = ucontext->cqe_version;
+
+       if (field_avail(struct mlx5_ib_create_srq, uidx, inlen) &&
+           !cqe_version && (ucmd->uidx == MLX5_IB_DEFAULT_UIDX))
+               return 0;
+
+       if (!!(field_avail(struct mlx5_ib_create_srq, uidx, inlen) !=
+              !!cqe_version))
+               return -EINVAL;
+
+       return verify_assign_uidx(cqe_version, ucmd->uidx, user_index);
+}
 #endif /* MLX5_IB_USER_H */
index 40ba833..a6531ff 100644 (file)
@@ -608,9 +608,6 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
                        entry->opcode    = IB_WC_FETCH_ADD;
                        entry->byte_len  = MTHCA_ATOMIC_BYTE_LEN;
                        break;
-               case MTHCA_OPCODE_BIND_MW:
-                       entry->opcode    = IB_WC_BIND_MW;
-                       break;
                default:
                        entry->opcode    = MTHCA_OPCODE_INVALID;
                        break;
index dc2d48c..9866c35 100644 (file)
@@ -898,89 +898,6 @@ static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc)
        return &mr->ibmr;
 }
 
-static struct ib_mr *mthca_reg_phys_mr(struct ib_pd       *pd,
-                                      struct ib_phys_buf *buffer_list,
-                                      int                 num_phys_buf,
-                                      int                 acc,
-                                      u64                *iova_start)
-{
-       struct mthca_mr *mr;
-       u64 *page_list;
-       u64 total_size;
-       unsigned long mask;
-       int shift;
-       int npages;
-       int err;
-       int i, j, n;
-
-       mask = buffer_list[0].addr ^ *iova_start;
-       total_size = 0;
-       for (i = 0; i < num_phys_buf; ++i) {
-               if (i != 0)
-                       mask |= buffer_list[i].addr;
-               if (i != num_phys_buf - 1)
-                       mask |= buffer_list[i].addr + buffer_list[i].size;
-
-               total_size += buffer_list[i].size;
-       }
-
-       if (mask & ~PAGE_MASK)
-               return ERR_PTR(-EINVAL);
-
-       shift = __ffs(mask | 1 << 31);
-
-       buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1);
-       buffer_list[0].addr &= ~0ull << shift;
-
-       mr = kmalloc(sizeof *mr, GFP_KERNEL);
-       if (!mr)
-               return ERR_PTR(-ENOMEM);
-
-       npages = 0;
-       for (i = 0; i < num_phys_buf; ++i)
-               npages += (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
-
-       if (!npages)
-               return &mr->ibmr;
-
-       page_list = kmalloc(npages * sizeof *page_list, GFP_KERNEL);
-       if (!page_list) {
-               kfree(mr);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       n = 0;
-       for (i = 0; i < num_phys_buf; ++i)
-               for (j = 0;
-                    j < (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
-                    ++j)
-                       page_list[n++] = buffer_list[i].addr + ((u64) j << shift);
-
-       mthca_dbg(to_mdev(pd->device), "Registering memory at %llx (iova %llx) "
-                 "in PD %x; shift %d, npages %d.\n",
-                 (unsigned long long) buffer_list[0].addr,
-                 (unsigned long long) *iova_start,
-                 to_mpd(pd)->pd_num,
-                 shift, npages);
-
-       err = mthca_mr_alloc_phys(to_mdev(pd->device),
-                                 to_mpd(pd)->pd_num,
-                                 page_list, shift, npages,
-                                 *iova_start, total_size,
-                                 convert_access(acc), mr);
-
-       if (err) {
-               kfree(page_list);
-               kfree(mr);
-               return ERR_PTR(err);
-       }
-
-       kfree(page_list);
-       mr->umem = NULL;
-
-       return &mr->ibmr;
-}
-
 static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                       u64 virt, int acc, struct ib_udata *udata)
 {
@@ -1346,7 +1263,6 @@ int mthca_register_device(struct mthca_dev *dev)
        dev->ib_dev.destroy_cq           = mthca_destroy_cq;
        dev->ib_dev.poll_cq              = mthca_poll_cq;
        dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
-       dev->ib_dev.reg_phys_mr          = mthca_reg_phys_mr;
        dev->ib_dev.reg_user_mr          = mthca_reg_user_mr;
        dev->ib_dev.dereg_mr             = mthca_dereg_mr;
        dev->ib_dev.get_port_immutable   = mthca_port_immutable;
index 35fe506..96e5fb9 100644 (file)
@@ -1485,7 +1485,7 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
        u16 pkey;
 
        ib_ud_header_init(256, /* assume a MAD */ 1, 0, 0,
-                         mthca_ah_grh_present(to_mah(wr->ah)), 0,
+                         mthca_ah_grh_present(to_mah(wr->ah)), 0, 0, 0,
                          &sqp->ud_header);
 
        err = mthca_read_ah(dev, to_mah(wr->ah), &sqp->ud_header);
index 8a3ad17..cb9f0f2 100644 (file)
@@ -134,7 +134,7 @@ static void record_ird_ord(struct nes_cm_node *, u16, u16);
 /* External CM API Interface */
 /* instance of function pointers for client API */
 /* set address of this instance to cm_core->cm_ops at cm_core alloc */
-static struct nes_cm_ops nes_cm_api = {
+static const struct nes_cm_ops nes_cm_api = {
        mini_cm_accelerated,
        mini_cm_listen,
        mini_cm_del_listen,
@@ -3232,7 +3232,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        int passive_state;
        struct nes_ib_device *nesibdev;
        struct ib_mr *ibmr = NULL;
-       struct ib_phys_buf ibphysbuf;
        struct nes_pd *nespd;
        u64 tagged_offset;
        u8 mpa_frame_offset = 0;
@@ -3316,21 +3315,19 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
                u64temp = (unsigned long)nesqp;
                nesibdev = nesvnic->nesibdev;
                nespd = nesqp->nespd;
-               ibphysbuf.addr = nesqp->ietf_frame_pbase + mpa_frame_offset;
-               ibphysbuf.size = buff_len;
                tagged_offset = (u64)(unsigned long)*start_buff;
-               ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
-                                                  &ibphysbuf, 1,
-                                                  IB_ACCESS_LOCAL_WRITE,
-                                                  &tagged_offset);
-               if (!ibmr) {
+               ibmr = nes_reg_phys_mr(&nespd->ibpd,
+                               nesqp->ietf_frame_pbase + mpa_frame_offset,
+                               buff_len, IB_ACCESS_LOCAL_WRITE,
+                               &tagged_offset);
+               if (IS_ERR(ibmr)) {
                        nes_debug(NES_DBG_CM, "Unable to register memory region"
                                  "for lSMM for cm_node = %p \n",
                                  cm_node);
                        pci_free_consistent(nesdev->pcidev,
                                            nesqp->private_data_len + nesqp->ietf_frame_size,
                                            nesqp->ietf_frame, nesqp->ietf_frame_pbase);
-                       return -ENOMEM;
+                       return PTR_ERR(ibmr);
                }
 
                ibmr->pd = &nespd->ibpd;
index 32a6420..147c2c8 100644 (file)
@@ -423,7 +423,7 @@ struct nes_cm_core {
 
        struct timer_list       tcp_timer;
 
-       struct nes_cm_ops       *api;
+       const struct nes_cm_ops *api;
 
        int (*post_event)(struct nes_cm_event *event);
        atomic_t                events_posted;
index 2042c0f..6d3a169 100644 (file)
@@ -727,7 +727,7 @@ int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 acti
        if (action == NES_ARP_DELETE) {
                nes_debug(NES_DBG_NETDEV, "DELETE, arp_index=%d\n", arp_index);
                nesadapter->arp_table[arp_index].ip_addr = 0;
-               memset(nesadapter->arp_table[arp_index].mac_addr, 0x00, ETH_ALEN);
+               eth_zero_addr(nesadapter->arp_table[arp_index].mac_addr);
                nes_free_resource(nesadapter, nesadapter->allocated_arps, arp_index);
                return arp_index;
        }
index 137880a..8c4daf7 100644 (file)
@@ -206,80 +206,6 @@ static int nes_dealloc_mw(struct ib_mw *ibmw)
 }
 
 
-/**
- * nes_bind_mw
- */
-static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw,
-               struct ib_mw_bind *ibmw_bind)
-{
-       u64 u64temp;
-       struct nes_vnic *nesvnic = to_nesvnic(ibqp->device);
-       struct nes_device *nesdev = nesvnic->nesdev;
-       /* struct nes_mr *nesmr = to_nesmw(ibmw); */
-       struct nes_qp *nesqp = to_nesqp(ibqp);
-       struct nes_hw_qp_wqe *wqe;
-       unsigned long flags = 0;
-       u32 head;
-       u32 wqe_misc = 0;
-       u32 qsize;
-
-       if (nesqp->ibqp_state > IB_QPS_RTS)
-               return -EINVAL;
-
-       spin_lock_irqsave(&nesqp->lock, flags);
-
-       head = nesqp->hwqp.sq_head;
-       qsize = nesqp->hwqp.sq_tail;
-
-       /* Check for SQ overflow */
-       if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) {
-               spin_unlock_irqrestore(&nesqp->lock, flags);
-               return -ENOMEM;
-       }
-
-       wqe = &nesqp->hwqp.sq_vbase[head];
-       /* nes_debug(NES_DBG_MR, "processing sq wqe at %p, head = %u.\n", wqe, head); */
-       nes_fill_init_qp_wqe(wqe, nesqp, head);
-       u64temp = ibmw_bind->wr_id;
-       set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, u64temp);
-       wqe_misc = NES_IWARP_SQ_OP_BIND;
-
-       wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE;
-
-       if (ibmw_bind->send_flags & IB_SEND_SIGNALED)
-               wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL;
-
-       if (ibmw_bind->bind_info.mw_access_flags & IB_ACCESS_REMOTE_WRITE)
-               wqe_misc |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE;
-       if (ibmw_bind->bind_info.mw_access_flags & IB_ACCESS_REMOTE_READ)
-               wqe_misc |= NES_CQP_STAG_RIGHTS_REMOTE_READ;
-
-       set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_MISC_IDX, wqe_misc);
-       set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_MR_IDX,
-                           ibmw_bind->bind_info.mr->lkey);
-       set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_MW_IDX, ibmw->rkey);
-       set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_LENGTH_LOW_IDX,
-                       ibmw_bind->bind_info.length);
-       wqe->wqe_words[NES_IWARP_SQ_BIND_WQE_LENGTH_HIGH_IDX] = 0;
-       u64temp = (u64)ibmw_bind->bind_info.addr;
-       set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_VA_FBO_LOW_IDX, u64temp);
-
-       head++;
-       if (head >= qsize)
-               head = 0;
-
-       nesqp->hwqp.sq_head = head;
-       barrier();
-
-       nes_write32(nesdev->regs+NES_WQE_ALLOC,
-                       (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id);
-
-       spin_unlock_irqrestore(&nesqp->lock, flags);
-
-       return 0;
-}
-
-
 /*
  * nes_alloc_fast_mr
  */
@@ -2074,9 +2000,8 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
 /**
  * nes_reg_phys_mr
  */
-static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
-               struct ib_phys_buf *buffer_list, int num_phys_buf, int acc,
-               u64 * iova_start)
+struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size,
+               int acc, u64 *iova_start)
 {
        u64 region_length;
        struct nes_pd *nespd = to_nespd(ib_pd);
@@ -2088,13 +2013,10 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
        struct nes_vpbl vpbl;
        struct nes_root_vpbl root_vpbl;
        u32 stag;
-       u32 i;
        unsigned long mask;
        u32 stag_index = 0;
        u32 next_stag_index = 0;
        u32 driver_key = 0;
-       u32 root_pbl_index = 0;
-       u32 cur_pbl_index = 0;
        int err = 0;
        int ret = 0;
        u16 pbl_count = 0;
@@ -2113,11 +2035,8 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
 
        next_stag_index >>= 8;
        next_stag_index %= nesadapter->max_mr;
-       if (num_phys_buf > (1024*512)) {
-               return ERR_PTR(-E2BIG);
-       }
 
-       if ((buffer_list[0].addr ^ *iova_start) & ~PAGE_MASK)
+       if ((addr ^ *iova_start) & ~PAGE_MASK)
                return ERR_PTR(-EINVAL);
 
        err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, nesadapter->max_mr,
@@ -2132,84 +2051,33 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
                return ERR_PTR(-ENOMEM);
        }
 
-       for (i = 0; i < num_phys_buf; i++) {
+       /* Allocate a 4K buffer for the PBL */
+       vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096,
+                       &vpbl.pbl_pbase);
+       nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%016lX\n",
+                       vpbl.pbl_vbase, (unsigned long)vpbl.pbl_pbase);
+       if (!vpbl.pbl_vbase) {
+               nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
+               ibmr = ERR_PTR(-ENOMEM);
+               kfree(nesmr);
+               goto reg_phys_err;
+       }
 
-               if ((i & 0x01FF) == 0) {
-                       if (root_pbl_index == 1) {
-                               /* Allocate the root PBL */
-                               root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 8192,
-                                               &root_vpbl.pbl_pbase);
-                               nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n",
-                                               root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase);
-                               if (!root_vpbl.pbl_vbase) {
-                                       pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase,
-                                                       vpbl.pbl_pbase);
-                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-                                       kfree(nesmr);
-                                       return ERR_PTR(-ENOMEM);
-                               }
-                               root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024, GFP_KERNEL);
-                               if (!root_vpbl.leaf_vpbl) {
-                                       pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase,
-                                                       root_vpbl.pbl_pbase);
-                                       pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase,
-                                                       vpbl.pbl_pbase);
-                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-                                       kfree(nesmr);
-                                       return ERR_PTR(-ENOMEM);
-                               }
-                               root_vpbl.pbl_vbase[0].pa_low = cpu_to_le32((u32)vpbl.pbl_pbase);
-                               root_vpbl.pbl_vbase[0].pa_high =
-                                               cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32)));
-                               root_vpbl.leaf_vpbl[0] = vpbl;
-                       }
-                       /* Allocate a 4K buffer for the PBL */
-                       vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096,
-                                       &vpbl.pbl_pbase);
-                       nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%016lX\n",
-                                       vpbl.pbl_vbase, (unsigned long)vpbl.pbl_pbase);
-                       if (!vpbl.pbl_vbase) {
-                               nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-                               ibmr = ERR_PTR(-ENOMEM);
-                               kfree(nesmr);
-                               goto reg_phys_err;
-                       }
-                       /* Fill in the root table */
-                       if (1 <= root_pbl_index) {
-                               root_vpbl.pbl_vbase[root_pbl_index].pa_low =
-                                               cpu_to_le32((u32)vpbl.pbl_pbase);
-                               root_vpbl.pbl_vbase[root_pbl_index].pa_high =
-                                               cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32)));
-                               root_vpbl.leaf_vpbl[root_pbl_index] = vpbl;
-                       }
-                       root_pbl_index++;
-                       cur_pbl_index = 0;
-               }
 
-               mask = !buffer_list[i].size;
-               if (i != 0)
-                       mask |= buffer_list[i].addr;
-               if (i != num_phys_buf - 1)
-                       mask |= buffer_list[i].addr + buffer_list[i].size;
-
-               if (mask & ~PAGE_MASK) {
-                       nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-                       nes_debug(NES_DBG_MR, "Invalid buffer addr or size\n");
-                       ibmr = ERR_PTR(-EINVAL);
-                       kfree(nesmr);
-                       goto reg_phys_err;
-               }
+       mask = !size;
 
-               region_length += buffer_list[i].size;
-               if ((i != 0) && (single_page)) {
-                       if ((buffer_list[i-1].addr+PAGE_SIZE) != buffer_list[i].addr)
-                               single_page = 0;
-               }
-               vpbl.pbl_vbase[cur_pbl_index].pa_low = cpu_to_le32((u32)buffer_list[i].addr & PAGE_MASK);
-               vpbl.pbl_vbase[cur_pbl_index++].pa_high =
-                               cpu_to_le32((u32)((((u64)buffer_list[i].addr) >> 32)));
+       if (mask & ~PAGE_MASK) {
+               nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
+               nes_debug(NES_DBG_MR, "Invalid buffer addr or size\n");
+               ibmr = ERR_PTR(-EINVAL);
+               kfree(nesmr);
+               goto reg_phys_err;
        }
 
+       region_length += size;
+       vpbl.pbl_vbase[0].pa_low = cpu_to_le32((u32)addr & PAGE_MASK);
+       vpbl.pbl_vbase[0].pa_high = cpu_to_le32((u32)((((u64)addr) >> 32)));
+
        stag = stag_index << 8;
        stag |= driver_key;
        stag += (u32)stag_key;
@@ -2219,17 +2087,15 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
                        stag, (unsigned long)*iova_start, (unsigned long)region_length, stag_index);
 
        /* Make the leaf PBL the root if only one PBL */
-       if (root_pbl_index == 1) {
-               root_vpbl.pbl_pbase = vpbl.pbl_pbase;
-       }
+       root_vpbl.pbl_pbase = vpbl.pbl_pbase;
 
        if (single_page) {
                pbl_count = 0;
        } else {
-               pbl_count = root_pbl_index;
+               pbl_count = 1;
        }
        ret = nes_reg_mr(nesdev, nespd, stag, region_length, &root_vpbl,
-                       buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start,
+                       addr, pbl_count, 1, acc, iova_start,
                        &nesmr->pbls_used, &nesmr->pbl_4k);
 
        if (ret == 0) {
@@ -2242,21 +2108,9 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
                ibmr = ERR_PTR(-ENOMEM);
        }
 
-       reg_phys_err:
-       /* free the resources */
-       if (root_pbl_index == 1) {
-               /* single PBL case */
-               pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, vpbl.pbl_pbase);
-       } else {
-               for (i=0; i<root_pbl_index; i++) {
-                       pci_free_consistent(nesdev->pcidev, 4096, root_vpbl.leaf_vpbl[i].pbl_vbase,
-                                       root_vpbl.leaf_vpbl[i].pbl_pbase);
-               }
-               kfree(root_vpbl.leaf_vpbl);
-               pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase,
-                               root_vpbl.pbl_pbase);
-       }
-
+reg_phys_err:
+       /* single PBL case */
+       pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, vpbl.pbl_pbase);
        return ibmr;
 }
 
@@ -2266,17 +2120,13 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
  */
 static struct ib_mr *nes_get_dma_mr(struct ib_pd *pd, int acc)
 {
-       struct ib_phys_buf bl;
        u64 kva = 0;
 
        nes_debug(NES_DBG_MR, "\n");
 
-       bl.size = (u64)0xffffffffffULL;
-       bl.addr = 0;
-       return nes_reg_phys_mr(pd, &bl, 1, acc, &kva);
+       return nes_reg_phys_mr(pd, 0, 0xffffffffffULL, acc, &kva);
 }
 
-
 /**
  * nes_reg_user_mr
  */
@@ -3888,12 +3738,10 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
        nesibdev->ibdev.destroy_cq = nes_destroy_cq;
        nesibdev->ibdev.poll_cq = nes_poll_cq;
        nesibdev->ibdev.get_dma_mr = nes_get_dma_mr;
-       nesibdev->ibdev.reg_phys_mr = nes_reg_phys_mr;
        nesibdev->ibdev.reg_user_mr = nes_reg_user_mr;
        nesibdev->ibdev.dereg_mr = nes_dereg_mr;
        nesibdev->ibdev.alloc_mw = nes_alloc_mw;
        nesibdev->ibdev.dealloc_mw = nes_dealloc_mw;
-       nesibdev->ibdev.bind_mw = nes_bind_mw;
 
        nesibdev->ibdev.alloc_mr = nes_alloc_mr;
        nesibdev->ibdev.map_mr_sg = nes_map_mr_sg;
index a204b67..7029088 100644 (file)
@@ -190,4 +190,8 @@ struct nes_qp {
        u8                    pau_state;
        __u64                 nesuqp_addr;
 };
+
+struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
+               u64 addr, u64 size, int acc, u64 *iova_start);
+
 #endif                 /* NES_VERBS_H */
index 9820074..3790771 100644 (file)
@@ -152,9 +152,10 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
        if ((pd->uctx) &&
            (!rdma_is_multicast_addr((struct in6_addr *)attr->grh.dgid.raw)) &&
            (!rdma_link_local_addr((struct in6_addr *)attr->grh.dgid.raw))) {
-               status = rdma_addr_find_dmac_by_grh(&sgid, &attr->grh.dgid,
-                                                   attr->dmac, &vlan_tag,
-                                                   sgid_attr.ndev->ifindex);
+               status = rdma_addr_find_l2_eth_by_grh(&sgid, &attr->grh.dgid,
+                                                     attr->dmac, &vlan_tag,
+                                                     &sgid_attr.ndev->ifindex,
+                                                     NULL);
                if (status) {
                        pr_err("%s(): Failed to resolve dmac from gid." 
                                "status = %d\n", __func__, status);
index 3afb40b..5738493 100644 (file)
@@ -175,7 +175,6 @@ static int ocrdma_register_device(struct ocrdma_dev *dev)
        dev->ibdev.req_notify_cq = ocrdma_arm_cq;
 
        dev->ibdev.get_dma_mr = ocrdma_get_dma_mr;
-       dev->ibdev.reg_phys_mr = ocrdma_reg_kernel_mr;
        dev->ibdev.dereg_mr = ocrdma_dereg_mr;
        dev->ibdev.reg_user_mr = ocrdma_reg_user_mr;
 
index 76e96f9..d4c687b 100644 (file)
@@ -3066,169 +3066,6 @@ pl_err:
        return ERR_PTR(-ENOMEM);
 }
 
-#define MAX_KERNEL_PBE_SIZE 65536
-static inline int count_kernel_pbes(struct ib_phys_buf *buf_list,
-                                   int buf_cnt, u32 *pbe_size)
-{
-       u64 total_size = 0;
-       u64 buf_size = 0;
-       int i;
-       *pbe_size = roundup(buf_list[0].size, PAGE_SIZE);
-       *pbe_size = roundup_pow_of_two(*pbe_size);
-
-       /* find the smallest PBE size that we can have */
-       for (i = 0; i < buf_cnt; i++) {
-               /* first addr may not be page aligned, so ignore checking */
-               if ((i != 0) && ((buf_list[i].addr & ~PAGE_MASK) ||
-                                (buf_list[i].size & ~PAGE_MASK))) {
-                       return 0;
-               }
-
-               /* if configured PBE size is greater then the chosen one,
-                * reduce the PBE size.
-                */
-               buf_size = roundup(buf_list[i].size, PAGE_SIZE);
-               /* pbe_size has to be even multiple of 4K 1,2,4,8...*/
-               buf_size = roundup_pow_of_two(buf_size);
-               if (*pbe_size > buf_size)
-                       *pbe_size = buf_size;
-
-               total_size += buf_size;
-       }
-       *pbe_size = *pbe_size > MAX_KERNEL_PBE_SIZE ?
-           (MAX_KERNEL_PBE_SIZE) : (*pbe_size);
-
-       /* num_pbes = total_size / (*pbe_size);  this is implemented below. */
-
-       return total_size >> ilog2(*pbe_size);
-}
-
-static void build_kernel_pbes(struct ib_phys_buf *buf_list, int ib_buf_cnt,
-                             u32 pbe_size, struct ocrdma_pbl *pbl_tbl,
-                             struct ocrdma_hw_mr *hwmr)
-{
-       int i;
-       int idx;
-       int pbes_per_buf = 0;
-       u64 buf_addr = 0;
-       int num_pbes;
-       struct ocrdma_pbe *pbe;
-       int total_num_pbes = 0;
-
-       if (!hwmr->num_pbes)
-               return;
-
-       pbe = (struct ocrdma_pbe *)pbl_tbl->va;
-       num_pbes = 0;
-
-       /* go through the OS phy regions & fill hw pbe entries into pbls. */
-       for (i = 0; i < ib_buf_cnt; i++) {
-               buf_addr = buf_list[i].addr;
-               pbes_per_buf =
-                   roundup_pow_of_two(roundup(buf_list[i].size, PAGE_SIZE)) /
-                   pbe_size;
-               hwmr->len += buf_list[i].size;
-               /* number of pbes can be more for one OS buf, when
-                * buffers are of different sizes.
-                * split the ib_buf to one or more pbes.
-                */
-               for (idx = 0; idx < pbes_per_buf; idx++) {
-                       /* we program always page aligned addresses,
-                        * first unaligned address is taken care by fbo.
-                        */
-                       if (i == 0) {
-                               /* for non zero fbo, assign the
-                                * start of the page.
-                                */
-                               pbe->pa_lo =
-                                   cpu_to_le32((u32) (buf_addr & PAGE_MASK));
-                               pbe->pa_hi =
-                                   cpu_to_le32((u32) upper_32_bits(buf_addr));
-                       } else {
-                               pbe->pa_lo =
-                                   cpu_to_le32((u32) (buf_addr & 0xffffffff));
-                               pbe->pa_hi =
-                                   cpu_to_le32((u32) upper_32_bits(buf_addr));
-                       }
-                       buf_addr += pbe_size;
-                       num_pbes += 1;
-                       total_num_pbes += 1;
-                       pbe++;
-
-                       if (total_num_pbes == hwmr->num_pbes)
-                               goto mr_tbl_done;
-                       /* if the pbl is full storing the pbes,
-                        * move to next pbl.
-                        */
-                       if (num_pbes == (hwmr->pbl_size/sizeof(u64))) {
-                               pbl_tbl++;
-                               pbe = (struct ocrdma_pbe *)pbl_tbl->va;
-                               num_pbes = 0;
-                       }
-               }
-       }
-mr_tbl_done:
-       return;
-}
-
-struct ib_mr *ocrdma_reg_kernel_mr(struct ib_pd *ibpd,
-                                  struct ib_phys_buf *buf_list,
-                                  int buf_cnt, int acc, u64 *iova_start)
-{
-       int status = -ENOMEM;
-       struct ocrdma_mr *mr;
-       struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
-       struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
-       u32 num_pbes;
-       u32 pbe_size = 0;
-
-       if ((acc & IB_ACCESS_REMOTE_WRITE) && !(acc & IB_ACCESS_LOCAL_WRITE))
-               return ERR_PTR(-EINVAL);
-
-       mr = kzalloc(sizeof(*mr), GFP_KERNEL);
-       if (!mr)
-               return ERR_PTR(status);
-
-       num_pbes = count_kernel_pbes(buf_list, buf_cnt, &pbe_size);
-       if (num_pbes == 0) {
-               status = -EINVAL;
-               goto pbl_err;
-       }
-       status = ocrdma_get_pbl_info(dev, mr, num_pbes);
-       if (status)
-               goto pbl_err;
-
-       mr->hwmr.pbe_size = pbe_size;
-       mr->hwmr.fbo = *iova_start - (buf_list[0].addr & PAGE_MASK);
-       mr->hwmr.va = *iova_start;
-       mr->hwmr.local_rd = 1;
-       mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
-       mr->hwmr.remote_rd = (acc & IB_ACCESS_REMOTE_READ) ? 1 : 0;
-       mr->hwmr.local_wr = (acc & IB_ACCESS_LOCAL_WRITE) ? 1 : 0;
-       mr->hwmr.remote_atomic = (acc & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0;
-       mr->hwmr.mw_bind = (acc & IB_ACCESS_MW_BIND) ? 1 : 0;
-
-       status = ocrdma_build_pbl_tbl(dev, &mr->hwmr);
-       if (status)
-               goto pbl_err;
-       build_kernel_pbes(buf_list, buf_cnt, pbe_size, mr->hwmr.pbl_table,
-                         &mr->hwmr);
-       status = ocrdma_reg_mr(dev, &mr->hwmr, pd->id, acc);
-       if (status)
-               goto mbx_err;
-
-       mr->ibmr.lkey = mr->hwmr.lkey;
-       if (mr->hwmr.remote_wr || mr->hwmr.remote_rd)
-               mr->ibmr.rkey = mr->hwmr.lkey;
-       return &mr->ibmr;
-
-mbx_err:
-       ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
-pbl_err:
-       kfree(mr);
-       return ERR_PTR(status);
-}
-
 static int ocrdma_set_page(struct ib_mr *ibmr, u64 addr)
 {
        struct ocrdma_mr *mr = get_ocrdma_mr(ibmr);
index a2f3b4d..8b517fd 100644 (file)
@@ -117,9 +117,6 @@ int ocrdma_post_srq_recv(struct ib_srq *, struct ib_recv_wr *,
 
 int ocrdma_dereg_mr(struct ib_mr *);
 struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *, int acc);
-struct ib_mr *ocrdma_reg_kernel_mr(struct ib_pd *,
-                                  struct ib_phys_buf *buffer_list,
-                                  int num_phys_buf, int acc, u64 *iova_start);
 struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *, u64 start, u64 length,
                                 u64 virt, int acc, struct ib_udata *);
 struct ib_mr *ocrdma_alloc_mr(struct ib_pd *pd,
index 13ef22b..fcdf379 100644 (file)
@@ -89,14 +89,14 @@ static int create_file(const char *name, umode_t mode,
 {
        int error;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        *dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(*dentry))
                error = qibfs_mknod(d_inode(parent), *dentry,
                                    mode, fops, data);
        else
                error = PTR_ERR(*dentry);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
 
        return error;
 }
@@ -481,7 +481,7 @@ static int remove_device_files(struct super_block *sb,
        int ret, i;
 
        root = dget(sb->s_root);
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
        snprintf(unit, sizeof(unit), "%u", dd->unit);
        dir = lookup_one_len(unit, root, strlen(unit));
 
@@ -491,7 +491,7 @@ static int remove_device_files(struct super_block *sb,
                goto bail;
        }
 
-       mutex_lock(&d_inode(dir)->i_mutex);
+       inode_lock(d_inode(dir));
        remove_file(dir, "counters");
        remove_file(dir, "counter_names");
        remove_file(dir, "portcounter_names");
@@ -506,13 +506,13 @@ static int remove_device_files(struct super_block *sb,
                }
        }
        remove_file(dir, "flash");
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        ret = simple_rmdir(d_inode(root), dir);
        d_delete(dir);
        dput(dir);
 
 bail:
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        dput(root);
        return ret;
 }
index 294f5c7..5f53304 100644 (file)
@@ -150,10 +150,7 @@ static struct qib_mr *alloc_mr(int count, struct ib_pd *pd)
        rval = init_qib_mregion(&mr->mr, pd, count);
        if (rval)
                goto bail;
-       /*
-        * ib_reg_phys_mr() will initialize mr->ibmr except for
-        * lkey and rkey.
-        */
+
        rval = qib_alloc_lkey(&mr->mr, 0);
        if (rval)
                goto bail_mregion;
@@ -170,52 +167,6 @@ bail:
        goto done;
 }
 
-/**
- * qib_reg_phys_mr - register a physical memory region
- * @pd: protection domain for this memory region
- * @buffer_list: pointer to the list of physical buffers to register
- * @num_phys_buf: the number of physical buffers to register
- * @iova_start: the starting address passed over IB which maps to this MR
- *
- * Returns the memory region on success, otherwise returns an errno.
- */
-struct ib_mr *qib_reg_phys_mr(struct ib_pd *pd,
-                             struct ib_phys_buf *buffer_list,
-                             int num_phys_buf, int acc, u64 *iova_start)
-{
-       struct qib_mr *mr;
-       int n, m, i;
-       struct ib_mr *ret;
-
-       mr = alloc_mr(num_phys_buf, pd);
-       if (IS_ERR(mr)) {
-               ret = (struct ib_mr *)mr;
-               goto bail;
-       }
-
-       mr->mr.user_base = *iova_start;
-       mr->mr.iova = *iova_start;
-       mr->mr.access_flags = acc;
-
-       m = 0;
-       n = 0;
-       for (i = 0; i < num_phys_buf; i++) {
-               mr->mr.map[m]->segs[n].vaddr = (void *) buffer_list[i].addr;
-               mr->mr.map[m]->segs[n].length = buffer_list[i].size;
-               mr->mr.length += buffer_list[i].size;
-               n++;
-               if (n == QIB_SEGSZ) {
-                       m++;
-                       n = 0;
-               }
-       }
-
-       ret = &mr->ibmr;
-
-bail:
-       return ret;
-}
-
 /**
  * qib_reg_user_mr - register a userspace memory region
  * @pd: protection domain for this memory region
index 40f85bb..3eff35c 100644 (file)
@@ -100,9 +100,10 @@ static u32 credit_table[31] = {
        32768                   /* 1E */
 };
 
-static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map)
+static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map,
+                        gfp_t gfp)
 {
-       unsigned long page = get_zeroed_page(GFP_KERNEL);
+       unsigned long page = get_zeroed_page(gfp);
 
        /*
         * Free the page if someone raced with us installing it.
@@ -121,7 +122,7 @@ static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map)
  * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
  */
 static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
-                    enum ib_qp_type type, u8 port)
+                    enum ib_qp_type type, u8 port, gfp_t gfp)
 {
        u32 i, offset, max_scan, qpn;
        struct qpn_map *map;
@@ -151,7 +152,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
        max_scan = qpt->nmaps - !offset;
        for (i = 0;;) {
                if (unlikely(!map->page)) {
-                       get_map_page(qpt, map);
+                       get_map_page(qpt, map, gfp);
                        if (unlikely(!map->page))
                                break;
                }
@@ -983,13 +984,21 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
        size_t sz;
        size_t sg_list_sz;
        struct ib_qp *ret;
+       gfp_t gfp;
+
 
        if (init_attr->cap.max_send_sge > ib_qib_max_sges ||
            init_attr->cap.max_send_wr > ib_qib_max_qp_wrs ||
-           init_attr->create_flags) {
-               ret = ERR_PTR(-EINVAL);
-               goto bail;
-       }
+           init_attr->create_flags & ~(IB_QP_CREATE_USE_GFP_NOIO))
+               return ERR_PTR(-EINVAL);
+
+       /* GFP_NOIO is applicable in RC QPs only */
+       if (init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO &&
+           init_attr->qp_type != IB_QPT_RC)
+               return ERR_PTR(-EINVAL);
+
+       gfp = init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO ?
+                       GFP_NOIO : GFP_KERNEL;
 
        /* Check receive queue parameters if no SRQ is specified. */
        if (!init_attr->srq) {
@@ -1021,7 +1030,8 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
                sz = sizeof(struct qib_sge) *
                        init_attr->cap.max_send_sge +
                        sizeof(struct qib_swqe);
-               swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz);
+               swq = __vmalloc((init_attr->cap.max_send_wr + 1) * sz,
+                               gfp, PAGE_KERNEL);
                if (swq == NULL) {
                        ret = ERR_PTR(-ENOMEM);
                        goto bail;
@@ -1037,13 +1047,13 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
                } else if (init_attr->cap.max_recv_sge > 1)
                        sg_list_sz = sizeof(*qp->r_sg_list) *
                                (init_attr->cap.max_recv_sge - 1);
-               qp = kzalloc(sz + sg_list_sz, GFP_KERNEL);
+               qp = kzalloc(sz + sg_list_sz, gfp);
                if (!qp) {
                        ret = ERR_PTR(-ENOMEM);
                        goto bail_swq;
                }
                RCU_INIT_POINTER(qp->next, NULL);
-               qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), GFP_KERNEL);
+               qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), gfp);
                if (!qp->s_hdr) {
                        ret = ERR_PTR(-ENOMEM);
                        goto bail_qp;
@@ -1058,8 +1068,16 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
                        qp->r_rq.max_sge = init_attr->cap.max_recv_sge;
                        sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +
                                sizeof(struct qib_rwqe);
-                       qp->r_rq.wq = vmalloc_user(sizeof(struct qib_rwq) +
-                                                  qp->r_rq.size * sz);
+                       if (gfp != GFP_NOIO)
+                               qp->r_rq.wq = vmalloc_user(
+                                               sizeof(struct qib_rwq) +
+                                               qp->r_rq.size * sz);
+                       else
+                               qp->r_rq.wq = __vmalloc(
+                                               sizeof(struct qib_rwq) +
+                                               qp->r_rq.size * sz,
+                                               gfp, PAGE_KERNEL);
+
                        if (!qp->r_rq.wq) {
                                ret = ERR_PTR(-ENOMEM);
                                goto bail_qp;
@@ -1090,7 +1108,7 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
                dev = to_idev(ibpd->device);
                dd = dd_from_dev(dev);
                err = alloc_qpn(dd, &dev->qpn_table, init_attr->qp_type,
-                               init_attr->port_num);
+                               init_attr->port_num, gfp);
                if (err < 0) {
                        ret = ERR_PTR(err);
                        vfree(qp->r_rq.wq);
index de6cb6f..baf1e42 100644 (file)
@@ -346,6 +346,7 @@ static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr,
        unsigned long flags;
        struct qib_lkey_table *rkt;
        struct qib_pd *pd;
+       int avoid_schedule = 0;
 
        spin_lock_irqsave(&qp->s_lock, flags);
 
@@ -438,11 +439,15 @@ static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr,
            qp->ibqp.qp_type == IB_QPT_RC) {
                if (wqe->length > 0x80000000U)
                        goto bail_inval_free;
+               if (wqe->length <= qp->pmtu)
+                       avoid_schedule = 1;
        } else if (wqe->length > (dd_from_ibdev(qp->ibqp.device)->pport +
-                                 qp->port_num - 1)->ibmtu)
+                                 qp->port_num - 1)->ibmtu) {
                goto bail_inval_free;
-       else
+       } else {
                atomic_inc(&to_iah(ud_wr(wr)->ah)->refcount);
+               avoid_schedule = 1;
+       }
        wqe->ssn = qp->s_ssn++;
        qp->s_head = next;
 
@@ -458,7 +463,7 @@ bail_inval_free:
 bail_inval:
        ret = -EINVAL;
 bail:
-       if (!ret && !wr->next &&
+       if (!ret && !wr->next && !avoid_schedule &&
         !qib_sdma_empty(
           dd_from_ibdev(qp->ibqp.device)->pport + qp->port_num - 1)) {
                qib_schedule_send(qp);
@@ -2256,7 +2261,6 @@ int qib_register_ib_device(struct qib_devdata *dd)
        ibdev->poll_cq = qib_poll_cq;
        ibdev->req_notify_cq = qib_req_notify_cq;
        ibdev->get_dma_mr = qib_get_dma_mr;
-       ibdev->reg_phys_mr = qib_reg_phys_mr;
        ibdev->reg_user_mr = qib_reg_user_mr;
        ibdev->dereg_mr = qib_dereg_mr;
        ibdev->alloc_mr = qib_alloc_mr;
index bc803f3..6c5e777 100644 (file)
@@ -1032,10 +1032,6 @@ int qib_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
 
 struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc);
 
-struct ib_mr *qib_reg_phys_mr(struct ib_pd *pd,
-                             struct ib_phys_buf *buffer_list,
-                             int num_phys_buf, int acc, u64 *iova_start);
-
 struct ib_mr *qib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                              u64 virt_addr, int mr_access_flags,
                              struct ib_udata *udata);
index f8ea069..b2fb528 100644 (file)
@@ -286,15 +286,13 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
        struct qib_ibdev *dev = to_idev(ibqp->device);
        struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num);
        struct qib_mcast *mcast = NULL;
-       struct qib_mcast_qp *p, *tmp;
+       struct qib_mcast_qp *p, *tmp, *delp = NULL;
        struct rb_node *n;
        int last = 0;
        int ret;
 
-       if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) {
-               ret = -EINVAL;
-               goto bail;
-       }
+       if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET)
+               return -EINVAL;
 
        spin_lock_irq(&ibp->lock);
 
@@ -303,8 +301,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
        while (1) {
                if (n == NULL) {
                        spin_unlock_irq(&ibp->lock);
-                       ret = -EINVAL;
-                       goto bail;
+                       return -EINVAL;
                }
 
                mcast = rb_entry(n, struct qib_mcast, rb_node);
@@ -328,6 +325,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                 */
                list_del_rcu(&p->list);
                mcast->n_attached--;
+               delp = p;
 
                /* If this was the last attached QP, remove the GID too. */
                if (list_empty(&mcast->qp_list)) {
@@ -338,15 +336,16 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
        }
 
        spin_unlock_irq(&ibp->lock);
+       /* QP not attached */
+       if (!delp)
+               return -EINVAL;
+       /*
+        * Wait for any list walkers to finish before freeing the
+        * list element.
+        */
+       wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
+       qib_mcast_qp_free(delp);
 
-       if (p) {
-               /*
-                * Wait for any list walkers to finish before freeing the
-                * list element.
-                */
-               wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
-               qib_mcast_qp_free(p);
-       }
        if (last) {
                atomic_dec(&mcast->refcount);
                wait_event(mcast->wait, !atomic_read(&mcast->refcount));
@@ -355,11 +354,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                dev->n_mcast_grps_allocated--;
                spin_unlock_irq(&dev->n_mcast_grps_lock);
        }
-
-       ret = 0;
-
-bail:
-       return ret;
+       return 0;
 }
 
 int qib_mcast_tree_empty(struct qib_ibport *ibp)
index 5e55b8b..92dc66c 100644 (file)
@@ -157,8 +157,9 @@ void usnic_debugfs_flow_add(struct usnic_ib_qp_grp_flow *qp_flow)
                                                        qp_flow,
                                                        &flowinfo_ops);
        if (IS_ERR_OR_NULL(qp_flow->dbgfs_dentry)) {
-               usnic_err("Failed to create dbg fs entry for flow %u\n",
-                               qp_flow->flow->flow_id);
+               usnic_err("Failed to create dbg fs entry for flow %u with error %ld\n",
+                               qp_flow->flow->flow_id,
+                               PTR_ERR(qp_flow->dbgfs_dentry));
        }
 }
 
index fcea3a2..5f44b66 100644 (file)
@@ -521,7 +521,7 @@ int usnic_ib_qp_grp_modify(struct usnic_ib_qp_grp *qp_grp,
 
        if (!status) {
                qp_grp->state = new_state;
-               usnic_info("Transistioned %u from %s to %s",
+               usnic_info("Transitioned %u from %s to %s",
                qp_grp->grp_id,
                usnic_ib_qp_grp_state_to_string(old_state),
                usnic_ib_qp_grp_state_to_string(new_state));
@@ -575,7 +575,7 @@ alloc_res_chunk_list(struct usnic_vnic *vnic,
        return res_chunk_list;
 
 out_free_res:
-       for (i--; i > 0; i--)
+       for (i--; i >= 0; i--)
                usnic_vnic_put_resources(res_chunk_list[i]);
        kfree(res_chunk_list);
        return ERR_PTR(err);
index f8e3211..6cdb4d2 100644 (file)
@@ -51,7 +51,7 @@
 
 static void usnic_ib_fw_string_to_u64(char *fw_ver_str, u64 *fw_ver)
 {
-       *fw_ver = (u64) *fw_ver_str;
+       *fw_ver = *((u64 *)fw_ver_str);
 }
 
 static int usnic_ib_fill_create_qp_resp(struct usnic_ib_qp_grp *qp_grp,
@@ -571,20 +571,20 @@ int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 
        qp_grp = to_uqp_grp(ibqp);
 
-       /* TODO: Future Support All States */
        mutex_lock(&qp_grp->vf->pf->usdev_lock);
-       if ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_INIT) {
-               status = usnic_ib_qp_grp_modify(qp_grp, IB_QPS_INIT, NULL);
-       } else if ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_RTR) {
-               status = usnic_ib_qp_grp_modify(qp_grp, IB_QPS_RTR, NULL);
-       } else if ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_RTS) {
-               status = usnic_ib_qp_grp_modify(qp_grp, IB_QPS_RTS, NULL);
+       if ((attr_mask & IB_QP_PORT) && attr->port_num != 1) {
+               /* usnic devices only have one port */
+               status = -EINVAL;
+               goto out_unlock;
+       }
+       if (attr_mask & IB_QP_STATE) {
+               status = usnic_ib_qp_grp_modify(qp_grp, attr->qp_state, NULL);
        } else {
-               usnic_err("Unexpected combination mask: %u state: %u\n",
-                               attr_mask & IB_QP_STATE, attr->qp_state);
+               usnic_err("Unhandled request, attr_mask=0x%x\n", attr_mask);
                status = -EINVAL;
        }
 
+out_unlock:
        mutex_unlock(&qp_grp->vf->pf->usdev_lock);
        return status;
 }
@@ -625,8 +625,8 @@ struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
                        virt_addr, length);
 
        mr = kzalloc(sizeof(*mr), GFP_KERNEL);
-       if (IS_ERR_OR_NULL(mr))
-               return ERR_PTR(mr ? PTR_ERR(mr) : -ENOMEM);
+       if (!mr)
+               return ERR_PTR(-ENOMEM);
 
        mr->umem = usnic_uiom_reg_get(to_upd(pd)->umem_pd, start, length,
                                        access_flags, 0);
index 414eaa5..0d9d2e6 100644 (file)
@@ -43,8 +43,6 @@ int usnic_ib_query_device(struct ib_device *ibdev,
                          struct ib_udata *uhw);
 int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
                                struct ib_port_attr *props);
-enum rdma_protocol_type
-usnic_ib_query_protocol(struct ib_device *device, u8 port_num);
 int usnic_ib_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
                                int qp_attr_mask,
                                struct ib_qp_init_attr *qp_init_attr);
index 66de93f..8875107 100644 (file)
@@ -237,7 +237,7 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
        struct usnic_vnic_res *res;
        int i;
 
-       if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 1 || !owner)
+       if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 0 || !owner)
                return ERR_PTR(-EINVAL);
 
        ret = kzalloc(sizeof(*ret), GFP_ATOMIC);
@@ -247,26 +247,28 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
                return ERR_PTR(-ENOMEM);
        }
 
-       ret->res = kzalloc(sizeof(*(ret->res))*cnt, GFP_ATOMIC);
-       if (!ret->res) {
-               usnic_err("Failed to allocate resources for %s. Out of memory\n",
-                               usnic_vnic_pci_name(vnic));
-               kfree(ret);
-               return ERR_PTR(-ENOMEM);
-       }
+       if (cnt > 0) {
+               ret->res = kcalloc(cnt, sizeof(*(ret->res)), GFP_ATOMIC);
+               if (!ret->res) {
+                       usnic_err("Failed to allocate resources for %s. Out of memory\n",
+                                       usnic_vnic_pci_name(vnic));
+                       kfree(ret);
+                       return ERR_PTR(-ENOMEM);
+               }
 
-       spin_lock(&vnic->res_lock);
-       src = &vnic->chunks[type];
-       for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
-               res = src->res[i];
-               if (!res->owner) {
-                       src->free_cnt--;
-                       res->owner = owner;
-                       ret->res[ret->cnt++] = res;
+               spin_lock(&vnic->res_lock);
+               src = &vnic->chunks[type];
+               for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
+                       res = src->res[i];
+                       if (!res->owner) {
+                               src->free_cnt--;
+                               res->owner = owner;
+                               ret->res[ret->cnt++] = res;
+                       }
                }
-       }
 
-       spin_unlock(&vnic->res_lock);
+               spin_unlock(&vnic->res_lock);
+       }
        ret->type = type;
        ret->vnic = vnic;
        WARN_ON(ret->cnt != cnt);
@@ -281,14 +283,16 @@ void usnic_vnic_put_resources(struct usnic_vnic_res_chunk *chunk)
        int i;
        struct usnic_vnic *vnic = chunk->vnic;
 
-       spin_lock(&vnic->res_lock);
-       while ((i = --chunk->cnt) >= 0) {
-               res = chunk->res[i];
-               chunk->res[i] = NULL;
-               res->owner = NULL;
-               vnic->chunks[res->type].free_cnt++;
+       if (chunk->cnt > 0) {
+               spin_lock(&vnic->res_lock);
+               while ((i = --chunk->cnt) >= 0) {
+                       res = chunk->res[i];
+                       chunk->res[i] = NULL;
+                       res->owner = NULL;
+                       vnic->chunks[res->type].free_cnt++;
+               }
+               spin_unlock(&vnic->res_lock);
        }
-       spin_unlock(&vnic->res_lock);
 
        kfree(chunk->res);
        kfree(chunk);
index 3ede103..a6f3eab 100644 (file)
@@ -495,7 +495,6 @@ void ipoib_dev_cleanup(struct net_device *dev);
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
 void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb);
-void ipoib_mcast_free(struct ipoib_mcast *mc);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
@@ -549,8 +548,9 @@ void ipoib_path_iter_read(struct ipoib_path_iter *iter,
 
 int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
                       union ib_gid *mgid, int set_qkey);
-int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast);
-struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, void *mgid);
+void ipoib_mcast_remove_list(struct list_head *remove_list);
+void ipoib_check_and_add_mcast_sendonly(struct ipoib_dev_priv *priv, u8 *mgid,
+                               struct list_head *remove_list);
 
 int ipoib_init_qp(struct net_device *dev);
 int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca);
index 3ae9726..917e46e 100644 (file)
@@ -70,7 +70,6 @@ static struct ib_qp_attr ipoib_cm_err_attr = {
 #define IPOIB_CM_RX_DRAIN_WRID 0xffffffff
 
 static struct ib_send_wr ipoib_cm_rx_drain_wr = {
-       .wr_id = IPOIB_CM_RX_DRAIN_WRID,
        .opcode = IB_WR_SEND,
 };
 
@@ -223,6 +222,7 @@ static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv *priv)
         * error" WC will be immediately generated for each WR we post.
         */
        p = list_entry(priv->cm.rx_flush_list.next, typeof(*p), list);
+       ipoib_cm_rx_drain_wr.wr_id = IPOIB_CM_RX_DRAIN_WRID;
        if (ib_post_send(p->qp, &ipoib_cm_rx_drain_wr, &bad_wr))
                ipoib_warn(priv, "failed to post drain wr\n");
 
@@ -1522,8 +1522,7 @@ static void ipoib_cm_create_srq(struct net_device *dev, int max_sge)
 int ipoib_cm_dev_init(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       int i, ret;
-       struct ib_device_attr attr;
+       int max_srq_sge, i;
 
        INIT_LIST_HEAD(&priv->cm.passive_ids);
        INIT_LIST_HEAD(&priv->cm.reap_list);
@@ -1540,19 +1539,13 @@ int ipoib_cm_dev_init(struct net_device *dev)
 
        skb_queue_head_init(&priv->cm.skb_queue);
 
-       ret = ib_query_device(priv->ca, &attr);
-       if (ret) {
-               printk(KERN_WARNING "ib_query_device() failed with %d\n", ret);
-               return ret;
-       }
-
-       ipoib_dbg(priv, "max_srq_sge=%d\n", attr.max_srq_sge);
+       ipoib_dbg(priv, "max_srq_sge=%d\n", priv->ca->attrs.max_srq_sge);
 
-       attr.max_srq_sge = min_t(int, IPOIB_CM_RX_SG, attr.max_srq_sge);
-       ipoib_cm_create_srq(dev, attr.max_srq_sge);
+       max_srq_sge = min_t(int, IPOIB_CM_RX_SG, priv->ca->attrs.max_srq_sge);
+       ipoib_cm_create_srq(dev, max_srq_sge);
        if (ipoib_cm_has_srq(dev)) {
-               priv->cm.max_cm_mtu = attr.max_srq_sge * PAGE_SIZE - 0x10;
-               priv->cm.num_frags  = attr.max_srq_sge;
+               priv->cm.max_cm_mtu = max_srq_sge * PAGE_SIZE - 0x10;
+               priv->cm.num_frags  = max_srq_sge;
                ipoib_dbg(priv, "max_cm_mtu = 0x%x, num_frags=%d\n",
                          priv->cm.max_cm_mtu, priv->cm.num_frags);
        } else {
index 078cadd..a53fa5f 100644 (file)
@@ -40,15 +40,11 @@ static void ipoib_get_drvinfo(struct net_device *netdev,
                              struct ethtool_drvinfo *drvinfo)
 {
        struct ipoib_dev_priv *priv = netdev_priv(netdev);
-       struct ib_device_attr *attr;
-
-       attr = kmalloc(sizeof(*attr), GFP_KERNEL);
-       if (attr && !ib_query_device(priv->ca, attr))
-               snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
-                        "%d.%d.%d", (int)(attr->fw_ver >> 32),
-                        (int)(attr->fw_ver >> 16) & 0xffff,
-                        (int)attr->fw_ver & 0xffff);
-       kfree(attr);
+
+       snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+                "%d.%d.%d", (int)(priv->ca->attrs.fw_ver >> 32),
+                (int)(priv->ca->attrs.fw_ver >> 16) & 0xffff,
+                (int)priv->ca->attrs.fw_ver & 0xffff);
 
        strlcpy(drvinfo->bus_info, dev_name(priv->ca->dma_device),
                sizeof(drvinfo->bus_info));
index 7d32818..25509bb 100644 (file)
@@ -1150,8 +1150,6 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
        unsigned long flags;
        int i;
        LIST_HEAD(remove_list);
-       struct ipoib_mcast *mcast, *tmcast;
-       struct net_device *dev = priv->dev;
 
        if (test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags))
                return;
@@ -1179,18 +1177,8 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
                                                          lockdep_is_held(&priv->lock))) != NULL) {
                        /* was the neigh idle for two GC periods */
                        if (time_after(neigh_obsolete, neigh->alive)) {
-                               u8 *mgid = neigh->daddr + 4;
 
-                               /* Is this multicast ? */
-                               if (*mgid == 0xff) {
-                                       mcast = __ipoib_mcast_find(dev, mgid);
-
-                                       if (mcast && test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
-                                               list_del(&mcast->list);
-                                               rb_erase(&mcast->rb_node, &priv->multicast_tree);
-                                               list_add_tail(&mcast->list, &remove_list);
-                                       }
-                               }
+                               ipoib_check_and_add_mcast_sendonly(priv, neigh->daddr + 4, &remove_list);
 
                                rcu_assign_pointer(*np,
                                                   rcu_dereference_protected(neigh->hnext,
@@ -1207,10 +1195,7 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
 
 out_unlock:
        spin_unlock_irqrestore(&priv->lock, flags);
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
-               ipoib_mcast_leave(dev, mcast);
-               ipoib_mcast_free(mcast);
-       }
+       ipoib_mcast_remove_list(&remove_list);
 }
 
 static void ipoib_reap_neigh(struct work_struct *work)
@@ -1777,26 +1762,7 @@ int ipoib_add_pkey_attr(struct net_device *dev)
 
 int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
 {
-       struct ib_device_attr *device_attr;
-       int result = -ENOMEM;
-
-       device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
-       if (!device_attr) {
-               printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
-                      hca->name, sizeof *device_attr);
-               return result;
-       }
-
-       result = ib_query_device(hca, device_attr);
-       if (result) {
-               printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
-                      hca->name, result);
-               kfree(device_attr);
-               return result;
-       }
-       priv->hca_caps = device_attr->device_cap_flags;
-
-       kfree(device_attr);
+       priv->hca_caps = hca->attrs.device_cap_flags;
 
        if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
                priv->dev->hw_features = NETIF_F_SG |
index f357ca6..050dfa1 100644 (file)
@@ -106,7 +106,7 @@ static void __ipoib_mcast_schedule_join_thread(struct ipoib_dev_priv *priv,
                queue_delayed_work(priv->wq, &priv->mcast_task, 0);
 }
 
-void ipoib_mcast_free(struct ipoib_mcast *mcast)
+static void ipoib_mcast_free(struct ipoib_mcast *mcast)
 {
        struct net_device *dev = mcast->dev;
        int tx_dropped = 0;
@@ -153,7 +153,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev,
        return mcast;
 }
 
-struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, void *mgid)
+static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, void *mgid)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct rb_node *n = priv->multicast_tree.rb_node;
@@ -677,7 +677,7 @@ int ipoib_mcast_stop_thread(struct net_device *dev)
        return 0;
 }
 
-int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
+static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        int ret = 0;
@@ -704,6 +704,35 @@ int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
        return 0;
 }
 
+/*
+ * Check if the multicast group is sendonly. If so remove it from the maps
+ * and add to the remove list
+ */
+void ipoib_check_and_add_mcast_sendonly(struct ipoib_dev_priv *priv, u8 *mgid,
+                               struct list_head *remove_list)
+{
+       /* Is this multicast ? */
+       if (*mgid == 0xff) {
+               struct ipoib_mcast *mcast = __ipoib_mcast_find(priv->dev, mgid);
+
+               if (mcast && test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
+                       list_del(&mcast->list);
+                       rb_erase(&mcast->rb_node, &priv->multicast_tree);
+                       list_add_tail(&mcast->list, remove_list);
+               }
+       }
+}
+
+void ipoib_mcast_remove_list(struct list_head *remove_list)
+{
+       struct ipoib_mcast *mcast, *tmcast;
+
+       list_for_each_entry_safe(mcast, tmcast, remove_list, list) {
+               ipoib_mcast_leave(mcast->dev, mcast);
+               ipoib_mcast_free(mcast);
+       }
+}
+
 void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -810,10 +839,7 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
                if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
                        wait_for_completion(&mcast->done);
 
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
-               ipoib_mcast_leave(dev, mcast);
-               ipoib_mcast_free(mcast);
-       }
+       ipoib_mcast_remove_list(&remove_list);
 }
 
 static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast)
@@ -939,10 +965,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
                if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
                        wait_for_completion(&mcast->done);
 
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
-               ipoib_mcast_leave(mcast->dev, mcast);
-               ipoib_mcast_free(mcast);
-       }
+       ipoib_mcast_remove_list(&remove_list);
 
        /*
         * Double check that we are still up
index 9080161..c827c93 100644 (file)
@@ -644,7 +644,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
 
                ib_conn = &iser_conn->ib_conn;
                if (ib_conn->pi_support) {
-                       u32 sig_caps = ib_conn->device->dev_attr.sig_prot_cap;
+                       u32 sig_caps = ib_conn->device->ib_device->attrs.sig_prot_cap;
 
                        scsi_host_set_prot(shost, iser_dif_prot_caps(sig_caps));
                        scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP |
@@ -656,7 +656,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
                 * max fastreg page list length.
                 */
                shost->sg_tablesize = min_t(unsigned short, shost->sg_tablesize,
-                       ib_conn->device->dev_attr.max_fast_reg_page_list_len);
+                       ib_conn->device->ib_device->attrs.max_fast_reg_page_list_len);
                shost->max_sectors = min_t(unsigned int,
                        1024, (shost->sg_tablesize * PAGE_SIZE) >> 9);
 
@@ -1059,7 +1059,8 @@ static int __init iser_init(void)
        release_wq = alloc_workqueue("release workqueue", 0, 0);
        if (!release_wq) {
                iser_err("failed to allocate release workqueue\n");
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_alloc_wq;
        }
 
        iscsi_iser_scsi_transport = iscsi_register_transport(
@@ -1067,12 +1068,14 @@ static int __init iser_init(void)
        if (!iscsi_iser_scsi_transport) {
                iser_err("iscsi_register_transport failed\n");
                err = -EINVAL;
-               goto register_transport_failure;
+               goto err_reg;
        }
 
        return 0;
 
-register_transport_failure:
+err_reg:
+       destroy_workqueue(release_wq);
+err_alloc_wq:
        kmem_cache_destroy(ig.desc_cache);
 
        return err;
index 8a5998e..95f0a64 100644 (file)
@@ -48,6 +48,7 @@
 #include <scsi/scsi_transport_iscsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
+#include <scsi/iser.h>
 
 #include <linux/interrupt.h>
 #include <linux/wait.h>
                                         - ISER_MAX_RX_MISC_PDUS) /     \
                                         (1 + ISER_INFLIGHT_DATAOUTS))
 
-#define ISER_WC_BATCH_COUNT   16
 #define ISER_SIGNAL_CMD_COUNT 32
 
-#define ISER_VER                       0x10
-#define ISER_WSV                       0x08
-#define ISER_RSV                       0x04
-
-#define ISER_FASTREG_LI_WRID           0xffffffffffffffffULL
-#define ISER_BEACON_WRID               0xfffffffffffffffeULL
-
-/**
- * struct iser_hdr - iSER header
- *
- * @flags:        flags support (zbva, remote_inv)
- * @rsvd:         reserved
- * @write_stag:   write rkey
- * @write_va:     write virtual address
- * @reaf_stag:    read rkey
- * @read_va:      read virtual address
- */
-struct iser_hdr {
-       u8      flags;
-       u8      rsvd[3];
-       __be32  write_stag;
-       __be64  write_va;
-       __be32  read_stag;
-       __be64  read_va;
-} __attribute__((packed));
-
-
-#define ISER_ZBVA_NOT_SUPPORTED                0x80
-#define ISER_SEND_W_INV_NOT_SUPPORTED  0x40
-
-struct iser_cm_hdr {
-       u8      flags;
-       u8      rsvd[3];
-} __packed;
-
 /* Constant PDU lengths calculations */
-#define ISER_HEADERS_LEN  (sizeof(struct iser_hdr) + sizeof(struct iscsi_hdr))
+#define ISER_HEADERS_LEN       (sizeof(struct iser_ctrl) + sizeof(struct iscsi_hdr))
 
 #define ISER_RECV_DATA_SEG_LEN 128
 #define ISER_RX_PAYLOAD_SIZE   (ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
@@ -269,7 +234,7 @@ enum iser_desc_type {
 #define ISER_MAX_WRS 7
 
 /**
- * struct iser_tx_desc - iSER TX descriptor (for send wr_id)
+ * struct iser_tx_desc - iSER TX descriptor
  *
  * @iser_header:   iser header
  * @iscsi_header:  iscsi header
@@ -287,12 +252,13 @@ enum iser_desc_type {
  * @sig_attrs:     Signature attributes
  */
 struct iser_tx_desc {
-       struct iser_hdr              iser_header;
+       struct iser_ctrl             iser_header;
        struct iscsi_hdr             iscsi_header;
        enum   iser_desc_type        type;
        u64                          dma_addr;
        struct ib_sge                tx_sg[2];
        int                          num_sge;
+       struct ib_cqe                cqe;
        bool                         mapped;
        u8                           wr_idx;
        union iser_wr {
@@ -306,9 +272,10 @@ struct iser_tx_desc {
 };
 
 #define ISER_RX_PAD_SIZE       (256 - (ISER_RX_PAYLOAD_SIZE + \
-                                       sizeof(u64) + sizeof(struct ib_sge)))
+                                sizeof(u64) + sizeof(struct ib_sge) + \
+                                sizeof(struct ib_cqe)))
 /**
- * struct iser_rx_desc - iSER RX descriptor (for recv wr_id)
+ * struct iser_rx_desc - iSER RX descriptor
  *
  * @iser_header:   iser header
  * @iscsi_header:  iscsi header
@@ -318,12 +285,32 @@ struct iser_tx_desc {
  * @pad:           for sense data TODO: Modify to maximum sense length supported
  */
 struct iser_rx_desc {
-       struct iser_hdr              iser_header;
+       struct iser_ctrl             iser_header;
        struct iscsi_hdr             iscsi_header;
        char                         data[ISER_RECV_DATA_SEG_LEN];
        u64                          dma_addr;
        struct ib_sge                rx_sg;
+       struct ib_cqe                cqe;
        char                         pad[ISER_RX_PAD_SIZE];
+} __packed;
+
+/**
+ * struct iser_login_desc - iSER login descriptor
+ *
+ * @req:           pointer to login request buffer
+ * @resp:          pointer to login response buffer
+ * @req_dma:       DMA address of login request buffer
+ * @rsp_dma:      DMA address of login response buffer
+ * @sge:           IB sge for login post recv
+ * @cqe:           completion handler
+ */
+struct iser_login_desc {
+       void                         *req;
+       void                         *rsp;
+       u64                          req_dma;
+       u64                          rsp_dma;
+       struct ib_sge                sge;
+       struct ib_cqe                cqe;
 } __attribute__((packed));
 
 struct iser_conn;
@@ -333,18 +320,12 @@ struct iscsi_iser_task;
 /**
  * struct iser_comp - iSER completion context
  *
- * @device:     pointer to device handle
  * @cq:         completion queue
- * @wcs:        work completion array
- * @tasklet:    Tasklet handle
  * @active_qps: Number of active QPs attached
  *              to completion context
  */
 struct iser_comp {
-       struct iser_device      *device;
        struct ib_cq            *cq;
-       struct ib_wc             wcs[ISER_WC_BATCH_COUNT];
-       struct tasklet_struct    tasklet;
        int                      active_qps;
 };
 
@@ -380,7 +361,6 @@ struct iser_reg_ops {
  *
  * @ib_device:     RDMA device
  * @pd:            Protection Domain for this device
- * @dev_attr:      Device attributes container
  * @mr:            Global DMA memory region
  * @event_handler: IB events handle routine
  * @ig_list:      entry in devices list
@@ -389,18 +369,19 @@ struct iser_reg_ops {
  *                 cpus and device max completion vectors
  * @comps:         Dinamically allocated array of completion handlers
  * @reg_ops:       Registration ops
+ * @remote_inv_sup: Remote invalidate is supported on this device
  */
 struct iser_device {
        struct ib_device             *ib_device;
        struct ib_pd                 *pd;
-       struct ib_device_attr        dev_attr;
        struct ib_mr                 *mr;
        struct ib_event_handler      event_handler;
        struct list_head             ig_list;
        int                          refcount;
        int                          comps_used;
        struct iser_comp             *comps;
-       struct iser_reg_ops          *reg_ops;
+       const struct iser_reg_ops    *reg_ops;
+       bool                         remote_inv_sup;
 };
 
 #define ISER_CHECK_GUARD       0xc0
@@ -475,10 +456,11 @@ struct iser_fr_pool {
  * @rx_wr:               receive work request for batch posts
  * @device:              reference to iser device
  * @comp:                iser completion context
- * @pi_support:          Indicate device T10-PI support
- * @beacon:              beacon send wr to signal all flush errors were drained
- * @flush_comp:          completes when all connection completions consumed
  * @fr_pool:             connection fast registration poool
+ * @pi_support:          Indicate device T10-PI support
+ * @last:                last send wr to signal all flush errors were drained
+ * @last_cqe:            cqe handler for last wr
+ * @last_comp:           completes when all connection completions consumed
  */
 struct ib_conn {
        struct rdma_cm_id           *cma_id;
@@ -488,10 +470,12 @@ struct ib_conn {
        struct ib_recv_wr            rx_wr[ISER_MIN_POSTED_RX];
        struct iser_device          *device;
        struct iser_comp            *comp;
-       bool                         pi_support;
-       struct ib_send_wr            beacon;
-       struct completion            flush_comp;
        struct iser_fr_pool          fr_pool;
+       bool                         pi_support;
+       struct ib_send_wr            last;
+       struct ib_cqe                last_cqe;
+       struct ib_cqe                reg_cqe;
+       struct completion            last_comp;
 };
 
 /**
@@ -514,11 +498,7 @@ struct ib_conn {
  * @up_completion:    connection establishment completed
  *                    (state is ISER_CONN_UP)
  * @conn_list:        entry in ig conn list
- * @login_buf:        login data buffer (stores login parameters)
- * @login_req_buf:    login request buffer
- * @login_req_dma:    login request buffer dma address
- * @login_resp_buf:   login response buffer
- * @login_resp_dma:   login response buffer dma address
+ * @login_desc:       login descriptor
  * @rx_desc_head:     head of rx_descs cyclic buffer
  * @rx_descs:         rx buffers array (cyclic buffer)
  * @num_rx_descs:     number of rx descriptors
@@ -541,15 +521,13 @@ struct iser_conn {
        struct completion            ib_completion;
        struct completion            up_completion;
        struct list_head             conn_list;
-
-       char                         *login_buf;
-       char                         *login_req_buf, *login_resp_buf;
-       u64                          login_req_dma, login_resp_dma;
+       struct iser_login_desc       login_desc;
        unsigned int                 rx_desc_head;
        struct iser_rx_desc          *rx_descs;
        u32                          num_rx_descs;
        unsigned short               scsi_sg_tablesize;
        unsigned int                 scsi_max_sectors;
+       bool                         snd_w_inv;
 };
 
 /**
@@ -579,9 +557,8 @@ struct iscsi_iser_task {
 
 struct iser_page_vec {
        u64 *pages;
-       int length;
-       int offset;
-       int data_size;
+       int npages;
+       struct ib_mr fake_mr;
 };
 
 /**
@@ -633,12 +610,14 @@ int iser_conn_terminate(struct iser_conn *iser_conn);
 
 void iser_release_work(struct work_struct *work);
 
-void iser_rcv_completion(struct iser_rx_desc *desc,
-                        unsigned long dto_xfer_len,
-                        struct ib_conn *ib_conn);
-
-void iser_snd_completion(struct iser_tx_desc *desc,
-                        struct ib_conn *ib_conn);
+void iser_err_comp(struct ib_wc *wc, const char *type);
+void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc);
+void iser_task_rsp(struct ib_cq *cq, struct ib_wc *wc);
+void iser_cmd_comp(struct ib_cq *cq, struct ib_wc *wc);
+void iser_ctrl_comp(struct ib_cq *cq, struct ib_wc *wc);
+void iser_dataout_comp(struct ib_cq *cq, struct ib_wc *wc);
+void iser_reg_comp(struct ib_cq *cq, struct ib_wc *wc);
+void iser_last_comp(struct ib_cq *cq, struct ib_wc *wc);
 
 void iser_task_rdma_init(struct iscsi_iser_task *task);
 
@@ -651,7 +630,8 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
                                     enum iser_data_dir cmd_dir);
 
 int iser_reg_rdma_mem(struct iscsi_iser_task *task,
-                     enum iser_data_dir dir);
+                     enum iser_data_dir dir,
+                     bool all_imm);
 void iser_unreg_rdma_mem(struct iscsi_iser_task *task,
                         enum iser_data_dir dir);
 
@@ -719,4 +699,28 @@ iser_tx_next_wr(struct iser_tx_desc *tx_desc)
        return cur_wr;
 }
 
+static inline struct iser_conn *
+to_iser_conn(struct ib_conn *ib_conn)
+{
+       return container_of(ib_conn, struct iser_conn, ib_conn);
+}
+
+static inline struct iser_rx_desc *
+iser_rx(struct ib_cqe *cqe)
+{
+       return container_of(cqe, struct iser_rx_desc, cqe);
+}
+
+static inline struct iser_tx_desc *
+iser_tx(struct ib_cqe *cqe)
+{
+       return container_of(cqe, struct iser_tx_desc, cqe);
+}
+
+static inline struct iser_login_desc *
+iser_login(struct ib_cqe *cqe)
+{
+       return container_of(cqe, struct iser_login_desc, cqe);
+}
+
 #endif
index ffd00c4..ed54b38 100644 (file)
@@ -51,7 +51,7 @@ static int iser_prepare_read_cmd(struct iscsi_task *task)
        struct iscsi_iser_task *iser_task = task->dd_data;
        struct iser_mem_reg *mem_reg;
        int err;
-       struct iser_hdr *hdr = &iser_task->desc.iser_header;
+       struct iser_ctrl *hdr = &iser_task->desc.iser_header;
        struct iser_data_buf *buf_in = &iser_task->data[ISER_DIR_IN];
 
        err = iser_dma_map_task_data(iser_task,
@@ -72,7 +72,7 @@ static int iser_prepare_read_cmd(struct iscsi_task *task)
                        return err;
        }
 
-       err = iser_reg_rdma_mem(iser_task, ISER_DIR_IN);
+       err = iser_reg_rdma_mem(iser_task, ISER_DIR_IN, false);
        if (err) {
                iser_err("Failed to set up Data-IN RDMA\n");
                return err;
@@ -104,7 +104,7 @@ iser_prepare_write_cmd(struct iscsi_task *task,
        struct iscsi_iser_task *iser_task = task->dd_data;
        struct iser_mem_reg *mem_reg;
        int err;
-       struct iser_hdr *hdr = &iser_task->desc.iser_header;
+       struct iser_ctrl *hdr = &iser_task->desc.iser_header;
        struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
        struct ib_sge *tx_dsg = &iser_task->desc.tx_sg[1];
 
@@ -126,7 +126,8 @@ iser_prepare_write_cmd(struct iscsi_task *task,
                        return err;
        }
 
-       err = iser_reg_rdma_mem(iser_task, ISER_DIR_OUT);
+       err = iser_reg_rdma_mem(iser_task, ISER_DIR_OUT,
+                               buf_out->data_len == imm_sz);
        if (err != 0) {
                iser_err("Failed to register write cmd RDMA mem\n");
                return err;
@@ -166,7 +167,7 @@ static void iser_create_send_desc(struct iser_conn  *iser_conn,
        ib_dma_sync_single_for_cpu(device->ib_device,
                tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
 
-       memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
+       memset(&tx_desc->iser_header, 0, sizeof(struct iser_ctrl));
        tx_desc->iser_header.flags = ISER_VER;
        tx_desc->num_sge = 1;
 }
@@ -174,73 +175,63 @@ static void iser_create_send_desc(struct iser_conn        *iser_conn,
 static void iser_free_login_buf(struct iser_conn *iser_conn)
 {
        struct iser_device *device = iser_conn->ib_conn.device;
+       struct iser_login_desc *desc = &iser_conn->login_desc;
 
-       if (!iser_conn->login_buf)
+       if (!desc->req)
                return;
 
-       if (iser_conn->login_req_dma)
-               ib_dma_unmap_single(device->ib_device,
-                                   iser_conn->login_req_dma,
-                                   ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
+       ib_dma_unmap_single(device->ib_device, desc->req_dma,
+                           ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
 
-       if (iser_conn->login_resp_dma)
-               ib_dma_unmap_single(device->ib_device,
-                                   iser_conn->login_resp_dma,
-                                   ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
+       ib_dma_unmap_single(device->ib_device, desc->rsp_dma,
+                           ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
 
-       kfree(iser_conn->login_buf);
+       kfree(desc->req);
+       kfree(desc->rsp);
 
        /* make sure we never redo any unmapping */
-       iser_conn->login_req_dma = 0;
-       iser_conn->login_resp_dma = 0;
-       iser_conn->login_buf = NULL;
+       desc->req = NULL;
+       desc->rsp = NULL;
 }
 
 static int iser_alloc_login_buf(struct iser_conn *iser_conn)
 {
        struct iser_device *device = iser_conn->ib_conn.device;
-       int                     req_err, resp_err;
-
-       BUG_ON(device == NULL);
-
-       iser_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN +
-                                    ISER_RX_LOGIN_SIZE, GFP_KERNEL);
-       if (!iser_conn->login_buf)
-               goto out_err;
-
-       iser_conn->login_req_buf  = iser_conn->login_buf;
-       iser_conn->login_resp_buf = iser_conn->login_buf +
-                                               ISCSI_DEF_MAX_RECV_SEG_LEN;
-
-       iser_conn->login_req_dma = ib_dma_map_single(device->ib_device,
-                                                    iser_conn->login_req_buf,
-                                                    ISCSI_DEF_MAX_RECV_SEG_LEN,
-                                                    DMA_TO_DEVICE);
-
-       iser_conn->login_resp_dma = ib_dma_map_single(device->ib_device,
-                                                     iser_conn->login_resp_buf,
-                                                     ISER_RX_LOGIN_SIZE,
-                                                     DMA_FROM_DEVICE);
-
-       req_err  = ib_dma_mapping_error(device->ib_device,
-                                       iser_conn->login_req_dma);
-       resp_err = ib_dma_mapping_error(device->ib_device,
-                                       iser_conn->login_resp_dma);
-
-       if (req_err || resp_err) {
-               if (req_err)
-                       iser_conn->login_req_dma = 0;
-               if (resp_err)
-                       iser_conn->login_resp_dma = 0;
-               goto free_login_buf;
-       }
+       struct iser_login_desc *desc = &iser_conn->login_desc;
+
+       desc->req = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL);
+       if (!desc->req)
+               return -ENOMEM;
+
+       desc->req_dma = ib_dma_map_single(device->ib_device, desc->req,
+                                         ISCSI_DEF_MAX_RECV_SEG_LEN,
+                                         DMA_TO_DEVICE);
+       if (ib_dma_mapping_error(device->ib_device,
+                               desc->req_dma))
+               goto free_req;
+
+       desc->rsp = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
+       if (!desc->rsp)
+               goto unmap_req;
+
+       desc->rsp_dma = ib_dma_map_single(device->ib_device, desc->rsp,
+                                          ISER_RX_LOGIN_SIZE,
+                                          DMA_FROM_DEVICE);
+       if (ib_dma_mapping_error(device->ib_device,
+                               desc->rsp_dma))
+               goto free_rsp;
+
        return 0;
 
-free_login_buf:
-       iser_free_login_buf(iser_conn);
+free_rsp:
+       kfree(desc->rsp);
+unmap_req:
+       ib_dma_unmap_single(device->ib_device, desc->req_dma,
+                           ISCSI_DEF_MAX_RECV_SEG_LEN,
+                           DMA_TO_DEVICE);
+free_req:
+       kfree(desc->req);
 
-out_err:
-       iser_err("unable to alloc or map login buf\n");
        return -ENOMEM;
 }
 
@@ -280,11 +271,11 @@ int iser_alloc_rx_descriptors(struct iser_conn *iser_conn,
                        goto rx_desc_dma_map_failed;
 
                rx_desc->dma_addr = dma_addr;
-
+               rx_desc->cqe.done = iser_task_rsp;
                rx_sg = &rx_desc->rx_sg;
-               rx_sg->addr   = rx_desc->dma_addr;
+               rx_sg->addr = rx_desc->dma_addr;
                rx_sg->length = ISER_RX_PAYLOAD_SIZE;
-               rx_sg->lkey   = device->pd->local_dma_lkey;
+               rx_sg->lkey = device->pd->local_dma_lkey;
        }
 
        iser_conn->rx_desc_head = 0;
@@ -383,6 +374,7 @@ int iser_send_command(struct iscsi_conn *conn,
 
        /* build the tx desc regd header and add it to the tx desc dto */
        tx_desc->type = ISCSI_TX_SCSI_COMMAND;
+       tx_desc->cqe.done = iser_cmd_comp;
        iser_create_send_desc(iser_conn, tx_desc);
 
        if (hdr->flags & ISCSI_FLAG_CMD_READ) {
@@ -464,6 +456,7 @@ int iser_send_data_out(struct iscsi_conn *conn,
        }
 
        tx_desc->type = ISCSI_TX_DATAOUT;
+       tx_desc->cqe.done = iser_dataout_comp;
        tx_desc->iser_header.flags = ISER_VER;
        memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr));
 
@@ -513,6 +506,7 @@ int iser_send_control(struct iscsi_conn *conn,
 
        /* build the tx desc regd header and add it to the tx desc dto */
        mdesc->type = ISCSI_TX_CONTROL;
+       mdesc->cqe.done = iser_ctrl_comp;
        iser_create_send_desc(iser_conn, mdesc);
 
        device = iser_conn->ib_conn.device;
@@ -520,25 +514,25 @@ int iser_send_control(struct iscsi_conn *conn,
        data_seg_len = ntoh24(task->hdr->dlength);
 
        if (data_seg_len > 0) {
+               struct iser_login_desc *desc = &iser_conn->login_desc;
                struct ib_sge *tx_dsg = &mdesc->tx_sg[1];
+
                if (task != conn->login_task) {
                        iser_err("data present on non login task!!!\n");
                        goto send_control_error;
                }
 
-               ib_dma_sync_single_for_cpu(device->ib_device,
-                       iser_conn->login_req_dma, task->data_count,
-                       DMA_TO_DEVICE);
+               ib_dma_sync_single_for_cpu(device->ib_device, desc->req_dma,
+                                          task->data_count, DMA_TO_DEVICE);
 
-               memcpy(iser_conn->login_req_buf, task->data, task->data_count);
+               memcpy(desc->req, task->data, task->data_count);
 
-               ib_dma_sync_single_for_device(device->ib_device,
-                       iser_conn->login_req_dma, task->data_count,
-                       DMA_TO_DEVICE);
+               ib_dma_sync_single_for_device(device->ib_device, desc->req_dma,
+                                             task->data_count, DMA_TO_DEVICE);
 
-               tx_dsg->addr    = iser_conn->login_req_dma;
-               tx_dsg->length  = task->data_count;
-               tx_dsg->lkey    = device->pd->local_dma_lkey;
+               tx_dsg->addr = desc->req_dma;
+               tx_dsg->length = task->data_count;
+               tx_dsg->lkey = device->pd->local_dma_lkey;
                mdesc->num_sge = 2;
        }
 
@@ -562,41 +556,126 @@ send_control_error:
        return err;
 }
 
-/**
- * iser_rcv_dto_completion - recv DTO completion
- */
-void iser_rcv_completion(struct iser_rx_desc *rx_desc,
-                        unsigned long rx_xfer_len,
-                        struct ib_conn *ib_conn)
+void iser_login_rsp(struct ib_cq *cq, struct ib_wc *wc)
 {
-       struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn,
-                                                  ib_conn);
+       struct ib_conn *ib_conn = wc->qp->qp_context;
+       struct iser_conn *iser_conn = to_iser_conn(ib_conn);
+       struct iser_login_desc *desc = iser_login(wc->wr_cqe);
        struct iscsi_hdr *hdr;
-       u64 rx_dma;
-       int rx_buflen, outstanding, count, err;
+       char *data;
+       int length;
 
-       /* differentiate between login to all other PDUs */
-       if ((char *)rx_desc == iser_conn->login_resp_buf) {
-               rx_dma = iser_conn->login_resp_dma;
-               rx_buflen = ISER_RX_LOGIN_SIZE;
-       } else {
-               rx_dma = rx_desc->dma_addr;
-               rx_buflen = ISER_RX_PAYLOAD_SIZE;
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               iser_err_comp(wc, "login_rsp");
+               return;
+       }
+
+       ib_dma_sync_single_for_cpu(ib_conn->device->ib_device,
+                                  desc->rsp_dma, ISER_RX_LOGIN_SIZE,
+                                  DMA_FROM_DEVICE);
+
+       hdr = desc->rsp + sizeof(struct iser_ctrl);
+       data = desc->rsp + ISER_HEADERS_LEN;
+       length = wc->byte_len - ISER_HEADERS_LEN;
+
+       iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
+                hdr->itt, length);
+
+       iscsi_iser_recv(iser_conn->iscsi_conn, hdr, data, length);
+
+       ib_dma_sync_single_for_device(ib_conn->device->ib_device,
+                                     desc->rsp_dma, ISER_RX_LOGIN_SIZE,
+                                     DMA_FROM_DEVICE);
+
+       ib_conn->post_recv_buf_count--;
+}
+
+static inline void
+iser_inv_desc(struct iser_fr_desc *desc, u32 rkey)
+{
+       if (likely(rkey == desc->rsc.mr->rkey))
+               desc->rsc.mr_valid = 0;
+       else if (likely(rkey == desc->pi_ctx->sig_mr->rkey))
+               desc->pi_ctx->sig_mr_valid = 0;
+}
+
+static int
+iser_check_remote_inv(struct iser_conn *iser_conn,
+                     struct ib_wc *wc,
+                     struct iscsi_hdr *hdr)
+{
+       if (wc->wc_flags & IB_WC_WITH_INVALIDATE) {
+               struct iscsi_task *task;
+               u32 rkey = wc->ex.invalidate_rkey;
+
+               iser_dbg("conn %p: remote invalidation for rkey %#x\n",
+                        iser_conn, rkey);
+
+               if (unlikely(!iser_conn->snd_w_inv)) {
+                       iser_err("conn %p: unexepected remote invalidation, "
+                                "terminating connection\n", iser_conn);
+                       return -EPROTO;
+               }
+
+               task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt);
+               if (likely(task)) {
+                       struct iscsi_iser_task *iser_task = task->dd_data;
+                       struct iser_fr_desc *desc;
+
+                       if (iser_task->dir[ISER_DIR_IN]) {
+                               desc = iser_task->rdma_reg[ISER_DIR_IN].mem_h;
+                               iser_inv_desc(desc, rkey);
+                       }
+
+                       if (iser_task->dir[ISER_DIR_OUT]) {
+                               desc = iser_task->rdma_reg[ISER_DIR_OUT].mem_h;
+                               iser_inv_desc(desc, rkey);
+                       }
+               } else {
+                       iser_err("failed to get task for itt=%d\n", hdr->itt);
+                       return -EINVAL;
+               }
        }
 
-       ib_dma_sync_single_for_cpu(ib_conn->device->ib_device, rx_dma,
-                                  rx_buflen, DMA_FROM_DEVICE);
+       return 0;
+}
 
-       hdr = &rx_desc->iscsi_header;
+
+void iser_task_rsp(struct ib_cq *cq, struct ib_wc *wc)
+{
+       struct ib_conn *ib_conn = wc->qp->qp_context;
+       struct iser_conn *iser_conn = to_iser_conn(ib_conn);
+       struct iser_rx_desc *desc = iser_rx(wc->wr_cqe);
+       struct iscsi_hdr *hdr;
+       int length;
+       int outstanding, count, err;
+
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               iser_err_comp(wc, "task_rsp");
+               return;
+       }
+
+       ib_dma_sync_single_for_cpu(ib_conn->device->ib_device,
+                                  desc->dma_addr, ISER_RX_PAYLOAD_SIZE,
+                                  DMA_FROM_DEVICE);
+
+       hdr = &desc->iscsi_header;
+       length = wc->byte_len - ISER_HEADERS_LEN;
 
        iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
-                       hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
+                hdr->itt, length);
+
+       if (iser_check_remote_inv(iser_conn, wc, hdr)) {
+               iscsi_conn_failure(iser_conn->iscsi_conn,
+                                  ISCSI_ERR_CONN_FAILED);
+               return;
+       }
 
-       iscsi_iser_recv(iser_conn->iscsi_conn, hdr, rx_desc->data,
-                       rx_xfer_len - ISER_HEADERS_LEN);
+       iscsi_iser_recv(iser_conn->iscsi_conn, hdr, desc->data, length);
 
-       ib_dma_sync_single_for_device(ib_conn->device->ib_device, rx_dma,
-                                     rx_buflen, DMA_FROM_DEVICE);
+       ib_dma_sync_single_for_device(ib_conn->device->ib_device,
+                                     desc->dma_addr, ISER_RX_PAYLOAD_SIZE,
+                                     DMA_FROM_DEVICE);
 
        /* decrementing conn->post_recv_buf_count only --after-- freeing the   *
         * task eliminates the need to worry on tasks which are completed in   *
@@ -604,9 +683,6 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
         * for the posted rx bufs refcount to become zero handles everything   */
        ib_conn->post_recv_buf_count--;
 
-       if (rx_dma == iser_conn->login_resp_dma)
-               return;
-
        outstanding = ib_conn->post_recv_buf_count;
        if (outstanding + iser_conn->min_posted_rx <= iser_conn->qp_max_recv_dtos) {
                count = min(iser_conn->qp_max_recv_dtos - outstanding,
@@ -617,26 +693,47 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
        }
 }
 
-void iser_snd_completion(struct iser_tx_desc *tx_desc,
-                       struct ib_conn *ib_conn)
+void iser_cmd_comp(struct ib_cq *cq, struct ib_wc *wc)
 {
+       if (unlikely(wc->status != IB_WC_SUCCESS))
+               iser_err_comp(wc, "command");
+}
+
+void iser_ctrl_comp(struct ib_cq *cq, struct ib_wc *wc)
+{
+       struct iser_tx_desc *desc = iser_tx(wc->wr_cqe);
        struct iscsi_task *task;
-       struct iser_device *device = ib_conn->device;
 
-       if (tx_desc->type == ISCSI_TX_DATAOUT) {
-               ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr,
-                                       ISER_HEADERS_LEN, DMA_TO_DEVICE);
-               kmem_cache_free(ig.desc_cache, tx_desc);
-               tx_desc = NULL;
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               iser_err_comp(wc, "control");
+               return;
        }
 
-       if (tx_desc && tx_desc->type == ISCSI_TX_CONTROL) {
-               /* this arithmetic is legal by libiscsi dd_data allocation */
-               task = (void *) ((long)(void *)tx_desc -
-                                 sizeof(struct iscsi_task));
-               if (task->hdr->itt == RESERVED_ITT)
-                       iscsi_put_task(task);
-       }
+       /* this arithmetic is legal by libiscsi dd_data allocation */
+       task = (void *)desc - sizeof(struct iscsi_task);
+       if (task->hdr->itt == RESERVED_ITT)
+               iscsi_put_task(task);
+}
+
+void iser_dataout_comp(struct ib_cq *cq, struct ib_wc *wc)
+{
+       struct iser_tx_desc *desc = iser_tx(wc->wr_cqe);
+       struct ib_conn *ib_conn = wc->qp->qp_context;
+       struct iser_device *device = ib_conn->device;
+
+       if (unlikely(wc->status != IB_WC_SUCCESS))
+               iser_err_comp(wc, "dataout");
+
+       ib_dma_unmap_single(device->ib_device, desc->dma_addr,
+                           ISER_HEADERS_LEN, DMA_TO_DEVICE);
+       kmem_cache_free(ig.desc_cache, desc);
+}
+
+void iser_last_comp(struct ib_cq *cq, struct ib_wc *wc)
+{
+       struct ib_conn *ib_conn = wc->qp->qp_context;
+
+       complete(&ib_conn->last_comp);
 }
 
 void iser_task_rdma_init(struct iscsi_iser_task *iser_task)
index ea765fb..9a391cc 100644 (file)
@@ -49,7 +49,7 @@ int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
                     struct iser_reg_resources *rsc,
                     struct iser_mem_reg *mem_reg);
 
-static struct iser_reg_ops fastreg_ops = {
+static const struct iser_reg_ops fastreg_ops = {
        .alloc_reg_res  = iser_alloc_fastreg_pool,
        .free_reg_res   = iser_free_fastreg_pool,
        .reg_mem        = iser_fast_reg_mr,
@@ -58,7 +58,7 @@ static struct iser_reg_ops fastreg_ops = {
        .reg_desc_put   = iser_reg_desc_put_fr,
 };
 
-static struct iser_reg_ops fmr_ops = {
+static const struct iser_reg_ops fmr_ops = {
        .alloc_reg_res  = iser_alloc_fmr_pool,
        .free_reg_res   = iser_free_fmr_pool,
        .reg_mem        = iser_fast_reg_fmr,
@@ -67,19 +67,24 @@ static struct iser_reg_ops fmr_ops = {
        .reg_desc_put   = iser_reg_desc_put_fmr,
 };
 
+void iser_reg_comp(struct ib_cq *cq, struct ib_wc *wc)
+{
+       iser_err_comp(wc, "memreg");
+}
+
 int iser_assign_reg_ops(struct iser_device *device)
 {
-       struct ib_device_attr *dev_attr = &device->dev_attr;
+       struct ib_device *ib_dev = device->ib_device;
 
        /* Assign function handles  - based on FMR support */
-       if (device->ib_device->alloc_fmr && device->ib_device->dealloc_fmr &&
-           device->ib_device->map_phys_fmr && device->ib_device->unmap_fmr) {
+       if (ib_dev->alloc_fmr && ib_dev->dealloc_fmr &&
+           ib_dev->map_phys_fmr && ib_dev->unmap_fmr) {
                iser_info("FMR supported, using FMR for registration\n");
                device->reg_ops = &fmr_ops;
-       } else
-       if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
+       } else if (ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
                iser_info("FastReg supported, using FastReg for registration\n");
                device->reg_ops = &fastreg_ops;
+               device->remote_inv_sup = iser_always_reg;
        } else {
                iser_err("IB device does not support FMRs nor FastRegs, can't register memory\n");
                return -1;
@@ -131,67 +136,6 @@ iser_reg_desc_put_fmr(struct ib_conn *ib_conn,
 {
 }
 
-#define IS_4K_ALIGNED(addr)    ((((unsigned long)addr) & ~MASK_4K) == 0)
-
-/**
- * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses
- * and returns the length of resulting physical address array (may be less than
- * the original due to possible compaction).
- *
- * we build a "page vec" under the assumption that the SG meets the RDMA
- * alignment requirements. Other then the first and last SG elements, all
- * the "internal" elements can be compacted into a list whose elements are
- * dma addresses of physical pages. The code supports also the weird case
- * where --few fragments of the same page-- are present in the SG as
- * consecutive elements. Also, it handles one entry SG.
- */
-
-static int iser_sg_to_page_vec(struct iser_data_buf *data,
-                              struct ib_device *ibdev, u64 *pages,
-                              int *offset, int *data_size)
-{
-       struct scatterlist *sg, *sgl = data->sg;
-       u64 start_addr, end_addr, page, chunk_start = 0;
-       unsigned long total_sz = 0;
-       unsigned int dma_len;
-       int i, new_chunk, cur_page, last_ent = data->dma_nents - 1;
-
-       /* compute the offset of first element */
-       *offset = (u64) sgl[0].offset & ~MASK_4K;
-
-       new_chunk = 1;
-       cur_page  = 0;
-       for_each_sg(sgl, sg, data->dma_nents, i) {
-               start_addr = ib_sg_dma_address(ibdev, sg);
-               if (new_chunk)
-                       chunk_start = start_addr;
-               dma_len = ib_sg_dma_len(ibdev, sg);
-               end_addr = start_addr + dma_len;
-               total_sz += dma_len;
-
-               /* collect page fragments until aligned or end of SG list */
-               if (!IS_4K_ALIGNED(end_addr) && i < last_ent) {
-                       new_chunk = 0;
-                       continue;
-               }
-               new_chunk = 1;
-
-               /* address of the first page in the contiguous chunk;
-                  masking relevant for the very first SG entry,
-                  which might be unaligned */
-               page = chunk_start & MASK_4K;
-               do {
-                       pages[cur_page++] = page;
-                       page += SIZE_4K;
-               } while (page < end_addr);
-       }
-
-       *data_size = total_sz;
-       iser_dbg("page_vec->data_size:%d cur_page %d\n",
-                *data_size, cur_page);
-       return cur_page;
-}
-
 static void iser_data_buf_dump(struct iser_data_buf *data,
                               struct ib_device *ibdev)
 {
@@ -210,10 +154,10 @@ static void iser_dump_page_vec(struct iser_page_vec *page_vec)
 {
        int i;
 
-       iser_err("page vec length %d data size %d\n",
-                page_vec->length, page_vec->data_size);
-       for (i = 0; i < page_vec->length; i++)
-               iser_err("%d %lx\n",i,(unsigned long)page_vec->pages[i]);
+       iser_err("page vec npages %d data length %d\n",
+                page_vec->npages, page_vec->fake_mr.length);
+       for (i = 0; i < page_vec->npages; i++)
+               iser_err("vec[%d]: %llx\n", i, page_vec->pages[i]);
 }
 
 int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
@@ -251,7 +195,11 @@ iser_reg_dma(struct iser_device *device, struct iser_data_buf *mem,
        struct scatterlist *sg = mem->sg;
 
        reg->sge.lkey = device->pd->local_dma_lkey;
-       reg->rkey = device->mr->rkey;
+       /*
+        * FIXME: rework the registration code path to differentiate
+        * rkey/lkey use cases
+        */
+       reg->rkey = device->mr ? device->mr->rkey : 0;
        reg->sge.addr = ib_sg_dma_address(device->ib_device, &sg[0]);
        reg->sge.length = ib_sg_dma_len(device->ib_device, &sg[0]);
 
@@ -262,11 +210,16 @@ iser_reg_dma(struct iser_device *device, struct iser_data_buf *mem,
        return 0;
 }
 
-/**
- * iser_reg_page_vec - Register physical memory
- *
- * returns: 0 on success, errno code on failure
- */
+static int iser_set_page(struct ib_mr *mr, u64 addr)
+{
+       struct iser_page_vec *page_vec =
+               container_of(mr, struct iser_page_vec, fake_mr);
+
+       page_vec->pages[page_vec->npages++] = addr;
+
+       return 0;
+}
+
 static
 int iser_fast_reg_fmr(struct iscsi_iser_task *iser_task,
                      struct iser_data_buf *mem,
@@ -280,22 +233,19 @@ int iser_fast_reg_fmr(struct iscsi_iser_task *iser_task,
        struct ib_pool_fmr *fmr;
        int ret, plen;
 
-       plen = iser_sg_to_page_vec(mem, device->ib_device,
-                                  page_vec->pages,
-                                  &page_vec->offset,
-                                  &page_vec->data_size);
-       page_vec->length = plen;
-       if (plen * SIZE_4K < page_vec->data_size) {
+       page_vec->npages = 0;
+       page_vec->fake_mr.page_size = SIZE_4K;
+       plen = ib_sg_to_pages(&page_vec->fake_mr, mem->sg,
+                             mem->size, iser_set_page);
+       if (unlikely(plen < mem->size)) {
                iser_err("page vec too short to hold this SG\n");
                iser_data_buf_dump(mem, device->ib_device);
                iser_dump_page_vec(page_vec);
                return -EINVAL;
        }
 
-       fmr  = ib_fmr_pool_map_phys(fmr_pool,
-                                   page_vec->pages,
-                                   page_vec->length,
-                                   page_vec->pages[0]);
+       fmr  = ib_fmr_pool_map_phys(fmr_pool, page_vec->pages,
+                                   page_vec->npages, page_vec->pages[0]);
        if (IS_ERR(fmr)) {
                ret = PTR_ERR(fmr);
                iser_err("ib_fmr_pool_map_phys failed: %d\n", ret);
@@ -304,8 +254,8 @@ int iser_fast_reg_fmr(struct iscsi_iser_task *iser_task,
 
        reg->sge.lkey = fmr->fmr->lkey;
        reg->rkey = fmr->fmr->rkey;
-       reg->sge.addr = page_vec->pages[0] + page_vec->offset;
-       reg->sge.length = page_vec->data_size;
+       reg->sge.addr = page_vec->fake_mr.iova;
+       reg->sge.length = page_vec->fake_mr.length;
        reg->mem_h = fmr;
 
        iser_dbg("fmr reg: lkey=0x%x, rkey=0x%x, addr=0x%llx,"
@@ -413,19 +363,16 @@ iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
                *mask |= ISER_CHECK_GUARD;
 }
 
-static void
-iser_inv_rkey(struct ib_send_wr *inv_wr, struct ib_mr *mr)
+static inline void
+iser_inv_rkey(struct ib_send_wr *inv_wr,
+             struct ib_mr *mr,
+             struct ib_cqe *cqe)
 {
-       u32 rkey;
-
        inv_wr->opcode = IB_WR_LOCAL_INV;
-       inv_wr->wr_id = ISER_FASTREG_LI_WRID;
+       inv_wr->wr_cqe = cqe;
        inv_wr->ex.invalidate_rkey = mr->rkey;
        inv_wr->send_flags = 0;
        inv_wr->num_sge = 0;
-
-       rkey = ib_inc_rkey(mr->rkey);
-       ib_update_fast_reg_key(mr, rkey);
 }
 
 static int
@@ -437,7 +384,9 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
 {
        struct iser_tx_desc *tx_desc = &iser_task->desc;
        struct ib_sig_attrs *sig_attrs = &tx_desc->sig_attrs;
+       struct ib_cqe *cqe = &iser_task->iser_conn->ib_conn.reg_cqe;
        struct ib_sig_handover_wr *wr;
+       struct ib_mr *mr = pi_ctx->sig_mr;
        int ret;
 
        memset(sig_attrs, 0, sizeof(*sig_attrs));
@@ -447,17 +396,19 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
 
        iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask);
 
-       if (!pi_ctx->sig_mr_valid)
-               iser_inv_rkey(iser_tx_next_wr(tx_desc), pi_ctx->sig_mr);
+       if (pi_ctx->sig_mr_valid)
+               iser_inv_rkey(iser_tx_next_wr(tx_desc), mr, cqe);
+
+       ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
 
        wr = sig_handover_wr(iser_tx_next_wr(tx_desc));
        wr->wr.opcode = IB_WR_REG_SIG_MR;
-       wr->wr.wr_id = ISER_FASTREG_LI_WRID;
+       wr->wr.wr_cqe = cqe;
        wr->wr.sg_list = &data_reg->sge;
        wr->wr.num_sge = 1;
        wr->wr.send_flags = 0;
        wr->sig_attrs = sig_attrs;
-       wr->sig_mr = pi_ctx->sig_mr;
+       wr->sig_mr = mr;
        if (scsi_prot_sg_count(iser_task->sc))
                wr->prot = &prot_reg->sge;
        else
@@ -465,10 +416,10 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
        wr->access_flags = IB_ACCESS_LOCAL_WRITE |
                           IB_ACCESS_REMOTE_READ |
                           IB_ACCESS_REMOTE_WRITE;
-       pi_ctx->sig_mr_valid = 0;
+       pi_ctx->sig_mr_valid = 1;
 
-       sig_reg->sge.lkey = pi_ctx->sig_mr->lkey;
-       sig_reg->rkey = pi_ctx->sig_mr->rkey;
+       sig_reg->sge.lkey = mr->lkey;
+       sig_reg->rkey = mr->rkey;
        sig_reg->sge.addr = 0;
        sig_reg->sge.length = scsi_transfer_length(iser_task->sc);
 
@@ -485,12 +436,15 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
                            struct iser_mem_reg *reg)
 {
        struct iser_tx_desc *tx_desc = &iser_task->desc;
+       struct ib_cqe *cqe = &iser_task->iser_conn->ib_conn.reg_cqe;
        struct ib_mr *mr = rsc->mr;
        struct ib_reg_wr *wr;
        int n;
 
-       if (!rsc->mr_valid)
-               iser_inv_rkey(iser_tx_next_wr(tx_desc), mr);
+       if (rsc->mr_valid)
+               iser_inv_rkey(iser_tx_next_wr(tx_desc), mr, cqe);
+
+       ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
 
        n = ib_map_mr_sg(mr, mem->sg, mem->size, SIZE_4K);
        if (unlikely(n != mem->size)) {
@@ -501,7 +455,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
 
        wr = reg_wr(iser_tx_next_wr(tx_desc));
        wr->wr.opcode = IB_WR_REG_MR;
-       wr->wr.wr_id = ISER_FASTREG_LI_WRID;
+       wr->wr.wr_cqe = cqe;
        wr->wr.send_flags = 0;
        wr->wr.num_sge = 0;
        wr->mr = mr;
@@ -510,7 +464,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
                     IB_ACCESS_REMOTE_WRITE |
                     IB_ACCESS_REMOTE_READ;
 
-       rsc->mr_valid = 0;
+       rsc->mr_valid = 1;
 
        reg->sge.lkey = mr->lkey;
        reg->rkey = mr->rkey;
@@ -554,7 +508,8 @@ iser_reg_data_sg(struct iscsi_iser_task *task,
 }
 
 int iser_reg_rdma_mem(struct iscsi_iser_task *task,
-                     enum iser_data_dir dir)
+                     enum iser_data_dir dir,
+                     bool all_imm)
 {
        struct ib_conn *ib_conn = &task->iser_conn->ib_conn;
        struct iser_device *device = ib_conn->device;
@@ -565,8 +520,8 @@ int iser_reg_rdma_mem(struct iscsi_iser_task *task,
        bool use_dma_key;
        int err;
 
-       use_dma_key = (mem->dma_nents == 1 && !iser_always_reg &&
-                      scsi_get_prot_op(task->sc) == SCSI_PROT_NORMAL);
+       use_dma_key = mem->dma_nents == 1 && (all_imm || !iser_always_reg) &&
+                     scsi_get_prot_op(task->sc) == SCSI_PROT_NORMAL;
 
        if (!use_dma_key) {
                desc = device->reg_ops->reg_desc_get(ib_conn);
index 42f4da6..40c0f49 100644 (file)
 #define ISER_MAX_CQ_LEN                (ISER_MAX_RX_LEN + ISER_MAX_TX_LEN + \
                                 ISCSI_ISER_MAX_CONN)
 
-static int iser_cq_poll_limit = 512;
-
-static void iser_cq_tasklet_fn(unsigned long data);
-static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
-
-static void iser_cq_event_callback(struct ib_event *cause, void *context)
-{
-       iser_err("cq event %s (%d)\n",
-                ib_event_msg(cause->event), cause->event);
-}
-
 static void iser_qp_event_callback(struct ib_event *cause, void *context)
 {
        iser_err("qp event %s (%d)\n",
@@ -78,59 +67,40 @@ static void iser_event_handler(struct ib_event_handler *handler,
  */
 static int iser_create_device_ib_res(struct iser_device *device)
 {
-       struct ib_device_attr *dev_attr = &device->dev_attr;
+       struct ib_device *ib_dev = device->ib_device;
        int ret, i, max_cqe;
 
-       ret = ib_query_device(device->ib_device, dev_attr);
-       if (ret) {
-               pr_warn("Query device failed for %s\n", device->ib_device->name);
-               return ret;
-       }
-
        ret = iser_assign_reg_ops(device);
        if (ret)
                return ret;
 
        device->comps_used = min_t(int, num_online_cpus(),
-                                device->ib_device->num_comp_vectors);
+                                ib_dev->num_comp_vectors);
 
        device->comps = kcalloc(device->comps_used, sizeof(*device->comps),
                                GFP_KERNEL);
        if (!device->comps)
                goto comps_err;
 
-       max_cqe = min(ISER_MAX_CQ_LEN, dev_attr->max_cqe);
+       max_cqe = min(ISER_MAX_CQ_LEN, ib_dev->attrs.max_cqe);
 
        iser_info("using %d CQs, device %s supports %d vectors max_cqe %d\n",
-                 device->comps_used, device->ib_device->name,
-                 device->ib_device->num_comp_vectors, max_cqe);
+                 device->comps_used, ib_dev->name,
+                 ib_dev->num_comp_vectors, max_cqe);
 
-       device->pd = ib_alloc_pd(device->ib_device);
+       device->pd = ib_alloc_pd(ib_dev);
        if (IS_ERR(device->pd))
                goto pd_err;
 
        for (i = 0; i < device->comps_used; i++) {
-               struct ib_cq_init_attr cq_attr = {};
                struct iser_comp *comp = &device->comps[i];
 
-               comp->device = device;
-               cq_attr.cqe = max_cqe;
-               cq_attr.comp_vector = i;
-               comp->cq = ib_create_cq(device->ib_device,
-                                       iser_cq_callback,
-                                       iser_cq_event_callback,
-                                       (void *)comp,
-                                       &cq_attr);
+               comp->cq = ib_alloc_cq(ib_dev, comp, max_cqe, i,
+                                      IB_POLL_SOFTIRQ);
                if (IS_ERR(comp->cq)) {
                        comp->cq = NULL;
                        goto cq_err;
                }
-
-               if (ib_req_notify_cq(comp->cq, IB_CQ_NEXT_COMP))
-                       goto cq_err;
-
-               tasklet_init(&comp->tasklet, iser_cq_tasklet_fn,
-                            (unsigned long)comp);
        }
 
        if (!iser_always_reg) {
@@ -140,11 +110,11 @@ static int iser_create_device_ib_res(struct iser_device *device)
 
                device->mr = ib_get_dma_mr(device->pd, access);
                if (IS_ERR(device->mr))
-                       goto dma_mr_err;
+                       goto cq_err;
        }
 
-       INIT_IB_EVENT_HANDLER(&device->event_handler, device->ib_device,
-                               iser_event_handler);
+       INIT_IB_EVENT_HANDLER(&device->event_handler, ib_dev,
+                             iser_event_handler);
        if (ib_register_event_handler(&device->event_handler))
                goto handler_err;
 
@@ -153,15 +123,12 @@ static int iser_create_device_ib_res(struct iser_device *device)
 handler_err:
        if (device->mr)
                ib_dereg_mr(device->mr);
-dma_mr_err:
-       for (i = 0; i < device->comps_used; i++)
-               tasklet_kill(&device->comps[i].tasklet);
 cq_err:
        for (i = 0; i < device->comps_used; i++) {
                struct iser_comp *comp = &device->comps[i];
 
                if (comp->cq)
-                       ib_destroy_cq(comp->cq);
+                       ib_free_cq(comp->cq);
        }
        ib_dealloc_pd(device->pd);
 pd_err:
@@ -182,8 +149,7 @@ static void iser_free_device_ib_res(struct iser_device *device)
        for (i = 0; i < device->comps_used; i++) {
                struct iser_comp *comp = &device->comps[i];
 
-               tasklet_kill(&comp->tasklet);
-               ib_destroy_cq(comp->cq);
+               ib_free_cq(comp->cq);
                comp->cq = NULL;
        }
 
@@ -299,7 +265,7 @@ iser_alloc_reg_res(struct ib_device *ib_device,
                iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret);
                return ret;
        }
-       res->mr_valid = 1;
+       res->mr_valid = 0;
 
        return 0;
 }
@@ -336,7 +302,7 @@ iser_alloc_pi_ctx(struct ib_device *ib_device,
                ret = PTR_ERR(pi_ctx->sig_mr);
                goto sig_mr_failure;
        }
-       pi_ctx->sig_mr_valid = 1;
+       pi_ctx->sig_mr_valid = 0;
        desc->pi_ctx->sig_protected = 0;
 
        return 0;
@@ -461,10 +427,9 @@ void iser_free_fastreg_pool(struct ib_conn *ib_conn)
  */
 static int iser_create_ib_conn_res(struct ib_conn *ib_conn)
 {
-       struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn,
-                                                  ib_conn);
+       struct iser_conn *iser_conn = to_iser_conn(ib_conn);
        struct iser_device      *device;
-       struct ib_device_attr *dev_attr;
+       struct ib_device        *ib_dev;
        struct ib_qp_init_attr  init_attr;
        int                     ret = -ENOMEM;
        int index, min_index = 0;
@@ -472,7 +437,7 @@ static int iser_create_ib_conn_res(struct ib_conn *ib_conn)
        BUG_ON(ib_conn->device == NULL);
 
        device = ib_conn->device;
-       dev_attr = &device->dev_attr;
+       ib_dev = device->ib_device;
 
        memset(&init_attr, 0, sizeof init_attr);
 
@@ -503,16 +468,16 @@ static int iser_create_ib_conn_res(struct ib_conn *ib_conn)
                iser_conn->max_cmds =
                        ISER_GET_MAX_XMIT_CMDS(ISER_QP_SIG_MAX_REQ_DTOS);
        } else {
-               if (dev_attr->max_qp_wr > ISER_QP_MAX_REQ_DTOS) {
+               if (ib_dev->attrs.max_qp_wr > ISER_QP_MAX_REQ_DTOS) {
                        init_attr.cap.max_send_wr  = ISER_QP_MAX_REQ_DTOS + 1;
                        iser_conn->max_cmds =
                                ISER_GET_MAX_XMIT_CMDS(ISER_QP_MAX_REQ_DTOS);
                } else {
-                       init_attr.cap.max_send_wr = dev_attr->max_qp_wr;
+                       init_attr.cap.max_send_wr = ib_dev->attrs.max_qp_wr;
                        iser_conn->max_cmds =
-                               ISER_GET_MAX_XMIT_CMDS(dev_attr->max_qp_wr);
+                               ISER_GET_MAX_XMIT_CMDS(ib_dev->attrs.max_qp_wr);
                        iser_dbg("device %s supports max_send_wr %d\n",
-                                device->ib_device->name, dev_attr->max_qp_wr);
+                                device->ib_device->name, ib_dev->attrs.max_qp_wr);
                }
        }
 
@@ -724,13 +689,13 @@ int iser_conn_terminate(struct iser_conn *iser_conn)
                                 iser_conn, err);
 
                /* post an indication that all flush errors were consumed */
-               err = ib_post_send(ib_conn->qp, &ib_conn->beacon, &bad_wr);
+               err = ib_post_send(ib_conn->qp, &ib_conn->last, &bad_wr);
                if (err) {
-                       iser_err("conn %p failed to post beacon", ib_conn);
+                       iser_err("conn %p failed to post last wr", ib_conn);
                        return 1;
                }
 
-               wait_for_completion(&ib_conn->flush_comp);
+               wait_for_completion(&ib_conn->last_comp);
        }
 
        return 1;
@@ -756,7 +721,7 @@ iser_calc_scsi_params(struct iser_conn *iser_conn,
 
        sg_tablesize = DIV_ROUND_UP(max_sectors * 512, SIZE_4K);
        sup_sg_tablesize = min_t(unsigned, ISCSI_ISER_MAX_SG_TABLESIZE,
-                                device->dev_attr.max_fast_reg_page_list_len);
+                                device->ib_device->attrs.max_fast_reg_page_list_len);
 
        if (sg_tablesize > sup_sg_tablesize) {
                sg_tablesize = sup_sg_tablesize;
@@ -799,7 +764,7 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id)
 
        /* connection T10-PI support */
        if (iser_pi_enable) {
-               if (!(device->dev_attr.device_cap_flags &
+               if (!(device->ib_device->attrs.device_cap_flags &
                      IB_DEVICE_SIGNATURE_HANDOVER)) {
                        iser_warn("T10-PI requested but not supported on %s, "
                                  "continue without T10-PI\n",
@@ -841,16 +806,17 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
                goto failure;
 
        memset(&conn_param, 0, sizeof conn_param);
-       conn_param.responder_resources = device->dev_attr.max_qp_rd_atom;
+       conn_param.responder_resources = device->ib_device->attrs.max_qp_rd_atom;
        conn_param.initiator_depth     = 1;
        conn_param.retry_count         = 7;
        conn_param.rnr_retry_count     = 6;
 
        memset(&req_hdr, 0, sizeof(req_hdr));
-       req_hdr.flags = (ISER_ZBVA_NOT_SUPPORTED |
-                       ISER_SEND_W_INV_NOT_SUPPORTED);
-       conn_param.private_data         = (void *)&req_hdr;
-       conn_param.private_data_len     = sizeof(struct iser_cm_hdr);
+       req_hdr.flags = ISER_ZBVA_NOT_SUP;
+       if (!device->remote_inv_sup)
+               req_hdr.flags |= ISER_SEND_W_INV_NOT_SUP;
+       conn_param.private_data = (void *)&req_hdr;
+       conn_param.private_data_len = sizeof(struct iser_cm_hdr);
 
        ret = rdma_connect(cma_id, &conn_param);
        if (ret) {
@@ -863,7 +829,8 @@ failure:
        iser_connect_error(cma_id);
 }
 
-static void iser_connected_handler(struct rdma_cm_id *cma_id)
+static void iser_connected_handler(struct rdma_cm_id *cma_id,
+                                  const void *private_data)
 {
        struct iser_conn *iser_conn;
        struct ib_qp_attr attr;
@@ -877,6 +844,15 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id)
        (void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr);
        iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num);
 
+       if (private_data) {
+               u8 flags = *(u8 *)private_data;
+
+               iser_conn->snd_w_inv = !(flags & ISER_SEND_W_INV_NOT_SUP);
+       }
+
+       iser_info("conn %p: negotiated %s invalidation\n",
+                 iser_conn, iser_conn->snd_w_inv ? "remote" : "local");
+
        iser_conn->state = ISER_CONN_UP;
        complete(&iser_conn->up_completion);
 }
@@ -928,7 +904,7 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
                iser_route_handler(cma_id);
                break;
        case RDMA_CM_EVENT_ESTABLISHED:
-               iser_connected_handler(cma_id);
+               iser_connected_handler(cma_id, event->param.conn.private_data);
                break;
        case RDMA_CM_EVENT_ADDR_ERROR:
        case RDMA_CM_EVENT_ROUTE_ERROR:
@@ -967,14 +943,21 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
 
 void iser_conn_init(struct iser_conn *iser_conn)
 {
+       struct ib_conn *ib_conn = &iser_conn->ib_conn;
+
        iser_conn->state = ISER_CONN_INIT;
-       iser_conn->ib_conn.post_recv_buf_count = 0;
-       init_completion(&iser_conn->ib_conn.flush_comp);
        init_completion(&iser_conn->stop_completion);
        init_completion(&iser_conn->ib_completion);
        init_completion(&iser_conn->up_completion);
        INIT_LIST_HEAD(&iser_conn->conn_list);
        mutex_init(&iser_conn->state_mutex);
+
+       ib_conn->post_recv_buf_count = 0;
+       ib_conn->reg_cqe.done = iser_reg_comp;
+       ib_conn->last_cqe.done = iser_last_comp;
+       ib_conn->last.wr_cqe = &ib_conn->last_cqe;
+       ib_conn->last.opcode = IB_WR_SEND;
+       init_completion(&ib_conn->last_comp);
 }
 
  /**
@@ -1000,9 +983,6 @@ int iser_connect(struct iser_conn   *iser_conn,
 
        iser_conn->state = ISER_CONN_PENDING;
 
-       ib_conn->beacon.wr_id = ISER_BEACON_WRID;
-       ib_conn->beacon.opcode = IB_WR_SEND;
-
        ib_conn->cma_id = rdma_create_id(&init_net, iser_cma_handler,
                                         (void *)iser_conn,
                                         RDMA_PS_TCP, IB_QPT_RC);
@@ -1045,56 +1025,60 @@ connect_failure:
 
 int iser_post_recvl(struct iser_conn *iser_conn)
 {
-       struct ib_recv_wr rx_wr, *rx_wr_failed;
        struct ib_conn *ib_conn = &iser_conn->ib_conn;
-       struct ib_sge     sge;
+       struct iser_login_desc *desc = &iser_conn->login_desc;
+       struct ib_recv_wr wr, *wr_failed;
        int ib_ret;
 
-       sge.addr   = iser_conn->login_resp_dma;
-       sge.length = ISER_RX_LOGIN_SIZE;
-       sge.lkey   = ib_conn->device->pd->local_dma_lkey;
+       desc->sge.addr = desc->rsp_dma;
+       desc->sge.length = ISER_RX_LOGIN_SIZE;
+       desc->sge.lkey = ib_conn->device->pd->local_dma_lkey;
 
-       rx_wr.wr_id   = (uintptr_t)iser_conn->login_resp_buf;
-       rx_wr.sg_list = &sge;
-       rx_wr.num_sge = 1;
-       rx_wr.next    = NULL;
+       desc->cqe.done = iser_login_rsp;
+       wr.wr_cqe = &desc->cqe;
+       wr.sg_list = &desc->sge;
+       wr.num_sge = 1;
+       wr.next = NULL;
 
        ib_conn->post_recv_buf_count++;
-       ib_ret  = ib_post_recv(ib_conn->qp, &rx_wr, &rx_wr_failed);
+       ib_ret = ib_post_recv(ib_conn->qp, &wr, &wr_failed);
        if (ib_ret) {
                iser_err("ib_post_recv failed ret=%d\n", ib_ret);
                ib_conn->post_recv_buf_count--;
        }
+
        return ib_ret;
 }
 
 int iser_post_recvm(struct iser_conn *iser_conn, int count)
 {
-       struct ib_recv_wr *rx_wr, *rx_wr_failed;
-       int i, ib_ret;
        struct ib_conn *ib_conn = &iser_conn->ib_conn;
        unsigned int my_rx_head = iser_conn->rx_desc_head;
        struct iser_rx_desc *rx_desc;
+       struct ib_recv_wr *wr, *wr_failed;
+       int i, ib_ret;
 
-       for (rx_wr = ib_conn->rx_wr, i = 0; i < count; i++, rx_wr++) {
-               rx_desc         = &iser_conn->rx_descs[my_rx_head];
-               rx_wr->wr_id    = (uintptr_t)rx_desc;
-               rx_wr->sg_list  = &rx_desc->rx_sg;
-               rx_wr->num_sge  = 1;
-               rx_wr->next     = rx_wr + 1;
+       for (wr = ib_conn->rx_wr, i = 0; i < count; i++, wr++) {
+               rx_desc = &iser_conn->rx_descs[my_rx_head];
+               rx_desc->cqe.done = iser_task_rsp;
+               wr->wr_cqe = &rx_desc->cqe;
+               wr->sg_list = &rx_desc->rx_sg;
+               wr->num_sge = 1;
+               wr->next = wr + 1;
                my_rx_head = (my_rx_head + 1) & iser_conn->qp_max_recv_dtos_mask;
        }
 
-       rx_wr--;
-       rx_wr->next = NULL; /* mark end of work requests list */
+       wr--;
+       wr->next = NULL; /* mark end of work requests list */
 
        ib_conn->post_recv_buf_count += count;
-       ib_ret  = ib_post_recv(ib_conn->qp, ib_conn->rx_wr, &rx_wr_failed);
+       ib_ret = ib_post_recv(ib_conn->qp, ib_conn->rx_wr, &wr_failed);
        if (ib_ret) {
                iser_err("ib_post_recv failed ret=%d\n", ib_ret);
                ib_conn->post_recv_buf_count -= count;
        } else
                iser_conn->rx_desc_head = my_rx_head;
+
        return ib_ret;
 }
 
@@ -1115,7 +1099,7 @@ int iser_post_send(struct ib_conn *ib_conn, struct iser_tx_desc *tx_desc,
                                      DMA_TO_DEVICE);
 
        wr->next = NULL;
-       wr->wr_id = (uintptr_t)tx_desc;
+       wr->wr_cqe = &tx_desc->cqe;
        wr->sg_list = tx_desc->tx_sg;
        wr->num_sge = tx_desc->num_sge;
        wr->opcode = IB_WR_SEND;
@@ -1129,149 +1113,6 @@ int iser_post_send(struct ib_conn *ib_conn, struct iser_tx_desc *tx_desc,
        return ib_ret;
 }
 
-/**
- * is_iser_tx_desc - Indicate if the completion wr_id
- *     is a TX descriptor or not.
- * @iser_conn: iser connection
- * @wr_id: completion WR identifier
- *
- * Since we cannot rely on wc opcode in FLUSH errors
- * we must work around it by checking if the wr_id address
- * falls in the iser connection rx_descs buffer. If so
- * it is an RX descriptor, otherwize it is a TX.
- */
-static inline bool
-is_iser_tx_desc(struct iser_conn *iser_conn, void *wr_id)
-{
-       void *start = iser_conn->rx_descs;
-       int len = iser_conn->num_rx_descs * sizeof(*iser_conn->rx_descs);
-
-       if (wr_id >= start && wr_id < start + len)
-               return false;
-
-       return true;
-}
-
-/**
- * iser_handle_comp_error() - Handle error completion
- * @ib_conn:   connection RDMA resources
- * @wc:        work completion
- *
- * Notes: We may handle a FLUSH error completion and in this case
- *        we only cleanup in case TX type was DATAOUT. For non-FLUSH
- *        error completion we should also notify iscsi layer that
- *        connection is failed (in case we passed bind stage).
- */
-static void
-iser_handle_comp_error(struct ib_conn *ib_conn,
-                      struct ib_wc *wc)
-{
-       void *wr_id = (void *)(uintptr_t)wc->wr_id;
-       struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn,
-                                                  ib_conn);
-
-       if (wc->status != IB_WC_WR_FLUSH_ERR)
-               if (iser_conn->iscsi_conn)
-                       iscsi_conn_failure(iser_conn->iscsi_conn,
-                                          ISCSI_ERR_CONN_FAILED);
-
-       if (wc->wr_id == ISER_FASTREG_LI_WRID)
-               return;
-
-       if (is_iser_tx_desc(iser_conn, wr_id)) {
-               struct iser_tx_desc *desc = wr_id;
-
-               if (desc->type == ISCSI_TX_DATAOUT)
-                       kmem_cache_free(ig.desc_cache, desc);
-       } else {
-               ib_conn->post_recv_buf_count--;
-       }
-}
-
-/**
- * iser_handle_wc - handle a single work completion
- * @wc: work completion
- *
- * Soft-IRQ context, work completion can be either
- * SEND or RECV, and can turn out successful or
- * with error (or flush error).
- */
-static void iser_handle_wc(struct ib_wc *wc)
-{
-       struct ib_conn *ib_conn;
-       struct iser_tx_desc *tx_desc;
-       struct iser_rx_desc *rx_desc;
-
-       ib_conn = wc->qp->qp_context;
-       if (likely(wc->status == IB_WC_SUCCESS)) {
-               if (wc->opcode == IB_WC_RECV) {
-                       rx_desc = (struct iser_rx_desc *)(uintptr_t)wc->wr_id;
-                       iser_rcv_completion(rx_desc, wc->byte_len,
-                                           ib_conn);
-               } else
-               if (wc->opcode == IB_WC_SEND) {
-                       tx_desc = (struct iser_tx_desc *)(uintptr_t)wc->wr_id;
-                       iser_snd_completion(tx_desc, ib_conn);
-               } else {
-                       iser_err("Unknown wc opcode %d\n", wc->opcode);
-               }
-       } else {
-               if (wc->status != IB_WC_WR_FLUSH_ERR)
-                       iser_err("%s (%d): wr id %llx vend_err %x\n",
-                                ib_wc_status_msg(wc->status), wc->status,
-                                wc->wr_id, wc->vendor_err);
-               else
-                       iser_dbg("%s (%d): wr id %llx\n",
-                                ib_wc_status_msg(wc->status), wc->status,
-                                wc->wr_id);
-
-               if (wc->wr_id == ISER_BEACON_WRID)
-                       /* all flush errors were consumed */
-                       complete(&ib_conn->flush_comp);
-               else
-                       iser_handle_comp_error(ib_conn, wc);
-       }
-}
-
-/**
- * iser_cq_tasklet_fn - iSER completion polling loop
- * @data: iSER completion context
- *
- * Soft-IRQ context, polling connection CQ until
- * either CQ was empty or we exausted polling budget
- */
-static void iser_cq_tasklet_fn(unsigned long data)
-{
-       struct iser_comp *comp = (struct iser_comp *)data;
-       struct ib_cq *cq = comp->cq;
-       struct ib_wc *const wcs = comp->wcs;
-       int i, n, completed = 0;
-
-       while ((n = ib_poll_cq(cq, ARRAY_SIZE(comp->wcs), wcs)) > 0) {
-               for (i = 0; i < n; i++)
-                       iser_handle_wc(&wcs[i]);
-
-               completed += n;
-               if (completed >= iser_cq_poll_limit)
-                       break;
-       }
-
-       /*
-        * It is assumed here that arming CQ only once its empty
-        * would not cause interrupts to be missed.
-        */
-       ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-
-       iser_dbg("got %d completions\n", completed);
-}
-
-static void iser_cq_callback(struct ib_cq *cq, void *cq_context)
-{
-       struct iser_comp *comp = cq_context;
-
-       tasklet_schedule(&comp->tasklet);
-}
-
 u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
                             enum iser_data_dir cmd_dir, sector_t *sector)
 {
@@ -1319,3 +1160,21 @@ err:
        /* Not alot we can do here, return ambiguous guard error */
        return 0x1;
 }
+
+void iser_err_comp(struct ib_wc *wc, const char *type)
+{
+       if (wc->status != IB_WC_WR_FLUSH_ERR) {
+               struct iser_conn *iser_conn = to_iser_conn(wc->qp->qp_context);
+
+               iser_err("%s failure: %s (%d) vend_err %x\n", type,
+                        ib_wc_status_msg(wc->status), wc->status,
+                        wc->vendor_err);
+
+               if (iser_conn->iscsi_conn)
+                       iscsi_conn_failure(iser_conn->iscsi_conn,
+                                          ISCSI_ERR_CONN_FAILED);
+       } else {
+               iser_dbg("%s failure: %s (%d)\n", type,
+                        ib_wc_status_msg(wc->status), wc->status);
+       }
+}
index 8a51c3b..f121e61 100644 (file)
@@ -29,7 +29,6 @@
 #include <target/iscsi/iscsi_transport.h>
 #include <linux/semaphore.h>
 
-#include "isert_proto.h"
 #include "ib_isert.h"
 
 #define        ISERT_MAX_CONN          8
@@ -95,22 +94,6 @@ isert_qp_event_callback(struct ib_event *e, void *context)
        }
 }
 
-static int
-isert_query_device(struct ib_device *ib_dev, struct ib_device_attr *devattr)
-{
-       int ret;
-
-       ret = ib_query_device(ib_dev, devattr);
-       if (ret) {
-               isert_err("ib_query_device() failed: %d\n", ret);
-               return ret;
-       }
-       isert_dbg("devattr->max_sge: %d\n", devattr->max_sge);
-       isert_dbg("devattr->max_sge_rd: %d\n", devattr->max_sge_rd);
-
-       return 0;
-}
-
 static struct isert_comp *
 isert_comp_get(struct isert_conn *isert_conn)
 {
@@ -157,9 +140,9 @@ isert_create_qp(struct isert_conn *isert_conn,
        attr.recv_cq = comp->cq;
        attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS;
        attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;
-       attr.cap.max_send_sge = device->dev_attr.max_sge;
-       isert_conn->max_sge = min(device->dev_attr.max_sge,
-                                 device->dev_attr.max_sge_rd);
+       attr.cap.max_send_sge = device->ib_device->attrs.max_sge;
+       isert_conn->max_sge = min(device->ib_device->attrs.max_sge,
+                                 device->ib_device->attrs.max_sge_rd);
        attr.cap.max_recv_sge = 1;
        attr.sq_sig_type = IB_SIGNAL_REQ_WR;
        attr.qp_type = IB_QPT_RC;
@@ -287,8 +270,7 @@ isert_free_comps(struct isert_device *device)
 }
 
 static int
-isert_alloc_comps(struct isert_device *device,
-                 struct ib_device_attr *attr)
+isert_alloc_comps(struct isert_device *device)
 {
        int i, max_cqe, ret = 0;
 
@@ -308,7 +290,7 @@ isert_alloc_comps(struct isert_device *device,
                return -ENOMEM;
        }
 
-       max_cqe = min(ISER_MAX_CQ_LEN, attr->max_cqe);
+       max_cqe = min(ISER_MAX_CQ_LEN, device->ib_device->attrs.max_cqe);
 
        for (i = 0; i < device->comps_used; i++) {
                struct ib_cq_init_attr cq_attr = {};
@@ -344,17 +326,15 @@ out_cq:
 static int
 isert_create_device_ib_res(struct isert_device *device)
 {
-       struct ib_device_attr *dev_attr;
+       struct ib_device *ib_dev = device->ib_device;
        int ret;
 
-       dev_attr = &device->dev_attr;
-       ret = isert_query_device(device->ib_device, dev_attr);
-       if (ret)
-               return ret;
+       isert_dbg("devattr->max_sge: %d\n", ib_dev->attrs.max_sge);
+       isert_dbg("devattr->max_sge_rd: %d\n", ib_dev->attrs.max_sge_rd);
 
        /* asign function handlers */
-       if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS &&
-           dev_attr->device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER) {
+       if (ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS &&
+           ib_dev->attrs.device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER) {
                device->use_fastreg = 1;
                device->reg_rdma_mem = isert_reg_rdma;
                device->unreg_rdma_mem = isert_unreg_rdma;
@@ -364,11 +344,11 @@ isert_create_device_ib_res(struct isert_device *device)
                device->unreg_rdma_mem = isert_unmap_cmd;
        }
 
-       ret = isert_alloc_comps(device, dev_attr);
+       ret = isert_alloc_comps(device);
        if (ret)
-               return ret;
+               goto out;
 
-       device->pd = ib_alloc_pd(device->ib_device);
+       device->pd = ib_alloc_pd(ib_dev);
        if (IS_ERR(device->pd)) {
                ret = PTR_ERR(device->pd);
                isert_err("failed to allocate pd, device %p, ret=%d\n",
@@ -377,13 +357,16 @@ isert_create_device_ib_res(struct isert_device *device)
        }
 
        /* Check signature cap */
-       device->pi_capable = dev_attr->device_cap_flags &
+       device->pi_capable = ib_dev->attrs.device_cap_flags &
                             IB_DEVICE_SIGNATURE_HANDOVER ? true : false;
 
        return 0;
 
 out_cq:
        isert_free_comps(device);
+out:
+       if (ret > 0)
+               ret = -EINVAL;
        return ret;
 }
 
@@ -673,6 +656,32 @@ out_login_buf:
        return ret;
 }
 
+static void
+isert_set_nego_params(struct isert_conn *isert_conn,
+                     struct rdma_conn_param *param)
+{
+       struct ib_device_attr *attr = &isert_conn->device->ib_device->attrs;
+
+       /* Set max inflight RDMA READ requests */
+       isert_conn->initiator_depth = min_t(u8, param->initiator_depth,
+                               attr->max_qp_init_rd_atom);
+       isert_dbg("Using initiator_depth: %u\n", isert_conn->initiator_depth);
+
+       if (param->private_data) {
+               u8 flags = *(u8 *)param->private_data;
+
+               /*
+                * use remote invalidation if the both initiator
+                * and the HCA support it
+                */
+               isert_conn->snd_w_inv = !(flags & ISER_SEND_W_INV_NOT_SUP) &&
+                                         (attr->device_cap_flags &
+                                          IB_DEVICE_MEM_MGT_EXTENSIONS);
+               if (isert_conn->snd_w_inv)
+                       isert_info("Using remote invalidation\n");
+       }
+}
+
 static int
 isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
 {
@@ -711,11 +720,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
        }
        isert_conn->device = device;
 
-       /* Set max inflight RDMA READ requests */
-       isert_conn->initiator_depth = min_t(u8,
-                               event->param.conn.initiator_depth,
-                               device->dev_attr.max_qp_init_rd_atom);
-       isert_dbg("Using initiator_depth: %u\n", isert_conn->initiator_depth);
+       isert_set_nego_params(isert_conn, &event->param.conn);
 
        ret = isert_conn_setup_qp(isert_conn, cma_id);
        if (ret)
@@ -1047,8 +1052,8 @@ isert_create_send_desc(struct isert_conn *isert_conn,
        ib_dma_sync_single_for_cpu(ib_dev, tx_desc->dma_addr,
                                   ISER_HEADERS_LEN, DMA_TO_DEVICE);
 
-       memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
-       tx_desc->iser_header.flags = ISER_VER;
+       memset(&tx_desc->iser_header, 0, sizeof(struct iser_ctrl));
+       tx_desc->iser_header.flags = ISCSI_CTRL;
 
        tx_desc->num_sge = 1;
        tx_desc->isert_cmd = isert_cmd;
@@ -1094,7 +1099,14 @@ isert_init_send_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
 
        isert_cmd->rdma_wr.iser_ib_op = ISER_IB_SEND;
        send_wr->wr_id = (uintptr_t)&isert_cmd->tx_desc;
-       send_wr->opcode = IB_WR_SEND;
+
+       if (isert_conn->snd_w_inv && isert_cmd->inv_rkey) {
+               send_wr->opcode  = IB_WR_SEND_WITH_INV;
+               send_wr->ex.invalidate_rkey = isert_cmd->inv_rkey;
+       } else {
+               send_wr->opcode = IB_WR_SEND;
+       }
+
        send_wr->sg_list = &tx_desc->tx_sg[0];
        send_wr->num_sge = isert_cmd->tx_desc.num_sge;
        send_wr->send_flags = IB_SEND_SIGNALED;
@@ -1483,6 +1495,7 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
                isert_cmd->read_va = read_va;
                isert_cmd->write_stag = write_stag;
                isert_cmd->write_va = write_va;
+               isert_cmd->inv_rkey = read_stag ? read_stag : write_stag;
 
                ret = isert_handle_scsi_cmd(isert_conn, isert_cmd, cmd,
                                        rx_desc, (unsigned char *)hdr);
@@ -1540,21 +1553,21 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
 static void
 isert_rx_do_work(struct iser_rx_desc *rx_desc, struct isert_conn *isert_conn)
 {
-       struct iser_hdr *iser_hdr = &rx_desc->iser_header;
+       struct iser_ctrl *iser_ctrl = &rx_desc->iser_header;
        uint64_t read_va = 0, write_va = 0;
        uint32_t read_stag = 0, write_stag = 0;
 
-       switch (iser_hdr->flags & 0xF0) {
+       switch (iser_ctrl->flags & 0xF0) {
        case ISCSI_CTRL:
-               if (iser_hdr->flags & ISER_RSV) {
-                       read_stag = be32_to_cpu(iser_hdr->read_stag);
-                       read_va = be64_to_cpu(iser_hdr->read_va);
+               if (iser_ctrl->flags & ISER_RSV) {
+                       read_stag = be32_to_cpu(iser_ctrl->read_stag);
+                       read_va = be64_to_cpu(iser_ctrl->read_va);
                        isert_dbg("ISER_RSV: read_stag: 0x%x read_va: 0x%llx\n",
                                  read_stag, (unsigned long long)read_va);
                }
-               if (iser_hdr->flags & ISER_WSV) {
-                       write_stag = be32_to_cpu(iser_hdr->write_stag);
-                       write_va = be64_to_cpu(iser_hdr->write_va);
+               if (iser_ctrl->flags & ISER_WSV) {
+                       write_stag = be32_to_cpu(iser_ctrl->write_stag);
+                       write_va = be64_to_cpu(iser_ctrl->write_va);
                        isert_dbg("ISER_WSV: write_stag: 0x%x write_va: 0x%llx\n",
                                  write_stag, (unsigned long long)write_va);
                }
@@ -1565,7 +1578,7 @@ isert_rx_do_work(struct iser_rx_desc *rx_desc, struct isert_conn *isert_conn)
                isert_err("iSER Hello message\n");
                break;
        default:
-               isert_warn("Unknown iSER hdr flags: 0x%02x\n", iser_hdr->flags);
+               isert_warn("Unknown iSER hdr flags: 0x%02x\n", iser_ctrl->flags);
                break;
        }
 
@@ -3092,12 +3105,20 @@ isert_rdma_accept(struct isert_conn *isert_conn)
        struct rdma_cm_id *cm_id = isert_conn->cm_id;
        struct rdma_conn_param cp;
        int ret;
+       struct iser_cm_hdr rsp_hdr;
 
        memset(&cp, 0, sizeof(struct rdma_conn_param));
        cp.initiator_depth = isert_conn->initiator_depth;
        cp.retry_count = 7;
        cp.rnr_retry_count = 7;
 
+       memset(&rsp_hdr, 0, sizeof(rsp_hdr));
+       rsp_hdr.flags = ISERT_ZBVA_NOT_USED;
+       if (!isert_conn->snd_w_inv)
+               rsp_hdr.flags = rsp_hdr.flags | ISERT_SEND_W_INV_NOT_USED;
+       cp.private_data = (void *)&rsp_hdr;
+       cp.private_data_len = sizeof(rsp_hdr);
+
        ret = rdma_accept(cm_id, &cp);
        if (ret) {
                isert_err("rdma_accept() failed with: %d\n", ret);
index 3d7fbc4..8d50453 100644 (file)
@@ -3,6 +3,8 @@
 #include <linux/in6.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
+#include <scsi/iser.h>
+
 
 #define DRV_NAME       "isert"
 #define PFX            DRV_NAME ": "
 #define isert_err(fmt, arg...) \
        pr_err(PFX "%s: " fmt, __func__ , ## arg)
 
+/* Constant PDU lengths calculations */
+#define ISER_HEADERS_LEN       (sizeof(struct iser_ctrl) + \
+                                sizeof(struct iscsi_hdr))
+#define ISER_RECV_DATA_SEG_LEN 8192
+#define ISER_RX_PAYLOAD_SIZE   (ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
+#define ISER_RX_LOGIN_SIZE     (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
+
+/* QP settings */
+/* Maximal bounds on received asynchronous PDUs */
+#define ISERT_MAX_TX_MISC_PDUS 4 /* NOOP_IN(2) , ASYNC_EVENT(2)   */
+
+#define ISERT_MAX_RX_MISC_PDUS 6 /*
+                                  * NOOP_OUT(2), TEXT(1),
+                                  * SCSI_TMFUNC(2), LOGOUT(1)
+                                  */
+
+#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* from libiscsi.h, must be power of 2 */
+
+#define ISERT_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX)
+
+#define ISERT_MIN_POSTED_RX    (ISCSI_DEF_XMIT_CMDS_MAX >> 2)
+
+#define ISERT_INFLIGHT_DATAOUTS        8
+
+#define ISERT_QP_MAX_REQ_DTOS  (ISCSI_DEF_XMIT_CMDS_MAX *    \
+                               (1 + ISERT_INFLIGHT_DATAOUTS) + \
+                               ISERT_MAX_TX_MISC_PDUS  + \
+                               ISERT_MAX_RX_MISC_PDUS)
+
+#define ISER_RX_PAD_SIZE       (ISER_RECV_DATA_SEG_LEN + 4096 - \
+               (ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge)))
+
 #define ISCSI_ISER_SG_TABLESIZE                256
 #define ISER_FASTREG_LI_WRID           0xffffffffffffffffULL
 #define ISER_BEACON_WRID               0xfffffffffffffffeULL
@@ -56,7 +90,7 @@ enum iser_conn_state {
 };
 
 struct iser_rx_desc {
-       struct iser_hdr iser_header;
+       struct iser_ctrl iser_header;
        struct iscsi_hdr iscsi_header;
        char            data[ISER_RECV_DATA_SEG_LEN];
        u64             dma_addr;
@@ -65,7 +99,7 @@ struct iser_rx_desc {
 } __packed;
 
 struct iser_tx_desc {
-       struct iser_hdr iser_header;
+       struct iser_ctrl iser_header;
        struct iscsi_hdr iscsi_header;
        enum isert_desc_type type;
        u64             dma_addr;
@@ -129,6 +163,7 @@ struct isert_cmd {
        uint32_t                write_stag;
        uint64_t                read_va;
        uint64_t                write_va;
+       uint32_t                inv_rkey;
        u64                     pdu_buf_dma;
        u32                     pdu_buf_len;
        struct isert_conn       *conn;
@@ -176,6 +211,7 @@ struct isert_conn {
        struct work_struct      release_work;
        struct ib_recv_wr       beacon;
        bool                    logout_posted;
+       bool                    snd_w_inv;
 };
 
 #define ISERT_MAX_CQ 64
@@ -207,7 +243,6 @@ struct isert_device {
        struct isert_comp       *comps;
        int                     comps_used;
        struct list_head        dev_node;
-       struct ib_device_attr   dev_attr;
        int                     (*reg_rdma_mem)(struct iscsi_conn *conn,
                                                    struct iscsi_cmd *cmd,
                                                    struct isert_rdma_wr *wr);
diff --git a/drivers/infiniband/ulp/isert/isert_proto.h b/drivers/infiniband/ulp/isert/isert_proto.h
deleted file mode 100644 (file)
index 4dccd31..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* From iscsi_iser.h */
-
-struct iser_hdr {
-       u8      flags;
-       u8      rsvd[3];
-       __be32  write_stag; /* write rkey */
-       __be64  write_va;
-       __be32  read_stag;  /* read rkey */
-       __be64  read_va;
-} __packed;
-
-/*Constant PDU lengths calculations */
-#define ISER_HEADERS_LEN  (sizeof(struct iser_hdr) + sizeof(struct iscsi_hdr))
-
-#define ISER_RECV_DATA_SEG_LEN  8192
-#define ISER_RX_PAYLOAD_SIZE    (ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
-#define ISER_RX_LOGIN_SIZE      (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
-
-/* QP settings */
-/* Maximal bounds on received asynchronous PDUs */
-#define ISERT_MAX_TX_MISC_PDUS 4 /* NOOP_IN(2) , ASYNC_EVENT(2)   */
-
-#define ISERT_MAX_RX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1),         *
-                                  * SCSI_TMFUNC(2), LOGOUT(1) */
-
-#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* from libiscsi.h, must be power of 2 */
-
-#define ISERT_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX)
-
-#define ISERT_MIN_POSTED_RX    (ISCSI_DEF_XMIT_CMDS_MAX >> 2)
-
-#define ISERT_INFLIGHT_DATAOUTS        8
-
-#define ISERT_QP_MAX_REQ_DTOS  (ISCSI_DEF_XMIT_CMDS_MAX *    \
-                               (1 + ISERT_INFLIGHT_DATAOUTS) + \
-                               ISERT_MAX_TX_MISC_PDUS  + \
-                               ISERT_MAX_RX_MISC_PDUS)
-
-#define ISER_RX_PAD_SIZE       (ISER_RECV_DATA_SEG_LEN + 4096 - \
-               (ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge)))
-
-#define ISER_VER       0x10
-#define ISER_WSV       0x08
-#define ISER_RSV       0x04
-#define ISCSI_CTRL     0x10
-#define ISER_HELLO     0x20
-#define ISER_HELLORPLY 0x30
index 3db9a65..03022f6 100644 (file)
@@ -132,8 +132,9 @@ MODULE_PARM_DESC(ch_count,
 
 static void srp_add_one(struct ib_device *device);
 static void srp_remove_one(struct ib_device *device, void *client_data);
-static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr);
-static void srp_send_completion(struct ib_cq *cq, void *ch_ptr);
+static void srp_recv_done(struct ib_cq *cq, struct ib_wc *wc);
+static void srp_handle_qp_err(struct ib_cq *cq, struct ib_wc *wc,
+               const char *opname);
 static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
 
 static struct scsi_transport_template *ib_srp_transport_template;
@@ -445,6 +446,17 @@ static struct srp_fr_pool *srp_alloc_fr_pool(struct srp_target_port *target)
                                  dev->max_pages_per_mr);
 }
 
+static void srp_drain_done(struct ib_cq *cq, struct ib_wc *wc)
+{
+       struct srp_rdma_ch *ch = cq->cq_context;
+
+       complete(&ch->done);
+}
+
+static struct ib_cqe srp_drain_cqe = {
+       .done           = srp_drain_done,
+};
+
 /**
  * srp_destroy_qp() - destroy an RDMA queue pair
  * @ch: SRP RDMA channel.
@@ -457,10 +469,11 @@ static struct srp_fr_pool *srp_alloc_fr_pool(struct srp_target_port *target)
 static void srp_destroy_qp(struct srp_rdma_ch *ch)
 {
        static struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };
-       static struct ib_recv_wr wr = { .wr_id = SRP_LAST_WR_ID };
+       static struct ib_recv_wr wr = { 0 };
        struct ib_recv_wr *bad_wr;
        int ret;
 
+       wr.wr_cqe = &srp_drain_cqe;
        /* Destroying a QP and reusing ch->done is only safe if not connected */
        WARN_ON_ONCE(ch->connected);
 
@@ -489,34 +502,27 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
        struct ib_fmr_pool *fmr_pool = NULL;
        struct srp_fr_pool *fr_pool = NULL;
        const int m = dev->use_fast_reg ? 3 : 1;
-       struct ib_cq_init_attr cq_attr = {};
        int ret;
 
        init_attr = kzalloc(sizeof *init_attr, GFP_KERNEL);
        if (!init_attr)
                return -ENOMEM;
 
-       /* + 1 for SRP_LAST_WR_ID */
-       cq_attr.cqe = target->queue_size + 1;
-       cq_attr.comp_vector = ch->comp_vector;
-       recv_cq = ib_create_cq(dev->dev, srp_recv_completion, NULL, ch,
-                              &cq_attr);
+       /* queue_size + 1 for ib_drain_qp */
+       recv_cq = ib_alloc_cq(dev->dev, ch, target->queue_size + 1,
+                               ch->comp_vector, IB_POLL_SOFTIRQ);
        if (IS_ERR(recv_cq)) {
                ret = PTR_ERR(recv_cq);
                goto err;
        }
 
-       cq_attr.cqe = m * target->queue_size;
-       cq_attr.comp_vector = ch->comp_vector;
-       send_cq = ib_create_cq(dev->dev, srp_send_completion, NULL, ch,
-                              &cq_attr);
+       send_cq = ib_alloc_cq(dev->dev, ch, m * target->queue_size,
+                               ch->comp_vector, IB_POLL_DIRECT);
        if (IS_ERR(send_cq)) {
                ret = PTR_ERR(send_cq);
                goto err_recv_cq;
        }
 
-       ib_req_notify_cq(recv_cq, IB_CQ_NEXT_COMP);
-
        init_attr->event_handler       = srp_qp_event;
        init_attr->cap.max_send_wr     = m * target->queue_size;
        init_attr->cap.max_recv_wr     = target->queue_size + 1;
@@ -558,9 +564,9 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
        if (ch->qp)
                srp_destroy_qp(ch);
        if (ch->recv_cq)
-               ib_destroy_cq(ch->recv_cq);
+               ib_free_cq(ch->recv_cq);
        if (ch->send_cq)
-               ib_destroy_cq(ch->send_cq);
+               ib_free_cq(ch->send_cq);
 
        ch->qp = qp;
        ch->recv_cq = recv_cq;
@@ -580,13 +586,13 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
        return 0;
 
 err_qp:
-       ib_destroy_qp(qp);
+       srp_destroy_qp(ch);
 
 err_send_cq:
-       ib_destroy_cq(send_cq);
+       ib_free_cq(send_cq);
 
 err_recv_cq:
-       ib_destroy_cq(recv_cq);
+       ib_free_cq(recv_cq);
 
 err:
        kfree(init_attr);
@@ -622,9 +628,10 @@ static void srp_free_ch_ib(struct srp_target_port *target,
                if (ch->fmr_pool)
                        ib_destroy_fmr_pool(ch->fmr_pool);
        }
+
        srp_destroy_qp(ch);
-       ib_destroy_cq(ch->send_cq);
-       ib_destroy_cq(ch->recv_cq);
+       ib_free_cq(ch->send_cq);
+       ib_free_cq(ch->recv_cq);
 
        /*
         * Avoid that the SCSI error handler tries to use this channel after
@@ -1041,18 +1048,25 @@ out:
        return ret <= 0 ? ret : -ENODEV;
 }
 
-static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey)
+static void srp_inv_rkey_err_done(struct ib_cq *cq, struct ib_wc *wc)
+{
+       srp_handle_qp_err(cq, wc, "INV RKEY");
+}
+
+static int srp_inv_rkey(struct srp_request *req, struct srp_rdma_ch *ch,
+               u32 rkey)
 {
        struct ib_send_wr *bad_wr;
        struct ib_send_wr wr = {
                .opcode             = IB_WR_LOCAL_INV,
-               .wr_id              = LOCAL_INV_WR_ID_MASK,
                .next               = NULL,
                .num_sge            = 0,
                .send_flags         = 0,
                .ex.invalidate_rkey = rkey,
        };
 
+       wr.wr_cqe = &req->reg_cqe;
+       req->reg_cqe.done = srp_inv_rkey_err_done;
        return ib_post_send(ch->qp, &wr, &bad_wr);
 }
 
@@ -1074,7 +1088,7 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
                struct srp_fr_desc **pfr;
 
                for (i = req->nmdesc, pfr = req->fr_list; i > 0; i--, pfr++) {
-                       res = srp_inv_rkey(ch, (*pfr)->mr->rkey);
+                       res = srp_inv_rkey(req, ch, (*pfr)->mr->rkey);
                        if (res < 0) {
                                shost_printk(KERN_ERR, target->scsi_host, PFX
                                  "Queueing INV WR for rkey %#x failed (%d)\n",
@@ -1312,7 +1326,13 @@ reset_state:
        return 0;
 }
 
+static void srp_reg_mr_err_done(struct ib_cq *cq, struct ib_wc *wc)
+{
+       srp_handle_qp_err(cq, wc, "FAST REG");
+}
+
 static int srp_map_finish_fr(struct srp_map_state *state,
+                            struct srp_request *req,
                             struct srp_rdma_ch *ch, int sg_nents)
 {
        struct srp_target_port *target = ch->target;
@@ -1349,9 +1369,11 @@ static int srp_map_finish_fr(struct srp_map_state *state,
        if (unlikely(n < 0))
                return n;
 
+       req->reg_cqe.done = srp_reg_mr_err_done;
+
        wr.wr.next = NULL;
        wr.wr.opcode = IB_WR_REG_MR;
-       wr.wr.wr_id = FAST_REG_WR_ID_MASK;
+       wr.wr.wr_cqe = &req->reg_cqe;
        wr.wr.num_sge = 0;
        wr.wr.send_flags = 0;
        wr.mr = desc->mr;
@@ -1455,7 +1477,7 @@ static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch,
        while (count) {
                int i, n;
 
-               n = srp_map_finish_fr(state, ch, count);
+               n = srp_map_finish_fr(state, req, ch, count);
                if (unlikely(n < 0))
                        return n;
 
@@ -1524,7 +1546,7 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,
 #ifdef CONFIG_NEED_SG_DMA_LENGTH
                idb_sg->dma_length = idb_sg->length;          /* hack^2 */
 #endif
-               ret = srp_map_finish_fr(&state, ch, 1);
+               ret = srp_map_finish_fr(&state, req, ch, 1);
                if (ret < 0)
                        return ret;
        } else if (dev->use_fmr) {
@@ -1719,7 +1741,7 @@ static struct srp_iu *__srp_get_tx_iu(struct srp_rdma_ch *ch,
        s32 rsv = (iu_type == SRP_IU_TSK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE;
        struct srp_iu *iu;
 
-       srp_send_completion(ch->send_cq, ch);
+       ib_process_cq_direct(ch->send_cq, -1);
 
        if (list_empty(&ch->free_tx))
                return NULL;
@@ -1739,6 +1761,19 @@ static struct srp_iu *__srp_get_tx_iu(struct srp_rdma_ch *ch,
        return iu;
 }
 
+static void srp_send_done(struct ib_cq *cq, struct ib_wc *wc)
+{
+       struct srp_iu *iu = container_of(wc->wr_cqe, struct srp_iu, cqe);
+       struct srp_rdma_ch *ch = cq->cq_context;
+
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               srp_handle_qp_err(cq, wc, "SEND");
+               return;
+       }
+
+       list_add(&iu->list, &ch->free_tx);
+}
+
 static int srp_post_send(struct srp_rdma_ch *ch, struct srp_iu *iu, int len)
 {
        struct srp_target_port *target = ch->target;
@@ -1749,8 +1784,10 @@ static int srp_post_send(struct srp_rdma_ch *ch, struct srp_iu *iu, int len)
        list.length = len;
        list.lkey   = target->lkey;
 
+       iu->cqe.done = srp_send_done;
+
        wr.next       = NULL;
-       wr.wr_id      = (uintptr_t) iu;
+       wr.wr_cqe     = &iu->cqe;
        wr.sg_list    = &list;
        wr.num_sge    = 1;
        wr.opcode     = IB_WR_SEND;
@@ -1769,8 +1806,10 @@ static int srp_post_recv(struct srp_rdma_ch *ch, struct srp_iu *iu)
        list.length = iu->size;
        list.lkey   = target->lkey;
 
+       iu->cqe.done = srp_recv_done;
+
        wr.next     = NULL;
-       wr.wr_id    = (uintptr_t) iu;
+       wr.wr_cqe   = &iu->cqe;
        wr.sg_list  = &list;
        wr.num_sge  = 1;
 
@@ -1902,14 +1941,20 @@ static void srp_process_aer_req(struct srp_rdma_ch *ch,
                             "problems processing SRP_AER_REQ\n");
 }
 
-static void srp_handle_recv(struct srp_rdma_ch *ch, struct ib_wc *wc)
+static void srp_recv_done(struct ib_cq *cq, struct ib_wc *wc)
 {
+       struct srp_iu *iu = container_of(wc->wr_cqe, struct srp_iu, cqe);
+       struct srp_rdma_ch *ch = cq->cq_context;
        struct srp_target_port *target = ch->target;
        struct ib_device *dev = target->srp_host->srp_dev->dev;
-       struct srp_iu *iu = (struct srp_iu *) (uintptr_t) wc->wr_id;
        int res;
        u8 opcode;
 
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               srp_handle_qp_err(cq, wc, "RECV");
+               return;
+       }
+
        ib_dma_sync_single_for_cpu(dev, iu->dma, ch->max_ti_iu_len,
                                   DMA_FROM_DEVICE);
 
@@ -1972,68 +2017,22 @@ static void srp_tl_err_work(struct work_struct *work)
                srp_start_tl_fail_timers(target->rport);
 }
 
-static void srp_handle_qp_err(u64 wr_id, enum ib_wc_status wc_status,
-                             bool send_err, struct srp_rdma_ch *ch)
+static void srp_handle_qp_err(struct ib_cq *cq, struct ib_wc *wc,
+               const char *opname)
 {
+       struct srp_rdma_ch *ch = cq->cq_context;
        struct srp_target_port *target = ch->target;
 
-       if (wr_id == SRP_LAST_WR_ID) {
-               complete(&ch->done);
-               return;
-       }
-
        if (ch->connected && !target->qp_in_error) {
-               if (wr_id & LOCAL_INV_WR_ID_MASK) {
-                       shost_printk(KERN_ERR, target->scsi_host, PFX
-                                    "LOCAL_INV failed with status %s (%d)\n",
-                                    ib_wc_status_msg(wc_status), wc_status);
-               } else if (wr_id & FAST_REG_WR_ID_MASK) {
-                       shost_printk(KERN_ERR, target->scsi_host, PFX
-                                    "FAST_REG_MR failed status %s (%d)\n",
-                                    ib_wc_status_msg(wc_status), wc_status);
-               } else {
-                       shost_printk(KERN_ERR, target->scsi_host,
-                                    PFX "failed %s status %s (%d) for iu %p\n",
-                                    send_err ? "send" : "receive",
-                                    ib_wc_status_msg(wc_status), wc_status,
-                                    (void *)(uintptr_t)wr_id);
-               }
+               shost_printk(KERN_ERR, target->scsi_host,
+                            PFX "failed %s status %s (%d) for CQE %p\n",
+                            opname, ib_wc_status_msg(wc->status), wc->status,
+                            wc->wr_cqe);
                queue_work(system_long_wq, &target->tl_err_work);
        }
        target->qp_in_error = true;
 }
 
-static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr)
-{
-       struct srp_rdma_ch *ch = ch_ptr;
-       struct ib_wc wc;
-
-       ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-       while (ib_poll_cq(cq, 1, &wc) > 0) {
-               if (likely(wc.status == IB_WC_SUCCESS)) {
-                       srp_handle_recv(ch, &wc);
-               } else {
-                       srp_handle_qp_err(wc.wr_id, wc.status, false, ch);
-               }
-       }
-}
-
-static void srp_send_completion(struct ib_cq *cq, void *ch_ptr)
-{
-       struct srp_rdma_ch *ch = ch_ptr;
-       struct ib_wc wc;
-       struct srp_iu *iu;
-
-       while (ib_poll_cq(cq, 1, &wc) > 0) {
-               if (likely(wc.status == IB_WC_SUCCESS)) {
-                       iu = (struct srp_iu *) (uintptr_t) wc.wr_id;
-                       list_add(&iu->list, &ch->free_tx);
-               } else {
-                       srp_handle_qp_err(wc.wr_id, wc.status, true, ch);
-               }
-       }
-}
-
 static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
 {
        struct srp_target_port *target = host_to_target(shost);
@@ -3439,27 +3438,17 @@ free_host:
 static void srp_add_one(struct ib_device *device)
 {
        struct srp_device *srp_dev;
-       struct ib_device_attr *dev_attr;
        struct srp_host *host;
        int mr_page_shift, p;
        u64 max_pages_per_mr;
 
-       dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL);
-       if (!dev_attr)
-               return;
-
-       if (ib_query_device(device, dev_attr)) {
-               pr_warn("Query device failed for %s\n", device->name);
-               goto free_attr;
-       }
-
        srp_dev = kmalloc(sizeof *srp_dev, GFP_KERNEL);
        if (!srp_dev)
-               goto free_attr;
+               return;
 
        srp_dev->has_fmr = (device->alloc_fmr && device->dealloc_fmr &&
                            device->map_phys_fmr && device->unmap_fmr);
-       srp_dev->has_fr = (dev_attr->device_cap_flags &
+       srp_dev->has_fr = (device->attrs.device_cap_flags &
                           IB_DEVICE_MEM_MGT_EXTENSIONS);
        if (!srp_dev->has_fmr && !srp_dev->has_fr)
                dev_warn(&device->dev, "neither FMR nor FR is supported\n");
@@ -3473,23 +3462,23 @@ static void srp_add_one(struct ib_device *device)
         * minimum of 4096 bytes. We're unlikely to build large sglists
         * out of smaller entries.
         */
-       mr_page_shift           = max(12, ffs(dev_attr->page_size_cap) - 1);
+       mr_page_shift           = max(12, ffs(device->attrs.page_size_cap) - 1);
        srp_dev->mr_page_size   = 1 << mr_page_shift;
        srp_dev->mr_page_mask   = ~((u64) srp_dev->mr_page_size - 1);
-       max_pages_per_mr        = dev_attr->max_mr_size;
+       max_pages_per_mr        = device->attrs.max_mr_size;
        do_div(max_pages_per_mr, srp_dev->mr_page_size);
        srp_dev->max_pages_per_mr = min_t(u64, SRP_MAX_PAGES_PER_MR,
                                          max_pages_per_mr);
        if (srp_dev->use_fast_reg) {
                srp_dev->max_pages_per_mr =
                        min_t(u32, srp_dev->max_pages_per_mr,
-                             dev_attr->max_fast_reg_page_list_len);
+                             device->attrs.max_fast_reg_page_list_len);
        }
        srp_dev->mr_max_size    = srp_dev->mr_page_size *
                                   srp_dev->max_pages_per_mr;
-       pr_debug("%s: mr_page_shift = %d, dev_attr->max_mr_size = %#llx, dev_attr->max_fast_reg_page_list_len = %u, max_pages_per_mr = %d, mr_max_size = %#x\n",
-                device->name, mr_page_shift, dev_attr->max_mr_size,
-                dev_attr->max_fast_reg_page_list_len,
+       pr_debug("%s: mr_page_shift = %d, device->max_mr_size = %#llx, device->max_fast_reg_page_list_len = %u, max_pages_per_mr = %d, mr_max_size = %#x\n",
+                device->name, mr_page_shift, device->attrs.max_mr_size,
+                device->attrs.max_fast_reg_page_list_len,
                 srp_dev->max_pages_per_mr, srp_dev->mr_max_size);
 
        INIT_LIST_HEAD(&srp_dev->dev_list);
@@ -3517,17 +3506,13 @@ static void srp_add_one(struct ib_device *device)
        }
 
        ib_set_client_data(device, &srp_client, srp_dev);
-
-       goto free_attr;
+       return;
 
 err_pd:
        ib_dealloc_pd(srp_dev->pd);
 
 free_dev:
        kfree(srp_dev);
-
-free_attr:
-       kfree(dev_attr);
 }
 
 static void srp_remove_one(struct ib_device *device, void *client_data)
@@ -3587,8 +3572,6 @@ static int __init srp_init_module(void)
 {
        int ret;
 
-       BUILD_BUG_ON(FIELD_SIZEOF(struct ib_wc, wr_id) < sizeof(void *));
-
        if (srp_sg_tablesize) {
                pr_warn("srp_sg_tablesize is deprecated, please use cmd_sg_entries\n");
                if (!cmd_sg_entries)
index f6af531..9e05ce4 100644 (file)
@@ -66,11 +66,6 @@ enum {
        SRP_TAG_TSK_MGMT        = 1U << 31,
 
        SRP_MAX_PAGES_PER_MR    = 512,
-
-       LOCAL_INV_WR_ID_MASK    = 1,
-       FAST_REG_WR_ID_MASK     = 2,
-
-       SRP_LAST_WR_ID          = 0xfffffffcU,
 };
 
 enum srp_target_state {
@@ -128,6 +123,7 @@ struct srp_request {
        struct srp_direct_buf  *indirect_desc;
        dma_addr_t              indirect_dma_addr;
        short                   nmdesc;
+       struct ib_cqe           reg_cqe;
 };
 
 /**
@@ -231,6 +227,7 @@ struct srp_iu {
        void                   *buf;
        size_t                  size;
        enum dma_data_direction direction;
+       struct ib_cqe           cqe;
 };
 
 /**
index 2e2fe81..0c37fee 100644 (file)
@@ -93,6 +93,8 @@ MODULE_PARM_DESC(srpt_service_guid,
 static struct ib_client srpt_client;
 static void srpt_release_channel(struct srpt_rdma_ch *ch);
 static int srpt_queue_status(struct se_cmd *cmd);
+static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc);
+static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc);
 
 /**
  * opposite_dma_dir() - Swap DMA_TO_DEVICE and DMA_FROM_DEVICE.
@@ -341,10 +343,10 @@ static void srpt_get_ioc(struct srpt_port *sport, u32 slot,
        memset(iocp, 0, sizeof *iocp);
        strcpy(iocp->id_string, SRPT_ID_STRING);
        iocp->guid = cpu_to_be64(srpt_service_guid);
-       iocp->vendor_id = cpu_to_be32(sdev->dev_attr.vendor_id);
-       iocp->device_id = cpu_to_be32(sdev->dev_attr.vendor_part_id);
-       iocp->device_version = cpu_to_be16(sdev->dev_attr.hw_ver);
-       iocp->subsys_vendor_id = cpu_to_be32(sdev->dev_attr.vendor_id);
+       iocp->vendor_id = cpu_to_be32(sdev->device->attrs.vendor_id);
+       iocp->device_id = cpu_to_be32(sdev->device->attrs.vendor_part_id);
+       iocp->device_version = cpu_to_be16(sdev->device->attrs.hw_ver);
+       iocp->subsys_vendor_id = cpu_to_be32(sdev->device->attrs.vendor_id);
        iocp->subsys_device_id = 0x0;
        iocp->io_class = cpu_to_be16(SRP_REV16A_IB_IO_CLASS);
        iocp->io_subclass = cpu_to_be16(SRP_IO_SUBCLASS);
@@ -453,6 +455,7 @@ static void srpt_mad_send_handler(struct ib_mad_agent *mad_agent,
  * srpt_mad_recv_handler() - MAD reception callback function.
  */
 static void srpt_mad_recv_handler(struct ib_mad_agent *mad_agent,
+                                 struct ib_mad_send_buf *send_buf,
                                  struct ib_mad_recv_wc *mad_wc)
 {
        struct srpt_port *sport = (struct srpt_port *)mad_agent->context;
@@ -778,12 +781,12 @@ static int srpt_post_recv(struct srpt_device *sdev,
        struct ib_recv_wr wr, *bad_wr;
 
        BUG_ON(!sdev);
-       wr.wr_id = encode_wr_id(SRPT_RECV, ioctx->ioctx.index);
-
        list.addr = ioctx->ioctx.dma;
        list.length = srp_max_req_size;
        list.lkey = sdev->pd->local_dma_lkey;
 
+       ioctx->ioctx.cqe.done = srpt_recv_done;
+       wr.wr_cqe = &ioctx->ioctx.cqe;
        wr.next = NULL;
        wr.sg_list = &list;
        wr.num_sge = 1;
@@ -819,8 +822,9 @@ static int srpt_post_send(struct srpt_rdma_ch *ch,
        list.length = len;
        list.lkey = sdev->pd->local_dma_lkey;
 
+       ioctx->ioctx.cqe.done = srpt_send_done;
        wr.next = NULL;
-       wr.wr_id = encode_wr_id(SRPT_SEND, ioctx->ioctx.index);
+       wr.wr_cqe = &ioctx->ioctx.cqe;
        wr.sg_list = &list;
        wr.num_sge = 1;
        wr.opcode = IB_WR_SEND;
@@ -1052,13 +1056,13 @@ static void srpt_unmap_sg_to_ib_sge(struct srpt_rdma_ch *ch,
 
        BUG_ON(!ch);
        BUG_ON(!ioctx);
-       BUG_ON(ioctx->n_rdma && !ioctx->rdma_ius);
+       BUG_ON(ioctx->n_rdma && !ioctx->rdma_wrs);
 
        while (ioctx->n_rdma)
-               kfree(ioctx->rdma_ius[--ioctx->n_rdma].sge);
+               kfree(ioctx->rdma_wrs[--ioctx->n_rdma].wr.sg_list);
 
-       kfree(ioctx->rdma_ius);
-       ioctx->rdma_ius = NULL;
+       kfree(ioctx->rdma_wrs);
+       ioctx->rdma_wrs = NULL;
 
        if (ioctx->mapped_sg_count) {
                sg = ioctx->sg;
@@ -1082,7 +1086,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
        struct scatterlist *sg, *sg_orig;
        int sg_cnt;
        enum dma_data_direction dir;
-       struct rdma_iu *riu;
+       struct ib_rdma_wr *riu;
        struct srp_direct_buf *db;
        dma_addr_t dma_addr;
        struct ib_sge *sge;
@@ -1109,23 +1113,24 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
 
        ioctx->mapped_sg_count = count;
 
-       if (ioctx->rdma_ius && ioctx->n_rdma_ius)
-               nrdma = ioctx->n_rdma_ius;
+       if (ioctx->rdma_wrs && ioctx->n_rdma_wrs)
+               nrdma = ioctx->n_rdma_wrs;
        else {
                nrdma = (count + SRPT_DEF_SG_PER_WQE - 1) / SRPT_DEF_SG_PER_WQE
                        + ioctx->n_rbuf;
 
-               ioctx->rdma_ius = kzalloc(nrdma * sizeof *riu, GFP_KERNEL);
-               if (!ioctx->rdma_ius)
+               ioctx->rdma_wrs = kcalloc(nrdma, sizeof(*ioctx->rdma_wrs),
+                               GFP_KERNEL);
+               if (!ioctx->rdma_wrs)
                        goto free_mem;
 
-               ioctx->n_rdma_ius = nrdma;
+               ioctx->n_rdma_wrs = nrdma;
        }
 
        db = ioctx->rbufs;
        tsize = cmd->data_length;
        dma_len = ib_sg_dma_len(dev, &sg[0]);
-       riu = ioctx->rdma_ius;
+       riu = ioctx->rdma_wrs;
 
        /*
         * For each remote desc - calculate the #ib_sge.
@@ -1139,9 +1144,9 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
             j < count && i < ioctx->n_rbuf && tsize > 0; ++i, ++riu, ++db) {
                rsize = be32_to_cpu(db->len);
                raddr = be64_to_cpu(db->va);
-               riu->raddr = raddr;
+               riu->remote_addr = raddr;
                riu->rkey = be32_to_cpu(db->key);
-               riu->sge_cnt = 0;
+               riu->wr.num_sge = 0;
 
                /* calculate how many sge required for this remote_buf */
                while (rsize > 0 && tsize > 0) {
@@ -1165,33 +1170,35 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
                                rsize = 0;
                        }
 
-                       ++riu->sge_cnt;
+                       ++riu->wr.num_sge;
 
-                       if (rsize > 0 && riu->sge_cnt == SRPT_DEF_SG_PER_WQE) {
+                       if (rsize > 0 &&
+                           riu->wr.num_sge == SRPT_DEF_SG_PER_WQE) {
                                ++ioctx->n_rdma;
-                               riu->sge =
-                                   kmalloc(riu->sge_cnt * sizeof *riu->sge,
-                                           GFP_KERNEL);
-                               if (!riu->sge)
+                               riu->wr.sg_list = kmalloc_array(riu->wr.num_sge,
+                                               sizeof(*riu->wr.sg_list),
+                                               GFP_KERNEL);
+                               if (!riu->wr.sg_list)
                                        goto free_mem;
 
                                ++riu;
-                               riu->sge_cnt = 0;
-                               riu->raddr = raddr;
+                               riu->wr.num_sge = 0;
+                               riu->remote_addr = raddr;
                                riu->rkey = be32_to_cpu(db->key);
                        }
                }
 
                ++ioctx->n_rdma;
-               riu->sge = kmalloc(riu->sge_cnt * sizeof *riu->sge,
-                                  GFP_KERNEL);
-               if (!riu->sge)
+               riu->wr.sg_list = kmalloc_array(riu->wr.num_sge,
+                                       sizeof(*riu->wr.sg_list),
+                                       GFP_KERNEL);
+               if (!riu->wr.sg_list)
                        goto free_mem;
        }
 
        db = ioctx->rbufs;
        tsize = cmd->data_length;
-       riu = ioctx->rdma_ius;
+       riu = ioctx->rdma_wrs;
        sg = sg_orig;
        dma_len = ib_sg_dma_len(dev, &sg[0]);
        dma_addr = ib_sg_dma_address(dev, &sg[0]);
@@ -1200,7 +1207,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
        for (i = 0, j = 0;
             j < count && i < ioctx->n_rbuf && tsize > 0; ++i, ++riu, ++db) {
                rsize = be32_to_cpu(db->len);
-               sge = riu->sge;
+               sge = riu->wr.sg_list;
                k = 0;
 
                while (rsize > 0 && tsize > 0) {
@@ -1232,9 +1239,9 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
                        }
 
                        ++k;
-                       if (k == riu->sge_cnt && rsize > 0 && tsize > 0) {
+                       if (k == riu->wr.num_sge && rsize > 0 && tsize > 0) {
                                ++riu;
-                               sge = riu->sge;
+                               sge = riu->wr.sg_list;
                                k = 0;
                        } else if (rsize > 0 && tsize > 0)
                                ++sge;
@@ -1277,8 +1284,8 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
        ioctx->n_rbuf = 0;
        ioctx->rbufs = NULL;
        ioctx->n_rdma = 0;
-       ioctx->n_rdma_ius = 0;
-       ioctx->rdma_ius = NULL;
+       ioctx->n_rdma_wrs = 0;
+       ioctx->rdma_wrs = NULL;
        ioctx->mapped_sg_count = 0;
        init_completion(&ioctx->tx_done);
        ioctx->queue_status_only = false;
@@ -1380,118 +1387,44 @@ out:
 }
 
 /**
- * srpt_handle_send_err_comp() - Process an IB_WC_SEND error completion.
- */
-static void srpt_handle_send_err_comp(struct srpt_rdma_ch *ch, u64 wr_id)
-{
-       struct srpt_send_ioctx *ioctx;
-       enum srpt_command_state state;
-       u32 index;
-
-       atomic_inc(&ch->sq_wr_avail);
-
-       index = idx_from_wr_id(wr_id);
-       ioctx = ch->ioctx_ring[index];
-       state = srpt_get_cmd_state(ioctx);
-
-       WARN_ON(state != SRPT_STATE_CMD_RSP_SENT
-               && state != SRPT_STATE_MGMT_RSP_SENT
-               && state != SRPT_STATE_NEED_DATA
-               && state != SRPT_STATE_DONE);
-
-       /* If SRP_RSP sending failed, undo the ch->req_lim change. */
-       if (state == SRPT_STATE_CMD_RSP_SENT
-           || state == SRPT_STATE_MGMT_RSP_SENT)
-               atomic_dec(&ch->req_lim);
-
-       srpt_abort_cmd(ioctx);
-}
-
-/**
- * srpt_handle_send_comp() - Process an IB send completion notification.
- */
-static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
-                                 struct srpt_send_ioctx *ioctx)
-{
-       enum srpt_command_state state;
-
-       atomic_inc(&ch->sq_wr_avail);
-
-       state = srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
-
-       if (WARN_ON(state != SRPT_STATE_CMD_RSP_SENT
-                   && state != SRPT_STATE_MGMT_RSP_SENT
-                   && state != SRPT_STATE_DONE))
-               pr_debug("state = %d\n", state);
-
-       if (state != SRPT_STATE_DONE) {
-               srpt_unmap_sg_to_ib_sge(ch, ioctx);
-               transport_generic_free_cmd(&ioctx->cmd, 0);
-       } else {
-               pr_err("IB completion has been received too late for"
-                      " wr_id = %u.\n", ioctx->ioctx.index);
-       }
-}
-
-/**
- * srpt_handle_rdma_comp() - Process an IB RDMA completion notification.
- *
  * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping
  * the data that has been transferred via IB RDMA had to be postponed until the
  * check_stop_free() callback.  None of this is necessary anymore and needs to
  * be cleaned up.
  */
-static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch,
-                                 struct srpt_send_ioctx *ioctx,
-                                 enum srpt_opcode opcode)
+static void srpt_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)
 {
+       struct srpt_rdma_ch *ch = cq->cq_context;
+       struct srpt_send_ioctx *ioctx =
+               container_of(wc->wr_cqe, struct srpt_send_ioctx, rdma_cqe);
+
        WARN_ON(ioctx->n_rdma <= 0);
        atomic_add(ioctx->n_rdma, &ch->sq_wr_avail);
 
-       if (opcode == SRPT_RDMA_READ_LAST) {
-               if (srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA,
-                                               SRPT_STATE_DATA_IN))
-                       target_execute_cmd(&ioctx->cmd);
-               else
-                       pr_err("%s[%d]: wrong state = %d\n", __func__,
-                              __LINE__, srpt_get_cmd_state(ioctx));
-       } else if (opcode == SRPT_RDMA_ABORT) {
-               ioctx->rdma_aborted = true;
-       } else {
-               WARN(true, "unexpected opcode %d\n", opcode);
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               pr_info("RDMA_READ for ioctx 0x%p failed with status %d\n",
+                       ioctx, wc->status);
+               srpt_abort_cmd(ioctx);
+               return;
        }
+
+       if (srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA,
+                                       SRPT_STATE_DATA_IN))
+               target_execute_cmd(&ioctx->cmd);
+       else
+               pr_err("%s[%d]: wrong state = %d\n", __func__,
+                      __LINE__, srpt_get_cmd_state(ioctx));
 }
 
-/**
- * srpt_handle_rdma_err_comp() - Process an IB RDMA error completion.
- */
-static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch,
-                                     struct srpt_send_ioctx *ioctx,
-                                     enum srpt_opcode opcode)
+static void srpt_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc)
 {
-       enum srpt_command_state state;
+       struct srpt_send_ioctx *ioctx =
+               container_of(wc->wr_cqe, struct srpt_send_ioctx, rdma_cqe);
 
-       state = srpt_get_cmd_state(ioctx);
-       switch (opcode) {
-       case SRPT_RDMA_READ_LAST:
-               if (ioctx->n_rdma <= 0) {
-                       pr_err("Received invalid RDMA read"
-                              " error completion with idx %d\n",
-                              ioctx->ioctx.index);
-                       break;
-               }
-               atomic_add(ioctx->n_rdma, &ch->sq_wr_avail);
-               if (state == SRPT_STATE_NEED_DATA)
-                       srpt_abort_cmd(ioctx);
-               else
-                       pr_err("%s[%d]: wrong state = %d\n",
-                              __func__, __LINE__, state);
-               break;
-       case SRPT_RDMA_WRITE_LAST:
-               break;
-       default:
-               pr_err("%s[%d]: opcode = %u\n", __func__, __LINE__, opcode);
-               break;
+       if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               pr_info("RDMA_WRITE for ioctx 0x%p failed with status %d\n",
+                       ioctx, wc->status);
+               srpt_abort_cmd(ioctx);
        }
 }
 
@@ -1926,32 +1859,26 @@ out:
        return;
 }
 
-static void srpt_process_rcv_completion(struct ib_cq *cq,
-                                       struct srpt_rdma_ch *ch,
-                                       struct ib_wc *wc)
+static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc)
 {
-       struct srpt_device *sdev = ch->sport->sdev;
-       struct srpt_recv_ioctx *ioctx;
-       u32 index;
+       struct srpt_rdma_ch *ch = cq->cq_context;
+       struct srpt_recv_ioctx *ioctx =
+               container_of(wc->wr_cqe, struct srpt_recv_ioctx, ioctx.cqe);
 
-       index = idx_from_wr_id(wc->wr_id);
        if (wc->status == IB_WC_SUCCESS) {
                int req_lim;
 
                req_lim = atomic_dec_return(&ch->req_lim);
                if (unlikely(req_lim < 0))
                        pr_err("req_lim = %d < 0\n", req_lim);
-               ioctx = sdev->ioctx_ring[index];
                srpt_handle_new_iu(ch, ioctx, NULL);
        } else {
-               pr_info("receiving failed for idx %u with status %d\n",
-                       index, wc->status);
+               pr_info("receiving failed for ioctx %p with status %d\n",
+                       ioctx, wc->status);
        }
 }
 
 /**
- * srpt_process_send_completion() - Process an IB send completion.
- *
  * Note: Although this has not yet been observed during tests, at least in
  * theory it is possible that the srpt_get_send_ioctx() call invoked by
  * srpt_handle_new_iu() fails. This is possible because the req_lim_delta
@@ -1964,108 +1891,51 @@ static void srpt_process_rcv_completion(struct ib_cq *cq,
  * are queued on cmd_wait_list. The code below processes these delayed
  * requests one at a time.
  */
-static void srpt_process_send_completion(struct ib_cq *cq,
-                                        struct srpt_rdma_ch *ch,
-                                        struct ib_wc *wc)
+static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc)
 {
-       struct srpt_send_ioctx *send_ioctx;
-       uint32_t index;
-       enum srpt_opcode opcode;
+       struct srpt_rdma_ch *ch = cq->cq_context;
+       struct srpt_send_ioctx *ioctx =
+               container_of(wc->wr_cqe, struct srpt_send_ioctx, ioctx.cqe);
+       enum srpt_command_state state;
 
-       index = idx_from_wr_id(wc->wr_id);
-       opcode = opcode_from_wr_id(wc->wr_id);
-       send_ioctx = ch->ioctx_ring[index];
-       if (wc->status == IB_WC_SUCCESS) {
-               if (opcode == SRPT_SEND)
-                       srpt_handle_send_comp(ch, send_ioctx);
-               else {
-                       WARN_ON(opcode != SRPT_RDMA_ABORT &&
-                               wc->opcode != IB_WC_RDMA_READ);
-                       srpt_handle_rdma_comp(ch, send_ioctx, opcode);
-               }
+       state = srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
+
+       WARN_ON(state != SRPT_STATE_CMD_RSP_SENT &&
+               state != SRPT_STATE_MGMT_RSP_SENT);
+
+       atomic_inc(&ch->sq_wr_avail);
+
+       if (wc->status != IB_WC_SUCCESS) {
+               pr_info("sending response for ioctx 0x%p failed"
+                       " with status %d\n", ioctx, wc->status);
+
+               atomic_dec(&ch->req_lim);
+               srpt_abort_cmd(ioctx);
+               goto out;
+       }
+
+       if (state != SRPT_STATE_DONE) {
+               srpt_unmap_sg_to_ib_sge(ch, ioctx);
+               transport_generic_free_cmd(&ioctx->cmd, 0);
        } else {
-               if (opcode == SRPT_SEND) {
-                       pr_info("sending response for idx %u failed"
-                               " with status %d\n", index, wc->status);
-                       srpt_handle_send_err_comp(ch, wc->wr_id);
-               } else if (opcode != SRPT_RDMA_MID) {
-                       pr_info("RDMA t %d for idx %u failed with"
-                               " status %d\n", opcode, index, wc->status);
-                       srpt_handle_rdma_err_comp(ch, send_ioctx, opcode);
-               }
+               pr_err("IB completion has been received too late for"
+                      " wr_id = %u.\n", ioctx->ioctx.index);
        }
 
-       while (unlikely(opcode == SRPT_SEND
-                       && !list_empty(&ch->cmd_wait_list)
-                       && srpt_get_ch_state(ch) == CH_LIVE
-                       && (send_ioctx = srpt_get_send_ioctx(ch)) != NULL)) {
+out:
+       while (!list_empty(&ch->cmd_wait_list) &&
+              srpt_get_ch_state(ch) == CH_LIVE &&
+              (ioctx = srpt_get_send_ioctx(ch)) != NULL) {
                struct srpt_recv_ioctx *recv_ioctx;
 
                recv_ioctx = list_first_entry(&ch->cmd_wait_list,
                                              struct srpt_recv_ioctx,
                                              wait_list);
                list_del(&recv_ioctx->wait_list);
-               srpt_handle_new_iu(ch, recv_ioctx, send_ioctx);
-       }
-}
-
-static void srpt_process_completion(struct ib_cq *cq, struct srpt_rdma_ch *ch)
-{
-       struct ib_wc *const wc = ch->wc;
-       int i, n;
-
-       WARN_ON(cq != ch->cq);
-
-       ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-       while ((n = ib_poll_cq(cq, ARRAY_SIZE(ch->wc), wc)) > 0) {
-               for (i = 0; i < n; i++) {
-                       if (opcode_from_wr_id(wc[i].wr_id) == SRPT_RECV)
-                               srpt_process_rcv_completion(cq, ch, &wc[i]);
-                       else
-                               srpt_process_send_completion(cq, ch, &wc[i]);
-               }
+               srpt_handle_new_iu(ch, recv_ioctx, ioctx);
        }
 }
 
-/**
- * srpt_completion() - IB completion queue callback function.
- *
- * Notes:
- * - It is guaranteed that a completion handler will never be invoked
- *   concurrently on two different CPUs for the same completion queue. See also
- *   Documentation/infiniband/core_locking.txt and the implementation of
- *   handle_edge_irq() in kernel/irq/chip.c.
- * - When threaded IRQs are enabled, completion handlers are invoked in thread
- *   context instead of interrupt context.
- */
-static void srpt_completion(struct ib_cq *cq, void *ctx)
-{
-       struct srpt_rdma_ch *ch = ctx;
-
-       wake_up_interruptible(&ch->wait_queue);
-}
-
-static int srpt_compl_thread(void *arg)
-{
-       struct srpt_rdma_ch *ch;
-
-       /* Hibernation / freezing of the SRPT kernel thread is not supported. */
-       current->flags |= PF_NOFREEZE;
-
-       ch = arg;
-       BUG_ON(!ch);
-       pr_info("Session %s: kernel thread %s (PID %d) started\n",
-               ch->sess_name, ch->thread->comm, current->pid);
-       while (!kthread_should_stop()) {
-               wait_event_interruptible(ch->wait_queue,
-                       (srpt_process_completion(ch->cq, ch),
-                        kthread_should_stop()));
-       }
-       pr_info("Session %s: kernel thread %s (PID %d) stopped\n",
-               ch->sess_name, ch->thread->comm, current->pid);
-       return 0;
-}
-
 /**
  * srpt_create_ch_ib() - Create receive and send completion queues.
  */
@@ -2075,7 +1945,6 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
        struct srpt_port *sport = ch->sport;
        struct srpt_device *sdev = sport->sdev;
        u32 srp_sq_size = sport->port_attrib.srp_sq_size;
-       struct ib_cq_init_attr cq_attr = {};
        int ret;
 
        WARN_ON(ch->rq_size < 1);
@@ -2086,9 +1955,8 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
                goto out;
 
 retry:
-       cq_attr.cqe = ch->rq_size + srp_sq_size;
-       ch->cq = ib_create_cq(sdev->device, srpt_completion, NULL, ch,
-                             &cq_attr);
+       ch->cq = ib_alloc_cq(sdev->device, ch, ch->rq_size + srp_sq_size,
+                       0 /* XXX: spread CQs */, IB_POLL_WORKQUEUE);
        if (IS_ERR(ch->cq)) {
                ret = PTR_ERR(ch->cq);
                pr_err("failed to create CQ cqe= %d ret= %d\n",
@@ -2131,18 +1999,6 @@ retry:
        if (ret)
                goto err_destroy_qp;
 
-       init_waitqueue_head(&ch->wait_queue);
-
-       pr_debug("creating thread for session %s\n", ch->sess_name);
-
-       ch->thread = kthread_run(srpt_compl_thread, ch, "ib_srpt_compl");
-       if (IS_ERR(ch->thread)) {
-               pr_err("failed to create kernel thread %ld\n",
-                      PTR_ERR(ch->thread));
-               ch->thread = NULL;
-               goto err_destroy_qp;
-       }
-
 out:
        kfree(qp_init);
        return ret;
@@ -2150,17 +2006,14 @@ out:
 err_destroy_qp:
        ib_destroy_qp(ch->qp);
 err_destroy_cq:
-       ib_destroy_cq(ch->cq);
+       ib_free_cq(ch->cq);
        goto out;
 }
 
 static void srpt_destroy_ch_ib(struct srpt_rdma_ch *ch)
 {
-       if (ch->thread)
-               kthread_stop(ch->thread);
-
        ib_destroy_qp(ch->qp);
-       ib_destroy_cq(ch->cq);
+       ib_free_cq(ch->cq);
 }
 
 /**
@@ -2370,31 +2223,6 @@ static void srpt_release_channel_work(struct work_struct *w)
        kfree(ch);
 }
 
-static struct srpt_node_acl *__srpt_lookup_acl(struct srpt_port *sport,
-                                              u8 i_port_id[16])
-{
-       struct srpt_node_acl *nacl;
-
-       list_for_each_entry(nacl, &sport->port_acl_list, list)
-               if (memcmp(nacl->i_port_id, i_port_id,
-                          sizeof(nacl->i_port_id)) == 0)
-                       return nacl;
-
-       return NULL;
-}
-
-static struct srpt_node_acl *srpt_lookup_acl(struct srpt_port *sport,
-                                            u8 i_port_id[16])
-{
-       struct srpt_node_acl *nacl;
-
-       spin_lock_irq(&sport->port_acl_lock);
-       nacl = __srpt_lookup_acl(sport, i_port_id);
-       spin_unlock_irq(&sport->port_acl_lock);
-
-       return nacl;
-}
-
 /**
  * srpt_cm_req_recv() - Process the event IB_CM_REQ_RECEIVED.
  *
@@ -2412,10 +2240,10 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
        struct srp_login_rej *rej;
        struct ib_cm_rep_param *rep_param;
        struct srpt_rdma_ch *ch, *tmp_ch;
-       struct srpt_node_acl *nacl;
+       struct se_node_acl *se_acl;
        u32 it_iu_len;
-       int i;
-       int ret = 0;
+       int i, ret = 0;
+       unsigned char *p;
 
        WARN_ON_ONCE(irqs_disabled());
 
@@ -2565,33 +2393,47 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
                       " RTR failed (error code = %d)\n", ret);
                goto destroy_ib;
        }
+
        /*
-        * Use the initator port identifier as the session name.
+        * Use the initator port identifier as the session name, when
+        * checking against se_node_acl->initiatorname[] this can be
+        * with or without preceeding '0x'.
         */
        snprintf(ch->sess_name, sizeof(ch->sess_name), "0x%016llx%016llx",
                        be64_to_cpu(*(__be64 *)ch->i_port_id),
                        be64_to_cpu(*(__be64 *)(ch->i_port_id + 8)));
 
        pr_debug("registering session %s\n", ch->sess_name);
+       p = &ch->sess_name[0];
 
-       nacl = srpt_lookup_acl(sport, ch->i_port_id);
-       if (!nacl) {
-               pr_info("Rejected login because no ACL has been"
-                       " configured yet for initiator %s.\n", ch->sess_name);
+       ch->sess = transport_init_session(TARGET_PROT_NORMAL);
+       if (IS_ERR(ch->sess)) {
                rej->reason = cpu_to_be32(
-                             SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED);
+                               SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
+               pr_debug("Failed to create session\n");
                goto destroy_ib;
        }
 
-       ch->sess = transport_init_session(TARGET_PROT_NORMAL);
-       if (IS_ERR(ch->sess)) {
+try_again:
+       se_acl = core_tpg_get_initiator_node_acl(&sport->port_tpg_1, p);
+       if (!se_acl) {
+               pr_info("Rejected login because no ACL has been"
+                       " configured yet for initiator %s.\n", ch->sess_name);
+               /*
+                * XXX: Hack to retry of ch->i_port_id without leading '0x'
+                */
+               if (p == &ch->sess_name[0]) {
+                       p += 2;
+                       goto try_again;
+               }
                rej->reason = cpu_to_be32(
-                             SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
-               pr_debug("Failed to create session\n");
-               goto deregister_session;
+                               SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED);
+               transport_free_session(ch->sess);
+               goto destroy_ib;
        }
-       ch->sess->se_node_acl = &nacl->nacl;
-       transport_register_session(&sport->port_tpg_1, &nacl->nacl, ch->sess, ch);
+       ch->sess->se_node_acl = se_acl;
+
+       transport_register_session(&sport->port_tpg_1, se_acl, ch->sess, ch);
 
        pr_debug("Establish connection sess=%p name=%s cm_id=%p\n", ch->sess,
                 ch->sess_name, ch->cm_id);
@@ -2635,8 +2477,6 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
 release_channel:
        srpt_set_ch_state(ch, CH_RELEASING);
        transport_deregister_session_configfs(ch->sess);
-
-deregister_session:
        transport_deregister_session(ch->sess);
        ch->sess = NULL;
 
@@ -2821,12 +2661,8 @@ static int srpt_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
 static int srpt_perform_rdmas(struct srpt_rdma_ch *ch,
                              struct srpt_send_ioctx *ioctx)
 {
-       struct ib_rdma_wr wr;
        struct ib_send_wr *bad_wr;
-       struct rdma_iu *riu;
-       int i;
-       int ret;
-       int sq_wr_avail;
+       int sq_wr_avail, ret, i;
        enum dma_data_direction dir;
        const int n_rdma = ioctx->n_rdma;
 
@@ -2842,59 +2678,32 @@ static int srpt_perform_rdmas(struct srpt_rdma_ch *ch,
                }
        }
 
-       ioctx->rdma_aborted = false;
-       ret = 0;
-       riu = ioctx->rdma_ius;
-       memset(&wr, 0, sizeof wr);
-
-       for (i = 0; i < n_rdma; ++i, ++riu) {
-               if (dir == DMA_FROM_DEVICE) {
-                       wr.wr.opcode = IB_WR_RDMA_WRITE;
-                       wr.wr.wr_id = encode_wr_id(i == n_rdma - 1 ?
-                                               SRPT_RDMA_WRITE_LAST :
-                                               SRPT_RDMA_MID,
-                                               ioctx->ioctx.index);
-               } else {
-                       wr.wr.opcode = IB_WR_RDMA_READ;
-                       wr.wr.wr_id = encode_wr_id(i == n_rdma - 1 ?
-                                               SRPT_RDMA_READ_LAST :
-                                               SRPT_RDMA_MID,
-                                               ioctx->ioctx.index);
-               }
-               wr.wr.next = NULL;
-               wr.remote_addr = riu->raddr;
-               wr.rkey = riu->rkey;
-               wr.wr.num_sge = riu->sge_cnt;
-               wr.wr.sg_list = riu->sge;
+       for (i = 0; i < n_rdma; i++) {
+               struct ib_send_wr *wr = &ioctx->rdma_wrs[i].wr;
 
-               /* only get completion event for the last rdma write */
-               if (i == (n_rdma - 1) && dir == DMA_TO_DEVICE)
-                       wr.wr.send_flags = IB_SEND_SIGNALED;
+               wr->opcode = (dir == DMA_FROM_DEVICE) ?
+                               IB_WR_RDMA_WRITE : IB_WR_RDMA_READ;
 
-               ret = ib_post_send(ch->qp, &wr.wr, &bad_wr);
-               if (ret)
-                       break;
+               if (i == n_rdma - 1) {
+                       /* only get completion event for the last rdma read */
+                       if (dir == DMA_TO_DEVICE) {
+                               wr->send_flags = IB_SEND_SIGNALED;
+                               ioctx->rdma_cqe.done = srpt_rdma_read_done;
+                       } else {
+                               ioctx->rdma_cqe.done = srpt_rdma_write_done;
+                       }
+                       wr->wr_cqe = &ioctx->rdma_cqe;
+                       wr->next = NULL;
+               } else {
+                       wr->wr_cqe = NULL;
+                       wr->next = &ioctx->rdma_wrs[i + 1].wr;
+               }
        }
 
+       ret = ib_post_send(ch->qp, &ioctx->rdma_wrs->wr, &bad_wr);
        if (ret)
                pr_err("%s[%d]: ib_post_send() returned %d for %d/%d\n",
                                 __func__, __LINE__, ret, i, n_rdma);
-       if (ret && i > 0) {
-               wr.wr.num_sge = 0;
-               wr.wr.wr_id = encode_wr_id(SRPT_RDMA_ABORT, ioctx->ioctx.index);
-               wr.wr.send_flags = IB_SEND_SIGNALED;
-               while (ch->state == CH_LIVE &&
-                       ib_post_send(ch->qp, &wr.wr, &bad_wr) != 0) {
-                       pr_info("Trying to abort failed RDMA transfer [%d]\n",
-                               ioctx->ioctx.index);
-                       msleep(1000);
-               }
-               while (ch->state != CH_RELEASING && !ioctx->rdma_aborted) {
-                       pr_info("Waiting until RDMA abort finished [%d]\n",
-                               ioctx->ioctx.index);
-                       msleep(1000);
-               }
-       }
 out:
        if (unlikely(dir == DMA_TO_DEVICE && ret < 0))
                atomic_add(n_rdma, &ch->sq_wr_avail);
@@ -3203,14 +3012,11 @@ static void srpt_add_one(struct ib_device *device)
        init_waitqueue_head(&sdev->ch_releaseQ);
        spin_lock_init(&sdev->spinlock);
 
-       if (ib_query_device(device, &sdev->dev_attr))
-               goto free_dev;
-
        sdev->pd = ib_alloc_pd(device);
        if (IS_ERR(sdev->pd))
                goto free_dev;
 
-       sdev->srq_size = min(srpt_srq_size, sdev->dev_attr.max_srq_wr);
+       sdev->srq_size = min(srpt_srq_size, sdev->device->attrs.max_srq_wr);
 
        srq_attr.event_handler = srpt_srq_event;
        srq_attr.srq_context = (void *)sdev;
@@ -3224,7 +3030,7 @@ static void srpt_add_one(struct ib_device *device)
                goto err_pd;
 
        pr_debug("%s: create SRQ #wr= %d max_allow=%d dev= %s\n",
-                __func__, sdev->srq_size, sdev->dev_attr.max_srq_wr,
+                __func__, sdev->srq_size, sdev->device->attrs.max_srq_wr,
                 device->name);
 
        if (!srpt_service_guid)
@@ -3273,8 +3079,6 @@ static void srpt_add_one(struct ib_device *device)
                sport->port_attrib.srp_max_rsp_size = DEFAULT_MAX_RSP_SIZE;
                sport->port_attrib.srp_sq_size = DEF_SRPT_SQ_SIZE;
                INIT_WORK(&sport->work, srpt_refresh_port_work);
-               INIT_LIST_HEAD(&sport->port_acl_list);
-               spin_lock_init(&sport->port_acl_lock);
 
                if (srpt_refresh_port(sport)) {
                        pr_err("MAD registration failed for %s-%d.\n",
@@ -3508,42 +3312,15 @@ out:
  */
 static int srpt_init_nodeacl(struct se_node_acl *se_nacl, const char *name)
 {
-       struct srpt_port *sport =
-               container_of(se_nacl->se_tpg, struct srpt_port, port_tpg_1);
-       struct srpt_node_acl *nacl =
-               container_of(se_nacl, struct srpt_node_acl, nacl);
        u8 i_port_id[16];
 
        if (srpt_parse_i_port_id(i_port_id, name) < 0) {
                pr_err("invalid initiator port ID %s\n", name);
                return -EINVAL;
        }
-
-       memcpy(&nacl->i_port_id[0], &i_port_id[0], 16);
-       nacl->sport = sport;
-
-       spin_lock_irq(&sport->port_acl_lock);
-       list_add_tail(&nacl->list, &sport->port_acl_list);
-       spin_unlock_irq(&sport->port_acl_lock);
-
        return 0;
 }
 
-/*
- * configfs callback function invoked for
- * rmdir /sys/kernel/config/target/$driver/$port/$tpg/acls/$i_port_id
- */
-static void srpt_cleanup_nodeacl(struct se_node_acl *se_nacl)
-{
-       struct srpt_node_acl *nacl =
-               container_of(se_nacl, struct srpt_node_acl, nacl);
-       struct srpt_port *sport = nacl->sport;
-
-       spin_lock_irq(&sport->port_acl_lock);
-       list_del(&nacl->list);
-       spin_unlock_irq(&sport->port_acl_lock);
-}
-
 static ssize_t srpt_tpg_attrib_srp_max_rdma_size_show(struct config_item *item,
                char *page)
 {
@@ -3820,7 +3597,6 @@ static const struct target_core_fabric_ops srpt_template = {
        .fabric_make_tpg                = srpt_make_tpg,
        .fabric_drop_tpg                = srpt_drop_tpg,
        .fabric_init_nodeacl            = srpt_init_nodeacl,
-       .fabric_cleanup_nodeacl         = srpt_cleanup_nodeacl,
 
        .tfc_wwn_attrs                  = srpt_wwn_attrs,
        .tfc_tpg_base_attrs             = srpt_tpg_attrs,
index 5faad8a..09037f2 100644 (file)
@@ -128,36 +128,6 @@ enum {
        DEFAULT_MAX_RDMA_SIZE = 65536,
 };
 
-enum srpt_opcode {
-       SRPT_RECV,
-       SRPT_SEND,
-       SRPT_RDMA_MID,
-       SRPT_RDMA_ABORT,
-       SRPT_RDMA_READ_LAST,
-       SRPT_RDMA_WRITE_LAST,
-};
-
-static inline u64 encode_wr_id(u8 opcode, u32 idx)
-{
-       return ((u64)opcode << 32) | idx;
-}
-static inline enum srpt_opcode opcode_from_wr_id(u64 wr_id)
-{
-       return wr_id >> 32;
-}
-static inline u32 idx_from_wr_id(u64 wr_id)
-{
-       return (u32)wr_id;
-}
-
-struct rdma_iu {
-       u64             raddr;
-       u32             rkey;
-       struct ib_sge   *sge;
-       u32             sge_cnt;
-       int             mem_id;
-};
-
 /**
  * enum srpt_command_state - SCSI command state managed by SRPT.
  * @SRPT_STATE_NEW:           New command arrived and is being processed.
@@ -189,6 +159,7 @@ enum srpt_command_state {
  * @index: Index of the I/O context in its ioctx_ring array.
  */
 struct srpt_ioctx {
+       struct ib_cqe           cqe;
        void                    *buf;
        dma_addr_t              dma;
        uint32_t                index;
@@ -215,32 +186,30 @@ struct srpt_recv_ioctx {
  * @sg:          Pointer to sg-list associated with this I/O context.
  * @sg_cnt:      SG-list size.
  * @mapped_sg_count: ib_dma_map_sg() return value.
- * @n_rdma_ius:  Number of elements in the rdma_ius array.
- * @rdma_ius:    Array with information about the RDMA mapping.
+ * @n_rdma_wrs:  Number of elements in the rdma_wrs array.
+ * @rdma_wrs:    Array with information about the RDMA mapping.
  * @tag:         Tag of the received SRP information unit.
  * @spinlock:    Protects 'state'.
  * @state:       I/O context state.
- * @rdma_aborted: If initiating a multipart RDMA transfer failed, whether
- *              the already initiated transfers have finished.
  * @cmd:         Target core command data structure.
  * @sense_data:  SCSI sense data.
  */
 struct srpt_send_ioctx {
        struct srpt_ioctx       ioctx;
        struct srpt_rdma_ch     *ch;
-       struct rdma_iu          *rdma_ius;
+       struct ib_rdma_wr       *rdma_wrs;
+       struct ib_cqe           rdma_cqe;
        struct srp_direct_buf   *rbufs;
        struct srp_direct_buf   single_rbuf;
        struct scatterlist      *sg;
        struct list_head        free_list;
        spinlock_t              spinlock;
        enum srpt_command_state state;
-       bool                    rdma_aborted;
        struct se_cmd           cmd;
        struct completion       tx_done;
        int                     sg_cnt;
        int                     mapped_sg_count;
-       u16                     n_rdma_ius;
+       u16                     n_rdma_wrs;
        u8                      n_rdma;
        u8                      n_rbuf;
        bool                    queue_status_only;
@@ -267,9 +236,6 @@ enum rdma_ch_state {
 
 /**
  * struct srpt_rdma_ch - RDMA channel.
- * @wait_queue:    Allows the kernel thread to wait for more work.
- * @thread:        Kernel thread that processes the IB queues associated with
- *                 the channel.
  * @cm_id:         IB CM ID associated with the channel.
  * @qp:            IB queue pair used for communicating over this channel.
  * @cq:            IB completion queue for this channel.
@@ -288,7 +254,6 @@ enum rdma_ch_state {
  * @free_list:     Head of list with free send I/O contexts.
  * @state:         channel state. See also enum rdma_ch_state.
  * @ioctx_ring:    Send ring.
- * @wc:            IB work completion array for srpt_process_completion().
  * @list:          Node for insertion in the srpt_device.rch_list list.
  * @cmd_wait_list: List of SCSI commands that arrived before the RTU event. This
  *                 list contains struct srpt_ioctx elements and is protected
@@ -299,8 +264,6 @@ enum rdma_ch_state {
  * @release_done:  Enables waiting for srpt_release_channel() completion.
  */
 struct srpt_rdma_ch {
-       wait_queue_head_t       wait_queue;
-       struct task_struct      *thread;
        struct ib_cm_id         *cm_id;
        struct ib_qp            *qp;
        struct ib_cq            *cq;
@@ -317,7 +280,6 @@ struct srpt_rdma_ch {
        struct list_head        free_list;
        enum rdma_ch_state      state;
        struct srpt_send_ioctx  **ioctx_ring;
-       struct ib_wc            wc[16];
        struct list_head        list;
        struct list_head        cmd_wait_list;
        struct se_session       *sess;
@@ -364,11 +326,9 @@ struct srpt_port {
        u16                     sm_lid;
        u16                     lid;
        union ib_gid            gid;
-       spinlock_t              port_acl_lock;
        struct work_struct      work;
        struct se_portal_group  port_tpg_1;
        struct se_wwn           port_wwn;
-       struct list_head        port_acl_list;
        struct srpt_port_attrib port_attrib;
 };
 
@@ -379,8 +339,6 @@ struct srpt_port {
  * @mr:            L_Key (local key) with write access to all local memory.
  * @srq:           Per-HCA SRQ (shared receive queue).
  * @cm_id:         Connection identifier.
- * @dev_attr:      Attributes of the InfiniBand device as obtained during the
- *                 ib_client.add() callback.
  * @srq_size:      SRQ size.
  * @ioctx_ring:    Per-HCA SRQ.
  * @rch_list:      Per-device channel list -- see also srpt_rdma_ch.list.
@@ -395,7 +353,6 @@ struct srpt_device {
        struct ib_pd            *pd;
        struct ib_srq           *srq;
        struct ib_cm_id         *cm_id;
-       struct ib_device_attr   dev_attr;
        int                     srq_size;
        struct srpt_recv_ioctx  **ioctx_ring;
        struct list_head        rch_list;
@@ -409,15 +366,9 @@ struct srpt_device {
 /**
  * struct srpt_node_acl - Per-initiator ACL data (managed via configfs).
  * @nacl:      Target core node ACL information.
- * @i_port_id: 128-bit SRP initiator port ID.
- * @sport:     port information.
- * @list:      Element of the per-HCA ACL list.
  */
 struct srpt_node_acl {
        struct se_node_acl      nacl;
-       u8                      i_port_id[16];
-       struct srpt_port        *sport;
-       struct list_head        list;
 };
 
 #endif                         /* IB_SRPT_H */
index fd4100d..6727954 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/rcupdate.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/module.h>
 #include <linux/usb/input.h>
+#include <linux/usb/quirks.h>
 
 #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
 #define DRIVER_DESC "X-Box pad driver"
@@ -125,7 +128,7 @@ static const struct xpad_device {
        { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
        { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
        { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
-       { 0x045e, 0x02dd, "Microsoft X-Box One pad (Covert Forces)", 0, XTYPE_XBOXONE },
+       { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
        { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
        { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
        { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
@@ -317,21 +320,42 @@ static struct usb_device_id xpad_table[] = {
 
 MODULE_DEVICE_TABLE(usb, xpad_table);
 
+struct xpad_output_packet {
+       u8 data[XPAD_PKT_LEN];
+       u8 len;
+       bool pending;
+};
+
+#define XPAD_OUT_CMD_IDX       0
+#define XPAD_OUT_FF_IDX                1
+#define XPAD_OUT_LED_IDX       (1 + IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF))
+#define XPAD_NUM_OUT_PACKETS   (1 + \
+                                IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF) + \
+                                IS_ENABLED(CONFIG_JOYSTICK_XPAD_LEDS))
+
 struct usb_xpad {
        struct input_dev *dev;          /* input device interface */
+       struct input_dev __rcu *x360w_dev;
        struct usb_device *udev;        /* usb device */
        struct usb_interface *intf;     /* usb interface */
 
-       int pad_present;
+       bool pad_present;
+       bool input_created;
 
        struct urb *irq_in;             /* urb for interrupt in report */
        unsigned char *idata;           /* input data */
        dma_addr_t idata_dma;
 
        struct urb *irq_out;            /* urb for interrupt out report */
+       struct usb_anchor irq_out_anchor;
+       bool irq_out_active;            /* we must not use an active URB */
+       u8 odata_serial;                /* serial number for xbox one protocol */
        unsigned char *odata;           /* output data */
        dma_addr_t odata_dma;
-       struct mutex odata_mutex;
+       spinlock_t odata_lock;
+
+       struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
+       int last_out_packet;
 
 #if defined(CONFIG_JOYSTICK_XPAD_LEDS)
        struct xpad_led *led;
@@ -343,8 +367,12 @@ struct usb_xpad {
        int xtype;                      /* type of xbox device */
        int pad_nr;                     /* the order x360 pads were attached */
        const char *name;               /* name of the device */
+       struct work_struct work;        /* init/remove device from callback */
 };
 
+static int xpad_init_input(struct usb_xpad *xpad);
+static void xpad_deinit_input(struct usb_xpad *xpad);
+
 /*
  *     xpad_process_packet
  *
@@ -424,11 +452,9 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
  *             http://www.free60.org/wiki/Gamepad
  */
 
-static void xpad360_process_packet(struct usb_xpad *xpad,
+static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
                                   u16 cmd, unsigned char *data)
 {
-       struct input_dev *dev = xpad->dev;
-
        /* digital pad */
        if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
                /* dpad as buttons (left, right, up, down) */
@@ -495,7 +521,30 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
        input_sync(dev);
 }
 
-static void xpad_identify_controller(struct usb_xpad *xpad);
+static void xpad_presence_work(struct work_struct *work)
+{
+       struct usb_xpad *xpad = container_of(work, struct usb_xpad, work);
+       int error;
+
+       if (xpad->pad_present) {
+               error = xpad_init_input(xpad);
+               if (error) {
+                       /* complain only, not much else we can do here */
+                       dev_err(&xpad->dev->dev,
+                               "unable to init device: %d\n", error);
+               } else {
+                       rcu_assign_pointer(xpad->x360w_dev, xpad->dev);
+               }
+       } else {
+               RCU_INIT_POINTER(xpad->x360w_dev, NULL);
+               synchronize_rcu();
+               /*
+                * Now that we are sure xpad360w_process_packet is not
+                * using input device we can get rid of it.
+                */
+               xpad_deinit_input(xpad);
+       }
+}
 
 /*
  * xpad360w_process_packet
@@ -513,24 +562,28 @@ static void xpad_identify_controller(struct usb_xpad *xpad);
  */
 static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
 {
+       struct input_dev *dev;
+       bool present;
+
        /* Presence change */
        if (data[0] & 0x08) {
-               if (data[1] & 0x80) {
-                       xpad->pad_present = 1;
-                       /*
-                        * Light up the segment corresponding to
-                        * controller number.
-                        */
-                       xpad_identify_controller(xpad);
-               } else
-                       xpad->pad_present = 0;
+               present = (data[1] & 0x80) != 0;
+
+               if (xpad->pad_present != present) {
+                       xpad->pad_present = present;
+                       schedule_work(&xpad->work);
+               }
        }
 
        /* Valid pad data */
-       if (!(data[1] & 0x1))
+       if (data[1] != 0x1)
                return;
 
-       xpad360_process_packet(xpad, cmd, &data[4]);
+       rcu_read_lock();
+       dev = rcu_dereference(xpad->x360w_dev);
+       if (dev)
+               xpad360_process_packet(xpad, dev, cmd, &data[4]);
+       rcu_read_unlock();
 }
 
 /*
@@ -659,7 +712,7 @@ static void xpad_irq_in(struct urb *urb)
 
        switch (xpad->xtype) {
        case XTYPE_XBOX360:
-               xpad360_process_packet(xpad, 0, xpad->idata);
+               xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata);
                break;
        case XTYPE_XBOX360W:
                xpad360w_process_packet(xpad, 0, xpad->idata);
@@ -678,18 +731,73 @@ exit:
                        __func__, retval);
 }
 
+/* Callers must hold xpad->odata_lock spinlock */
+static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
+{
+       struct xpad_output_packet *pkt, *packet = NULL;
+       int i;
+
+       for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
+               if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
+                       xpad->last_out_packet = 0;
+
+               pkt = &xpad->out_packets[xpad->last_out_packet];
+               if (pkt->pending) {
+                       dev_dbg(&xpad->intf->dev,
+                               "%s - found pending output packet %d\n",
+                               __func__, xpad->last_out_packet);
+                       packet = pkt;
+                       break;
+               }
+       }
+
+       if (packet) {
+               memcpy(xpad->odata, packet->data, packet->len);
+               xpad->irq_out->transfer_buffer_length = packet->len;
+               return true;
+       }
+
+       return false;
+}
+
+/* Callers must hold xpad->odata_lock spinlock */
+static int xpad_try_sending_next_out_packet(struct usb_xpad *xpad)
+{
+       int error;
+
+       if (!xpad->irq_out_active && xpad_prepare_next_out_packet(xpad)) {
+               usb_anchor_urb(xpad->irq_out, &xpad->irq_out_anchor);
+               error = usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+               if (error) {
+                       dev_err(&xpad->intf->dev,
+                               "%s - usb_submit_urb failed with result %d\n",
+                               __func__, error);
+                       usb_unanchor_urb(xpad->irq_out);
+                       return -EIO;
+               }
+
+               xpad->irq_out_active = true;
+       }
+
+       return 0;
+}
+
 static void xpad_irq_out(struct urb *urb)
 {
        struct usb_xpad *xpad = urb->context;
        struct device *dev = &xpad->intf->dev;
-       int retval, status;
+       int status = urb->status;
+       int error;
+       unsigned long flags;
 
-       status = urb->status;
+       spin_lock_irqsave(&xpad->odata_lock, flags);
 
        switch (status) {
        case 0:
                /* success */
-               return;
+               xpad->out_packets[xpad->last_out_packet].pending = false;
+               xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
+               break;
 
        case -ECONNRESET:
        case -ENOENT:
@@ -697,19 +805,28 @@ static void xpad_irq_out(struct urb *urb)
                /* this urb is terminated, clean up */
                dev_dbg(dev, "%s - urb shutting down with status: %d\n",
                        __func__, status);
-               return;
+               xpad->irq_out_active = false;
+               break;
 
        default:
                dev_dbg(dev, "%s - nonzero urb status received: %d\n",
                        __func__, status);
-               goto exit;
+               break;
        }
 
-exit:
-       retval = usb_submit_urb(urb, GFP_ATOMIC);
-       if (retval)
-               dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
-                       __func__, retval);
+       if (xpad->irq_out_active) {
+               usb_anchor_urb(urb, &xpad->irq_out_anchor);
+               error = usb_submit_urb(urb, GFP_ATOMIC);
+               if (error) {
+                       dev_err(dev,
+                               "%s - usb_submit_urb failed with result %d\n",
+                               __func__, error);
+                       usb_unanchor_urb(urb);
+                       xpad->irq_out_active = false;
+               }
+       }
+
+       spin_unlock_irqrestore(&xpad->odata_lock, flags);
 }
 
 static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
@@ -721,6 +838,8 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
        if (xpad->xtype == XTYPE_UNKNOWN)
                return 0;
 
+       init_usb_anchor(&xpad->irq_out_anchor);
+
        xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
                                         GFP_KERNEL, &xpad->odata_dma);
        if (!xpad->odata) {
@@ -728,7 +847,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
                goto fail1;
        }
 
-       mutex_init(&xpad->odata_mutex);
+       spin_lock_init(&xpad->odata_lock);
 
        xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
        if (!xpad->irq_out) {
@@ -755,8 +874,14 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
 
 static void xpad_stop_output(struct usb_xpad *xpad)
 {
-       if (xpad->xtype != XTYPE_UNKNOWN)
-               usb_kill_urb(xpad->irq_out);
+       if (xpad->xtype != XTYPE_UNKNOWN) {
+               if (!usb_wait_anchor_empty_timeout(&xpad->irq_out_anchor,
+                                                  5000)) {
+                       dev_warn(&xpad->intf->dev,
+                                "timed out waiting for output URB to complete, killing\n");
+                       usb_kill_anchored_urbs(&xpad->irq_out_anchor);
+               }
+       }
 }
 
 static void xpad_deinit_output(struct usb_xpad *xpad)
@@ -770,27 +895,60 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
 
 static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
 {
+       struct xpad_output_packet *packet =
+                       &xpad->out_packets[XPAD_OUT_CMD_IDX];
+       unsigned long flags;
        int retval;
 
-       mutex_lock(&xpad->odata_mutex);
+       spin_lock_irqsave(&xpad->odata_lock, flags);
+
+       packet->data[0] = 0x08;
+       packet->data[1] = 0x00;
+       packet->data[2] = 0x0F;
+       packet->data[3] = 0xC0;
+       packet->data[4] = 0x00;
+       packet->data[5] = 0x00;
+       packet->data[6] = 0x00;
+       packet->data[7] = 0x00;
+       packet->data[8] = 0x00;
+       packet->data[9] = 0x00;
+       packet->data[10] = 0x00;
+       packet->data[11] = 0x00;
+       packet->len = 12;
+       packet->pending = true;
+
+       /* Reset the sequence so we send out presence first */
+       xpad->last_out_packet = -1;
+       retval = xpad_try_sending_next_out_packet(xpad);
+
+       spin_unlock_irqrestore(&xpad->odata_lock, flags);
 
-       xpad->odata[0] = 0x08;
-       xpad->odata[1] = 0x00;
-       xpad->odata[2] = 0x0F;
-       xpad->odata[3] = 0xC0;
-       xpad->odata[4] = 0x00;
-       xpad->odata[5] = 0x00;
-       xpad->odata[6] = 0x00;
-       xpad->odata[7] = 0x00;
-       xpad->odata[8] = 0x00;
-       xpad->odata[9] = 0x00;
-       xpad->odata[10] = 0x00;
-       xpad->odata[11] = 0x00;
-       xpad->irq_out->transfer_buffer_length = 12;
+       return retval;
+}
+
+static int xpad_start_xbox_one(struct usb_xpad *xpad)
+{
+       struct xpad_output_packet *packet =
+                       &xpad->out_packets[XPAD_OUT_CMD_IDX];
+       unsigned long flags;
+       int retval;
 
-       retval = usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+       spin_lock_irqsave(&xpad->odata_lock, flags);
 
-       mutex_unlock(&xpad->odata_mutex);
+       /* Xbox one controller needs to be initialized. */
+       packet->data[0] = 0x05;
+       packet->data[1] = 0x20;
+       packet->data[2] = xpad->odata_serial++; /* packet serial */
+       packet->data[3] = 0x01; /* rumble bit enable?  */
+       packet->data[4] = 0x00;
+       packet->len = 5;
+       packet->pending = true;
+
+       /* Reset the sequence so we send out start packet first */
+       xpad->last_out_packet = -1;
+       retval = xpad_try_sending_next_out_packet(xpad);
+
+       spin_unlock_irqrestore(&xpad->odata_lock, flags);
 
        return retval;
 }
@@ -799,8 +957,11 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
 static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
 {
        struct usb_xpad *xpad = input_get_drvdata(dev);
+       struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_FF_IDX];
        __u16 strong;
        __u16 weak;
+       int retval;
+       unsigned long flags;
 
        if (effect->type != FF_RUMBLE)
                return 0;
@@ -808,69 +969,81 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
        strong = effect->u.rumble.strong_magnitude;
        weak = effect->u.rumble.weak_magnitude;
 
+       spin_lock_irqsave(&xpad->odata_lock, flags);
+
        switch (xpad->xtype) {
        case XTYPE_XBOX:
-               xpad->odata[0] = 0x00;
-               xpad->odata[1] = 0x06;
-               xpad->odata[2] = 0x00;
-               xpad->odata[3] = strong / 256;  /* left actuator */
-               xpad->odata[4] = 0x00;
-               xpad->odata[5] = weak / 256;    /* right actuator */
-               xpad->irq_out->transfer_buffer_length = 6;
+               packet->data[0] = 0x00;
+               packet->data[1] = 0x06;
+               packet->data[2] = 0x00;
+               packet->data[3] = strong / 256; /* left actuator */
+               packet->data[4] = 0x00;
+               packet->data[5] = weak / 256;   /* right actuator */
+               packet->len = 6;
+               packet->pending = true;
                break;
 
        case XTYPE_XBOX360:
-               xpad->odata[0] = 0x00;
-               xpad->odata[1] = 0x08;
-               xpad->odata[2] = 0x00;
-               xpad->odata[3] = strong / 256;  /* left actuator? */
-               xpad->odata[4] = weak / 256;    /* right actuator? */
-               xpad->odata[5] = 0x00;
-               xpad->odata[6] = 0x00;
-               xpad->odata[7] = 0x00;
-               xpad->irq_out->transfer_buffer_length = 8;
+               packet->data[0] = 0x00;
+               packet->data[1] = 0x08;
+               packet->data[2] = 0x00;
+               packet->data[3] = strong / 256;  /* left actuator? */
+               packet->data[4] = weak / 256;   /* right actuator? */
+               packet->data[5] = 0x00;
+               packet->data[6] = 0x00;
+               packet->data[7] = 0x00;
+               packet->len = 8;
+               packet->pending = true;
                break;
 
        case XTYPE_XBOX360W:
-               xpad->odata[0] = 0x00;
-               xpad->odata[1] = 0x01;
-               xpad->odata[2] = 0x0F;
-               xpad->odata[3] = 0xC0;
-               xpad->odata[4] = 0x00;
-               xpad->odata[5] = strong / 256;
-               xpad->odata[6] = weak / 256;
-               xpad->odata[7] = 0x00;
-               xpad->odata[8] = 0x00;
-               xpad->odata[9] = 0x00;
-               xpad->odata[10] = 0x00;
-               xpad->odata[11] = 0x00;
-               xpad->irq_out->transfer_buffer_length = 12;
+               packet->data[0] = 0x00;
+               packet->data[1] = 0x01;
+               packet->data[2] = 0x0F;
+               packet->data[3] = 0xC0;
+               packet->data[4] = 0x00;
+               packet->data[5] = strong / 256;
+               packet->data[6] = weak / 256;
+               packet->data[7] = 0x00;
+               packet->data[8] = 0x00;
+               packet->data[9] = 0x00;
+               packet->data[10] = 0x00;
+               packet->data[11] = 0x00;
+               packet->len = 12;
+               packet->pending = true;
                break;
 
        case XTYPE_XBOXONE:
-               xpad->odata[0] = 0x09; /* activate rumble */
-               xpad->odata[1] = 0x08;
-               xpad->odata[2] = 0x00;
-               xpad->odata[3] = 0x08; /* continuous effect */
-               xpad->odata[4] = 0x00; /* simple rumble mode */
-               xpad->odata[5] = 0x03; /* L and R actuator only */
-               xpad->odata[6] = 0x00; /* TODO: LT actuator */
-               xpad->odata[7] = 0x00; /* TODO: RT actuator */
-               xpad->odata[8] = strong / 256;  /* left actuator */
-               xpad->odata[9] = weak / 256;    /* right actuator */
-               xpad->odata[10] = 0x80; /* length of pulse */
-               xpad->odata[11] = 0x00; /* stop period of pulse */
-               xpad->irq_out->transfer_buffer_length = 12;
+               packet->data[0] = 0x09; /* activate rumble */
+               packet->data[1] = 0x08;
+               packet->data[2] = xpad->odata_serial++;
+               packet->data[3] = 0x08; /* continuous effect */
+               packet->data[4] = 0x00; /* simple rumble mode */
+               packet->data[5] = 0x03; /* L and R actuator only */
+               packet->data[6] = 0x00; /* TODO: LT actuator */
+               packet->data[7] = 0x00; /* TODO: RT actuator */
+               packet->data[8] = strong / 512; /* left actuator */
+               packet->data[9] = weak / 512;   /* right actuator */
+               packet->data[10] = 0x80;        /* length of pulse */
+               packet->data[11] = 0x00;        /* stop period of pulse */
+               packet->data[12] = 0x00;
+               packet->len = 13;
+               packet->pending = true;
                break;
 
        default:
                dev_dbg(&xpad->dev->dev,
                        "%s - rumble command sent to unsupported xpad type: %d\n",
                        __func__, xpad->xtype);
-               return -EINVAL;
+               retval = -EINVAL;
+               goto out;
        }
 
-       return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
+       retval = xpad_try_sending_next_out_packet(xpad);
+
+out:
+       spin_unlock_irqrestore(&xpad->odata_lock, flags);
+       return retval;
 }
 
 static int xpad_init_ff(struct usb_xpad *xpad)
@@ -921,36 +1094,44 @@ struct xpad_led {
  */
 static void xpad_send_led_command(struct usb_xpad *xpad, int command)
 {
+       struct xpad_output_packet *packet =
+                       &xpad->out_packets[XPAD_OUT_LED_IDX];
+       unsigned long flags;
+
        command %= 16;
 
-       mutex_lock(&xpad->odata_mutex);
+       spin_lock_irqsave(&xpad->odata_lock, flags);
 
        switch (xpad->xtype) {
        case XTYPE_XBOX360:
-               xpad->odata[0] = 0x01;
-               xpad->odata[1] = 0x03;
-               xpad->odata[2] = command;
-               xpad->irq_out->transfer_buffer_length = 3;
+               packet->data[0] = 0x01;
+               packet->data[1] = 0x03;
+               packet->data[2] = command;
+               packet->len = 3;
+               packet->pending = true;
                break;
+
        case XTYPE_XBOX360W:
-               xpad->odata[0] = 0x00;
-               xpad->odata[1] = 0x00;
-               xpad->odata[2] = 0x08;
-               xpad->odata[3] = 0x40 + command;
-               xpad->odata[4] = 0x00;
-               xpad->odata[5] = 0x00;
-               xpad->odata[6] = 0x00;
-               xpad->odata[7] = 0x00;
-               xpad->odata[8] = 0x00;
-               xpad->odata[9] = 0x00;
-               xpad->odata[10] = 0x00;
-               xpad->odata[11] = 0x00;
-               xpad->irq_out->transfer_buffer_length = 12;
+               packet->data[0] = 0x00;
+               packet->data[1] = 0x00;
+               packet->data[2] = 0x08;
+               packet->data[3] = 0x40 + command;
+               packet->data[4] = 0x00;
+               packet->data[5] = 0x00;
+               packet->data[6] = 0x00;
+               packet->data[7] = 0x00;
+               packet->data[8] = 0x00;
+               packet->data[9] = 0x00;
+               packet->data[10] = 0x00;
+               packet->data[11] = 0x00;
+               packet->len = 12;
+               packet->pending = true;
                break;
        }
 
-       usb_submit_urb(xpad->irq_out, GFP_KERNEL);
-       mutex_unlock(&xpad->odata_mutex);
+       xpad_try_sending_next_out_packet(xpad);
+
+       spin_unlock_irqrestore(&xpad->odata_lock, flags);
 }
 
 /*
@@ -959,7 +1140,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command)
  */
 static void xpad_identify_controller(struct usb_xpad *xpad)
 {
-       xpad_send_led_command(xpad, (xpad->pad_nr % 4) + 2);
+       led_set_brightness(&xpad->led->led_cdev, (xpad->pad_nr % 4) + 2);
 }
 
 static void xpad_led_set(struct led_classdev *led_cdev,
@@ -1001,14 +1182,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
        if (error)
                goto err_free_id;
 
-       if (xpad->xtype == XTYPE_XBOX360) {
-               /*
-                * Light up the segment corresponding to controller
-                * number on wired devices. On wireless we'll do that
-                * when they respond to "presence" packet.
-                */
-               xpad_identify_controller(xpad);
-       }
+       xpad_identify_controller(xpad);
 
        return 0;
 
@@ -1036,37 +1210,73 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) { }
 static void xpad_identify_controller(struct usb_xpad *xpad) { }
 #endif
 
-static int xpad_open(struct input_dev *dev)
+static int xpad_start_input(struct usb_xpad *xpad)
 {
-       struct usb_xpad *xpad = input_get_drvdata(dev);
-
-       /* URB was submitted in probe */
-       if (xpad->xtype == XTYPE_XBOX360W)
-               return 0;
+       int error;
 
-       xpad->irq_in->dev = xpad->udev;
        if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
                return -EIO;
 
        if (xpad->xtype == XTYPE_XBOXONE) {
-               /* Xbox one controller needs to be initialized. */
-               xpad->odata[0] = 0x05;
-               xpad->odata[1] = 0x20;
-               xpad->irq_out->transfer_buffer_length = 2;
-               return usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+               error = xpad_start_xbox_one(xpad);
+               if (error) {
+                       usb_kill_urb(xpad->irq_in);
+                       return error;
+               }
        }
 
        return 0;
 }
 
-static void xpad_close(struct input_dev *dev)
+static void xpad_stop_input(struct usb_xpad *xpad)
 {
-       struct usb_xpad *xpad = input_get_drvdata(dev);
+       usb_kill_urb(xpad->irq_in);
+}
+
+static int xpad360w_start_input(struct usb_xpad *xpad)
+{
+       int error;
 
-       if (xpad->xtype != XTYPE_XBOX360W)
+       error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
+       if (error)
+               return -EIO;
+
+       /*
+        * Send presence packet.
+        * This will force the controller to resend connection packets.
+        * This is useful in the case we activate the module after the
+        * adapter has been plugged in, as it won't automatically
+        * send us info about the controllers.
+        */
+       error = xpad_inquiry_pad_presence(xpad);
+       if (error) {
                usb_kill_urb(xpad->irq_in);
+               return error;
+       }
 
-       xpad_stop_output(xpad);
+       return 0;
+}
+
+static void xpad360w_stop_input(struct usb_xpad *xpad)
+{
+       usb_kill_urb(xpad->irq_in);
+
+       /* Make sure we are done with presence work if it was scheduled */
+       flush_work(&xpad->work);
+}
+
+static int xpad_open(struct input_dev *dev)
+{
+       struct usb_xpad *xpad = input_get_drvdata(dev);
+
+       return xpad_start_input(xpad);
+}
+
+static void xpad_close(struct input_dev *dev)
+{
+       struct usb_xpad *xpad = input_get_drvdata(dev);
+
+       xpad_stop_input(xpad);
 }
 
 static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
@@ -1097,8 +1307,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
 
 static void xpad_deinit_input(struct usb_xpad *xpad)
 {
-       xpad_led_disconnect(xpad);
-       input_unregister_device(xpad->dev);
+       if (xpad->input_created) {
+               xpad->input_created = false;
+               xpad_led_disconnect(xpad);
+               input_unregister_device(xpad->dev);
+       }
 }
 
 static int xpad_init_input(struct usb_xpad *xpad)
@@ -1118,8 +1331,10 @@ static int xpad_init_input(struct usb_xpad *xpad)
 
        input_set_drvdata(input_dev, xpad);
 
-       input_dev->open = xpad_open;
-       input_dev->close = xpad_close;
+       if (xpad->xtype != XTYPE_XBOX360W) {
+               input_dev->open = xpad_open;
+               input_dev->close = xpad_close;
+       }
 
        __set_bit(EV_KEY, input_dev->evbit);
 
@@ -1181,6 +1396,7 @@ static int xpad_init_input(struct usb_xpad *xpad)
        if (error)
                goto err_disconnect_led;
 
+       xpad->input_created = true;
        return 0;
 
 err_disconnect_led:
@@ -1241,6 +1457,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
        xpad->mapping = xpad_device[i].mapping;
        xpad->xtype = xpad_device[i].xtype;
        xpad->name = xpad_device[i].name;
+       INIT_WORK(&xpad->work, xpad_presence_work);
 
        if (xpad->xtype == XTYPE_UNKNOWN) {
                if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
@@ -1277,10 +1494,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 
        usb_set_intfdata(intf, xpad);
 
-       error = xpad_init_input(xpad);
-       if (error)
-               goto err_deinit_output;
-
        if (xpad->xtype == XTYPE_XBOX360W) {
                /*
                 * Submit the int URB immediately rather than waiting for open
@@ -1289,28 +1502,24 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
                 * exactly the message that a controller has arrived that
                 * we're waiting for.
                 */
-               xpad->irq_in->dev = xpad->udev;
-               error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
+               error = xpad360w_start_input(xpad);
                if (error)
-                       goto err_deinit_input;
-
+                       goto err_deinit_output;
                /*
-                * Send presence packet.
-                * This will force the controller to resend connection packets.
-                * This is useful in the case we activate the module after the
-                * adapter has been plugged in, as it won't automatically
-                * send us info about the controllers.
+                * Wireless controllers require RESET_RESUME to work properly
+                * after suspend. Ideally this quirk should be in usb core
+                * quirk list, but we have too many vendors producing these
+                * controllers and we'd need to maintain 2 identical lists
+                * here in this driver and in usb core.
                 */
-               error = xpad_inquiry_pad_presence(xpad);
+               udev->quirks |= USB_QUIRK_RESET_RESUME;
+       } else {
+               error = xpad_init_input(xpad);
                if (error)
-                       goto err_kill_in_urb;
+                       goto err_deinit_output;
        }
        return 0;
 
-err_kill_in_urb:
-       usb_kill_urb(xpad->irq_in);
-err_deinit_input:
-       xpad_deinit_input(xpad);
 err_deinit_output:
        xpad_deinit_output(xpad);
 err_free_in_urb:
@@ -1320,19 +1529,24 @@ err_free_idata:
 err_free_mem:
        kfree(xpad);
        return error;
-
 }
 
 static void xpad_disconnect(struct usb_interface *intf)
 {
-       struct usb_xpad *xpad = usb_get_intfdata (intf);
+       struct usb_xpad *xpad = usb_get_intfdata(intf);
+
+       if (xpad->xtype == XTYPE_XBOX360W)
+               xpad360w_stop_input(xpad);
 
        xpad_deinit_input(xpad);
-       xpad_deinit_output(xpad);
 
-       if (xpad->xtype == XTYPE_XBOX360W) {
-               usb_kill_urb(xpad->irq_in);
-       }
+       /*
+        * Now that both input device and LED device are gone we can
+        * stop output URB.
+        */
+       xpad_stop_output(xpad);
+
+       xpad_deinit_output(xpad);
 
        usb_free_urb(xpad->irq_in);
        usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
@@ -1343,10 +1557,55 @@ static void xpad_disconnect(struct usb_interface *intf)
        usb_set_intfdata(intf, NULL);
 }
 
+static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usb_xpad *xpad = usb_get_intfdata(intf);
+       struct input_dev *input = xpad->dev;
+
+       if (xpad->xtype == XTYPE_XBOX360W) {
+               /*
+                * Wireless controllers always listen to input so
+                * they are notified when controller shows up
+                * or goes away.
+                */
+               xpad360w_stop_input(xpad);
+       } else {
+               mutex_lock(&input->mutex);
+               if (input->users)
+                       xpad_stop_input(xpad);
+               mutex_unlock(&input->mutex);
+       }
+
+       xpad_stop_output(xpad);
+
+       return 0;
+}
+
+static int xpad_resume(struct usb_interface *intf)
+{
+       struct usb_xpad *xpad = usb_get_intfdata(intf);
+       struct input_dev *input = xpad->dev;
+       int retval = 0;
+
+       if (xpad->xtype == XTYPE_XBOX360W) {
+               retval = xpad360w_start_input(xpad);
+       } else {
+               mutex_lock(&input->mutex);
+               if (input->users)
+                       retval = xpad_start_input(xpad);
+               mutex_unlock(&input->mutex);
+       }
+
+       return retval;
+}
+
 static struct usb_driver xpad_driver = {
        .name           = "xpad",
        .probe          = xpad_probe,
        .disconnect     = xpad_disconnect,
+       .suspend        = xpad_suspend,
+       .resume         = xpad_resume,
+       .reset_resume   = xpad_resume,
        .id_table       = xpad_table,
 };
 
index b9f01bd..2909365 100644 (file)
@@ -630,7 +630,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
        if (!node)
                return ERR_PTR(-ENODEV);
 
-       nbuttons = of_get_child_count(node);
+       nbuttons = of_get_available_child_count(node);
        if (nbuttons == 0)
                return ERR_PTR(-ENODEV);
 
@@ -645,8 +645,10 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 
        pdata->rep = !!of_get_property(node, "autorepeat", NULL);
 
+       of_property_read_string(node, "label", &pdata->name);
+
        i = 0;
-       for_each_child_of_node(node, pp) {
+       for_each_available_child_of_node(node, pp) {
                enum of_gpio_flags flags;
 
                button = &pdata->buttons[i++];
index 53a97b3..66c6264 100644 (file)
@@ -376,7 +376,7 @@ config TOUCHSCREEN_IPROC
 config TOUCHSCREEN_S3C2410
        tristate "Samsung S3C2410/generic touchscreen input driver"
        depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
-       select S3C_ADC
+       depends on S3C_ADC
        help
          Say Y here if you have the s3c2410 touchscreen.
 
index 2d5794e..2160512 100644 (file)
@@ -113,8 +113,8 @@ struct t7_config {
 #define MXT_T9_DETECT          (1 << 7)
 
 struct t9_range {
-       u16 x;
-       u16 y;
+       __le16 x;
+       __le16 y;
 } __packed;
 
 /* MXT_TOUCH_MULTI_T9 orient */
@@ -216,6 +216,7 @@ struct mxt_data {
        unsigned int irq;
        unsigned int max_x;
        unsigned int max_y;
+       bool xy_switch;
        bool in_bootloader;
        u16 mem_size;
        u8 t100_aux_ampl;
@@ -1665,8 +1666,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
        if (error)
                return error;
 
-       le16_to_cpus(&range.x);
-       le16_to_cpus(&range.y);
+       data->max_x = get_unaligned_le16(&range.x);
+       data->max_y = get_unaligned_le16(&range.y);
 
        error =  __mxt_read_reg(client,
                                object->start_address + MXT_T9_ORIENT,
@@ -1674,23 +1675,7 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
        if (error)
                return error;
 
-       /* Handle default values */
-       if (range.x == 0)
-               range.x = 1023;
-
-       if (range.y == 0)
-               range.y = 1023;
-
-       if (orient & MXT_T9_ORIENT_SWITCH) {
-               data->max_x = range.y;
-               data->max_y = range.x;
-       } else {
-               data->max_x = range.x;
-               data->max_y = range.y;
-       }
-
-       dev_dbg(&client->dev,
-               "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
+       data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
 
        return 0;
 }
@@ -1708,13 +1693,14 @@ static int mxt_read_t100_config(struct mxt_data *data)
        if (!object)
                return -EINVAL;
 
+       /* read touchscreen dimensions */
        error = __mxt_read_reg(client,
                               object->start_address + MXT_T100_XRANGE,
                               sizeof(range_x), &range_x);
        if (error)
                return error;
 
-       le16_to_cpus(&range_x);
+       data->max_x = get_unaligned_le16(&range_x);
 
        error = __mxt_read_reg(client,
                               object->start_address + MXT_T100_YRANGE,
@@ -1722,36 +1708,24 @@ static int mxt_read_t100_config(struct mxt_data *data)
        if (error)
                return error;
 
-       le16_to_cpus(&range_y);
+       data->max_y = get_unaligned_le16(&range_y);
 
+       /* read orientation config */
        error =  __mxt_read_reg(client,
                                object->start_address + MXT_T100_CFG1,
                                1, &cfg);
        if (error)
                return error;
 
+       data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+
+       /* allocate aux bytes */
        error =  __mxt_read_reg(client,
                                object->start_address + MXT_T100_TCHAUX,
                                1, &tchaux);
        if (error)
                return error;
 
-       /* Handle default values */
-       if (range_x == 0)
-               range_x = 1023;
-
-       if (range_y == 0)
-               range_y = 1023;
-
-       if (cfg & MXT_T100_CFG_SWITCHXY) {
-               data->max_x = range_y;
-               data->max_y = range_x;
-       } else {
-               data->max_x = range_x;
-               data->max_y = range_y;
-       }
-
-       /* allocate aux bytes */
        aux = 6;
 
        if (tchaux & MXT_T100_TCHAUX_VECT)
@@ -1767,9 +1741,6 @@ static int mxt_read_t100_config(struct mxt_data *data)
                "T100 aux mappings vect:%u ampl:%u area:%u\n",
                data->t100_aux_vect, data->t100_aux_ampl, data->t100_aux_area);
 
-       dev_info(&client->dev,
-                "T100 Touchscreen size X%uY%u\n", data->max_x, data->max_y);
-
        return 0;
 }
 
@@ -1828,6 +1799,19 @@ static int mxt_initialize_input_device(struct mxt_data *data)
                return -EINVAL;
        }
 
+       /* Handle default values and orientation switch */
+       if (data->max_x == 0)
+               data->max_x = 1023;
+
+       if (data->max_y == 0)
+               data->max_y = 1023;
+
+       if (data->xy_switch)
+               swap(data->max_x, data->max_y);
+
+       dev_info(dev, "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
+
+       /* Register input device */
        input_dev = input_allocate_device();
        if (!input_dev) {
                dev_err(dev, "Failed to allocate memory\n");
index 11fc2a2..715923d 100644 (file)
@@ -130,6 +130,11 @@ config ORION_IRQCHIP
        select IRQ_DOMAIN
        select MULTI_IRQ_HANDLER
 
+config PIC32_EVIC
+       bool
+       select GENERIC_IRQ_CHIP
+       select IRQ_DOMAIN
+
 config RENESAS_INTC_IRQPIN
        bool
        select IRQ_DOMAIN
index d4c2e4e..18caacb 100644 (file)
@@ -58,3 +58,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)                += irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)              += irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)              += irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)                        += irq-imx-gpcv2.o
+obj-$(CONFIG_PIC32_EVIC)               += irq-pic32-evic.o
diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c
new file mode 100644 (file)
index 0000000..e7155db
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Cristian Birsan <cristian.birsan@microchip.com>
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2016 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irq.h>
+
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/mach-pic32/pic32.h>
+
+#define REG_INTCON     0x0000
+#define REG_INTSTAT    0x0020
+#define REG_IFS_OFFSET 0x0040
+#define REG_IEC_OFFSET 0x00C0
+#define REG_IPC_OFFSET 0x0140
+#define REG_OFF_OFFSET 0x0540
+
+#define MAJPRI_MASK    0x07
+#define SUBPRI_MASK    0x03
+#define PRIORITY_MASK  0x1F
+
+#define PIC32_INT_PRI(pri, subpri)                             \
+       ((((pri) & MAJPRI_MASK) << 2) | ((subpri) & SUBPRI_MASK))
+
+struct evic_chip_data {
+       u32 irq_types[NR_IRQS];
+       u32 ext_irqs[8];
+};
+
+static struct irq_domain *evic_irq_domain;
+static void __iomem *evic_base;
+
+asmlinkage void __weak plat_irq_dispatch(void)
+{
+       unsigned int irq, hwirq;
+
+       hwirq = readl(evic_base + REG_INTSTAT) & 0xFF;
+       irq = irq_linear_revmap(evic_irq_domain, hwirq);
+       do_IRQ(irq);
+}
+
+static struct evic_chip_data *irqd_to_priv(struct irq_data *data)
+{
+       return (struct evic_chip_data *)data->domain->host_data;
+}
+
+static int pic32_set_ext_polarity(int bit, u32 type)
+{
+       /*
+        * External interrupts can be either edge rising or edge falling,
+        * but not both.
+        */
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               writel(BIT(bit), evic_base + PIC32_SET(REG_INTCON));
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               writel(BIT(bit), evic_base + PIC32_CLR(REG_INTCON));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int pic32_set_type_edge(struct irq_data *data,
+                              unsigned int flow_type)
+{
+       struct evic_chip_data *priv = irqd_to_priv(data);
+       int ret;
+       int i;
+
+       if (!(flow_type & IRQ_TYPE_EDGE_BOTH))
+               return -EBADR;
+
+       /* set polarity for external interrupts only */
+       for (i = 0; i < ARRAY_SIZE(priv->ext_irqs); i++) {
+               if (priv->ext_irqs[i] == data->hwirq) {
+                       ret = pic32_set_ext_polarity(i + 1, flow_type);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       irqd_set_trigger_type(data, flow_type);
+
+       return IRQ_SET_MASK_OK;
+}
+
+static void pic32_bind_evic_interrupt(int irq, int set)
+{
+       writel(set, evic_base + REG_OFF_OFFSET + irq * 4);
+}
+
+static void pic32_set_irq_priority(int irq, int priority)
+{
+       u32 reg, shift;
+
+       reg = irq / 4;
+       shift = (irq % 4) * 8;
+
+       writel(PRIORITY_MASK << shift,
+               evic_base + PIC32_CLR(REG_IPC_OFFSET + reg * 0x10));
+       writel(priority << shift,
+               evic_base + PIC32_SET(REG_IPC_OFFSET + reg * 0x10));
+}
+
+#define IRQ_REG_MASK(_hwirq, _reg, _mask)                     \
+       do {                                                   \
+               _reg = _hwirq / 32;                            \
+               _mask = 1 << (_hwirq % 32);                    \
+       } while (0)
+
+static int pic32_irq_domain_map(struct irq_domain *d, unsigned int virq,
+                               irq_hw_number_t hw)
+{
+       struct evic_chip_data *priv = d->host_data;
+       struct irq_data *data;
+       int ret;
+       u32 iecclr, ifsclr;
+       u32 reg, mask;
+
+       ret = irq_map_generic_chip(d, virq, hw);
+       if (ret)
+               return ret;
+
+       /*
+        * Piggyback on xlate function to move to an alternate chip as necessary
+        * at time of mapping instead of allowing the flow handler/chip to be
+        * changed later. This requires all interrupts to be configured through
+        * DT.
+        */
+       if (priv->irq_types[hw] & IRQ_TYPE_SENSE_MASK) {
+               data = irq_domain_get_irq_data(d, virq);
+               irqd_set_trigger_type(data, priv->irq_types[hw]);
+               irq_setup_alt_chip(data, priv->irq_types[hw]);
+       }
+
+       IRQ_REG_MASK(hw, reg, mask);
+
+       iecclr = PIC32_CLR(REG_IEC_OFFSET + reg * 0x10);
+       ifsclr = PIC32_CLR(REG_IFS_OFFSET + reg * 0x10);
+
+       /* mask and clear flag */
+       writel(mask, evic_base + iecclr);
+       writel(mask, evic_base + ifsclr);
+
+       /* default priority is required */
+       pic32_set_irq_priority(hw, PIC32_INT_PRI(2, 0));
+
+       return ret;
+}
+
+int pic32_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
+                          const u32 *intspec, unsigned int intsize,
+                          irq_hw_number_t *out_hwirq, unsigned int *out_type)
+{
+       struct evic_chip_data *priv = d->host_data;
+
+       if (WARN_ON(intsize < 2))
+               return -EINVAL;
+
+       if (WARN_ON(intspec[0] >= NR_IRQS))
+               return -EINVAL;
+
+       *out_hwirq = intspec[0];
+       *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+
+       priv->irq_types[intspec[0]] = intspec[1] & IRQ_TYPE_SENSE_MASK;
+
+       return 0;
+}
+
+static const struct irq_domain_ops pic32_irq_domain_ops = {
+       .map    = pic32_irq_domain_map,
+       .xlate  = pic32_irq_domain_xlate,
+};
+
+static void __init pic32_ext_irq_of_init(struct irq_domain *domain)
+{
+       struct device_node *node = irq_domain_get_of_node(domain);
+       struct evic_chip_data *priv = domain->host_data;
+       struct property *prop;
+       const __le32 *p;
+       u32 hwirq;
+       int i = 0;
+       const char *pname = "microchip,external-irqs";
+
+       of_property_for_each_u32(node, pname, prop, p, hwirq) {
+               if (i >= ARRAY_SIZE(priv->ext_irqs)) {
+                       pr_warn("More than %d external irq, skip rest\n",
+                               ARRAY_SIZE(priv->ext_irqs));
+                       break;
+               }
+
+               priv->ext_irqs[i] = hwirq;
+               i++;
+       }
+}
+
+static int __init pic32_of_init(struct device_node *node,
+                               struct device_node *parent)
+{
+       struct irq_chip_generic *gc;
+       struct evic_chip_data *priv;
+       unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+       int nchips, ret;
+       int i;
+
+       nchips = DIV_ROUND_UP(NR_IRQS, 32);
+
+       evic_base = of_iomap(node, 0);
+       if (!evic_base)
+               return -ENOMEM;
+
+       priv = kcalloc(nchips, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               ret = -ENOMEM;
+               goto err_iounmap;
+       }
+
+       evic_irq_domain = irq_domain_add_linear(node, nchips * 32,
+                                               &pic32_irq_domain_ops,
+                                               priv);
+       if (!evic_irq_domain) {
+               ret = -ENOMEM;
+               goto err_free_priv;
+       }
+
+       /*
+        * The PIC32 EVIC has a linear list of irqs and the type of each
+        * irq is determined by the hardware peripheral the EVIC is arbitrating.
+        * These irq types are defined in the datasheet as "persistent" and
+        * "non-persistent" which are mapped here to level and edge
+        * respectively. To manage the different flow handler requirements of
+        * each irq type, different chip_types are used.
+        */
+       ret = irq_alloc_domain_generic_chips(evic_irq_domain, 32, 2,
+                                            "evic-level", handle_level_irq,
+                                            clr, 0, 0);
+       if (ret)
+               goto err_domain_remove;
+
+       board_bind_eic_interrupt = &pic32_bind_evic_interrupt;
+
+       for (i = 0; i < nchips; i++) {
+               u32 ifsclr = PIC32_CLR(REG_IFS_OFFSET + (i * 0x10));
+               u32 iec = REG_IEC_OFFSET + (i * 0x10);
+
+               gc = irq_get_domain_generic_chip(evic_irq_domain, i * 32);
+
+               gc->reg_base = evic_base;
+               gc->unused = 0;
+
+               /*
+                * Level/persistent interrupts have a special requirement that
+                * the condition generating the interrupt be cleared before the
+                * interrupt flag (ifs) can be cleared. chip.irq_eoi is used to
+                * complete the interrupt with an ack.
+                */
+               gc->chip_types[0].type                  = IRQ_TYPE_LEVEL_MASK;
+               gc->chip_types[0].handler               = handle_fasteoi_irq;
+               gc->chip_types[0].regs.ack              = ifsclr;
+               gc->chip_types[0].regs.mask             = iec;
+               gc->chip_types[0].chip.name             = "evic-level";
+               gc->chip_types[0].chip.irq_eoi          = irq_gc_ack_set_bit;
+               gc->chip_types[0].chip.irq_mask         = irq_gc_mask_clr_bit;
+               gc->chip_types[0].chip.irq_unmask       = irq_gc_mask_set_bit;
+               gc->chip_types[0].chip.flags            = IRQCHIP_SKIP_SET_WAKE;
+
+               /* Edge interrupts */
+               gc->chip_types[1].type                  = IRQ_TYPE_EDGE_BOTH;
+               gc->chip_types[1].handler               = handle_edge_irq;
+               gc->chip_types[1].regs.ack              = ifsclr;
+               gc->chip_types[1].regs.mask             = iec;
+               gc->chip_types[1].chip.name             = "evic-edge";
+               gc->chip_types[1].chip.irq_ack          = irq_gc_ack_set_bit;
+               gc->chip_types[1].chip.irq_mask         = irq_gc_mask_clr_bit;
+               gc->chip_types[1].chip.irq_unmask       = irq_gc_mask_set_bit;
+               gc->chip_types[1].chip.irq_set_type     = pic32_set_type_edge;
+               gc->chip_types[1].chip.flags            = IRQCHIP_SKIP_SET_WAKE;
+
+               gc->private = &priv[i];
+       }
+
+       irq_set_default_host(evic_irq_domain);
+
+       /*
+        * External interrupts have software configurable edge polarity. These
+        * interrupts are defined in DT allowing polarity to be configured only
+        * for these interrupts when requested.
+        */
+       pic32_ext_irq_of_init(evic_irq_domain);
+
+       return 0;
+
+err_domain_remove:
+       irq_domain_remove(evic_irq_domain);
+
+err_free_priv:
+       kfree(priv);
+
+err_iounmap:
+       iounmap(evic_base);
+
+       return ret;
+}
+
+IRQCHIP_DECLARE(pic32_evic, "microchip,pic32mzda-evic", pic32_of_init);
index 8098ead..af8c6c6 100644 (file)
@@ -40,8 +40,8 @@ static void h8s_disable_irq(struct irq_data *data)
        addr = IPRA + ((ipr_table[irq - 16] & 0xf0) >> 3);
        pos = (ipr_table[irq - 16] & 0x0f) * 4;
        pri = ~(0x000f << pos);
-       pri &= ctrl_inw(addr);
-       ctrl_outw(pri, addr);
+       pri &= readw(addr);
+       writew(pri, addr);
 }
 
 static void h8s_enable_irq(struct irq_data *data)
@@ -54,9 +54,9 @@ static void h8s_enable_irq(struct irq_data *data)
        addr = IPRA + ((ipr_table[irq - 16] & 0xf0) >> 3);
        pos = (ipr_table[irq - 16] & 0x0f) * 4;
        pri = ~(0x000f << pos);
-       pri &= ctrl_inw(addr);
+       pri &= readw(addr);
        pri |= 1 << pos;
-       ctrl_outw(pri, addr);
+       writew(pri, addr);
 }
 
 struct irq_chip h8s_irq_chip = {
@@ -90,7 +90,7 @@ static int __init h8s_intc_of_init(struct device_node *intc,
        /* All interrupt priority is 0 (disable) */
        /* IPRA to IPRK */
        for (n = 0; n <= 'k' - 'a'; n++)
-               ctrl_outw(0x0000, IPRA + (n * 2));
+               writew(0x0000, IPRA + (n * 2));
 
        domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, NULL);
        BUG_ON(!domain);
index cadf104..598ab3f 100644 (file)
@@ -210,12 +210,7 @@ int __init fpga_irq_of_init(struct device_node *node,
                parent_irq = -1;
        }
 
-#ifdef CONFIG_ARCH_VERSATILE
-       fpga_irq_init(base, node->name, IRQ_SIC_START, parent_irq, valid_mask,
-                                 node);
-#else
        fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
-#endif
 
        writel(clear_mask, base + IRQ_ENABLE_CLEAR);
        writel(clear_mask, base + FIQ_ENABLE_CLEAR);
index 7e0f42a..a7a0a22 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for Open-Channel SSDs.
 #
 
-obj-$(CONFIG_NVM)              := core.o
+obj-$(CONFIG_NVM)              := core.o sysblk.o
 obj-$(CONFIG_NVM_GENNVM)       += gennvm.o
 obj-$(CONFIG_NVM_RRPC)         += rrpc.o
index 8f41b24..33224cb 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/miscdevice.h>
 #include <linux/lightnvm.h>
+#include <linux/sched/sysctl.h>
 #include <uapi/linux/lightnvm.h>
 
 static LIST_HEAD(nvm_targets);
@@ -105,6 +106,9 @@ struct nvmm_type *nvm_init_mgr(struct nvm_dev *dev)
        lockdep_assert_held(&nvm_lock);
 
        list_for_each_entry(mt, &nvm_mgrs, list) {
+               if (strncmp(dev->sb.mmtype, mt->name, NVM_MMTYPE_LEN))
+                       continue;
+
                ret = mt->register_mgr(dev);
                if (ret < 0) {
                        pr_err("nvm: media mgr failed to init (%d) on dev %s\n",
@@ -166,6 +170,20 @@ static struct nvm_dev *nvm_find_nvm_dev(const char *name)
        return NULL;
 }
 
+struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *dev, struct nvm_lun *lun,
+                                                       unsigned long flags)
+{
+       return dev->mt->get_blk_unlocked(dev, lun, flags);
+}
+EXPORT_SYMBOL(nvm_get_blk_unlocked);
+
+/* Assumes that all valid pages have already been moved on release to bm */
+void nvm_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk)
+{
+       return dev->mt->put_blk_unlocked(dev, blk);
+}
+EXPORT_SYMBOL(nvm_put_blk_unlocked);
+
 struct nvm_block *nvm_get_blk(struct nvm_dev *dev, struct nvm_lun *lun,
                                                        unsigned long flags)
 {
@@ -192,6 +210,206 @@ int nvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk)
 }
 EXPORT_SYMBOL(nvm_erase_blk);
 
+void nvm_addr_to_generic_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+       int i;
+
+       if (rqd->nr_pages > 1) {
+               for (i = 0; i < rqd->nr_pages; i++)
+                       rqd->ppa_list[i] = dev_to_generic_addr(dev,
+                                                       rqd->ppa_list[i]);
+       } else {
+               rqd->ppa_addr = dev_to_generic_addr(dev, rqd->ppa_addr);
+       }
+}
+EXPORT_SYMBOL(nvm_addr_to_generic_mode);
+
+void nvm_generic_to_addr_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+       int i;
+
+       if (rqd->nr_pages > 1) {
+               for (i = 0; i < rqd->nr_pages; i++)
+                       rqd->ppa_list[i] = generic_to_dev_addr(dev,
+                                                       rqd->ppa_list[i]);
+       } else {
+               rqd->ppa_addr = generic_to_dev_addr(dev, rqd->ppa_addr);
+       }
+}
+EXPORT_SYMBOL(nvm_generic_to_addr_mode);
+
+int nvm_set_rqd_ppalist(struct nvm_dev *dev, struct nvm_rq *rqd,
+                                       struct ppa_addr *ppas, int nr_ppas)
+{
+       int i, plane_cnt, pl_idx;
+
+       if (dev->plane_mode == NVM_PLANE_SINGLE && nr_ppas == 1) {
+               rqd->nr_pages = 1;
+               rqd->ppa_addr = ppas[0];
+
+               return 0;
+       }
+
+       plane_cnt = (1 << dev->plane_mode);
+       rqd->nr_pages = plane_cnt * nr_ppas;
+
+       if (dev->ops->max_phys_sect < rqd->nr_pages)
+               return -EINVAL;
+
+       rqd->ppa_list = nvm_dev_dma_alloc(dev, GFP_KERNEL, &rqd->dma_ppa_list);
+       if (!rqd->ppa_list) {
+               pr_err("nvm: failed to allocate dma memory\n");
+               return -ENOMEM;
+       }
+
+       for (pl_idx = 0; pl_idx < plane_cnt; pl_idx++) {
+               for (i = 0; i < nr_ppas; i++) {
+                       ppas[i].g.pl = pl_idx;
+                       rqd->ppa_list[(pl_idx * nr_ppas) + i] = ppas[i];
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(nvm_set_rqd_ppalist);
+
+void nvm_free_rqd_ppalist(struct nvm_dev *dev, struct nvm_rq *rqd)
+{
+       if (!rqd->ppa_list)
+               return;
+
+       nvm_dev_dma_free(dev, rqd->ppa_list, rqd->dma_ppa_list);
+}
+EXPORT_SYMBOL(nvm_free_rqd_ppalist);
+
+int nvm_erase_ppa(struct nvm_dev *dev, struct ppa_addr *ppas, int nr_ppas)
+{
+       struct nvm_rq rqd;
+       int ret;
+
+       if (!dev->ops->erase_block)
+               return 0;
+
+       memset(&rqd, 0, sizeof(struct nvm_rq));
+
+       ret = nvm_set_rqd_ppalist(dev, &rqd, ppas, nr_ppas);
+       if (ret)
+               return ret;
+
+       nvm_generic_to_addr_mode(dev, &rqd);
+
+       ret = dev->ops->erase_block(dev, &rqd);
+
+       nvm_free_rqd_ppalist(dev, &rqd);
+
+       return ret;
+}
+EXPORT_SYMBOL(nvm_erase_ppa);
+
+void nvm_end_io(struct nvm_rq *rqd, int error)
+{
+       rqd->error = error;
+       rqd->end_io(rqd);
+}
+EXPORT_SYMBOL(nvm_end_io);
+
+static void nvm_end_io_sync(struct nvm_rq *rqd)
+{
+       struct completion *waiting = rqd->wait;
+
+       rqd->wait = NULL;
+
+       complete(waiting);
+}
+
+int nvm_submit_ppa(struct nvm_dev *dev, struct ppa_addr *ppa, int nr_ppas,
+                               int opcode, int flags, void *buf, int len)
+{
+       DECLARE_COMPLETION_ONSTACK(wait);
+       struct nvm_rq rqd;
+       struct bio *bio;
+       int ret;
+       unsigned long hang_check;
+
+       bio = bio_map_kern(dev->q, buf, len, GFP_KERNEL);
+       if (IS_ERR_OR_NULL(bio))
+               return -ENOMEM;
+
+       memset(&rqd, 0, sizeof(struct nvm_rq));
+       ret = nvm_set_rqd_ppalist(dev, &rqd, ppa, nr_ppas);
+       if (ret) {
+               bio_put(bio);
+               return ret;
+       }
+
+       rqd.opcode = opcode;
+       rqd.bio = bio;
+       rqd.wait = &wait;
+       rqd.dev = dev;
+       rqd.end_io = nvm_end_io_sync;
+       rqd.flags = flags;
+       nvm_generic_to_addr_mode(dev, &rqd);
+
+       ret = dev->ops->submit_io(dev, &rqd);
+
+       /* Prevent hang_check timer from firing at us during very long I/O */
+       hang_check = sysctl_hung_task_timeout_secs;
+       if (hang_check)
+               while (!wait_for_completion_io_timeout(&wait, hang_check * (HZ/2)));
+       else
+               wait_for_completion_io(&wait);
+
+       nvm_free_rqd_ppalist(dev, &rqd);
+
+       return rqd.error;
+}
+EXPORT_SYMBOL(nvm_submit_ppa);
+
+static int nvm_init_slc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp)
+{
+       int i;
+
+       dev->lps_per_blk = dev->pgs_per_blk;
+       dev->lptbl = kcalloc(dev->lps_per_blk, sizeof(int), GFP_KERNEL);
+       if (!dev->lptbl)
+               return -ENOMEM;
+
+       /* Just a linear array */
+       for (i = 0; i < dev->lps_per_blk; i++)
+               dev->lptbl[i] = i;
+
+       return 0;
+}
+
+static int nvm_init_mlc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp)
+{
+       int i, p;
+       struct nvm_id_lp_mlc *mlc = &grp->lptbl.mlc;
+
+       if (!mlc->num_pairs)
+               return 0;
+
+       dev->lps_per_blk = mlc->num_pairs;
+       dev->lptbl = kcalloc(dev->lps_per_blk, sizeof(int), GFP_KERNEL);
+       if (!dev->lptbl)
+               return -ENOMEM;
+
+       /* The lower page table encoding consists of a list of bytes, where each
+        * has a lower and an upper half. The first half byte maintains the
+        * increment value and every value after is an offset added to the
+        * previous incrementation value */
+       dev->lptbl[0] = mlc->pairs[0] & 0xF;
+       for (i = 1; i < dev->lps_per_blk; i++) {
+               p = mlc->pairs[i >> 1];
+               if (i & 0x1) /* upper */
+                       dev->lptbl[i] = dev->lptbl[i - 1] + ((p & 0xF0) >> 4);
+               else /* lower */
+                       dev->lptbl[i] = dev->lptbl[i - 1] + (p & 0xF);
+       }
+
+       return 0;
+}
+
 static int nvm_core_init(struct nvm_dev *dev)
 {
        struct nvm_id *id = &dev->identity;
@@ -206,6 +424,7 @@ static int nvm_core_init(struct nvm_dev *dev)
        dev->sec_size = grp->csecs;
        dev->oob_size = grp->sos;
        dev->sec_per_pg = grp->fpg_sz / grp->csecs;
+       dev->mccap = grp->mccap;
        memcpy(&dev->ppaf, &id->ppaf, sizeof(struct nvm_addr_format));
 
        dev->plane_mode = NVM_PLANE_SINGLE;
@@ -216,11 +435,23 @@ static int nvm_core_init(struct nvm_dev *dev)
                return -EINVAL;
        }
 
-       if (grp->fmtype != 0 && grp->fmtype != 1) {
+       switch (grp->fmtype) {
+       case NVM_ID_FMTYPE_SLC:
+               if (nvm_init_slc_tbl(dev, grp))
+                       return -ENOMEM;
+               break;
+       case NVM_ID_FMTYPE_MLC:
+               if (nvm_init_mlc_tbl(dev, grp))
+                       return -ENOMEM;
+               break;
+       default:
                pr_err("nvm: flash type not supported\n");
                return -EINVAL;
        }
 
+       if (!dev->lps_per_blk)
+               pr_info("nvm: lower page programming table missing\n");
+
        if (grp->mpos & 0x020202)
                dev->plane_mode = NVM_PLANE_DOUBLE;
        if (grp->mpos & 0x040404)
@@ -238,6 +469,7 @@ static int nvm_core_init(struct nvm_dev *dev)
                                dev->nr_chnls;
        dev->total_pages = dev->total_blocks * dev->pgs_per_blk;
        INIT_LIST_HEAD(&dev->online_targets);
+       mutex_init(&dev->mlock);
 
        return 0;
 }
@@ -249,6 +481,8 @@ static void nvm_free(struct nvm_dev *dev)
 
        if (dev->mt)
                dev->mt->unregister_mgr(dev);
+
+       kfree(dev->lptbl);
 }
 
 static int nvm_init(struct nvm_dev *dev)
@@ -338,9 +572,16 @@ int nvm_register(struct request_queue *q, char *disk_name,
                }
        }
 
+       ret = nvm_get_sysblock(dev, &dev->sb);
+       if (!ret)
+               pr_err("nvm: device not initialized.\n");
+       else if (ret < 0)
+               pr_err("nvm: err (%d) on device initialization\n", ret);
+
        /* register device with a supported media manager */
        down_write(&nvm_lock);
-       dev->mt = nvm_init_mgr(dev);
+       if (ret > 0)
+               dev->mt = nvm_init_mgr(dev);
        list_add(&dev->devices, &nvm_devices);
        up_write(&nvm_lock);
 
@@ -788,6 +1029,97 @@ static long nvm_ioctl_dev_remove(struct file *file, void __user *arg)
        return __nvm_configure_remove(&remove);
 }
 
+static void nvm_setup_nvm_sb_info(struct nvm_sb_info *info)
+{
+       info->seqnr = 1;
+       info->erase_cnt = 0;
+       info->version = 1;
+}
+
+static long __nvm_ioctl_dev_init(struct nvm_ioctl_dev_init *init)
+{
+       struct nvm_dev *dev;
+       struct nvm_sb_info info;
+       int ret;
+
+       down_write(&nvm_lock);
+       dev = nvm_find_nvm_dev(init->dev);
+       up_write(&nvm_lock);
+       if (!dev) {
+               pr_err("nvm: device not found\n");
+               return -EINVAL;
+       }
+
+       nvm_setup_nvm_sb_info(&info);
+
+       strncpy(info.mmtype, init->mmtype, NVM_MMTYPE_LEN);
+       info.fs_ppa.ppa = -1;
+
+       ret = nvm_init_sysblock(dev, &info);
+       if (ret)
+               return ret;
+
+       memcpy(&dev->sb, &info, sizeof(struct nvm_sb_info));
+
+       down_write(&nvm_lock);
+       dev->mt = nvm_init_mgr(dev);
+       up_write(&nvm_lock);
+
+       return 0;
+}
+
+static long nvm_ioctl_dev_init(struct file *file, void __user *arg)
+{
+       struct nvm_ioctl_dev_init init;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (copy_from_user(&init, arg, sizeof(struct nvm_ioctl_dev_init)))
+               return -EFAULT;
+
+       if (init.flags != 0) {
+               pr_err("nvm: no flags supported\n");
+               return -EINVAL;
+       }
+
+       init.dev[DISK_NAME_LEN - 1] = '\0';
+
+       return __nvm_ioctl_dev_init(&init);
+}
+
+static long nvm_ioctl_dev_factory(struct file *file, void __user *arg)
+{
+       struct nvm_ioctl_dev_factory fact;
+       struct nvm_dev *dev;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (copy_from_user(&fact, arg, sizeof(struct nvm_ioctl_dev_factory)))
+               return -EFAULT;
+
+       fact.dev[DISK_NAME_LEN - 1] = '\0';
+
+       if (fact.flags & ~(NVM_FACTORY_NR_BITS - 1))
+               return -EINVAL;
+
+       down_write(&nvm_lock);
+       dev = nvm_find_nvm_dev(fact.dev);
+       up_write(&nvm_lock);
+       if (!dev) {
+               pr_err("nvm: device not found\n");
+               return -EINVAL;
+       }
+
+       if (dev->mt) {
+               dev->mt->unregister_mgr(dev);
+               dev->mt = NULL;
+       }
+
+       return nvm_dev_factory(dev, fact.flags);
+}
+
 static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
@@ -801,6 +1133,10 @@ static long nvm_ctl_ioctl(struct file *file, uint cmd, unsigned long arg)
                return nvm_ioctl_dev_create(file, argp);
        case NVM_DEV_REMOVE:
                return nvm_ioctl_dev_remove(file, argp);
+       case NVM_DEV_INIT:
+               return nvm_ioctl_dev_init(file, argp);
+       case NVM_DEV_FACTORY:
+               return nvm_ioctl_dev_factory(file, argp);
        }
        return 0;
 }
index a54b339..7fb725b 100644 (file)
@@ -60,7 +60,8 @@ static int gennvm_luns_init(struct nvm_dev *dev, struct gen_nvm *gn)
                lun->vlun.lun_id = i % dev->luns_per_chnl;
                lun->vlun.chnl_id = i / dev->luns_per_chnl;
                lun->vlun.nr_free_blocks = dev->blks_per_lun;
-               lun->vlun.nr_inuse_blocks = 0;
+               lun->vlun.nr_open_blocks = 0;
+               lun->vlun.nr_closed_blocks = 0;
                lun->vlun.nr_bad_blocks = 0;
        }
        return 0;
@@ -89,6 +90,7 @@ static int gennvm_block_bb(struct ppa_addr ppa, int nr_blocks, u8 *blks,
 
                list_move_tail(&blk->list, &lun->bb_list);
                lun->vlun.nr_bad_blocks++;
+               lun->vlun.nr_free_blocks--;
        }
 
        return 0;
@@ -133,15 +135,15 @@ static int gennvm_block_map(u64 slba, u32 nlb, __le64 *entries, void *private)
                pba = pba - (dev->sec_per_lun * lun_id);
                blk = &lun->vlun.blocks[div_u64(pba, dev->sec_per_blk)];
 
-               if (!blk->type) {
+               if (!blk->state) {
                        /* at this point, we don't know anything about the
                         * block. It's up to the FTL on top to re-etablish the
-                        * block state
+                        * block state. The block is assumed to be open.
                         */
                        list_move_tail(&blk->list, &lun->used_list);
-                       blk->type = 1;
+                       blk->state = NVM_BLK_ST_OPEN;
                        lun->vlun.nr_free_blocks--;
-                       lun->vlun.nr_inuse_blocks++;
+                       lun->vlun.nr_open_blocks++;
                }
        }
 
@@ -255,14 +257,14 @@ static void gennvm_unregister(struct nvm_dev *dev)
        module_put(THIS_MODULE);
 }
 
-static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
+static struct nvm_block *gennvm_get_blk_unlocked(struct nvm_dev *dev,
                                struct nvm_lun *vlun, unsigned long flags)
 {
        struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun);
        struct nvm_block *blk = NULL;
        int is_gc = flags & NVM_IOTYPE_GC;
 
-       spin_lock(&vlun->lock);
+       assert_spin_locked(&vlun->lock);
 
        if (list_empty(&lun->free_list)) {
                pr_err_ratelimited("gennvm: lun %u have no free pages available",
@@ -275,83 +277,64 @@ static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
 
        blk = list_first_entry(&lun->free_list, struct nvm_block, list);
        list_move_tail(&blk->list, &lun->used_list);
-       blk->type = 1;
+       blk->state = NVM_BLK_ST_OPEN;
 
        lun->vlun.nr_free_blocks--;
-       lun->vlun.nr_inuse_blocks++;
+       lun->vlun.nr_open_blocks++;
 
 out:
+       return blk;
+}
+
+static struct nvm_block *gennvm_get_blk(struct nvm_dev *dev,
+                               struct nvm_lun *vlun, unsigned long flags)
+{
+       struct nvm_block *blk;
+
+       spin_lock(&vlun->lock);
+       blk = gennvm_get_blk_unlocked(dev, vlun, flags);
        spin_unlock(&vlun->lock);
        return blk;
 }
 
-static void gennvm_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
+static void gennvm_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk)
 {
        struct nvm_lun *vlun = blk->lun;
        struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun);
 
-       spin_lock(&vlun->lock);
+       assert_spin_locked(&vlun->lock);
 
-       switch (blk->type) {
-       case 1:
+       if (blk->state & NVM_BLK_ST_OPEN) {
                list_move_tail(&blk->list, &lun->free_list);
+               lun->vlun.nr_open_blocks--;
                lun->vlun.nr_free_blocks++;
-               lun->vlun.nr_inuse_blocks--;
-               blk->type = 0;
-               break;
-       case 2:
+               blk->state = NVM_BLK_ST_FREE;
+       } else if (blk->state & NVM_BLK_ST_CLOSED) {
+               list_move_tail(&blk->list, &lun->free_list);
+               lun->vlun.nr_closed_blocks--;
+               lun->vlun.nr_free_blocks++;
+               blk->state = NVM_BLK_ST_FREE;
+       } else if (blk->state & NVM_BLK_ST_BAD) {
                list_move_tail(&blk->list, &lun->bb_list);
                lun->vlun.nr_bad_blocks++;
-               lun->vlun.nr_inuse_blocks--;
-               break;
-       default:
+               blk->state = NVM_BLK_ST_BAD;
+       } else {
                WARN_ON_ONCE(1);
                pr_err("gennvm: erroneous block type (%lu -> %u)\n",
-                                                       blk->id, blk->type);
+                                                       blk->id, blk->state);
                list_move_tail(&blk->list, &lun->bb_list);
                lun->vlun.nr_bad_blocks++;
-               lun->vlun.nr_inuse_blocks--;
-       }
-
-       spin_unlock(&vlun->lock);
-}
-
-static void gennvm_addr_to_generic_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
-{
-       int i;
-
-       if (rqd->nr_pages > 1) {
-               for (i = 0; i < rqd->nr_pages; i++)
-                       rqd->ppa_list[i] = dev_to_generic_addr(dev,
-                                                       rqd->ppa_list[i]);
-       } else {
-               rqd->ppa_addr = dev_to_generic_addr(dev, rqd->ppa_addr);
+               blk->state = NVM_BLK_ST_BAD;
        }
 }
 
-static void gennvm_generic_to_addr_mode(struct nvm_dev *dev, struct nvm_rq *rqd)
-{
-       int i;
-
-       if (rqd->nr_pages > 1) {
-               for (i = 0; i < rqd->nr_pages; i++)
-                       rqd->ppa_list[i] = generic_to_dev_addr(dev,
-                                                       rqd->ppa_list[i]);
-       } else {
-               rqd->ppa_addr = generic_to_dev_addr(dev, rqd->ppa_addr);
-       }
-}
-
-static int gennvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
+static void gennvm_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
 {
-       if (!dev->ops->submit_io)
-               return 0;
-
-       /* Convert address space */
-       gennvm_generic_to_addr_mode(dev, rqd);
+       struct nvm_lun *vlun = blk->lun;
 
-       rqd->dev = dev;
-       return dev->ops->submit_io(dev, rqd);
+       spin_lock(&vlun->lock);
+       gennvm_put_blk_unlocked(dev, blk);
+       spin_unlock(&vlun->lock);
 }
 
 static void gennvm_blk_set_type(struct nvm_dev *dev, struct ppa_addr *ppa,
@@ -376,7 +359,7 @@ static void gennvm_blk_set_type(struct nvm_dev *dev, struct ppa_addr *ppa,
        blk = &lun->vlun.blocks[ppa->g.blk];
 
        /* will be moved to bb list on put_blk from target */
-       blk->type = type;
+       blk->state = type;
 }
 
 /* mark block bad. It is expected the target recover from the error. */
@@ -390,77 +373,51 @@ static void gennvm_mark_blk_bad(struct nvm_dev *dev, struct nvm_rq *rqd)
        if (dev->ops->set_bb_tbl(dev, rqd, 1))
                return;
 
-       gennvm_addr_to_generic_mode(dev, rqd);
+       nvm_addr_to_generic_mode(dev, rqd);
 
        /* look up blocks and mark them as bad */
        if (rqd->nr_pages > 1)
                for (i = 0; i < rqd->nr_pages; i++)
-                       gennvm_blk_set_type(dev, &rqd->ppa_list[i], 2);
+                       gennvm_blk_set_type(dev, &rqd->ppa_list[i],
+                                               NVM_BLK_ST_BAD);
        else
-               gennvm_blk_set_type(dev, &rqd->ppa_addr, 2);
+               gennvm_blk_set_type(dev, &rqd->ppa_addr, NVM_BLK_ST_BAD);
 }
 
-static int gennvm_end_io(struct nvm_rq *rqd, int error)
+static void gennvm_end_io(struct nvm_rq *rqd)
 {
        struct nvm_tgt_instance *ins = rqd->ins;
-       int ret = 0;
 
-       switch (error) {
+       switch (rqd->error) {
        case NVM_RSP_SUCCESS:
-               break;
        case NVM_RSP_ERR_EMPTYPAGE:
                break;
        case NVM_RSP_ERR_FAILWRITE:
                gennvm_mark_blk_bad(rqd->dev, rqd);
-       default:
-               ret++;
        }
 
-       ret += ins->tt->end_io(rqd, error);
-
-       return ret;
+       ins->tt->end_io(rqd);
 }
 
-static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
-                                                       unsigned long flags)
+static int gennvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 {
-       int plane_cnt = 0, pl_idx, ret;
-       struct ppa_addr addr;
-       struct nvm_rq rqd;
-
-       if (!dev->ops->erase_block)
-               return 0;
-
-       addr = block_to_ppa(dev, blk);
-
-       if (dev->plane_mode == NVM_PLANE_SINGLE) {
-               rqd.nr_pages = 1;
-               rqd.ppa_addr = addr;
-       } else {
-               plane_cnt = (1 << dev->plane_mode);
-               rqd.nr_pages = plane_cnt;
-
-               rqd.ppa_list = nvm_dev_dma_alloc(dev, GFP_KERNEL,
-                                                       &rqd.dma_ppa_list);
-               if (!rqd.ppa_list) {
-                       pr_err("gennvm: failed to allocate dma memory\n");
-                       return -ENOMEM;
-               }
-
-               for (pl_idx = 0; pl_idx < plane_cnt; pl_idx++) {
-                       addr.g.pl = pl_idx;
-                       rqd.ppa_list[pl_idx] = addr;
-               }
-       }
+       if (!dev->ops->submit_io)
+               return -ENODEV;
 
-       gennvm_generic_to_addr_mode(dev, &rqd);
+       /* Convert address space */
+       nvm_generic_to_addr_mode(dev, rqd);
 
-       ret = dev->ops->erase_block(dev, &rqd);
+       rqd->dev = dev;
+       rqd->end_io = gennvm_end_io;
+       return dev->ops->submit_io(dev, rqd);
+}
 
-       if (plane_cnt)
-               nvm_dev_dma_free(dev, rqd.ppa_list, rqd.dma_ppa_list);
+static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
+                                                       unsigned long flags)
+{
+       struct ppa_addr addr = block_to_ppa(dev, blk);
 
-       return ret;
+       return nvm_erase_ppa(dev, &addr, 1);
 }
 
 static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid)
@@ -480,10 +437,11 @@ static void gennvm_lun_info_print(struct nvm_dev *dev)
        gennvm_for_each_lun(gn, lun, i) {
                spin_lock(&lun->vlun.lock);
 
-               pr_info("%s: lun%8u\t%u\t%u\t%u\n",
+               pr_info("%s: lun%8u\t%u\t%u\t%u\t%u\n",
                                dev->name, i,
                                lun->vlun.nr_free_blocks,
-                               lun->vlun.nr_inuse_blocks,
+                               lun->vlun.nr_open_blocks,
+                               lun->vlun.nr_closed_blocks,
                                lun->vlun.nr_bad_blocks);
 
                spin_unlock(&lun->vlun.lock);
@@ -491,21 +449,23 @@ static void gennvm_lun_info_print(struct nvm_dev *dev)
 }
 
 static struct nvmm_type gennvm = {
-       .name           = "gennvm",
-       .version        = {0, 1, 0},
+       .name                   = "gennvm",
+       .version                = {0, 1, 0},
+
+       .register_mgr           = gennvm_register,
+       .unregister_mgr         = gennvm_unregister,
 
-       .register_mgr   = gennvm_register,
-       .unregister_mgr = gennvm_unregister,
+       .get_blk_unlocked       = gennvm_get_blk_unlocked,
+       .put_blk_unlocked       = gennvm_put_blk_unlocked,
 
-       .get_blk        = gennvm_get_blk,
-       .put_blk        = gennvm_put_blk,
+       .get_blk                = gennvm_get_blk,
+       .put_blk                = gennvm_put_blk,
 
-       .submit_io      = gennvm_submit_io,
-       .end_io         = gennvm_end_io,
-       .erase_blk      = gennvm_erase_blk,
+       .submit_io              = gennvm_submit_io,
+       .erase_blk              = gennvm_erase_blk,
 
-       .get_lun        = gennvm_get_lun,
-       .lun_info_print = gennvm_lun_info_print,
+       .get_lun                = gennvm_get_lun,
+       .lun_info_print         = gennvm_lun_info_print,
 };
 
 static int __init gennvm_module_init(void)
index 134e4fa..d8c7595 100644 (file)
@@ -179,16 +179,23 @@ static void rrpc_set_lun_cur(struct rrpc_lun *rlun, struct rrpc_block *rblk)
 static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
                                                        unsigned long flags)
 {
+       struct nvm_lun *lun = rlun->parent;
        struct nvm_block *blk;
        struct rrpc_block *rblk;
 
-       blk = nvm_get_blk(rrpc->dev, rlun->parent, flags);
-       if (!blk)
+       spin_lock(&lun->lock);
+       blk = nvm_get_blk_unlocked(rrpc->dev, rlun->parent, flags);
+       if (!blk) {
+               pr_err("nvm: rrpc: cannot get new block from media manager\n");
+               spin_unlock(&lun->lock);
                return NULL;
+       }
 
        rblk = &rlun->blocks[blk->id];
-       blk->priv = rblk;
+       list_add_tail(&rblk->list, &rlun->open_list);
+       spin_unlock(&lun->lock);
 
+       blk->priv = rblk;
        bitmap_zero(rblk->invalid_pages, rrpc->dev->pgs_per_blk);
        rblk->next_page = 0;
        rblk->nr_invalid_pages = 0;
@@ -199,7 +206,13 @@ static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
 
 static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk)
 {
-       nvm_put_blk(rrpc->dev, rblk->parent);
+       struct rrpc_lun *rlun = rblk->rlun;
+       struct nvm_lun *lun = rlun->parent;
+
+       spin_lock(&lun->lock);
+       nvm_put_blk_unlocked(rrpc->dev, rblk->parent);
+       list_del(&rblk->list);
+       spin_unlock(&lun->lock);
 }
 
 static void rrpc_put_blks(struct rrpc *rrpc)
@@ -287,6 +300,8 @@ static int rrpc_move_valid_pages(struct rrpc *rrpc, struct rrpc_block *rblk)
        }
 
        page = mempool_alloc(rrpc->page_pool, GFP_NOIO);
+       if (!page)
+               return -ENOMEM;
 
        while ((slot = find_first_zero_bit(rblk->invalid_pages,
                                            nr_pgs_per_blk)) < nr_pgs_per_blk) {
@@ -328,6 +343,10 @@ try:
                        goto finished;
                }
                wait_for_completion_io(&wait);
+               if (bio->bi_error) {
+                       rrpc_inflight_laddr_release(rrpc, rqd);
+                       goto finished;
+               }
 
                bio_reset(bio);
                reinit_completion(&wait);
@@ -350,6 +369,8 @@ try:
                wait_for_completion_io(&wait);
 
                rrpc_inflight_laddr_release(rrpc, rqd);
+               if (bio->bi_error)
+                       goto finished;
 
                bio_reset(bio);
        }
@@ -373,16 +394,26 @@ static void rrpc_block_gc(struct work_struct *work)
        struct rrpc *rrpc = gcb->rrpc;
        struct rrpc_block *rblk = gcb->rblk;
        struct nvm_dev *dev = rrpc->dev;
+       struct nvm_lun *lun = rblk->parent->lun;
+       struct rrpc_lun *rlun = &rrpc->luns[lun->id - rrpc->lun_offset];
 
+       mempool_free(gcb, rrpc->gcb_pool);
        pr_debug("nvm: block '%lu' being reclaimed\n", rblk->parent->id);
 
        if (rrpc_move_valid_pages(rrpc, rblk))
-               goto done;
+               goto put_back;
+
+       if (nvm_erase_blk(dev, rblk->parent))
+               goto put_back;
 
-       nvm_erase_blk(dev, rblk->parent);
        rrpc_put_blk(rrpc, rblk);
-done:
-       mempool_free(gcb, rrpc->gcb_pool);
+
+       return;
+
+put_back:
+       spin_lock(&rlun->lock);
+       list_add_tail(&rblk->prio, &rlun->prio_list);
+       spin_unlock(&rlun->lock);
 }
 
 /* the block with highest number of invalid pages, will be in the beginning
@@ -427,7 +458,7 @@ static void rrpc_lun_gc(struct work_struct *work)
        if (nr_blocks_need < rrpc->nr_luns)
                nr_blocks_need = rrpc->nr_luns;
 
-       spin_lock(&lun->lock);
+       spin_lock(&rlun->lock);
        while (nr_blocks_need > lun->nr_free_blocks &&
                                        !list_empty(&rlun->prio_list)) {
                struct rrpc_block *rblock = block_prio_find_max(rlun);
@@ -436,16 +467,16 @@ static void rrpc_lun_gc(struct work_struct *work)
                if (!rblock->nr_invalid_pages)
                        break;
 
+               gcb = mempool_alloc(rrpc->gcb_pool, GFP_ATOMIC);
+               if (!gcb)
+                       break;
+
                list_del_init(&rblock->prio);
 
                BUG_ON(!block_is_full(rrpc, rblock));
 
                pr_debug("rrpc: selected block '%lu' for GC\n", block->id);
 
-               gcb = mempool_alloc(rrpc->gcb_pool, GFP_ATOMIC);
-               if (!gcb)
-                       break;
-
                gcb->rrpc = rrpc;
                gcb->rblk = rblock;
                INIT_WORK(&gcb->ws_gc, rrpc_block_gc);
@@ -454,7 +485,7 @@ static void rrpc_lun_gc(struct work_struct *work)
 
                nr_blocks_need--;
        }
-       spin_unlock(&lun->lock);
+       spin_unlock(&rlun->lock);
 
        /* TODO: Hint that request queue can be started again */
 }
@@ -635,12 +666,24 @@ static void rrpc_end_io_write(struct rrpc *rrpc, struct rrpc_rq *rrqd,
                lun = rblk->parent->lun;
 
                cmnt_size = atomic_inc_return(&rblk->data_cmnt_size);
-               if (unlikely(cmnt_size == rrpc->dev->pgs_per_blk))
+               if (unlikely(cmnt_size == rrpc->dev->pgs_per_blk)) {
+                       struct nvm_block *blk = rblk->parent;
+                       struct rrpc_lun *rlun = rblk->rlun;
+
+                       spin_lock(&lun->lock);
+                       lun->nr_open_blocks--;
+                       lun->nr_closed_blocks++;
+                       blk->state &= ~NVM_BLK_ST_OPEN;
+                       blk->state |= NVM_BLK_ST_CLOSED;
+                       list_move_tail(&rblk->list, &rlun->closed_list);
+                       spin_unlock(&lun->lock);
+
                        rrpc_run_gc(rrpc, rblk);
+               }
        }
 }
 
-static int rrpc_end_io(struct nvm_rq *rqd, int error)
+static void rrpc_end_io(struct nvm_rq *rqd)
 {
        struct rrpc *rrpc = container_of(rqd->ins, struct rrpc, instance);
        struct rrpc_rq *rrqd = nvm_rq_to_pdu(rqd);
@@ -650,11 +693,12 @@ static int rrpc_end_io(struct nvm_rq *rqd, int error)
        if (bio_data_dir(rqd->bio) == WRITE)
                rrpc_end_io_write(rrpc, rrqd, laddr, npages);
 
+       bio_put(rqd->bio);
+
        if (rrqd->flags & NVM_IOTYPE_GC)
-               return 0;
+               return;
 
        rrpc_unlock_rq(rrpc, rqd);
-       bio_put(rqd->bio);
 
        if (npages > 1)
                nvm_dev_dma_free(rrpc->dev, rqd->ppa_list, rqd->dma_ppa_list);
@@ -662,8 +706,6 @@ static int rrpc_end_io(struct nvm_rq *rqd, int error)
                nvm_dev_dma_free(rrpc->dev, rqd->metadata, rqd->dma_metadata);
 
        mempool_free(rqd, rrpc->rq_pool);
-
-       return 0;
 }
 
 static int rrpc_read_ppalist_rq(struct rrpc *rrpc, struct bio *bio,
@@ -841,6 +883,13 @@ static int rrpc_submit_io(struct rrpc *rrpc, struct bio *bio,
        err = nvm_submit_io(rrpc->dev, rqd);
        if (err) {
                pr_err("rrpc: I/O submission failed: %d\n", err);
+               bio_put(bio);
+               if (!(flags & NVM_IOTYPE_GC)) {
+                       rrpc_unlock_rq(rrpc, rqd);
+                       if (rqd->nr_pages > 1)
+                               nvm_dev_dma_free(rrpc->dev,
+                       rqd->ppa_list, rqd->dma_ppa_list);
+               }
                return NVM_IO_ERR;
        }
 
@@ -1090,6 +1139,11 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end)
        struct rrpc_lun *rlun;
        int i, j;
 
+       if (dev->pgs_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) {
+               pr_err("rrpc: number of pages per block too high.");
+               return -EINVAL;
+       }
+
        spin_lock_init(&rrpc->rev_lock);
 
        rrpc->luns = kcalloc(rrpc->nr_luns, sizeof(struct rrpc_lun),
@@ -1101,16 +1155,13 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end)
        for (i = 0; i < rrpc->nr_luns; i++) {
                struct nvm_lun *lun = dev->mt->get_lun(dev, lun_begin + i);
 
-               if (dev->pgs_per_blk >
-                               MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) {
-                       pr_err("rrpc: number of pages per block too high.");
-                       goto err;
-               }
-
                rlun = &rrpc->luns[i];
                rlun->rrpc = rrpc;
                rlun->parent = lun;
                INIT_LIST_HEAD(&rlun->prio_list);
+               INIT_LIST_HEAD(&rlun->open_list);
+               INIT_LIST_HEAD(&rlun->closed_list);
+
                INIT_WORK(&rlun->ws_gc, rrpc_lun_gc);
                spin_lock_init(&rlun->lock);
 
@@ -1127,6 +1178,7 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end)
                        struct nvm_block *blk = &lun->blocks[j];
 
                        rblk->parent = blk;
+                       rblk->rlun = rlun;
                        INIT_LIST_HEAD(&rblk->prio);
                        spin_lock_init(&rblk->lock);
                }
index a9696a0..ef13ac7 100644 (file)
@@ -54,7 +54,9 @@ struct rrpc_rq {
 
 struct rrpc_block {
        struct nvm_block *parent;
+       struct rrpc_lun *rlun;
        struct list_head prio;
+       struct list_head list;
 
 #define MAX_INVALID_PAGES_STORAGE 8
        /* Bitmap for invalid page intries */
@@ -73,7 +75,16 @@ struct rrpc_lun {
        struct nvm_lun *parent;
        struct rrpc_block *cur, *gc_cur;
        struct rrpc_block *blocks;      /* Reference to block allocation */
-       struct list_head prio_list;             /* Blocks that may be GC'ed */
+
+       struct list_head prio_list;     /* Blocks that may be GC'ed */
+       struct list_head open_list;     /* In-use open blocks. These are blocks
+                                        * that can be both written to and read
+                                        * from
+                                        */
+       struct list_head closed_list;   /* In-use closed blocks. These are
+                                        * blocks that can _only_ be read from
+                                        */
+
        struct work_struct ws_gc;
 
        spinlock_t lock;
diff --git a/drivers/lightnvm/sysblk.c b/drivers/lightnvm/sysblk.c
new file mode 100644 (file)
index 0000000..321de1f
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+ * Copyright (C) 2015 Matias Bjorling. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ */
+
+#include <linux/lightnvm.h>
+
+#define MAX_SYSBLKS 3  /* remember to update mapping scheme on change */
+#define MAX_BLKS_PR_SYSBLK 2 /* 2 blks with 256 pages and 3000 erases
+                             * enables ~1.5M updates per sysblk unit
+                             */
+
+struct sysblk_scan {
+       /* A row is a collection of flash blocks for a system block. */
+       int nr_rows;
+       int row;
+       int act_blk[MAX_SYSBLKS];
+
+       int nr_ppas;
+       struct ppa_addr ppas[MAX_SYSBLKS * MAX_BLKS_PR_SYSBLK];/* all sysblks */
+};
+
+static inline int scan_ppa_idx(int row, int blkid)
+{
+       return (row * MAX_BLKS_PR_SYSBLK) + blkid;
+}
+
+void nvm_sysblk_to_cpu(struct nvm_sb_info *info, struct nvm_system_block *sb)
+{
+       info->seqnr = be32_to_cpu(sb->seqnr);
+       info->erase_cnt = be32_to_cpu(sb->erase_cnt);
+       info->version = be16_to_cpu(sb->version);
+       strncpy(info->mmtype, sb->mmtype, NVM_MMTYPE_LEN);
+       info->fs_ppa.ppa = be64_to_cpu(sb->fs_ppa);
+}
+
+void nvm_cpu_to_sysblk(struct nvm_system_block *sb, struct nvm_sb_info *info)
+{
+       sb->magic = cpu_to_be32(NVM_SYSBLK_MAGIC);
+       sb->seqnr = cpu_to_be32(info->seqnr);
+       sb->erase_cnt = cpu_to_be32(info->erase_cnt);
+       sb->version = cpu_to_be16(info->version);
+       strncpy(sb->mmtype, info->mmtype, NVM_MMTYPE_LEN);
+       sb->fs_ppa = cpu_to_be64(info->fs_ppa.ppa);
+}
+
+static int nvm_setup_sysblks(struct nvm_dev *dev, struct ppa_addr *sysblk_ppas)
+{
+       int nr_rows = min_t(int, MAX_SYSBLKS, dev->nr_chnls);
+       int i;
+
+       for (i = 0; i < nr_rows; i++)
+               sysblk_ppas[i].ppa = 0;
+
+       /* if possible, place sysblk at first channel, middle channel and last
+        * channel of the device. If not, create only one or two sys blocks
+        */
+       switch (dev->nr_chnls) {
+       case 2:
+               sysblk_ppas[1].g.ch = 1;
+               /* fall-through */
+       case 1:
+               sysblk_ppas[0].g.ch = 0;
+               break;
+       default:
+               sysblk_ppas[0].g.ch = 0;
+               sysblk_ppas[1].g.ch = dev->nr_chnls / 2;
+               sysblk_ppas[2].g.ch = dev->nr_chnls - 1;
+               break;
+       }
+
+       return nr_rows;
+}
+
+void nvm_setup_sysblk_scan(struct nvm_dev *dev, struct sysblk_scan *s,
+                                               struct ppa_addr *sysblk_ppas)
+{
+       memset(s, 0, sizeof(struct sysblk_scan));
+       s->nr_rows = nvm_setup_sysblks(dev, sysblk_ppas);
+}
+
+static int sysblk_get_host_blks(struct ppa_addr ppa, int nr_blks, u8 *blks,
+                                                               void *private)
+{
+       struct sysblk_scan *s = private;
+       int i, nr_sysblk = 0;
+
+       for (i = 0; i < nr_blks; i++) {
+               if (blks[i] != NVM_BLK_T_HOST)
+                       continue;
+
+               if (s->nr_ppas == MAX_BLKS_PR_SYSBLK * MAX_SYSBLKS) {
+                       pr_err("nvm: too many host blks\n");
+                       return -EINVAL;
+               }
+
+               ppa.g.blk = i;
+
+               s->ppas[scan_ppa_idx(s->row, nr_sysblk)] = ppa;
+               s->nr_ppas++;
+               nr_sysblk++;
+       }
+
+       return 0;
+}
+
+static int nvm_get_all_sysblks(struct nvm_dev *dev, struct sysblk_scan *s,
+                               struct ppa_addr *ppas, nvm_bb_update_fn *fn)
+{
+       struct ppa_addr dppa;
+       int i, ret;
+
+       s->nr_ppas = 0;
+
+       for (i = 0; i < s->nr_rows; i++) {
+               dppa = generic_to_dev_addr(dev, ppas[i]);
+               s->row = i;
+
+               ret = dev->ops->get_bb_tbl(dev, dppa, dev->blks_per_lun, fn, s);
+               if (ret) {
+                       pr_err("nvm: failed bb tbl for ppa (%u %u)\n",
+                                                       ppas[i].g.ch,
+                                                       ppas[i].g.blk);
+                       return ret;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * scans a block for latest sysblk.
+ * Returns:
+ *     0 - newer sysblk not found. PPA is updated to latest page.
+ *     1 - newer sysblk found and stored in *cur. PPA is updated to
+ *         next valid page.
+ *     <0- error.
+ */
+static int nvm_scan_block(struct nvm_dev *dev, struct ppa_addr *ppa,
+                                               struct nvm_system_block *sblk)
+{
+       struct nvm_system_block *cur;
+       int pg, cursz, ret, found = 0;
+
+       /* the full buffer for a flash page is allocated. Only the first of it
+        * contains the system block information
+        */
+       cursz = dev->sec_size * dev->sec_per_pg * dev->nr_planes;
+       cur = kmalloc(cursz, GFP_KERNEL);
+       if (!cur)
+               return -ENOMEM;
+
+       /* perform linear scan through the block */
+       for (pg = 0; pg < dev->lps_per_blk; pg++) {
+               ppa->g.pg = ppa_to_slc(dev, pg);
+
+               ret = nvm_submit_ppa(dev, ppa, 1, NVM_OP_PREAD, NVM_IO_SLC_MODE,
+                                                               cur, cursz);
+               if (ret) {
+                       if (ret == NVM_RSP_ERR_EMPTYPAGE) {
+                               pr_debug("nvm: sysblk scan empty ppa (%u %u %u %u)\n",
+                                                       ppa->g.ch,
+                                                       ppa->g.lun,
+                                                       ppa->g.blk,
+                                                       ppa->g.pg);
+                               break;
+                       }
+                       pr_err("nvm: read failed (%x) for ppa (%u %u %u %u)",
+                                                       ret,
+                                                       ppa->g.ch,
+                                                       ppa->g.lun,
+                                                       ppa->g.blk,
+                                                       ppa->g.pg);
+                       break; /* if we can't read a page, continue to the
+                               * next blk
+                               */
+               }
+
+               if (be32_to_cpu(cur->magic) != NVM_SYSBLK_MAGIC) {
+                       pr_debug("nvm: scan break for ppa (%u %u %u %u)\n",
+                                                       ppa->g.ch,
+                                                       ppa->g.lun,
+                                                       ppa->g.blk,
+                                                       ppa->g.pg);
+                       break; /* last valid page already found */
+               }
+
+               if (be32_to_cpu(cur->seqnr) < be32_to_cpu(sblk->seqnr))
+                       continue;
+
+               memcpy(sblk, cur, sizeof(struct nvm_system_block));
+               found = 1;
+       }
+
+       kfree(cur);
+
+       return found;
+}
+
+static int nvm_set_bb_tbl(struct nvm_dev *dev, struct sysblk_scan *s, int type)
+{
+       struct nvm_rq rqd;
+       int ret;
+
+       if (s->nr_ppas > dev->ops->max_phys_sect) {
+               pr_err("nvm: unable to update all sysblocks atomically\n");
+               return -EINVAL;
+       }
+
+       memset(&rqd, 0, sizeof(struct nvm_rq));
+
+       nvm_set_rqd_ppalist(dev, &rqd, s->ppas, s->nr_ppas);
+       nvm_generic_to_addr_mode(dev, &rqd);
+
+       ret = dev->ops->set_bb_tbl(dev, &rqd, type);
+       nvm_free_rqd_ppalist(dev, &rqd);
+       if (ret) {
+               pr_err("nvm: sysblk failed bb mark\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int sysblk_get_free_blks(struct ppa_addr ppa, int nr_blks, u8 *blks,
+                                                               void *private)
+{
+       struct sysblk_scan *s = private;
+       struct ppa_addr *sppa;
+       int i, blkid = 0;
+
+       for (i = 0; i < nr_blks; i++) {
+               if (blks[i] == NVM_BLK_T_HOST)
+                       return -EEXIST;
+
+               if (blks[i] != NVM_BLK_T_FREE)
+                       continue;
+
+               sppa = &s->ppas[scan_ppa_idx(s->row, blkid)];
+               sppa->g.ch = ppa.g.ch;
+               sppa->g.lun = ppa.g.lun;
+               sppa->g.blk = i;
+               s->nr_ppas++;
+               blkid++;
+
+               pr_debug("nvm: use (%u %u %u) as sysblk\n",
+                                       sppa->g.ch, sppa->g.lun, sppa->g.blk);
+               if (blkid > MAX_BLKS_PR_SYSBLK - 1)
+                       return 0;
+       }
+
+       pr_err("nvm: sysblk failed get sysblk\n");
+       return -EINVAL;
+}
+
+static int nvm_write_and_verify(struct nvm_dev *dev, struct nvm_sb_info *info,
+                                                       struct sysblk_scan *s)
+{
+       struct nvm_system_block nvmsb;
+       void *buf;
+       int i, sect, ret, bufsz;
+       struct ppa_addr *ppas;
+
+       nvm_cpu_to_sysblk(&nvmsb, info);
+
+       /* buffer for flash page */
+       bufsz = dev->sec_size * dev->sec_per_pg * dev->nr_planes;
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       memcpy(buf, &nvmsb, sizeof(struct nvm_system_block));
+
+       ppas = kcalloc(dev->sec_per_pg, sizeof(struct ppa_addr), GFP_KERNEL);
+       if (!ppas) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       /* Write and verify */
+       for (i = 0; i < s->nr_rows; i++) {
+               ppas[0] = s->ppas[scan_ppa_idx(i, s->act_blk[i])];
+
+               pr_debug("nvm: writing sysblk to ppa (%u %u %u %u)\n",
+                                                       ppas[0].g.ch,
+                                                       ppas[0].g.lun,
+                                                       ppas[0].g.blk,
+                                                       ppas[0].g.pg);
+
+               /* Expand to all sectors within a flash page */
+               if (dev->sec_per_pg > 1) {
+                       for (sect = 1; sect < dev->sec_per_pg; sect++) {
+                               ppas[sect].ppa = ppas[0].ppa;
+                               ppas[sect].g.sec = sect;
+                       }
+               }
+
+               ret = nvm_submit_ppa(dev, ppas, dev->sec_per_pg, NVM_OP_PWRITE,
+                                               NVM_IO_SLC_MODE, buf, bufsz);
+               if (ret) {
+                       pr_err("nvm: sysblk failed program (%u %u %u)\n",
+                                                       ppas[0].g.ch,
+                                                       ppas[0].g.lun,
+                                                       ppas[0].g.blk);
+                       break;
+               }
+
+               ret = nvm_submit_ppa(dev, ppas, dev->sec_per_pg, NVM_OP_PREAD,
+                                               NVM_IO_SLC_MODE, buf, bufsz);
+               if (ret) {
+                       pr_err("nvm: sysblk failed read (%u %u %u)\n",
+                                                       ppas[0].g.ch,
+                                                       ppas[0].g.lun,
+                                                       ppas[0].g.blk);
+                       break;
+               }
+
+               if (memcmp(buf, &nvmsb, sizeof(struct nvm_system_block))) {
+                       pr_err("nvm: sysblk failed verify (%u %u %u)\n",
+                                                       ppas[0].g.ch,
+                                                       ppas[0].g.lun,
+                                                       ppas[0].g.blk);
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+
+       kfree(ppas);
+err:
+       kfree(buf);
+
+       return ret;
+}
+
+static int nvm_prepare_new_sysblks(struct nvm_dev *dev, struct sysblk_scan *s)
+{
+       int i, ret;
+       unsigned long nxt_blk;
+       struct ppa_addr *ppa;
+
+       for (i = 0; i < s->nr_rows; i++) {
+               nxt_blk = (s->act_blk[i] + 1) % MAX_BLKS_PR_SYSBLK;
+               ppa = &s->ppas[scan_ppa_idx(i, nxt_blk)];
+               ppa->g.pg = ppa_to_slc(dev, 0);
+
+               ret = nvm_erase_ppa(dev, ppa, 1);
+               if (ret)
+                       return ret;
+
+               s->act_blk[i] = nxt_blk;
+       }
+
+       return 0;
+}
+
+int nvm_get_sysblock(struct nvm_dev *dev, struct nvm_sb_info *info)
+{
+       struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+       struct sysblk_scan s;
+       struct nvm_system_block *cur;
+       int i, j, found = 0;
+       int ret = -ENOMEM;
+
+       /*
+        * 1. setup sysblk locations
+        * 2. get bad block list
+        * 3. filter on host-specific (type 3)
+        * 4. iterate through all and find the highest seq nr.
+        * 5. return superblock information
+        */
+
+       if (!dev->ops->get_bb_tbl)
+               return -EINVAL;
+
+       nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+
+       mutex_lock(&dev->mlock);
+       ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas, sysblk_get_host_blks);
+       if (ret)
+               goto err_sysblk;
+
+       /* no sysblocks initialized */
+       if (!s.nr_ppas)
+               goto err_sysblk;
+
+       cur = kzalloc(sizeof(struct nvm_system_block), GFP_KERNEL);
+       if (!cur)
+               goto err_sysblk;
+
+       /* find the latest block across all sysblocks */
+       for (i = 0; i < s.nr_rows; i++) {
+               for (j = 0; j < MAX_BLKS_PR_SYSBLK; j++) {
+                       struct ppa_addr ppa = s.ppas[scan_ppa_idx(i, j)];
+
+                       ret = nvm_scan_block(dev, &ppa, cur);
+                       if (ret > 0)
+                               found = 1;
+                       else if (ret < 0)
+                               break;
+               }
+       }
+
+       nvm_sysblk_to_cpu(info, cur);
+
+       kfree(cur);
+err_sysblk:
+       mutex_unlock(&dev->mlock);
+
+       if (found)
+               return 1;
+       return ret;
+}
+
+int nvm_update_sysblock(struct nvm_dev *dev, struct nvm_sb_info *new)
+{
+       /* 1. for each latest superblock
+        * 2. if room
+        *    a. write new flash page entry with the updated information
+        * 3. if no room
+        *    a. find next available block on lun (linear search)
+        *       if none, continue to next lun
+        *       if none at all, report error. also report that it wasn't
+        *       possible to write to all superblocks.
+        *    c. write data to block.
+        */
+       struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+       struct sysblk_scan s;
+       struct nvm_system_block *cur;
+       int i, j, ppaidx, found = 0;
+       int ret = -ENOMEM;
+
+       if (!dev->ops->get_bb_tbl)
+               return -EINVAL;
+
+       nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+
+       mutex_lock(&dev->mlock);
+       ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas, sysblk_get_host_blks);
+       if (ret)
+               goto err_sysblk;
+
+       cur = kzalloc(sizeof(struct nvm_system_block), GFP_KERNEL);
+       if (!cur)
+               goto err_sysblk;
+
+       /* Get the latest sysblk for each sysblk row */
+       for (i = 0; i < s.nr_rows; i++) {
+               found = 0;
+               for (j = 0; j < MAX_BLKS_PR_SYSBLK; j++) {
+                       ppaidx = scan_ppa_idx(i, j);
+                       ret = nvm_scan_block(dev, &s.ppas[ppaidx], cur);
+                       if (ret > 0) {
+                               s.act_blk[i] = j;
+                               found = 1;
+                       } else if (ret < 0)
+                               break;
+               }
+       }
+
+       if (!found) {
+               pr_err("nvm: no valid sysblks found to update\n");
+               ret = -EINVAL;
+               goto err_cur;
+       }
+
+       /*
+        * All sysblocks found. Check that they have same page id in their flash
+        * blocks
+        */
+       for (i = 1; i < s.nr_rows; i++) {
+               struct ppa_addr l = s.ppas[scan_ppa_idx(0, s.act_blk[0])];
+               struct ppa_addr r = s.ppas[scan_ppa_idx(i, s.act_blk[i])];
+
+               if (l.g.pg != r.g.pg) {
+                       pr_err("nvm: sysblks not on same page. Previous update failed.\n");
+                       ret = -EINVAL;
+                       goto err_cur;
+               }
+       }
+
+       /*
+        * Check that there haven't been another update to the seqnr since we
+        * began
+        */
+       if ((new->seqnr - 1) != be32_to_cpu(cur->seqnr)) {
+               pr_err("nvm: seq is not sequential\n");
+               ret = -EINVAL;
+               goto err_cur;
+       }
+
+       /*
+        * When all pages in a block has been written, a new block is selected
+        * and writing is performed on the new block.
+        */
+       if (s.ppas[scan_ppa_idx(0, s.act_blk[0])].g.pg ==
+                                               dev->lps_per_blk - 1) {
+               ret = nvm_prepare_new_sysblks(dev, &s);
+               if (ret)
+                       goto err_cur;
+       }
+
+       ret = nvm_write_and_verify(dev, new, &s);
+err_cur:
+       kfree(cur);
+err_sysblk:
+       mutex_unlock(&dev->mlock);
+
+       return ret;
+}
+
+int nvm_init_sysblock(struct nvm_dev *dev, struct nvm_sb_info *info)
+{
+       struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+       struct sysblk_scan s;
+       int ret;
+
+       /*
+        * 1. select master blocks and select first available blks
+        * 2. get bad block list
+        * 3. mark MAX_SYSBLKS block as host-based device allocated.
+        * 4. write and verify data to block
+        */
+
+       if (!dev->ops->get_bb_tbl || !dev->ops->set_bb_tbl)
+               return -EINVAL;
+
+       if (!(dev->mccap & NVM_ID_CAP_SLC) || !dev->lps_per_blk) {
+               pr_err("nvm: memory does not support SLC access\n");
+               return -EINVAL;
+       }
+
+       /* Index all sysblocks and mark them as host-driven */
+       nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+
+       mutex_lock(&dev->mlock);
+       ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas, sysblk_get_free_blks);
+       if (ret)
+               goto err_mark;
+
+       ret = nvm_set_bb_tbl(dev, &s, NVM_BLK_T_HOST);
+       if (ret)
+               goto err_mark;
+
+       /* Write to the first block of each row */
+       ret = nvm_write_and_verify(dev, info, &s);
+err_mark:
+       mutex_unlock(&dev->mlock);
+       return ret;
+}
+
+struct factory_blks {
+       struct nvm_dev *dev;
+       int flags;
+       unsigned long *blks;
+};
+
+static int factory_nblks(int nblks)
+{
+       /* Round up to nearest BITS_PER_LONG */
+       return (nblks + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
+}
+
+static unsigned int factory_blk_offset(struct nvm_dev *dev, int ch, int lun)
+{
+       int nblks = factory_nblks(dev->blks_per_lun);
+
+       return ((ch * dev->luns_per_chnl * nblks) + (lun * nblks)) /
+                                                               BITS_PER_LONG;
+}
+
+static int nvm_factory_blks(struct ppa_addr ppa, int nr_blks, u8 *blks,
+                                                               void *private)
+{
+       struct factory_blks *f = private;
+       struct nvm_dev *dev = f->dev;
+       int i, lunoff;
+
+       lunoff = factory_blk_offset(dev, ppa.g.ch, ppa.g.lun);
+
+       /* non-set bits correspond to the block must be erased */
+       for (i = 0; i < nr_blks; i++) {
+               switch (blks[i]) {
+               case NVM_BLK_T_FREE:
+                       if (f->flags & NVM_FACTORY_ERASE_ONLY_USER)
+                               set_bit(i, &f->blks[lunoff]);
+                       break;
+               case NVM_BLK_T_HOST:
+                       if (!(f->flags & NVM_FACTORY_RESET_HOST_BLKS))
+                               set_bit(i, &f->blks[lunoff]);
+                       break;
+               case NVM_BLK_T_GRWN_BAD:
+                       if (!(f->flags & NVM_FACTORY_RESET_GRWN_BBLKS))
+                               set_bit(i, &f->blks[lunoff]);
+                       break;
+               default:
+                       set_bit(i, &f->blks[lunoff]);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int nvm_fact_get_blks(struct nvm_dev *dev, struct ppa_addr *erase_list,
+                                       int max_ppas, struct factory_blks *f)
+{
+       struct ppa_addr ppa;
+       int ch, lun, blkid, idx, done = 0, ppa_cnt = 0;
+       unsigned long *offset;
+
+       while (!done) {
+               done = 1;
+               for (ch = 0; ch < dev->nr_chnls; ch++) {
+                       for (lun = 0; lun < dev->luns_per_chnl; lun++) {
+                               idx = factory_blk_offset(dev, ch, lun);
+                               offset = &f->blks[idx];
+
+                               blkid = find_first_zero_bit(offset,
+                                                       dev->blks_per_lun);
+                               if (blkid >= dev->blks_per_lun)
+                                       continue;
+                               set_bit(blkid, offset);
+
+                               ppa.ppa = 0;
+                               ppa.g.ch = ch;
+                               ppa.g.lun = lun;
+                               ppa.g.blk = blkid;
+                               pr_debug("nvm: erase ppa (%u %u %u)\n",
+                                                               ppa.g.ch,
+                                                               ppa.g.lun,
+                                                               ppa.g.blk);
+
+                               erase_list[ppa_cnt] = ppa;
+                               ppa_cnt++;
+                               done = 0;
+
+                               if (ppa_cnt == max_ppas)
+                                       return ppa_cnt;
+                       }
+               }
+       }
+
+       return ppa_cnt;
+}
+
+static int nvm_fact_get_bb_tbl(struct nvm_dev *dev, struct ppa_addr ppa,
+                                       nvm_bb_update_fn *fn, void *priv)
+{
+       struct ppa_addr dev_ppa;
+       int ret;
+
+       dev_ppa = generic_to_dev_addr(dev, ppa);
+
+       ret = dev->ops->get_bb_tbl(dev, dev_ppa, dev->blks_per_lun, fn, priv);
+       if (ret)
+               pr_err("nvm: failed bb tbl for ch%u lun%u\n",
+                                                       ppa.g.ch, ppa.g.blk);
+       return ret;
+}
+
+static int nvm_fact_select_blks(struct nvm_dev *dev, struct factory_blks *f)
+{
+       int ch, lun, ret;
+       struct ppa_addr ppa;
+
+       ppa.ppa = 0;
+       for (ch = 0; ch < dev->nr_chnls; ch++) {
+               for (lun = 0; lun < dev->luns_per_chnl; lun++) {
+                       ppa.g.ch = ch;
+                       ppa.g.lun = lun;
+
+                       ret = nvm_fact_get_bb_tbl(dev, ppa, nvm_factory_blks,
+                                                                       f);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+int nvm_dev_factory(struct nvm_dev *dev, int flags)
+{
+       struct factory_blks f;
+       struct ppa_addr *ppas;
+       int ppa_cnt, ret = -ENOMEM;
+       int max_ppas = dev->ops->max_phys_sect / dev->nr_planes;
+       struct ppa_addr sysblk_ppas[MAX_SYSBLKS];
+       struct sysblk_scan s;
+
+       f.blks = kzalloc(factory_nblks(dev->blks_per_lun) * dev->nr_luns,
+                                                               GFP_KERNEL);
+       if (!f.blks)
+               return ret;
+
+       ppas = kcalloc(max_ppas, sizeof(struct ppa_addr), GFP_KERNEL);
+       if (!ppas)
+               goto err_blks;
+
+       f.dev = dev;
+       f.flags = flags;
+
+       /* create list of blks to be erased */
+       ret = nvm_fact_select_blks(dev, &f);
+       if (ret)
+               goto err_ppas;
+
+       /* continue to erase until list of blks until empty */
+       while ((ppa_cnt = nvm_fact_get_blks(dev, ppas, max_ppas, &f)) > 0)
+               nvm_erase_ppa(dev, ppas, ppa_cnt);
+
+       /* mark host reserved blocks free */
+       if (flags & NVM_FACTORY_RESET_HOST_BLKS) {
+               nvm_setup_sysblk_scan(dev, &s, sysblk_ppas);
+               mutex_lock(&dev->mlock);
+               ret = nvm_get_all_sysblks(dev, &s, sysblk_ppas,
+                                                       sysblk_get_host_blks);
+               if (!ret)
+                       ret = nvm_set_bb_tbl(dev, &s, NVM_BLK_T_FREE);
+               mutex_unlock(&dev->mlock);
+       }
+err_ppas:
+       kfree(ppas);
+err_blks:
+       kfree(f.blks);
+       return ret;
+}
+EXPORT_SYMBOL(nvm_dev_factory);
index 83392f8..22b9e34 100644 (file)
@@ -1741,6 +1741,7 @@ static void bch_btree_gc(struct cache_set *c)
        do {
                ret = btree_root(gc_root, c, &op, &writes, &stats);
                closure_sync(&writes);
+               cond_resched();
 
                if (ret && ret != -EAGAIN)
                        pr_warn("gc failed!");
@@ -2162,8 +2163,10 @@ int bch_btree_insert_check_key(struct btree *b, struct btree_op *op,
                rw_lock(true, b, b->level);
 
                if (b->key.ptr[0] != btree_ptr ||
-                   b->seq != seq + 1)
+                   b->seq != seq + 1) {
+                       op->lock = b->level;
                        goto out;
+               }
        }
 
        SET_KEY_PTRS(check_key, 1);
index 679a093..8d0ead9 100644 (file)
@@ -685,6 +685,8 @@ static void bcache_device_link(struct bcache_device *d, struct cache_set *c,
        WARN(sysfs_create_link(&d->kobj, &c->kobj, "cache") ||
             sysfs_create_link(&c->kobj, &d->kobj, d->name),
             "Couldn't create device <-> cache set symlinks");
+
+       clear_bit(BCACHE_DEV_UNLINK_DONE, &d->flags);
 }
 
 static void bcache_device_detach(struct bcache_device *d)
@@ -847,8 +849,11 @@ void bch_cached_dev_run(struct cached_dev *dc)
        buf[SB_LABEL_SIZE] = '\0';
        env[2] = kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf);
 
-       if (atomic_xchg(&dc->running, 1))
+       if (atomic_xchg(&dc->running, 1)) {
+               kfree(env[1]);
+               kfree(env[2]);
                return;
+       }
 
        if (!d->c &&
            BDEV_STATE(&dc->sb) != BDEV_STATE_NONE) {
@@ -1933,6 +1938,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
                        else
                                err = "device busy";
                        mutex_unlock(&bch_register_lock);
+                       if (attr == &ksysfs_register_quiet)
+                               goto out;
                }
                goto err;
        }
@@ -1971,8 +1978,7 @@ out:
 err_close:
        blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
 err:
-       if (attr != &ksysfs_register_quiet)
-               pr_info("error opening %s: %s", path, err);
+       pr_info("error opening %s: %s", path, err);
        ret = -EINVAL;
        goto out;
 }
@@ -2066,8 +2072,10 @@ static int __init bcache_init(void)
        closure_debug_init();
 
        bcache_major = register_blkdev(0, "bcache");
-       if (bcache_major < 0)
+       if (bcache_major < 0) {
+               unregister_reboot_notifier(&reboot);
                return bcache_major;
+       }
 
        if (!(bcache_wq = create_workqueue("bcache")) ||
            !(bcache_kobj = kobject_create_and_add("bcache", fs_kobj)) ||
index b23f88d..b9346cd 100644 (file)
@@ -323,6 +323,10 @@ void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned inode,
 
 static bool dirty_pred(struct keybuf *buf, struct bkey *k)
 {
+       struct cached_dev *dc = container_of(buf, struct cached_dev, writeback_keys);
+
+       BUG_ON(KEY_INODE(k) != dc->disk.id);
+
        return KEY_DIRTY(k);
 }
 
@@ -372,11 +376,24 @@ next:
        }
 }
 
+/*
+ * Returns true if we scanned the entire disk
+ */
 static bool refill_dirty(struct cached_dev *dc)
 {
        struct keybuf *buf = &dc->writeback_keys;
+       struct bkey start = KEY(dc->disk.id, 0, 0);
        struct bkey end = KEY(dc->disk.id, MAX_KEY_OFFSET, 0);
-       bool searched_from_start = false;
+       struct bkey start_pos;
+
+       /*
+        * make sure keybuf pos is inside the range for this disk - at bringup
+        * we might not be attached yet so this disk's inode nr isn't
+        * initialized then
+        */
+       if (bkey_cmp(&buf->last_scanned, &start) < 0 ||
+           bkey_cmp(&buf->last_scanned, &end) > 0)
+               buf->last_scanned = start;
 
        if (dc->partial_stripes_expensive) {
                refill_full_stripes(dc);
@@ -384,14 +401,20 @@ static bool refill_dirty(struct cached_dev *dc)
                        return false;
        }
 
-       if (bkey_cmp(&buf->last_scanned, &end) >= 0) {
-               buf->last_scanned = KEY(dc->disk.id, 0, 0);
-               searched_from_start = true;
-       }
-
+       start_pos = buf->last_scanned;
        bch_refill_keybuf(dc->disk.c, buf, &end, dirty_pred);
 
-       return bkey_cmp(&buf->last_scanned, &end) >= 0 && searched_from_start;
+       if (bkey_cmp(&buf->last_scanned, &end) < 0)
+               return false;
+
+       /*
+        * If we get to the end start scanning again from the beginning, and
+        * only scan up to where we initially started scanning from:
+        */
+       buf->last_scanned = start;
+       bch_refill_keybuf(dc->disk.c, buf, &start_pos, dirty_pred);
+
+       return bkey_cmp(&buf->last_scanned, &start_pos) >= 0;
 }
 
 static int bch_writeback_thread(void *arg)
index 0a9dab1..073a042 100644 (file)
@@ -63,7 +63,8 @@ static inline bool should_writeback(struct cached_dev *dc, struct bio *bio,
 
 static inline void bch_writeback_queue(struct cached_dev *dc)
 {
-       wake_up_process(dc->writeback_thread);
+       if (!IS_ERR_OR_NULL(dc->writeback_thread))
+               wake_up_process(dc->writeback_thread);
 }
 
 static inline void bch_writeback_add(struct cached_dev *dc)
index 0c53805..5263594 100644 (file)
@@ -216,7 +216,6 @@ config VIDEO_STI_BDISP
        tristate "STMicroelectronics BDISP 2D blitter driver"
        depends on VIDEO_DEV && VIDEO_V4L2
        depends on ARCH_STI || COMPILE_TEST
-       depends on HAVE_DMA_ATTRS
        select VIDEOBUF2_DMA_CONTIG
        select V4L2_MEM2MEM_DEV
        help
index 21e7255..5a58e44 100644 (file)
@@ -1007,6 +1007,7 @@ static const struct tegra_smmu_soc tegra124_smmu_soc = {
        .num_swgroups = ARRAY_SIZE(tegra124_swgroups),
        .supports_round_robin_arbitration = true,
        .supports_request_limit = true,
+       .num_tlb_lines = 32,
        .num_asids = 128,
 };
 
index 24f2f84..84abf9d 100644 (file)
@@ -1909,7 +1909,7 @@ static void msb_io_work(struct work_struct *work)
                lba = blk_rq_pos(msb->req);
 
                sector_div(lba, msb->page_size / 512);
-               page = do_div(lba, msb->pages_in_block);
+               page = sector_div(lba, msb->pages_in_block);
 
                if (rq_data_dir(msb->req) == READ)
                        error = msb_do_read_request(msb, lba, page, sg,
index 22892c7..054fc10 100644 (file)
@@ -95,6 +95,7 @@ config DUMMY_IRQ
 config IBM_ASM
        tristate "Device driver for IBM RSA service processor"
        depends on X86 && PCI && INPUT
+       depends on SERIAL_8250 || SERIAL_8250=n
        ---help---
          This option enables device driver support for in-band access to the
          IBM RSA (Condor) service processor in eServer xSeries systems.
index 27678d8..75fc9c6 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
 
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/mei.h>
@@ -436,7 +437,7 @@ static inline void mei_me_set_pm_domain(struct mei_device *dev)
                dev->pg_domain.ops.runtime_resume = mei_me_pm_runtime_resume;
                dev->pg_domain.ops.runtime_idle = mei_me_pm_runtime_idle;
 
-               pdev->dev.pm_domain = &dev->pg_domain;
+               dev_pm_domain_set(&pdev->dev, &dev->pg_domain);
        }
 }
 
@@ -448,7 +449,7 @@ static inline void mei_me_set_pm_domain(struct mei_device *dev)
 static inline void mei_me_unset_pm_domain(struct mei_device *dev)
 {
        /* stop using pm callbacks if any */
-       dev->dev->pm_domain = NULL;
+       dev_pm_domain_set(dev->dev, NULL);
 }
 
 static const struct dev_pm_ops mei_me_pm_ops = {
index 0882c02..71f8a74 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/mei.h>
@@ -388,7 +389,7 @@ static inline void mei_txe_set_pm_domain(struct mei_device *dev)
                dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume;
                dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle;
 
-               pdev->dev.pm_domain = &dev->pg_domain;
+               dev_pm_domain_set(&pdev->dev, &dev->pg_domain);
        }
 }
 
@@ -400,7 +401,7 @@ static inline void mei_txe_set_pm_domain(struct mei_device *dev)
 static inline void mei_txe_unset_pm_domain(struct mei_device *dev)
 {
        /* stop using pm callbacks if any */
-       dev->dev->pm_domain = NULL;
+       dev_pm_domain_set(dev->dev, NULL);
 }
 
 static const struct dev_pm_ops mei_txe_pm_ops = {
index 154aced..65cc0ac 100644 (file)
@@ -170,7 +170,7 @@ static int mmc_ios_show(struct seq_file *s, void *data)
                str = "invalid";
                break;
        }
-       seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str);
+       seq_printf(s, "signal voltage:\t%u (%s)\n", ios->signal_voltage, str);
 
        switch (ios->drv_type) {
        case MMC_SET_DRIVER_TYPE_A:
index 2b16263..aba786d 100644 (file)
@@ -29,15 +29,18 @@ struct mmc_pwrseq_simple {
 static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
                                              int value)
 {
-       int i;
        struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
-       int values[reset_gpios->ndescs];
 
-       for (i = 0; i < reset_gpios->ndescs; i++)
-               values[i] = value;
+       if (!IS_ERR(reset_gpios)) {
+               int i;
+               int values[reset_gpios->ndescs];
 
-       gpiod_set_array_value_cansleep(reset_gpios->ndescs, reset_gpios->desc,
-                                      values);
+               for (i = 0; i < reset_gpios->ndescs; i++)
+                       values[i] = value;
+
+               gpiod_set_array_value_cansleep(
+                       reset_gpios->ndescs, reset_gpios->desc, values);
+       }
 }
 
 static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
@@ -79,7 +82,8 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
        struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
                                        struct mmc_pwrseq_simple, pwrseq);
 
-       gpiod_put_array(pwrseq->reset_gpios);
+       if (!IS_ERR(pwrseq->reset_gpios))
+               gpiod_put_array(pwrseq->reset_gpios);
 
        if (!IS_ERR(pwrseq->ext_clk))
                clk_put(pwrseq->ext_clk);
@@ -112,7 +116,9 @@ struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
        }
 
        pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
-       if (IS_ERR(pwrseq->reset_gpios)) {
+       if (IS_ERR(pwrseq->reset_gpios) &&
+           PTR_ERR(pwrseq->reset_gpios) != -ENOENT &&
+           PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) {
                ret = PTR_ERR(pwrseq->reset_gpios);
                goto clk_put;
        }
index f2b164b..bb39a29 100644 (file)
@@ -329,6 +329,7 @@ static int mmc_read_switch(struct mmc_card *card)
                card->sw_caps.sd3_bus_mode = status[13];
                /* Driver Strengths supported by the card */
                card->sw_caps.sd3_drv_type = status[9];
+               card->sw_caps.sd3_curr_limit = status[7] | status[6] << 8;
        }
 
 out:
@@ -545,14 +546,25 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
         * when we set current limit to 200ma, the card will draw 200ma, and
         * when we set current limit to 400/600/800ma, the card will draw its
         * maximum 300ma from the host.
+        *
+        * The above is incorrect: if we try to set a current limit that is
+        * not supported by the card, the card can rightfully error out the
+        * attempt, and remain at the default current limit.  This results
+        * in a 300mA card being limited to 200mA even though the host
+        * supports 800mA. Failures seen with SanDisk 8GB UHS cards with
+        * an iMX6 host. --rmk
         */
-       if (max_current >= 800)
+       if (max_current >= 800 &&
+           card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
                current_limit = SD_SET_CURRENT_LIMIT_800;
-       else if (max_current >= 600)
+       else if (max_current >= 600 &&
+                card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
                current_limit = SD_SET_CURRENT_LIMIT_600;
-       else if (max_current >= 400)
+       else if (max_current >= 400 &&
+                card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
                current_limit = SD_SET_CURRENT_LIMIT_400;
-       else if (max_current >= 200)
+       else if (max_current >= 200 &&
+                card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
                current_limit = SD_SET_CURRENT_LIMIT_200;
 
        if (current_limit != SD_SET_CURRENT_NO_CHANGE) {
@@ -626,9 +638,9 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
         * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
         */
        if (!mmc_host_is_spi(card->host) &&
-               (card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
-                card->sd_bus_speed == UHS_DDR50_BUS_SPEED ||
-                card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) {
+               (card->host->ios.timing == MMC_TIMING_UHS_SDR50 ||
+                card->host->ios.timing == MMC_TIMING_UHS_DDR50 ||
+                card->host->ios.timing == MMC_TIMING_UHS_SDR104)) {
                err = mmc_execute_tuning(card);
 
                /*
@@ -638,7 +650,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
                 * difference between v3.00 and 3.01 spec means that CMD19
                 * tuning is also available for DDR50 mode.
                 */
-               if (err && card->sd_bus_speed == UHS_DDR50_BUS_SPEED) {
+               if (err && card->host->ios.timing == MMC_TIMING_UHS_DDR50) {
                        pr_warn("%s: ddr50 tuning failed\n",
                                mmc_hostname(card->host));
                        err = 0;
index d61ba1a..467b3cf 100644 (file)
@@ -535,8 +535,8 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
         * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
         */
        if (!mmc_host_is_spi(card->host) &&
-           ((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) ||
-            (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)))
+           ((card->host->ios.timing == MMC_TIMING_UHS_SDR50) ||
+             (card->host->ios.timing == MMC_TIMING_UHS_SDR104)))
                err = mmc_execute_tuning(card);
 out:
        return err;
index 8e94e55..6f6fc52 100644 (file)
@@ -223,6 +223,7 @@ static const struct cis_tpl cis_tpl_list[] = {
        {       0x20,   4,      cistpl_manfid           },
        {       0x21,   2,      /* cistpl_funcid */     },
        {       0x22,   0,      cistpl_funce            },
+       {       0x91,   2,      /* cistpl_sdio_std */   },
 };
 
 static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
index fb26674..0d6ca41 100644 (file)
@@ -151,6 +151,7 @@ static struct variant_data variant_nomadik = {
        .fifosize               = 16 * 4,
        .fifohalfsize           = 8 * 4,
        .clkreg                 = MCI_CLK_ENABLE,
+       .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
        .datalength_bits        = 24,
        .datactrl_mask_sdio     = MCI_ST_DPSM_SDIOEN,
        .st_sdio                = true,
@@ -1886,7 +1887,7 @@ static struct amba_id mmci_ids[] = {
        {
                .id     = 0x00280180,
                .mask   = 0x00ffffff,
-               .data   = &variant_u300,
+               .data   = &variant_nomadik,
        },
        {
                .id     = 0x00480180,
index e4b05db..4a0d6b8 100644 (file)
@@ -94,9 +94,9 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
                        desc = NULL;
                        ret = cookie;
                }
+               dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
+                       __func__, host->sg_len, ret, cookie, host->mrq);
        }
-       dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
-               __func__, host->sg_len, ret, cookie, host->mrq);
 
 pio:
        if (!desc) {
@@ -116,8 +116,8 @@ pio:
                         "DMA failed: %d, falling back to PIO\n", ret);
        }
 
-       dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
-               desc, cookie, host->sg_len);
+       dev_dbg(&host->pdev->dev, "%s(): desc %p, sg[%d]\n", __func__,
+               desc, host->sg_len);
 }
 
 static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
@@ -174,9 +174,9 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
                        desc = NULL;
                        ret = cookie;
                }
+               dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
+                       __func__, host->sg_len, ret, cookie, host->mrq);
        }
-       dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
-               __func__, host->sg_len, ret, cookie, host->mrq);
 
 pio:
        if (!desc) {
@@ -196,8 +196,7 @@ pio:
                         "DMA failed: %d, falling back to PIO\n", ret);
        }
 
-       dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__,
-               desc, cookie);
+       dev_dbg(&host->pdev->dev, "%s(): desc %p\n", __func__, desc);
 }
 
 void tmio_mmc_start_dma(struct tmio_mmc_host *host,
index 4409369..cec3188 100644 (file)
@@ -24,6 +24,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/bcm963xx_tag.h>
 #include <linux/crc32.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mtd/partitions.h>
 
 #include <asm/mach-bcm63xx/bcm63xx_nvram.h>
-#include <asm/mach-bcm63xx/bcm963xx_tag.h>
 #include <asm/mach-bcm63xx/board_bcm963xx.h>
 
-#define BCM63XX_EXTENDED_SIZE  0xBFC00000      /* Extended flash address */
-
 #define BCM63XX_CFE_BLOCK_SIZE SZ_64K          /* always at least 64KiB */
 
 #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
@@ -123,8 +121,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
                pr_info("CFE boot tag found with version %s and board type %s\n",
                        tagversion, boardid);
 
-               kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
-               rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
+               kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE;
+               rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE;
                spareaddr = roundup(totallen, master->erasesize) + cfelen;
 
                if (rootfsaddr < kerneladdr) {
index 54e056d..ee2b74d 100644 (file)
@@ -174,9 +174,9 @@ static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end,
        struct ubi_device *ubi = desc->vol->ubi;
        struct inode *inode = file_inode(file);
        int err;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        err = ubi_sync(ubi->ubi_num);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err;
 }
 
index 2c2baab..d66c690 100644 (file)
@@ -157,6 +157,7 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
                [29] = "802.1ad offload support",
                [31] = "Modifying loopback source checks using UPDATE_QP support",
                [32] = "Loopback source checks support",
+               [33] = "RoCEv2 support"
        };
        int i;
 
@@ -626,6 +627,8 @@ out:
        return err;
 }
 
+static void disable_unsupported_roce_caps(void *buf);
+
 int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 {
        struct mlx4_cmd_mailbox *mailbox;
@@ -738,6 +741,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        if (err)
                goto out;
 
+       if (mlx4_is_mfunc(dev))
+               disable_unsupported_roce_caps(outbox);
        MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET);
        dev_cap->reserved_qps = 1 << (field & 0xf);
        MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET);
@@ -905,6 +910,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_EQE_STRIDE;
        MLX4_GET(dev_cap->bmme_flags, outbox,
                 QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
+       if (dev_cap->bmme_flags & MLX4_FLAG_ROCE_V1_V2)
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ROCE_V1_V2;
        if (dev_cap->bmme_flags & MLX4_FLAG_PORT_REMAP)
                dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_PORT_REMAP;
        MLX4_GET(field, outbox, QUERY_DEV_CAP_CONFIG_DEV_OFFSET);
@@ -1161,6 +1168,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        if (err)
                return err;
 
+       disable_unsupported_roce_caps(outbox->buf);
        /* add port mng change event capability and disable mw type 1
         * unconditionally to slaves
         */
@@ -1258,6 +1266,21 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        return 0;
 }
 
+static void disable_unsupported_roce_caps(void *buf)
+{
+       u32 flags;
+
+       MLX4_GET(flags, buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
+       flags &= ~(1UL << 31);
+       MLX4_PUT(buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
+       MLX4_GET(flags, buf, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
+       flags &= ~(1UL << 24);
+       MLX4_PUT(buf, flags, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
+       MLX4_GET(flags, buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
+       flags &= ~(MLX4_FLAG_ROCE_V1_V2);
+       MLX4_PUT(buf, flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
+}
+
 int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
                            struct mlx4_vhcr *vhcr,
                            struct mlx4_cmd_mailbox *inbox,
@@ -2239,7 +2262,8 @@ struct mlx4_config_dev {
        __be32  rsvd1[3];
        __be16  vxlan_udp_dport;
        __be16  rsvd2;
-       __be32  rsvd3;
+       __be16  roce_v2_entropy;
+       __be16  roce_v2_udp_dport;
        __be32  roce_flags;
        __be32  rsvd4[25];
        __be16  rsvd5;
@@ -2248,6 +2272,7 @@ struct mlx4_config_dev {
 };
 
 #define MLX4_VXLAN_UDP_DPORT (1 << 0)
+#define MLX4_ROCE_V2_UDP_DPORT BIT(3)
 #define MLX4_DISABLE_RX_PORT BIT(18)
 
 static int mlx4_CONFIG_DEV_set(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev)
@@ -2365,6 +2390,18 @@ int mlx4_disable_rx_port_check(struct mlx4_dev *dev, bool dis)
        return mlx4_CONFIG_DEV_set(dev, &config_dev);
 }
 
+int mlx4_config_roce_v2_port(struct mlx4_dev *dev, u16 udp_port)
+{
+       struct mlx4_config_dev config_dev;
+
+       memset(&config_dev, 0, sizeof(config_dev));
+       config_dev.update_flags    = cpu_to_be32(MLX4_ROCE_V2_UDP_DPORT);
+       config_dev.roce_v2_udp_dport = cpu_to_be16(udp_port);
+
+       return mlx4_CONFIG_DEV_set(dev, &config_dev);
+}
+EXPORT_SYMBOL_GPL(mlx4_config_roce_v2_port);
+
 int mlx4_virt2phy_port_map(struct mlx4_dev *dev, u32 port1, u32 port2)
 {
        struct mlx4_cmd_mailbox *mailbox;
index 2404c22..7baef52 100644 (file)
@@ -780,7 +780,10 @@ struct mlx4_set_port_general_context {
        u16 reserved1;
        u8 v_ignore_fcs;
        u8 flags;
-       u8 ignore_fcs;
+       union {
+               u8 ignore_fcs;
+               u8 roce_mode;
+       };
        u8 reserved2;
        __be16 mtu;
        u8 pptx;
index f255042..787b7bb 100644 (file)
@@ -1520,6 +1520,8 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz)
        return err;
 }
 
+#define SET_PORT_ROCE_2_FLAGS          0x10
+#define MLX4_SET_PORT_ROCE_V1_V2       0x2
 int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
                          u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
 {
@@ -1539,6 +1541,11 @@ int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
        context->pprx = (pprx * (!pfcrx)) << 7;
        context->pfcrx = pfcrx;
 
+       if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2) {
+               context->flags |= SET_PORT_ROCE_2_FLAGS;
+               context->roce_mode |=
+                       MLX4_SET_PORT_ROCE_V1_V2 << 4;
+       }
        in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
        err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
                       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
index 168823d..d1cd9c3 100644 (file)
@@ -167,6 +167,12 @@ static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
                context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
        }
 
+       if ((cur_state == MLX4_QP_STATE_RTR) &&
+           (new_state == MLX4_QP_STATE_RTS) &&
+           dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2)
+               context->roce_entropy =
+                       cpu_to_be16(mlx4_qp_roce_entropy(dev, qp->qpn));
+
        *(__be32 *) mailbox->buf = cpu_to_be32(optpar);
        memcpy(mailbox->buf + 8, context, sizeof *context);
 
@@ -921,3 +927,23 @@ int mlx4_qp_to_ready(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
        return 0;
 }
 EXPORT_SYMBOL_GPL(mlx4_qp_to_ready);
+
+u16 mlx4_qp_roce_entropy(struct mlx4_dev *dev, u32 qpn)
+{
+       struct mlx4_qp_context context;
+       struct mlx4_qp qp;
+       int err;
+
+       qp.qpn = qpn;
+       err = mlx4_qp_query(dev, &qp, &context);
+       if (!err) {
+               u32 dest_qpn = be32_to_cpu(context.remote_qpn) & 0xffffff;
+               u16 folded_dst = folded_qp(dest_qpn);
+               u16 folded_src = folded_qp(qpn);
+
+               return (dest_qpn != qpn) ?
+                       ((folded_dst ^ folded_src) | 0xC000) :
+                       folded_src | 0xC000;
+       }
+       return 0xdead;
+}
index 9ea49a8..aac071a 100644 (file)
@@ -39,8 +39,8 @@
 #include <linux/mlx5/qp.h>
 #include <linux/mlx5/cq.h>
 #include <linux/mlx5/vport.h>
+#include <linux/mlx5/transobj.h>
 #include "wq.h"
-#include "transobj.h"
 #include "mlx5_core.h"
 
 #define MLX5E_MAX_NUM_TC       8
index c56d91a..6a3e430 100644 (file)
@@ -2241,7 +2241,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
                goto err_unmap_free_uar;
        }
 
-       err = mlx5_alloc_transport_domain(mdev, &priv->tdn);
+       err = mlx5_core_alloc_transport_domain(mdev, &priv->tdn);
        if (err) {
                mlx5_core_err(mdev, "alloc td failed, %d\n", err);
                goto err_dealloc_pd;
@@ -2324,7 +2324,7 @@ err_destroy_mkey:
        mlx5_core_destroy_mkey(mdev, &priv->mr);
 
 err_dealloc_transport_domain:
-       mlx5_dealloc_transport_domain(mdev, priv->tdn);
+       mlx5_core_dealloc_transport_domain(mdev, priv->tdn);
 
 err_dealloc_pd:
        mlx5_core_dealloc_pd(mdev, priv->pdn);
@@ -2356,7 +2356,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
        mlx5e_close_drop_rq(priv);
        mlx5e_destroy_tises(priv);
        mlx5_core_destroy_mkey(priv->mdev, &priv->mr);
-       mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
+       mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn);
        mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
        mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
        free_netdev(netdev);
index 23c244a..647a3ca 100644 (file)
@@ -230,6 +230,7 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
                case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
                case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
                        rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
+                       rsn |= (eqe->data.qp_srq.type << MLX5_USER_INDEX_LEN);
                        mlx5_core_dbg(dev, "event %s(%d) arrived on resource 0x%x\n",
                                      eqe_type_str(eqe->type), eqe->type, rsn);
                        mlx5_rsc_event(dev, rsn, eqe->type);
index b37749a..1545a94 100644 (file)
@@ -78,6 +78,11 @@ struct mlx5_device_context {
        void                   *context;
 };
 
+enum {
+       MLX5_ATOMIC_REQ_MODE_BE = 0x0,
+       MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS = 0x1,
+};
+
 static struct mlx5_profile profile[] = {
        [0] = {
                .mask           = 0,
@@ -387,7 +392,7 @@ query_ex:
        return err;
 }
 
-static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
+static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz, int opmod)
 {
        u32 out[MLX5_ST_SZ_DW(set_hca_cap_out)];
        int err;
@@ -395,6 +400,7 @@ static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
        memset(out, 0, sizeof(out));
 
        MLX5_SET(set_hca_cap_in, in, opcode, MLX5_CMD_OP_SET_HCA_CAP);
+       MLX5_SET(set_hca_cap_in, in, op_mod, opmod << 1);
        err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
        if (err)
                return err;
@@ -404,6 +410,46 @@ static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
        return err;
 }
 
+static int handle_hca_cap_atomic(struct mlx5_core_dev *dev)
+{
+       void *set_ctx;
+       void *set_hca_cap;
+       int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in);
+       int req_endianness;
+       int err;
+
+       if (MLX5_CAP_GEN(dev, atomic)) {
+               err = mlx5_core_get_caps(dev, MLX5_CAP_ATOMIC,
+                                        HCA_CAP_OPMOD_GET_CUR);
+               if (err)
+                       return err;
+       } else {
+               return 0;
+       }
+
+       req_endianness =
+               MLX5_CAP_ATOMIC(dev,
+                               supported_atomic_req_8B_endianess_mode_1);
+
+       if (req_endianness != MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS)
+               return 0;
+
+       set_ctx = kzalloc(set_sz, GFP_KERNEL);
+       if (!set_ctx)
+               return -ENOMEM;
+
+       set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability);
+
+       /* Set requestor to host endianness */
+       MLX5_SET(atomic_caps, set_hca_cap, atomic_req_8B_endianess_mode,
+                MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS);
+
+       err = set_caps(dev, set_ctx, set_sz, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC);
+
+       kfree(set_ctx);
+       return err;
+}
+
 static int handle_hca_cap(struct mlx5_core_dev *dev)
 {
        void *set_ctx = NULL;
@@ -445,7 +491,8 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
 
        MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
 
-       err = set_caps(dev, set_ctx, set_sz);
+       err = set_caps(dev, set_ctx, set_sz,
+                      MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
 
 query_ex:
        kfree(set_ctx);
@@ -667,7 +714,6 @@ clean:
        return err;
 }
 
-#ifdef CONFIG_MLX5_CORE_EN
 static int mlx5_core_set_issi(struct mlx5_core_dev *dev)
 {
        u32 query_in[MLX5_ST_SZ_DW(query_issi_in)];
@@ -720,7 +766,6 @@ static int mlx5_core_set_issi(struct mlx5_core_dev *dev)
 
        return -ENOTSUPP;
 }
-#endif
 
 static int map_bf_area(struct mlx5_core_dev *dev)
 {
@@ -966,13 +1011,11 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
                goto err_pagealloc_cleanup;
        }
 
-#ifdef CONFIG_MLX5_CORE_EN
        err = mlx5_core_set_issi(dev);
        if (err) {
                dev_err(&pdev->dev, "failed to set issi\n");
                goto err_disable_hca;
        }
-#endif
 
        err = mlx5_satisfy_startup_pages(dev, 1);
        if (err) {
@@ -992,6 +1035,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
                goto reclaim_boot_pages;
        }
 
+       err = handle_hca_cap_atomic(dev);
+       if (err) {
+               dev_err(&pdev->dev, "handle_hca_cap_atomic failed\n");
+               goto reclaim_boot_pages;
+       }
+
        err = mlx5_satisfy_startup_pages(dev, 0);
        if (err) {
                dev_err(&pdev->dev, "failed to allocate init pages\n");
index 30e2ba3..def2893 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/mlx5/cmd.h>
 #include <linux/mlx5/qp.h>
 #include <linux/mlx5/driver.h>
+#include <linux/mlx5/transobj.h>
 
 #include "mlx5_core.h"
 
@@ -67,6 +68,52 @@ void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
                complete(&common->free);
 }
 
+static u64 qp_allowed_event_types(void)
+{
+       u64 mask;
+
+       mask = BIT(MLX5_EVENT_TYPE_PATH_MIG) |
+              BIT(MLX5_EVENT_TYPE_COMM_EST) |
+              BIT(MLX5_EVENT_TYPE_SQ_DRAINED) |
+              BIT(MLX5_EVENT_TYPE_SRQ_LAST_WQE) |
+              BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR) |
+              BIT(MLX5_EVENT_TYPE_PATH_MIG_FAILED) |
+              BIT(MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR) |
+              BIT(MLX5_EVENT_TYPE_WQ_ACCESS_ERROR);
+
+       return mask;
+}
+
+static u64 rq_allowed_event_types(void)
+{
+       u64 mask;
+
+       mask = BIT(MLX5_EVENT_TYPE_SRQ_LAST_WQE) |
+              BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
+
+       return mask;
+}
+
+static u64 sq_allowed_event_types(void)
+{
+       return BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
+}
+
+static bool is_event_type_allowed(int rsc_type, int event_type)
+{
+       switch (rsc_type) {
+       case MLX5_EVENT_QUEUE_TYPE_QP:
+               return BIT(event_type) & qp_allowed_event_types();
+       case MLX5_EVENT_QUEUE_TYPE_RQ:
+               return BIT(event_type) & rq_allowed_event_types();
+       case MLX5_EVENT_QUEUE_TYPE_SQ:
+               return BIT(event_type) & sq_allowed_event_types();
+       default:
+               WARN(1, "Event arrived for unknown resource type");
+               return false;
+       }
+}
+
 void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
 {
        struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
@@ -75,8 +122,16 @@ void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
        if (!common)
                return;
 
+       if (!is_event_type_allowed((rsn >> MLX5_USER_INDEX_LEN), event_type)) {
+               mlx5_core_warn(dev, "event 0x%.2x is not allowed on resource 0x%.8x\n",
+                              event_type, rsn);
+               return;
+       }
+
        switch (common->res) {
        case MLX5_RES_QP:
+       case MLX5_RES_RQ:
+       case MLX5_RES_SQ:
                qp = (struct mlx5_core_qp *)common;
                qp->event(qp, event_type);
                break;
@@ -177,27 +232,56 @@ void mlx5_eq_pagefault(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe)
 }
 #endif
 
+static int create_qprqsq_common(struct mlx5_core_dev *dev,
+                               struct mlx5_core_qp *qp,
+                               int rsc_type)
+{
+       struct mlx5_qp_table *table = &dev->priv.qp_table;
+       int err;
+
+       qp->common.res = rsc_type;
+       spin_lock_irq(&table->lock);
+       err = radix_tree_insert(&table->tree,
+                               qp->qpn | (rsc_type << MLX5_USER_INDEX_LEN),
+                               qp);
+       spin_unlock_irq(&table->lock);
+       if (err)
+               return err;
+
+       atomic_set(&qp->common.refcount, 1);
+       init_completion(&qp->common.free);
+       qp->pid = current->pid;
+
+       return 0;
+}
+
+static void destroy_qprqsq_common(struct mlx5_core_dev *dev,
+                                 struct mlx5_core_qp *qp)
+{
+       struct mlx5_qp_table *table = &dev->priv.qp_table;
+       unsigned long flags;
+
+       spin_lock_irqsave(&table->lock, flags);
+       radix_tree_delete(&table->tree,
+                         qp->qpn | (qp->common.res << MLX5_USER_INDEX_LEN));
+       spin_unlock_irqrestore(&table->lock, flags);
+       mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
+       wait_for_completion(&qp->common.free);
+}
+
 int mlx5_core_create_qp(struct mlx5_core_dev *dev,
                        struct mlx5_core_qp *qp,
                        struct mlx5_create_qp_mbox_in *in,
                        int inlen)
 {
-       struct mlx5_qp_table *table = &dev->priv.qp_table;
        struct mlx5_create_qp_mbox_out out;
        struct mlx5_destroy_qp_mbox_in din;
        struct mlx5_destroy_qp_mbox_out dout;
        int err;
-       void *qpc;
 
        memset(&out, 0, sizeof(out));
        in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP);
 
-       if (dev->issi) {
-               qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
-               /* 0xffffff means we ask to work with cqe version 0 */
-               MLX5_SET(qpc, qpc, user_index, 0xffffff);
-       }
-
        err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
        if (err) {
                mlx5_core_warn(dev, "ret %d\n", err);
@@ -213,24 +297,16 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
        qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
        mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
 
-       qp->common.res = MLX5_RES_QP;
-       spin_lock_irq(&table->lock);
-       err = radix_tree_insert(&table->tree, qp->qpn, qp);
-       spin_unlock_irq(&table->lock);
-       if (err) {
-               mlx5_core_warn(dev, "err %d\n", err);
+       err = create_qprqsq_common(dev, qp, MLX5_RES_QP);
+       if (err)
                goto err_cmd;
-       }
 
        err = mlx5_debug_qp_add(dev, qp);
        if (err)
                mlx5_core_dbg(dev, "failed adding QP 0x%x to debug file system\n",
                              qp->qpn);
 
-       qp->pid = current->pid;
-       atomic_set(&qp->common.refcount, 1);
        atomic_inc(&dev->num_qps);
-       init_completion(&qp->common.free);
 
        return 0;
 
@@ -250,18 +326,11 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
 {
        struct mlx5_destroy_qp_mbox_in in;
        struct mlx5_destroy_qp_mbox_out out;
-       struct mlx5_qp_table *table = &dev->priv.qp_table;
-       unsigned long flags;
        int err;
 
        mlx5_debug_qp_remove(dev, qp);
 
-       spin_lock_irqsave(&table->lock, flags);
-       radix_tree_delete(&table->tree, qp->qpn);
-       spin_unlock_irqrestore(&table->lock, flags);
-
-       mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
-       wait_for_completion(&qp->common.free);
+       destroy_qprqsq_common(dev, qp);
 
        memset(&in, 0, sizeof(in));
        memset(&out, 0, sizeof(out));
@@ -279,59 +348,15 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
 }
 EXPORT_SYMBOL_GPL(mlx5_core_destroy_qp);
 
-int mlx5_core_qp_modify(struct mlx5_core_dev *dev, enum mlx5_qp_state cur_state,
-                       enum mlx5_qp_state new_state,
+int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 operation,
                        struct mlx5_modify_qp_mbox_in *in, int sqd_event,
                        struct mlx5_core_qp *qp)
 {
-       static const u16 optab[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE] = {
-               [MLX5_QP_STATE_RST] = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-                       [MLX5_QP_STATE_INIT]    = MLX5_CMD_OP_RST2INIT_QP,
-               },
-               [MLX5_QP_STATE_INIT]  = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-                       [MLX5_QP_STATE_INIT]    = MLX5_CMD_OP_INIT2INIT_QP,
-                       [MLX5_QP_STATE_RTR]     = MLX5_CMD_OP_INIT2RTR_QP,
-               },
-               [MLX5_QP_STATE_RTR]   = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-                       [MLX5_QP_STATE_RTS]     = MLX5_CMD_OP_RTR2RTS_QP,
-               },
-               [MLX5_QP_STATE_RTS]   = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-                       [MLX5_QP_STATE_RTS]     = MLX5_CMD_OP_RTS2RTS_QP,
-               },
-               [MLX5_QP_STATE_SQD] = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-               },
-               [MLX5_QP_STATE_SQER] = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-                       [MLX5_QP_STATE_RTS]     = MLX5_CMD_OP_SQERR2RTS_QP,
-               },
-               [MLX5_QP_STATE_ERR] = {
-                       [MLX5_QP_STATE_RST]     = MLX5_CMD_OP_2RST_QP,
-                       [MLX5_QP_STATE_ERR]     = MLX5_CMD_OP_2ERR_QP,
-               }
-       };
-
        struct mlx5_modify_qp_mbox_out out;
        int err = 0;
-       u16 op;
-
-       if (cur_state >= MLX5_QP_NUM_STATE || new_state >= MLX5_QP_NUM_STATE ||
-           !optab[cur_state][new_state])
-               return -EINVAL;
 
        memset(&out, 0, sizeof(out));
-       op = optab[cur_state][new_state];
-       in->hdr.opcode = cpu_to_be16(op);
+       in->hdr.opcode = cpu_to_be16(operation);
        in->qpn = cpu_to_be32(qp->qpn);
        err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out));
        if (err)
@@ -449,3 +474,67 @@ int mlx5_core_page_fault_resume(struct mlx5_core_dev *dev, u32 qpn,
 }
 EXPORT_SYMBOL_GPL(mlx5_core_page_fault_resume);
 #endif
+
+int mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                               struct mlx5_core_qp *rq)
+{
+       int err;
+       u32 rqn;
+
+       err = mlx5_core_create_rq(dev, in, inlen, &rqn);
+       if (err)
+               return err;
+
+       rq->qpn = rqn;
+       err = create_qprqsq_common(dev, rq, MLX5_RES_RQ);
+       if (err)
+               goto err_destroy_rq;
+
+       return 0;
+
+err_destroy_rq:
+       mlx5_core_destroy_rq(dev, rq->qpn);
+
+       return err;
+}
+EXPORT_SYMBOL(mlx5_core_create_rq_tracked);
+
+void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
+                                 struct mlx5_core_qp *rq)
+{
+       destroy_qprqsq_common(dev, rq);
+       mlx5_core_destroy_rq(dev, rq->qpn);
+}
+EXPORT_SYMBOL(mlx5_core_destroy_rq_tracked);
+
+int mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                               struct mlx5_core_qp *sq)
+{
+       int err;
+       u32 sqn;
+
+       err = mlx5_core_create_sq(dev, in, inlen, &sqn);
+       if (err)
+               return err;
+
+       sq->qpn = sqn;
+       err = create_qprqsq_common(dev, sq, MLX5_RES_SQ);
+       if (err)
+               goto err_destroy_sq;
+
+       return 0;
+
+err_destroy_sq:
+       mlx5_core_destroy_sq(dev, sq->qpn);
+
+       return err;
+}
+EXPORT_SYMBOL(mlx5_core_create_sq_tracked);
+
+void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
+                                 struct mlx5_core_qp *sq)
+{
+       destroy_qprqsq_common(dev, sq);
+       mlx5_core_destroy_sq(dev, sq->qpn);
+}
+EXPORT_SYMBOL(mlx5_core_destroy_sq_tracked);
index ffada80..04bc522 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/mlx5/srq.h>
 #include <rdma/ib_verbs.h>
 #include "mlx5_core.h"
-#include "transobj.h"
+#include <linux/mlx5/transobj.h>
 
 void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type)
 {
@@ -241,8 +241,6 @@ static int create_xrc_srq_cmd(struct mlx5_core_dev *dev,
 
        memcpy(xrc_srqc, srqc, MLX5_ST_SZ_BYTES(srqc));
        memcpy(pas, in->pas, pas_size);
-       /* 0xffffff means we ask to work with cqe version 0 */
-       MLX5_SET(xrc_srqc,          xrc_srqc,  user_index, 0xffffff);
        MLX5_SET(create_xrc_srq_in, create_in, opcode,
                 MLX5_CMD_OP_CREATE_XRC_SRQ);
 
index d7068f5..03a5093 100644 (file)
@@ -32,9 +32,9 @@
 
 #include <linux/mlx5/driver.h>
 #include "mlx5_core.h"
-#include "transobj.h"
+#include <linux/mlx5/transobj.h>
 
-int mlx5_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn)
+int mlx5_core_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn)
 {
        u32 in[MLX5_ST_SZ_DW(alloc_transport_domain_in)];
        u32 out[MLX5_ST_SZ_DW(alloc_transport_domain_out)];
@@ -53,8 +53,9 @@ int mlx5_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn)
 
        return err;
 }
+EXPORT_SYMBOL(mlx5_core_alloc_transport_domain);
 
-void mlx5_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn)
+void mlx5_core_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn)
 {
        u32 in[MLX5_ST_SZ_DW(dealloc_transport_domain_in)];
        u32 out[MLX5_ST_SZ_DW(dealloc_transport_domain_out)];
@@ -68,6 +69,7 @@ void mlx5_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn)
 
        mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
 }
+EXPORT_SYMBOL(mlx5_core_dealloc_transport_domain);
 
 int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
 {
@@ -94,6 +96,7 @@ int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen)
        memset(out, 0, sizeof(out));
        return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
 }
+EXPORT_SYMBOL(mlx5_core_modify_rq);
 
 void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
 {
@@ -108,6 +111,18 @@ void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
        mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
 }
 
+int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out)
+{
+       u32 in[MLX5_ST_SZ_DW(query_rq_in)] = {0};
+       int outlen = MLX5_ST_SZ_BYTES(query_rq_out);
+
+       MLX5_SET(query_rq_in, in, opcode, MLX5_CMD_OP_QUERY_RQ);
+       MLX5_SET(query_rq_in, in, rqn, rqn);
+
+       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
+}
+EXPORT_SYMBOL(mlx5_core_query_rq);
+
 int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn)
 {
        u32 out[MLX5_ST_SZ_DW(create_sq_out)];
@@ -133,6 +148,7 @@ int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen)
        memset(out, 0, sizeof(out));
        return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
 }
+EXPORT_SYMBOL(mlx5_core_modify_sq);
 
 void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
 {
@@ -147,6 +163,18 @@ void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
        mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
 }
 
+int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out)
+{
+       u32 in[MLX5_ST_SZ_DW(query_sq_in)] = {0};
+       int outlen = MLX5_ST_SZ_BYTES(query_sq_out);
+
+       MLX5_SET(query_sq_in, in, opcode, MLX5_CMD_OP_QUERY_SQ);
+       MLX5_SET(query_sq_in, in, sqn, sqn);
+
+       return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
+}
+EXPORT_SYMBOL(mlx5_core_query_sq);
+
 int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
                         u32 *tirn)
 {
@@ -162,6 +190,7 @@ int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
 
        return err;
 }
+EXPORT_SYMBOL(mlx5_core_create_tir);
 
 int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in,
                         int inlen)
@@ -187,6 +216,7 @@ void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn)
 
        mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
 }
+EXPORT_SYMBOL(mlx5_core_destroy_tir);
 
 int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
                         u32 *tisn)
@@ -203,6 +233,19 @@ int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
 
        return err;
 }
+EXPORT_SYMBOL(mlx5_core_create_tis);
+
+int mlx5_core_modify_tis(struct mlx5_core_dev *dev, u32 tisn, u32 *in,
+                        int inlen)
+{
+       u32 out[MLX5_ST_SZ_DW(modify_tis_out)] = {0};
+
+       MLX5_SET(modify_tis_in, in, tisn, tisn);
+       MLX5_SET(modify_tis_in, in, opcode, MLX5_CMD_OP_MODIFY_TIS);
+
+       return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
+}
+EXPORT_SYMBOL(mlx5_core_modify_tis);
 
 void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
 {
@@ -216,6 +259,7 @@ void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
 
        mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
 }
+EXPORT_SYMBOL(mlx5_core_destroy_tis);
 
 int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen,
                         u32 *rmpn)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/transobj.h b/drivers/net/ethernet/mellanox/mlx5/core/transobj.h
deleted file mode 100644 (file)
index 74cae51..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __TRANSOBJ_H__
-#define __TRANSOBJ_H__
-
-int mlx5_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn);
-void mlx5_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn);
-int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                       u32 *rqn);
-int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen);
-void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn);
-int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                       u32 *sqn);
-int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen);
-void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn);
-int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                        u32 *tirn);
-int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in,
-                        int inlen);
-void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn);
-int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                        u32 *tisn);
-void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn);
-int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                        u32 *rmpn);
-int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen);
-int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn);
-int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out);
-int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm);
-int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                         u32 *rmpn);
-int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 rmpn);
-int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 rmpn, u32 *out);
-int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm);
-
-int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen,
-                        u32 *rqtn);
-int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in,
-                        int inlen);
-void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn);
-
-#endif /* __TRANSOBJ_H__ */
index 076197e..c7398b9 100644 (file)
@@ -76,7 +76,7 @@ u8 mlx5_query_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
 
        return MLX5_GET(query_vport_state_out, out, admin_state);
 }
-EXPORT_SYMBOL(mlx5_query_vport_admin_state);
+EXPORT_SYMBOL_GPL(mlx5_query_vport_admin_state);
 
 int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
                                  u16 vport, u8 state)
@@ -104,7 +104,7 @@ int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
 
        return err;
 }
-EXPORT_SYMBOL(mlx5_modify_vport_admin_state);
+EXPORT_SYMBOL_GPL(mlx5_modify_vport_admin_state);
 
 static int mlx5_query_nic_vport_context(struct mlx5_core_dev *mdev, u16 vport,
                                        u32 *out, int outlen)
@@ -151,12 +151,9 @@ int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
                                nic_vport_context.permanent_address);
 
        err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
-       if (err)
-               goto out;
-
-       ether_addr_copy(addr, &out_addr[2]);
+       if (!err)
+               ether_addr_copy(addr, &out_addr[2]);
 
-out:
        kvfree(out);
        return err;
 }
@@ -197,7 +194,7 @@ int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
 
        return err;
 }
-EXPORT_SYMBOL(mlx5_modify_nic_vport_mac_address);
+EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address);
 
 int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
                                  u32 vport,
@@ -430,6 +427,68 @@ int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
 }
 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_vlans);
 
+int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
+                                          u64 *system_image_guid)
+{
+       u32 *out;
+       int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
+
+       out = mlx5_vzalloc(outlen);
+       if (!out)
+               return -ENOMEM;
+
+       mlx5_query_nic_vport_context(mdev, 0, out, outlen);
+
+       *system_image_guid = MLX5_GET64(query_nic_vport_context_out, out,
+                                       nic_vport_context.system_image_guid);
+
+       kfree(out);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid);
+
+int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
+{
+       u32 *out;
+       int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
+
+       out = mlx5_vzalloc(outlen);
+       if (!out)
+               return -ENOMEM;
+
+       mlx5_query_nic_vport_context(mdev, 0, out, outlen);
+
+       *node_guid = MLX5_GET64(query_nic_vport_context_out, out,
+                               nic_vport_context.node_guid);
+
+       kfree(out);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid);
+
+int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
+                                       u16 *qkey_viol_cntr)
+{
+       u32 *out;
+       int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
+
+       out = mlx5_vzalloc(outlen);
+       if (!out)
+               return -ENOMEM;
+
+       mlx5_query_nic_vport_context(mdev, 0, out, outlen);
+
+       *qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out,
+                                  nic_vport_context.qkey_violation_counter);
+
+       kfree(out);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr);
+
 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
                             u8 port_num, u16  vf_num, u16 gid_index,
                             union ib_gid *gid)
@@ -750,3 +809,44 @@ int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
        return err;
 }
 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
+
+enum mlx5_vport_roce_state {
+       MLX5_VPORT_ROCE_DISABLED = 0,
+       MLX5_VPORT_ROCE_ENABLED  = 1,
+};
+
+static int mlx5_nic_vport_update_roce_state(struct mlx5_core_dev *mdev,
+                                           enum mlx5_vport_roce_state state)
+{
+       void *in;
+       int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
+       int err;
+
+       in = mlx5_vzalloc(inlen);
+       if (!in) {
+               mlx5_core_warn(mdev, "failed to allocate inbox\n");
+               return -ENOMEM;
+       }
+
+       MLX5_SET(modify_nic_vport_context_in, in, field_select.roce_en, 1);
+       MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.roce_en,
+                state);
+
+       err = mlx5_modify_nic_vport_context(mdev, in, inlen);
+
+       kvfree(in);
+
+       return err;
+}
+
+int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev)
+{
+       return mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_ENABLED);
+}
+EXPORT_SYMBOL_GPL(mlx5_nic_vport_enable_roce);
+
+int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev)
+{
+       return mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_DISABLED);
+}
+EXPORT_SYMBOL_GPL(mlx5_nic_vport_disable_roce);
index 4d5535c..7116472 100644 (file)
@@ -1 +1,2 @@
+source "drivers/ntb/hw/amd/Kconfig"
 source "drivers/ntb/hw/intel/Kconfig"
index 175d7c9..532e085 100644 (file)
@@ -1 +1,2 @@
+obj-$(CONFIG_NTB_AMD)  += amd/
 obj-$(CONFIG_NTB_INTEL)        += intel/
diff --git a/drivers/ntb/hw/amd/Kconfig b/drivers/ntb/hw/amd/Kconfig
new file mode 100644 (file)
index 0000000..cfe903c
--- /dev/null
@@ -0,0 +1,7 @@
+config NTB_AMD
+       tristate "AMD Non-Transparent Bridge support"
+       depends on X86_64
+       help
+        This driver supports AMD NTB on capable Zeppelin hardware.
+
+        If unsure, say N.
diff --git a/drivers/ntb/hw/amd/Makefile b/drivers/ntb/hw/amd/Makefile
new file mode 100644 (file)
index 0000000..ad54da9
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_NTB_AMD) += ntb_hw_amd.o
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c
new file mode 100644 (file)
index 0000000..588803a
--- /dev/null
@@ -0,0 +1,1143 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GPL LICENSE SUMMARY
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copy
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of AMD Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD PCIe NTB Linux driver
+ *
+ * Contact Information:
+ * Xiangliang Yu <Xiangliang.Yu@amd.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/pci.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/ntb.h>
+
+#include "ntb_hw_amd.h"
+
+#define NTB_NAME       "ntb_hw_amd"
+#define NTB_DESC       "AMD(R) PCI-E Non-Transparent Bridge Driver"
+#define NTB_VER                "1.0"
+
+MODULE_DESCRIPTION(NTB_DESC);
+MODULE_VERSION(NTB_VER);
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("AMD Inc.");
+
+static const struct file_operations amd_ntb_debugfs_info;
+static struct dentry *debugfs_dir;
+
+static int ndev_mw_to_bar(struct amd_ntb_dev *ndev, int idx)
+{
+       if (idx < 0 || idx > ndev->mw_count)
+               return -EINVAL;
+
+       return 1 << idx;
+}
+
+static int amd_ntb_mw_count(struct ntb_dev *ntb)
+{
+       return ntb_ndev(ntb)->mw_count;
+}
+
+static int amd_ntb_mw_get_range(struct ntb_dev *ntb, int idx,
+                               phys_addr_t *base,
+                               resource_size_t *size,
+                               resource_size_t *align,
+                               resource_size_t *align_size)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       int bar;
+
+       bar = ndev_mw_to_bar(ndev, idx);
+       if (bar < 0)
+               return bar;
+
+       if (base)
+               *base = pci_resource_start(ndev->ntb.pdev, bar);
+
+       if (size)
+               *size = pci_resource_len(ndev->ntb.pdev, bar);
+
+       if (align)
+               *align = SZ_4K;
+
+       if (align_size)
+               *align_size = 1;
+
+       return 0;
+}
+
+static int amd_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
+                               dma_addr_t addr, resource_size_t size)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       unsigned long xlat_reg, limit_reg = 0;
+       resource_size_t mw_size;
+       void __iomem *mmio, *peer_mmio;
+       u64 base_addr, limit, reg_val;
+       int bar;
+
+       bar = ndev_mw_to_bar(ndev, idx);
+       if (bar < 0)
+               return bar;
+
+       mw_size = pci_resource_len(ndev->ntb.pdev, bar);
+
+       /* make sure the range fits in the usable mw size */
+       if (size > mw_size)
+               return -EINVAL;
+
+       mmio = ndev->self_mmio;
+       peer_mmio = ndev->peer_mmio;
+
+       base_addr = pci_resource_start(ndev->ntb.pdev, bar);
+
+       if (bar != 1) {
+               xlat_reg = AMD_BAR23XLAT_OFFSET + ((bar - 2) << 3);
+               limit_reg = AMD_BAR23LMT_OFFSET + ((bar - 2) << 3);
+
+               /* Set the limit if supported */
+               limit = base_addr + size;
+
+               /* set and verify setting the translation address */
+               write64(addr, peer_mmio + xlat_reg);
+               reg_val = read64(peer_mmio + xlat_reg);
+               if (reg_val != addr) {
+                       write64(0, peer_mmio + xlat_reg);
+                       return -EIO;
+               }
+
+               /* set and verify setting the limit */
+               write64(limit, mmio + limit_reg);
+               reg_val = read64(mmio + limit_reg);
+               if (reg_val != limit) {
+                       write64(base_addr, mmio + limit_reg);
+                       write64(0, peer_mmio + xlat_reg);
+                       return -EIO;
+               }
+       } else {
+               xlat_reg = AMD_BAR1XLAT_OFFSET;
+               limit_reg = AMD_BAR1LMT_OFFSET;
+
+               /* split bar addr range must all be 32 bit */
+               if (addr & (~0ull << 32))
+                       return -EINVAL;
+               if ((addr + size) & (~0ull << 32))
+                       return -EINVAL;
+
+               /* Set the limit if supported */
+               limit = base_addr + size;
+
+               /* set and verify setting the translation address */
+               write64(addr, peer_mmio + xlat_reg);
+               reg_val = read64(peer_mmio + xlat_reg);
+               if (reg_val != addr) {
+                       write64(0, peer_mmio + xlat_reg);
+                       return -EIO;
+               }
+
+               /* set and verify setting the limit */
+               writel(limit, mmio + limit_reg);
+               reg_val = readl(mmio + limit_reg);
+               if (reg_val != limit) {
+                       writel(base_addr, mmio + limit_reg);
+                       writel(0, peer_mmio + xlat_reg);
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+static int amd_link_is_up(struct amd_ntb_dev *ndev)
+{
+       if (!ndev->peer_sta)
+               return NTB_LNK_STA_ACTIVE(ndev->cntl_sta);
+
+       /* If peer_sta is reset or D0 event, the ISR has
+        * started a timer to check link status of hardware.
+        * So here just clear status bit. And if peer_sta is
+        * D3 or PME_TO, D0/reset event will be happened when
+        * system wakeup/poweron, so do nothing here.
+        */
+       if (ndev->peer_sta & AMD_PEER_RESET_EVENT)
+               ndev->peer_sta &= ~AMD_PEER_RESET_EVENT;
+       else if (ndev->peer_sta & AMD_PEER_D0_EVENT)
+               ndev->peer_sta = 0;
+
+       return 0;
+}
+
+static int amd_ntb_link_is_up(struct ntb_dev *ntb,
+                             enum ntb_speed *speed,
+                             enum ntb_width *width)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       int ret = 0;
+
+       if (amd_link_is_up(ndev)) {
+               if (speed)
+                       *speed = NTB_LNK_STA_SPEED(ndev->lnk_sta);
+               if (width)
+                       *width = NTB_LNK_STA_WIDTH(ndev->lnk_sta);
+
+               dev_dbg(ndev_dev(ndev), "link is up.\n");
+
+               ret = 1;
+       } else {
+               if (speed)
+                       *speed = NTB_SPEED_NONE;
+               if (width)
+                       *width = NTB_WIDTH_NONE;
+
+               dev_dbg(ndev_dev(ndev), "link is down.\n");
+       }
+
+       return ret;
+}
+
+static int amd_ntb_link_enable(struct ntb_dev *ntb,
+                              enum ntb_speed max_speed,
+                              enum ntb_width max_width)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       u32 ntb_ctl;
+
+       /* Enable event interrupt */
+       ndev->int_mask &= ~AMD_EVENT_INTMASK;
+       writel(ndev->int_mask, mmio + AMD_INTMASK_OFFSET);
+
+       if (ndev->ntb.topo == NTB_TOPO_SEC)
+               return -EINVAL;
+       dev_dbg(ndev_dev(ndev), "Enabling Link.\n");
+
+       ntb_ctl = readl(mmio + AMD_CNTL_OFFSET);
+       ntb_ctl |= (PMM_REG_CTL | SMM_REG_CTL);
+       writel(ntb_ctl, mmio + AMD_CNTL_OFFSET);
+
+       return 0;
+}
+
+static int amd_ntb_link_disable(struct ntb_dev *ntb)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       u32 ntb_ctl;
+
+       /* Disable event interrupt */
+       ndev->int_mask |= AMD_EVENT_INTMASK;
+       writel(ndev->int_mask, mmio + AMD_INTMASK_OFFSET);
+
+       if (ndev->ntb.topo == NTB_TOPO_SEC)
+               return -EINVAL;
+       dev_dbg(ndev_dev(ndev), "Enabling Link.\n");
+
+       ntb_ctl = readl(mmio + AMD_CNTL_OFFSET);
+       ntb_ctl &= ~(PMM_REG_CTL | SMM_REG_CTL);
+       writel(ntb_ctl, mmio + AMD_CNTL_OFFSET);
+
+       return 0;
+}
+
+static u64 amd_ntb_db_valid_mask(struct ntb_dev *ntb)
+{
+       return ntb_ndev(ntb)->db_valid_mask;
+}
+
+static int amd_ntb_db_vector_count(struct ntb_dev *ntb)
+{
+       return ntb_ndev(ntb)->db_count;
+}
+
+static u64 amd_ntb_db_vector_mask(struct ntb_dev *ntb, int db_vector)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+
+       if (db_vector < 0 || db_vector > ndev->db_count)
+               return 0;
+
+       return ntb_ndev(ntb)->db_valid_mask & (1 << db_vector);
+}
+
+static u64 amd_ntb_db_read(struct ntb_dev *ntb)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+
+       return (u64)readw(mmio + AMD_DBSTAT_OFFSET);
+}
+
+static int amd_ntb_db_clear(struct ntb_dev *ntb, u64 db_bits)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+
+       writew((u16)db_bits, mmio + AMD_DBSTAT_OFFSET);
+
+       return 0;
+}
+
+static int amd_ntb_db_set_mask(struct ntb_dev *ntb, u64 db_bits)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       unsigned long flags;
+
+       if (db_bits & ~ndev->db_valid_mask)
+               return -EINVAL;
+
+       spin_lock_irqsave(&ndev->db_mask_lock, flags);
+       ndev->db_mask |= db_bits;
+       writew((u16)ndev->db_mask, mmio + AMD_DBMASK_OFFSET);
+       spin_unlock_irqrestore(&ndev->db_mask_lock, flags);
+
+       return 0;
+}
+
+static int amd_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       unsigned long flags;
+
+       if (db_bits & ~ndev->db_valid_mask)
+               return -EINVAL;
+
+       spin_lock_irqsave(&ndev->db_mask_lock, flags);
+       ndev->db_mask &= ~db_bits;
+       writew((u16)ndev->db_mask, mmio + AMD_DBMASK_OFFSET);
+       spin_unlock_irqrestore(&ndev->db_mask_lock, flags);
+
+       return 0;
+}
+
+static int amd_ntb_peer_db_addr(struct ntb_dev *ntb,
+                               phys_addr_t *db_addr,
+                               resource_size_t *db_size)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+
+       if (db_addr)
+               *db_addr = (phys_addr_t)(ndev->peer_mmio + AMD_DBREQ_OFFSET);
+       if (db_size)
+               *db_size = sizeof(u32);
+
+       return 0;
+}
+
+static int amd_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+
+       writew((u16)db_bits, mmio + AMD_DBREQ_OFFSET);
+
+       return 0;
+}
+
+static int amd_ntb_spad_count(struct ntb_dev *ntb)
+{
+       return ntb_ndev(ntb)->spad_count;
+}
+
+static u32 amd_ntb_spad_read(struct ntb_dev *ntb, int idx)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       u32 offset;
+
+       if (idx < 0 || idx >= ndev->spad_count)
+               return 0;
+
+       offset = ndev->self_spad + (idx << 2);
+       return readl(mmio + AMD_SPAD_OFFSET + offset);
+}
+
+static int amd_ntb_spad_write(struct ntb_dev *ntb,
+                             int idx, u32 val)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       u32 offset;
+
+       if (idx < 0 || idx >= ndev->spad_count)
+               return -EINVAL;
+
+       offset = ndev->self_spad + (idx << 2);
+       writel(val, mmio + AMD_SPAD_OFFSET + offset);
+
+       return 0;
+}
+
+static int amd_ntb_peer_spad_addr(struct ntb_dev *ntb, int idx,
+                                 phys_addr_t *spad_addr)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+
+       if (idx < 0 || idx >= ndev->spad_count)
+               return -EINVAL;
+
+       if (spad_addr)
+               *spad_addr = (phys_addr_t)(ndev->self_mmio + AMD_SPAD_OFFSET +
+                                          ndev->peer_spad + (idx << 2));
+       return 0;
+}
+
+static u32 amd_ntb_peer_spad_read(struct ntb_dev *ntb, int idx)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       u32 offset;
+
+       if (idx < 0 || idx >= ndev->spad_count)
+               return -EINVAL;
+
+       offset = ndev->peer_spad + (idx << 2);
+       return readl(mmio + AMD_SPAD_OFFSET + offset);
+}
+
+static int amd_ntb_peer_spad_write(struct ntb_dev *ntb,
+                                  int idx, u32 val)
+{
+       struct amd_ntb_dev *ndev = ntb_ndev(ntb);
+       void __iomem *mmio = ndev->self_mmio;
+       u32 offset;
+
+       if (idx < 0 || idx >= ndev->spad_count)
+               return -EINVAL;
+
+       offset = ndev->peer_spad + (idx << 2);
+       writel(val, mmio + AMD_SPAD_OFFSET + offset);
+
+       return 0;
+}
+
+static const struct ntb_dev_ops amd_ntb_ops = {
+       .mw_count               = amd_ntb_mw_count,
+       .mw_get_range           = amd_ntb_mw_get_range,
+       .mw_set_trans           = amd_ntb_mw_set_trans,
+       .link_is_up             = amd_ntb_link_is_up,
+       .link_enable            = amd_ntb_link_enable,
+       .link_disable           = amd_ntb_link_disable,
+       .db_valid_mask          = amd_ntb_db_valid_mask,
+       .db_vector_count        = amd_ntb_db_vector_count,
+       .db_vector_mask         = amd_ntb_db_vector_mask,
+       .db_read                = amd_ntb_db_read,
+       .db_clear               = amd_ntb_db_clear,
+       .db_set_mask            = amd_ntb_db_set_mask,
+       .db_clear_mask          = amd_ntb_db_clear_mask,
+       .peer_db_addr           = amd_ntb_peer_db_addr,
+       .peer_db_set            = amd_ntb_peer_db_set,
+       .spad_count             = amd_ntb_spad_count,
+       .spad_read              = amd_ntb_spad_read,
+       .spad_write             = amd_ntb_spad_write,
+       .peer_spad_addr         = amd_ntb_peer_spad_addr,
+       .peer_spad_read         = amd_ntb_peer_spad_read,
+       .peer_spad_write        = amd_ntb_peer_spad_write,
+};
+
+static void amd_ack_smu(struct amd_ntb_dev *ndev, u32 bit)
+{
+       void __iomem *mmio = ndev->self_mmio;
+       int reg;
+
+       reg = readl(mmio + AMD_SMUACK_OFFSET);
+       reg |= bit;
+       writel(reg, mmio + AMD_SMUACK_OFFSET);
+
+       ndev->peer_sta |= bit;
+}
+
+static void amd_handle_event(struct amd_ntb_dev *ndev, int vec)
+{
+       void __iomem *mmio = ndev->self_mmio;
+       u32 status;
+
+       status = readl(mmio + AMD_INTSTAT_OFFSET);
+       if (!(status & AMD_EVENT_INTMASK))
+               return;
+
+       dev_dbg(ndev_dev(ndev), "status = 0x%x and vec = %d\n", status, vec);
+
+       status &= AMD_EVENT_INTMASK;
+       switch (status) {
+       case AMD_PEER_FLUSH_EVENT:
+               dev_info(ndev_dev(ndev), "Flush is done.\n");
+               break;
+       case AMD_PEER_RESET_EVENT:
+               amd_ack_smu(ndev, AMD_PEER_RESET_EVENT);
+
+               /* link down first */
+               ntb_link_event(&ndev->ntb);
+               /* polling peer status */
+               schedule_delayed_work(&ndev->hb_timer, AMD_LINK_HB_TIMEOUT);
+
+               break;
+       case AMD_PEER_D3_EVENT:
+       case AMD_PEER_PMETO_EVENT:
+               amd_ack_smu(ndev, status);
+
+               /* link down */
+               ntb_link_event(&ndev->ntb);
+
+               break;
+       case AMD_PEER_D0_EVENT:
+               mmio = ndev->peer_mmio;
+               status = readl(mmio + AMD_PMESTAT_OFFSET);
+               /* check if this is WAKEUP event */
+               if (status & 0x1)
+                       dev_info(ndev_dev(ndev), "Wakeup is done.\n");
+
+               amd_ack_smu(ndev, AMD_PEER_D0_EVENT);
+
+               /* start a timer to poll link status */
+               schedule_delayed_work(&ndev->hb_timer,
+                                     AMD_LINK_HB_TIMEOUT);
+               break;
+       default:
+               dev_info(ndev_dev(ndev), "event status = 0x%x.\n", status);
+               break;
+       }
+}
+
+static irqreturn_t ndev_interrupt(struct amd_ntb_dev *ndev, int vec)
+{
+       dev_dbg(ndev_dev(ndev), "vec %d\n", vec);
+
+       if (vec > (AMD_DB_CNT - 1) || (ndev->msix_vec_count == 1))
+               amd_handle_event(ndev, vec);
+
+       if (vec < AMD_DB_CNT)
+               ntb_db_event(&ndev->ntb, vec);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t ndev_vec_isr(int irq, void *dev)
+{
+       struct amd_ntb_vec *nvec = dev;
+
+       return ndev_interrupt(nvec->ndev, nvec->num);
+}
+
+static irqreturn_t ndev_irq_isr(int irq, void *dev)
+{
+       struct amd_ntb_dev *ndev = dev;
+
+       return ndev_interrupt(ndev, irq - ndev_pdev(ndev)->irq);
+}
+
+static int ndev_init_isr(struct amd_ntb_dev *ndev,
+                        int msix_min, int msix_max)
+{
+       struct pci_dev *pdev;
+       int rc, i, msix_count, node;
+
+       pdev = ndev_pdev(ndev);
+
+       node = dev_to_node(&pdev->dev);
+
+       ndev->db_mask = ndev->db_valid_mask;
+
+       /* Try to set up msix irq */
+       ndev->vec = kzalloc_node(msix_max * sizeof(*ndev->vec),
+                                GFP_KERNEL, node);
+       if (!ndev->vec)
+               goto err_msix_vec_alloc;
+
+       ndev->msix = kzalloc_node(msix_max * sizeof(*ndev->msix),
+                                 GFP_KERNEL, node);
+       if (!ndev->msix)
+               goto err_msix_alloc;
+
+       for (i = 0; i < msix_max; ++i)
+               ndev->msix[i].entry = i;
+
+       msix_count = pci_enable_msix_range(pdev, ndev->msix,
+                                          msix_min, msix_max);
+       if (msix_count < 0)
+               goto err_msix_enable;
+
+       /* NOTE: Disable MSIX if msix count is less than 16 because of
+        * hardware limitation.
+        */
+       if (msix_count < msix_min) {
+               pci_disable_msix(pdev);
+               goto err_msix_enable;
+       }
+
+       for (i = 0; i < msix_count; ++i) {
+               ndev->vec[i].ndev = ndev;
+               ndev->vec[i].num = i;
+               rc = request_irq(ndev->msix[i].vector, ndev_vec_isr, 0,
+                                "ndev_vec_isr", &ndev->vec[i]);
+               if (rc)
+                       goto err_msix_request;
+       }
+
+       dev_dbg(ndev_dev(ndev), "Using msix interrupts\n");
+       ndev->db_count = msix_min;
+       ndev->msix_vec_count = msix_max;
+       return 0;
+
+err_msix_request:
+       while (i-- > 0)
+               free_irq(ndev->msix[i].vector, ndev);
+       pci_disable_msix(pdev);
+err_msix_enable:
+       kfree(ndev->msix);
+err_msix_alloc:
+       kfree(ndev->vec);
+err_msix_vec_alloc:
+       ndev->msix = NULL;
+       ndev->vec = NULL;
+
+       /* Try to set up msi irq */
+       rc = pci_enable_msi(pdev);
+       if (rc)
+               goto err_msi_enable;
+
+       rc = request_irq(pdev->irq, ndev_irq_isr, 0,
+                        "ndev_irq_isr", ndev);
+       if (rc)
+               goto err_msi_request;
+
+       dev_dbg(ndev_dev(ndev), "Using msi interrupts\n");
+       ndev->db_count = 1;
+       ndev->msix_vec_count = 1;
+       return 0;
+
+err_msi_request:
+       pci_disable_msi(pdev);
+err_msi_enable:
+
+       /* Try to set up intx irq */
+       pci_intx(pdev, 1);
+
+       rc = request_irq(pdev->irq, ndev_irq_isr, IRQF_SHARED,
+                        "ndev_irq_isr", ndev);
+       if (rc)
+               goto err_intx_request;
+
+       dev_dbg(ndev_dev(ndev), "Using intx interrupts\n");
+       ndev->db_count = 1;
+       ndev->msix_vec_count = 1;
+       return 0;
+
+err_intx_request:
+       return rc;
+}
+
+static void ndev_deinit_isr(struct amd_ntb_dev *ndev)
+{
+       struct pci_dev *pdev;
+       void __iomem *mmio = ndev->self_mmio;
+       int i;
+
+       pdev = ndev_pdev(ndev);
+
+       /* Mask all doorbell interrupts */
+       ndev->db_mask = ndev->db_valid_mask;
+       writel(ndev->db_mask, mmio + AMD_DBMASK_OFFSET);
+
+       if (ndev->msix) {
+               i = ndev->msix_vec_count;
+               while (i--)
+                       free_irq(ndev->msix[i].vector, &ndev->vec[i]);
+               pci_disable_msix(pdev);
+               kfree(ndev->msix);
+               kfree(ndev->vec);
+       } else {
+               free_irq(pdev->irq, ndev);
+               if (pci_dev_msi_enabled(pdev))
+                       pci_disable_msi(pdev);
+               else
+                       pci_intx(pdev, 0);
+       }
+}
+
+static ssize_t ndev_debugfs_read(struct file *filp, char __user *ubuf,
+                                size_t count, loff_t *offp)
+{
+       struct amd_ntb_dev *ndev;
+       void __iomem *mmio;
+       char *buf;
+       size_t buf_size;
+       ssize_t ret, off;
+       union { u64 v64; u32 v32; u16 v16; } u;
+
+       ndev = filp->private_data;
+       mmio = ndev->self_mmio;
+
+       buf_size = min(count, 0x800ul);
+
+       buf = kmalloc(buf_size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       off = 0;
+
+       off += scnprintf(buf + off, buf_size - off,
+                        "NTB Device Information:\n");
+
+       off += scnprintf(buf + off, buf_size - off,
+                        "Connection Topology -\t%s\n",
+                        ntb_topo_string(ndev->ntb.topo));
+
+       off += scnprintf(buf + off, buf_size - off,
+                        "LNK STA -\t\t%#06x\n", ndev->lnk_sta);
+
+       if (!amd_link_is_up(ndev)) {
+               off += scnprintf(buf + off, buf_size - off,
+                                "Link Status -\t\tDown\n");
+       } else {
+               off += scnprintf(buf + off, buf_size - off,
+                                "Link Status -\t\tUp\n");
+               off += scnprintf(buf + off, buf_size - off,
+                                "Link Speed -\t\tPCI-E Gen %u\n",
+                                NTB_LNK_STA_SPEED(ndev->lnk_sta));
+               off += scnprintf(buf + off, buf_size - off,
+                                "Link Width -\t\tx%u\n",
+                                NTB_LNK_STA_WIDTH(ndev->lnk_sta));
+       }
+
+       off += scnprintf(buf + off, buf_size - off,
+                        "Memory Window Count -\t%u\n", ndev->mw_count);
+       off += scnprintf(buf + off, buf_size - off,
+                        "Scratchpad Count -\t%u\n", ndev->spad_count);
+       off += scnprintf(buf + off, buf_size - off,
+                        "Doorbell Count -\t%u\n", ndev->db_count);
+       off += scnprintf(buf + off, buf_size - off,
+                        "MSIX Vector Count -\t%u\n", ndev->msix_vec_count);
+
+       off += scnprintf(buf + off, buf_size - off,
+                        "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask);
+
+       u.v32 = readl(ndev->self_mmio + AMD_DBMASK_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "Doorbell Mask -\t\t\t%#06x\n", u.v32);
+
+       u.v32 = readl(mmio + AMD_DBSTAT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "Doorbell Bell -\t\t\t%#06x\n", u.v32);
+
+       off += scnprintf(buf + off, buf_size - off,
+                        "\nNTB Incoming XLAT:\n");
+
+       u.v64 = read64(mmio + AMD_BAR1XLAT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "XLAT1 -\t\t%#018llx\n", u.v64);
+
+       u.v64 = read64(ndev->self_mmio + AMD_BAR23XLAT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "XLAT23 -\t\t%#018llx\n", u.v64);
+
+       u.v64 = read64(ndev->self_mmio + AMD_BAR45XLAT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "XLAT45 -\t\t%#018llx\n", u.v64);
+
+       u.v32 = readl(mmio + AMD_BAR1LMT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "LMT1 -\t\t\t%#06x\n", u.v32);
+
+       u.v64 = read64(ndev->self_mmio + AMD_BAR23LMT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "LMT23 -\t\t\t%#018llx\n", u.v64);
+
+       u.v64 = read64(ndev->self_mmio + AMD_BAR45LMT_OFFSET);
+       off += scnprintf(buf + off, buf_size - off,
+                        "LMT45 -\t\t\t%#018llx\n", u.v64);
+
+       ret = simple_read_from_buffer(ubuf, count, offp, buf, off);
+       kfree(buf);
+       return ret;
+}
+
+static void ndev_init_debugfs(struct amd_ntb_dev *ndev)
+{
+       if (!debugfs_dir) {
+               ndev->debugfs_dir = NULL;
+               ndev->debugfs_info = NULL;
+       } else {
+               ndev->debugfs_dir =
+                       debugfs_create_dir(ndev_name(ndev), debugfs_dir);
+               if (!ndev->debugfs_dir)
+                       ndev->debugfs_info = NULL;
+               else
+                       ndev->debugfs_info =
+                               debugfs_create_file("info", S_IRUSR,
+                                                   ndev->debugfs_dir, ndev,
+                                                   &amd_ntb_debugfs_info);
+       }
+}
+
+static void ndev_deinit_debugfs(struct amd_ntb_dev *ndev)
+{
+       debugfs_remove_recursive(ndev->debugfs_dir);
+}
+
+static inline void ndev_init_struct(struct amd_ntb_dev *ndev,
+                                   struct pci_dev *pdev)
+{
+       ndev->ntb.pdev = pdev;
+       ndev->ntb.topo = NTB_TOPO_NONE;
+       ndev->ntb.ops = &amd_ntb_ops;
+       ndev->int_mask = AMD_EVENT_INTMASK;
+       spin_lock_init(&ndev->db_mask_lock);
+}
+
+static int amd_poll_link(struct amd_ntb_dev *ndev)
+{
+       void __iomem *mmio = ndev->peer_mmio;
+       u32 reg, stat;
+       int rc;
+
+       reg = readl(mmio + AMD_SIDEINFO_OFFSET);
+       reg &= NTB_LIN_STA_ACTIVE_BIT;
+
+       dev_dbg(ndev_dev(ndev), "%s: reg_val = 0x%x.\n", __func__, reg);
+
+       if (reg == ndev->cntl_sta)
+               return 0;
+
+       ndev->cntl_sta = reg;
+
+       rc = pci_read_config_dword(ndev->ntb.pdev,
+                                  AMD_LINK_STATUS_OFFSET, &stat);
+       if (rc)
+               return 0;
+       ndev->lnk_sta = stat;
+
+       return 1;
+}
+
+static void amd_link_hb(struct work_struct *work)
+{
+       struct amd_ntb_dev *ndev = hb_ndev(work);
+
+       if (amd_poll_link(ndev))
+               ntb_link_event(&ndev->ntb);
+
+       if (!amd_link_is_up(ndev))
+               schedule_delayed_work(&ndev->hb_timer, AMD_LINK_HB_TIMEOUT);
+}
+
+static int amd_init_isr(struct amd_ntb_dev *ndev)
+{
+       return ndev_init_isr(ndev, AMD_DB_CNT, AMD_MSIX_VECTOR_CNT);
+}
+
+static void amd_init_side_info(struct amd_ntb_dev *ndev)
+{
+       void __iomem *mmio = ndev->self_mmio;
+       unsigned int reg;
+
+       reg = readl(mmio + AMD_SIDEINFO_OFFSET);
+       if (!(reg & AMD_SIDE_READY)) {
+               reg |= AMD_SIDE_READY;
+               writel(reg, mmio + AMD_SIDEINFO_OFFSET);
+       }
+}
+
+static void amd_deinit_side_info(struct amd_ntb_dev *ndev)
+{
+       void __iomem *mmio = ndev->self_mmio;
+       unsigned int reg;
+
+       reg = readl(mmio + AMD_SIDEINFO_OFFSET);
+       if (reg & AMD_SIDE_READY) {
+               reg &= ~AMD_SIDE_READY;
+               writel(reg, mmio + AMD_SIDEINFO_OFFSET);
+               readl(mmio + AMD_SIDEINFO_OFFSET);
+       }
+}
+
+static int amd_init_ntb(struct amd_ntb_dev *ndev)
+{
+       void __iomem *mmio = ndev->self_mmio;
+
+       ndev->mw_count = AMD_MW_CNT;
+       ndev->spad_count = AMD_SPADS_CNT;
+       ndev->db_count = AMD_DB_CNT;
+
+       switch (ndev->ntb.topo) {
+       case NTB_TOPO_PRI:
+       case NTB_TOPO_SEC:
+               ndev->spad_count >>= 1;
+               if (ndev->ntb.topo == NTB_TOPO_PRI) {
+                       ndev->self_spad = 0;
+                       ndev->peer_spad = 0x20;
+               } else {
+                       ndev->self_spad = 0x20;
+                       ndev->peer_spad = 0;
+               }
+
+               INIT_DELAYED_WORK(&ndev->hb_timer, amd_link_hb);
+               schedule_delayed_work(&ndev->hb_timer, AMD_LINK_HB_TIMEOUT);
+
+               break;
+       default:
+               dev_err(ndev_dev(ndev), "AMD NTB does not support B2B mode.\n");
+               return -EINVAL;
+       }
+
+       ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
+
+       /* Mask event interrupts */
+       writel(ndev->int_mask, mmio + AMD_INTMASK_OFFSET);
+
+       return 0;
+}
+
+static enum ntb_topo amd_get_topo(struct amd_ntb_dev *ndev)
+{
+       void __iomem *mmio = ndev->self_mmio;
+       u32 info;
+
+       info = readl(mmio + AMD_SIDEINFO_OFFSET);
+       if (info & AMD_SIDE_MASK)
+               return NTB_TOPO_SEC;
+       else
+               return NTB_TOPO_PRI;
+}
+
+static int amd_init_dev(struct amd_ntb_dev *ndev)
+{
+       struct pci_dev *pdev;
+       int rc = 0;
+
+       pdev = ndev_pdev(ndev);
+
+       ndev->ntb.topo = amd_get_topo(ndev);
+       dev_dbg(ndev_dev(ndev), "AMD NTB topo is %s\n",
+               ntb_topo_string(ndev->ntb.topo));
+
+       rc = amd_init_ntb(ndev);
+       if (rc)
+               return rc;
+
+       rc = amd_init_isr(ndev);
+       if (rc) {
+               dev_err(ndev_dev(ndev), "fail to init isr.\n");
+               return rc;
+       }
+
+       ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
+
+       return 0;
+}
+
+static void amd_deinit_dev(struct amd_ntb_dev *ndev)
+{
+       cancel_delayed_work_sync(&ndev->hb_timer);
+
+       ndev_deinit_isr(ndev);
+}
+
+static int amd_ntb_init_pci(struct amd_ntb_dev *ndev,
+                           struct pci_dev *pdev)
+{
+       int rc;
+
+       pci_set_drvdata(pdev, ndev);
+
+       rc = pci_enable_device(pdev);
+       if (rc)
+               goto err_pci_enable;
+
+       rc = pci_request_regions(pdev, NTB_NAME);
+       if (rc)
+               goto err_pci_regions;
+
+       pci_set_master(pdev);
+
+       rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+       if (rc) {
+               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+               if (rc)
+                       goto err_dma_mask;
+               dev_warn(ndev_dev(ndev), "Cannot DMA highmem\n");
+       }
+
+       rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+       if (rc) {
+               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+               if (rc)
+                       goto err_dma_mask;
+               dev_warn(ndev_dev(ndev), "Cannot DMA consistent highmem\n");
+       }
+
+       ndev->self_mmio = pci_iomap(pdev, 0, 0);
+       if (!ndev->self_mmio) {
+               rc = -EIO;
+               goto err_dma_mask;
+       }
+       ndev->peer_mmio = ndev->self_mmio + AMD_PEER_OFFSET;
+
+       return 0;
+
+err_dma_mask:
+       pci_clear_master(pdev);
+err_pci_regions:
+       pci_disable_device(pdev);
+err_pci_enable:
+       pci_set_drvdata(pdev, NULL);
+       return rc;
+}
+
+static void amd_ntb_deinit_pci(struct amd_ntb_dev *ndev)
+{
+       struct pci_dev *pdev = ndev_pdev(ndev);
+
+       pci_iounmap(pdev, ndev->self_mmio);
+
+       pci_clear_master(pdev);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+
+static int amd_ntb_pci_probe(struct pci_dev *pdev,
+                            const struct pci_device_id *id)
+{
+       struct amd_ntb_dev *ndev;
+       int rc, node;
+
+       node = dev_to_node(&pdev->dev);
+
+       ndev = kzalloc_node(sizeof(*ndev), GFP_KERNEL, node);
+       if (!ndev) {
+               rc = -ENOMEM;
+               goto err_ndev;
+       }
+
+       ndev_init_struct(ndev, pdev);
+
+       rc = amd_ntb_init_pci(ndev, pdev);
+       if (rc)
+               goto err_init_pci;
+
+       rc = amd_init_dev(ndev);
+       if (rc)
+               goto err_init_dev;
+
+       /* write side info */
+       amd_init_side_info(ndev);
+
+       amd_poll_link(ndev);
+
+       ndev_init_debugfs(ndev);
+
+       rc = ntb_register_device(&ndev->ntb);
+       if (rc)
+               goto err_register;
+
+       dev_info(&pdev->dev, "NTB device registered.\n");
+
+       return 0;
+
+err_register:
+       ndev_deinit_debugfs(ndev);
+       amd_deinit_dev(ndev);
+err_init_dev:
+       amd_ntb_deinit_pci(ndev);
+err_init_pci:
+       kfree(ndev);
+err_ndev:
+       return rc;
+}
+
+static void amd_ntb_pci_remove(struct pci_dev *pdev)
+{
+       struct amd_ntb_dev *ndev = pci_get_drvdata(pdev);
+
+       ntb_unregister_device(&ndev->ntb);
+       ndev_deinit_debugfs(ndev);
+       amd_deinit_side_info(ndev);
+       amd_deinit_dev(ndev);
+       amd_ntb_deinit_pci(ndev);
+       kfree(ndev);
+}
+
+static const struct file_operations amd_ntb_debugfs_info = {
+       .owner = THIS_MODULE,
+       .open = simple_open,
+       .read = ndev_debugfs_read,
+};
+
+static const struct pci_device_id amd_ntb_pci_tbl[] = {
+       {PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_NTB)},
+       {0}
+};
+MODULE_DEVICE_TABLE(pci, amd_ntb_pci_tbl);
+
+static struct pci_driver amd_ntb_pci_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = amd_ntb_pci_tbl,
+       .probe          = amd_ntb_pci_probe,
+       .remove         = amd_ntb_pci_remove,
+};
+
+static int __init amd_ntb_pci_driver_init(void)
+{
+       pr_info("%s %s\n", NTB_DESC, NTB_VER);
+
+       if (debugfs_initialized())
+               debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+       return pci_register_driver(&amd_ntb_pci_driver);
+}
+module_init(amd_ntb_pci_driver_init);
+
+static void __exit amd_ntb_pci_driver_exit(void)
+{
+       pci_unregister_driver(&amd_ntb_pci_driver);
+       debugfs_remove_recursive(debugfs_dir);
+}
+module_exit(amd_ntb_pci_driver_exit);
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.h b/drivers/ntb/hw/amd/ntb_hw_amd.h
new file mode 100644 (file)
index 0000000..2eac3cd
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GPL LICENSE SUMMARY
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copy
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of AMD Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD PCIe NTB Linux driver
+ *
+ * Contact Information:
+ * Xiangliang Yu <Xiangliang.Yu@amd.com>
+ */
+
+#ifndef NTB_HW_AMD_H
+#define NTB_HW_AMD_H
+
+#include <linux/ntb.h>
+#include <linux/pci.h>
+
+#define PCI_DEVICE_ID_AMD_NTB  0x145B
+#define AMD_LINK_HB_TIMEOUT    msecs_to_jiffies(1000)
+#define AMD_LINK_STATUS_OFFSET 0x68
+#define NTB_LIN_STA_ACTIVE_BIT 0x00000002
+#define NTB_LNK_STA_SPEED_MASK 0x000F0000
+#define NTB_LNK_STA_WIDTH_MASK 0x03F00000
+#define NTB_LNK_STA_ACTIVE(x)  (!!((x) & NTB_LIN_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x)   (((x) & NTB_LNK_STA_SPEED_MASK) >> 16)
+#define NTB_LNK_STA_WIDTH(x)   (((x) & NTB_LNK_STA_WIDTH_MASK) >> 20)
+
+#ifndef read64
+#ifdef readq
+#define read64 readq
+#else
+#define read64 _read64
+static inline u64 _read64(void __iomem *mmio)
+{
+       u64 low, high;
+
+       low = readl(mmio);
+       high = readl(mmio + sizeof(u32));
+       return low | (high << 32);
+}
+#endif
+#endif
+
+#ifndef write64
+#ifdef writeq
+#define write64 writeq
+#else
+#define write64 _write64
+static inline void _write64(u64 val, void __iomem *mmio)
+{
+       writel(val, mmio);
+       writel(val >> 32, mmio + sizeof(u32));
+}
+#endif
+#endif
+
+enum {
+       /* AMD NTB Capability */
+       AMD_MW_CNT              = 3,
+       AMD_DB_CNT              = 16,
+       AMD_MSIX_VECTOR_CNT     = 24,
+       AMD_SPADS_CNT           = 16,
+
+       /*  AMD NTB register offset */
+       AMD_CNTL_OFFSET         = 0x200,
+
+       /* NTB control register bits */
+       PMM_REG_CTL             = BIT(21),
+       SMM_REG_CTL             = BIT(20),
+       SMM_REG_ACC_PATH        = BIT(18),
+       PMM_REG_ACC_PATH        = BIT(17),
+       NTB_CLK_EN              = BIT(16),
+
+       AMD_STA_OFFSET          = 0x204,
+       AMD_PGSLV_OFFSET        = 0x208,
+       AMD_SPAD_MUX_OFFSET     = 0x20C,
+       AMD_SPAD_OFFSET         = 0x210,
+       AMD_RSMU_HCID           = 0x250,
+       AMD_RSMU_SIID           = 0x254,
+       AMD_PSION_OFFSET        = 0x300,
+       AMD_SSION_OFFSET        = 0x330,
+       AMD_MMINDEX_OFFSET      = 0x400,
+       AMD_MMDATA_OFFSET       = 0x404,
+       AMD_SIDEINFO_OFFSET     = 0x408,
+
+       AMD_SIDE_MASK           = BIT(0),
+       AMD_SIDE_READY          = BIT(1),
+
+       /* limit register */
+       AMD_ROMBARLMT_OFFSET    = 0x410,
+       AMD_BAR1LMT_OFFSET      = 0x414,
+       AMD_BAR23LMT_OFFSET     = 0x418,
+       AMD_BAR45LMT_OFFSET     = 0x420,
+       /* xlat address */
+       AMD_POMBARXLAT_OFFSET   = 0x428,
+       AMD_BAR1XLAT_OFFSET     = 0x430,
+       AMD_BAR23XLAT_OFFSET    = 0x438,
+       AMD_BAR45XLAT_OFFSET    = 0x440,
+       /* doorbell and interrupt */
+       AMD_DBFM_OFFSET         = 0x450,
+       AMD_DBREQ_OFFSET        = 0x454,
+       AMD_MIRRDBSTAT_OFFSET   = 0x458,
+       AMD_DBMASK_OFFSET       = 0x45C,
+       AMD_DBSTAT_OFFSET       = 0x460,
+       AMD_INTMASK_OFFSET      = 0x470,
+       AMD_INTSTAT_OFFSET      = 0x474,
+
+       /* event type */
+       AMD_PEER_FLUSH_EVENT    = BIT(0),
+       AMD_PEER_RESET_EVENT    = BIT(1),
+       AMD_PEER_D3_EVENT       = BIT(2),
+       AMD_PEER_PMETO_EVENT    = BIT(3),
+       AMD_PEER_D0_EVENT       = BIT(4),
+       AMD_EVENT_INTMASK       = (AMD_PEER_FLUSH_EVENT |
+                               AMD_PEER_RESET_EVENT | AMD_PEER_D3_EVENT |
+                               AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT),
+
+       AMD_PMESTAT_OFFSET      = 0x480,
+       AMD_PMSGTRIG_OFFSET     = 0x490,
+       AMD_LTRLATENCY_OFFSET   = 0x494,
+       AMD_FLUSHTRIG_OFFSET    = 0x498,
+
+       /* SMU register*/
+       AMD_SMUACK_OFFSET       = 0x4A0,
+       AMD_SINRST_OFFSET       = 0x4A4,
+       AMD_RSPNUM_OFFSET       = 0x4A8,
+       AMD_SMU_SPADMUTEX       = 0x4B0,
+       AMD_SMU_SPADOFFSET      = 0x4B4,
+
+       AMD_PEER_OFFSET         = 0x400,
+};
+
+struct amd_ntb_dev;
+
+struct amd_ntb_vec {
+       struct amd_ntb_dev      *ndev;
+       int                     num;
+};
+
+struct amd_ntb_dev {
+       struct ntb_dev ntb;
+
+       u32 ntb_side;
+       u32 lnk_sta;
+       u32 cntl_sta;
+       u32 peer_sta;
+
+       unsigned char mw_count;
+       unsigned char spad_count;
+       unsigned char db_count;
+       unsigned char msix_vec_count;
+
+       u64 db_valid_mask;
+       u64 db_mask;
+       u32 int_mask;
+
+       struct msix_entry *msix;
+       struct amd_ntb_vec *vec;
+
+       /* synchronize rmw access of db_mask and hw reg */
+       spinlock_t db_mask_lock;
+
+       void __iomem *self_mmio;
+       void __iomem *peer_mmio;
+       unsigned int self_spad;
+       unsigned int peer_spad;
+
+       struct delayed_work hb_timer;
+
+       struct dentry *debugfs_dir;
+       struct dentry *debugfs_info;
+};
+
+#define ndev_pdev(ndev) ((ndev)->ntb.pdev)
+#define ndev_name(ndev) pci_name(ndev_pdev(ndev))
+#define ndev_dev(ndev) (&ndev_pdev(ndev)->dev)
+#define ntb_ndev(__ntb) container_of(__ntb, struct amd_ntb_dev, ntb)
+#define hb_ndev(__work) container_of(__work, struct amd_ntb_dev, hb_timer.work)
+
+#endif
index a198f82..40d04ef 100644 (file)
@@ -875,7 +875,7 @@ static int intel_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
        limit_reg = bar2_off(ndev->xlat_reg->bar2_limit, bar);
 
        if (bar < 4 || !ndev->bar4_split) {
-               base = ioread64(mmio + base_reg);
+               base = ioread64(mmio + base_reg) & NTB_BAR_MASK_64;
 
                /* Set the limit if supported, if size is not mw_size */
                if (limit_reg && size != mw_size)
@@ -906,7 +906,7 @@ static int intel_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
                if ((addr + size) & (~0ull << 32))
                        return -EINVAL;
 
-               base = ioread32(mmio + base_reg);
+               base = ioread32(mmio + base_reg) & NTB_BAR_MASK_32;
 
                /* Set the limit if supported, if size is not mw_size */
                if (limit_reg && size != mw_size)
index 2eb4add..3ec149c 100644 (file)
 #define NTB_UNSAFE_DB                  BIT_ULL(0)
 #define NTB_UNSAFE_SPAD                        BIT_ULL(1)
 
+#define NTB_BAR_MASK_64                        ~(0xfull)
+#define NTB_BAR_MASK_32                        ~(0xfu)
+
 struct intel_ntb_dev;
 
 struct intel_ntb_reg {
@@ -334,7 +337,8 @@ struct intel_ntb_dev {
 #define ndev_pdev(ndev) ((ndev)->ntb.pdev)
 #define ndev_name(ndev) pci_name(ndev_pdev(ndev))
 #define ndev_dev(ndev) (&ndev_pdev(ndev)->dev)
-#define ntb_ndev(ntb) container_of(ntb, struct intel_ntb_dev, ntb)
-#define hb_ndev(work) container_of(work, struct intel_ntb_dev, hb_timer.work)
+#define ntb_ndev(__ntb) container_of(__ntb, struct intel_ntb_dev, ntb)
+#define hb_ndev(__work) container_of(__work, struct intel_ntb_dev, \
+                                    hb_timer.work)
 
 #endif
index 60654d5..ec4775f 100644 (file)
@@ -171,12 +171,14 @@ struct ntb_transport_qp {
        u64 rx_err_ver;
        u64 rx_memcpy;
        u64 rx_async;
+       u64 dma_rx_prep_err;
        u64 tx_bytes;
        u64 tx_pkts;
        u64 tx_ring_full;
        u64 tx_err_no_buf;
        u64 tx_memcpy;
        u64 tx_async;
+       u64 dma_tx_prep_err;
 };
 
 struct ntb_transport_mw {
@@ -249,6 +251,8 @@ enum {
 #define QP_TO_MW(nt, qp)       ((qp) % nt->mw_count)
 #define NTB_QP_DEF_NUM_ENTRIES 100
 #define NTB_LINK_DOWN_TIMEOUT  10
+#define DMA_RETRIES            20
+#define DMA_OUT_RESOURCE_TO    50
 
 static void ntb_transport_rxc_db(unsigned long data);
 static const struct ntb_ctx_ops ntb_transport_ops;
@@ -501,6 +505,12 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
                               "free tx - \t%u\n",
                               ntb_transport_tx_free_entry(qp));
+       out_offset += snprintf(buf + out_offset, out_count - out_offset,
+                              "DMA tx prep err - \t%llu\n",
+                              qp->dma_tx_prep_err);
+       out_offset += snprintf(buf + out_offset, out_count - out_offset,
+                              "DMA rx prep err - \t%llu\n",
+                              qp->dma_rx_prep_err);
 
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
                               "\n");
@@ -726,6 +736,8 @@ static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
        qp->tx_err_no_buf = 0;
        qp->tx_memcpy = 0;
        qp->tx_async = 0;
+       qp->dma_tx_prep_err = 0;
+       qp->dma_rx_prep_err = 0;
 }
 
 static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
@@ -1228,6 +1240,7 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset)
        struct dmaengine_unmap_data *unmap;
        dma_cookie_t cookie;
        void *buf = entry->buf;
+       int retries = 0;
 
        len = entry->len;
 
@@ -1263,11 +1276,21 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset)
 
        unmap->from_cnt = 1;
 
-       txd = device->device_prep_dma_memcpy(chan, unmap->addr[1],
-                                            unmap->addr[0], len,
-                                            DMA_PREP_INTERRUPT);
-       if (!txd)
+       for (retries = 0; retries < DMA_RETRIES; retries++) {
+               txd = device->device_prep_dma_memcpy(chan, unmap->addr[1],
+                                                    unmap->addr[0], len,
+                                                    DMA_PREP_INTERRUPT);
+               if (txd)
+                       break;
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(DMA_OUT_RESOURCE_TO);
+       }
+
+       if (!txd) {
+               qp->dma_rx_prep_err++;
                goto err_get_unmap;
+       }
 
        txd->callback = ntb_rx_copy_callback;
        txd->callback_param = entry;
@@ -1460,6 +1483,7 @@ static void ntb_async_tx(struct ntb_transport_qp *qp,
        void __iomem *offset;
        size_t len = entry->len;
        void *buf = entry->buf;
+       int retries = 0;
 
        offset = qp->tx_mw + qp->tx_max_frame * qp->tx_index;
        hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header);
@@ -1494,10 +1518,20 @@ static void ntb_async_tx(struct ntb_transport_qp *qp,
 
        unmap->to_cnt = 1;
 
-       txd = device->device_prep_dma_memcpy(chan, dest, unmap->addr[0], len,
-                                            DMA_PREP_INTERRUPT);
-       if (!txd)
+       for (retries = 0; retries < DMA_RETRIES; retries++) {
+               txd = device->device_prep_dma_memcpy(chan, dest, unmap->addr[0],
+                                                    len, DMA_PREP_INTERRUPT);
+               if (txd)
+                       break;
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(DMA_OUT_RESOURCE_TO);
+       }
+
+       if (!txd) {
+               qp->dma_tx_prep_err++;
                goto err_get_unmap;
+       }
 
        txd->callback = ntb_tx_copy_callback;
        txd->callback_param = entry;
@@ -1532,7 +1566,7 @@ static int ntb_process_tx(struct ntb_transport_qp *qp,
 
        if (entry->len > qp->tx_max_frame - sizeof(struct ntb_payload_header)) {
                if (qp->tx_handler)
-                       qp->tx_handler(qp->cb_data, qp, NULL, -EIO);
+                       qp->tx_handler(qp, qp->cb_data, NULL, -EIO);
 
                ntb_list_add(&qp->ntb_tx_free_q_lock, &entry->entry,
                             &qp->tx_free_q);
index 01852f9..a5d0eda 100644 (file)
@@ -17,3 +17,11 @@ config NTB_TOOL
         functioning at a basic level.
 
         If unsure, say N.
+
+config NTB_PERF
+       tristate "NTB RAW Perf Measuring Tool"
+       help
+        This is a tool to measure raw NTB performance by transferring data
+        to and from the window without additional software interaction.
+
+        If unsure, say N.
index 0ea32a3..9e77e0b 100644 (file)
@@ -1,2 +1,3 @@
 obj-$(CONFIG_NTB_PINGPONG) += ntb_pingpong.o
 obj-$(CONFIG_NTB_TOOL) += ntb_tool.o
+obj-$(CONFIG_NTB_PERF) += ntb_perf.o
diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
new file mode 100644 (file)
index 0000000..c8a37ba
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ *
+ *   GPL LICENSE SUMMARY
+ *
+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copy
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *   PCIe NTB Perf Linux driver
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/dmaengine.h>
+#include <linux/delay.h>
+#include <linux/sizes.h>
+#include <linux/ntb.h>
+
+#define DRIVER_NAME            "ntb_perf"
+#define DRIVER_DESCRIPTION     "PCIe NTB Performance Measurement Tool"
+
+#define DRIVER_LICENSE         "Dual BSD/GPL"
+#define DRIVER_VERSION         "1.0"
+#define DRIVER_AUTHOR          "Dave Jiang <dave.jiang@intel.com>"
+
+#define PERF_LINK_DOWN_TIMEOUT 10
+#define PERF_VERSION           0xffff0001
+#define MAX_THREADS            32
+#define MAX_TEST_SIZE          SZ_1M
+#define MAX_SRCS               32
+#define DMA_OUT_RESOURCE_TO    50
+#define DMA_RETRIES            20
+#define SZ_4G                  (1ULL << 32)
+#define MAX_SEG_ORDER          20 /* no larger than 1M for kmalloc buffer */
+
+MODULE_LICENSE(DRIVER_LICENSE);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+
+static struct dentry *perf_debugfs_dir;
+
+static unsigned int seg_order = 19; /* 512K */
+module_param(seg_order, uint, 0644);
+MODULE_PARM_DESC(seg_order, "size order [n^2] of buffer segment for testing");
+
+static unsigned int run_order = 32; /* 4G */
+module_param(run_order, uint, 0644);
+MODULE_PARM_DESC(run_order, "size order [n^2] of total data to transfer");
+
+static bool use_dma; /* default to 0 */
+module_param(use_dma, bool, 0644);
+MODULE_PARM_DESC(use_dma, "Using DMA engine to measure performance");
+
+struct perf_mw {
+       phys_addr_t     phys_addr;
+       resource_size_t phys_size;
+       resource_size_t xlat_align;
+       resource_size_t xlat_align_size;
+       void __iomem    *vbase;
+       size_t          xlat_size;
+       size_t          buf_size;
+       void            *virt_addr;
+       dma_addr_t      dma_addr;
+};
+
+struct perf_ctx;
+
+struct pthr_ctx {
+       struct task_struct      *thread;
+       struct perf_ctx         *perf;
+       atomic_t                dma_sync;
+       struct dma_chan         *dma_chan;
+       int                     dma_prep_err;
+       int                     src_idx;
+       void                    *srcs[MAX_SRCS];
+};
+
+struct perf_ctx {
+       struct ntb_dev          *ntb;
+       spinlock_t              db_lock;
+       struct perf_mw          mw;
+       bool                    link_is_up;
+       struct work_struct      link_cleanup;
+       struct delayed_work     link_work;
+       struct dentry           *debugfs_node_dir;
+       struct dentry           *debugfs_run;
+       struct dentry           *debugfs_threads;
+       u8                      perf_threads;
+       bool                    run;
+       struct pthr_ctx         pthr_ctx[MAX_THREADS];
+       atomic_t                tsync;
+};
+
+enum {
+       VERSION = 0,
+       MW_SZ_HIGH,
+       MW_SZ_LOW,
+       SPAD_MSG,
+       SPAD_ACK,
+       MAX_SPAD
+};
+
+static void perf_link_event(void *ctx)
+{
+       struct perf_ctx *perf = ctx;
+
+       if (ntb_link_is_up(perf->ntb, NULL, NULL) == 1)
+               schedule_delayed_work(&perf->link_work, 2*HZ);
+       else
+               schedule_work(&perf->link_cleanup);
+}
+
+static void perf_db_event(void *ctx, int vec)
+{
+       struct perf_ctx *perf = ctx;
+       u64 db_bits, db_mask;
+
+       db_mask = ntb_db_vector_mask(perf->ntb, vec);
+       db_bits = ntb_db_read(perf->ntb);
+
+       dev_dbg(&perf->ntb->dev, "doorbell vec %d mask %#llx bits %#llx\n",
+               vec, db_mask, db_bits);
+}
+
+static const struct ntb_ctx_ops perf_ops = {
+       .link_event = perf_link_event,
+       .db_event = perf_db_event,
+};
+
+static void perf_copy_callback(void *data)
+{
+       struct pthr_ctx *pctx = data;
+
+       atomic_dec(&pctx->dma_sync);
+}
+
+static ssize_t perf_copy(struct pthr_ctx *pctx, char *dst,
+                        char *src, size_t size)
+{
+       struct perf_ctx *perf = pctx->perf;
+       struct dma_async_tx_descriptor *txd;
+       struct dma_chan *chan = pctx->dma_chan;
+       struct dma_device *device;
+       struct dmaengine_unmap_data *unmap;
+       dma_cookie_t cookie;
+       size_t src_off, dst_off;
+       struct perf_mw *mw = &perf->mw;
+       u64 vbase, dst_vaddr;
+       dma_addr_t dst_phys;
+       int retries = 0;
+
+       if (!use_dma) {
+               memcpy_toio(dst, src, size);
+               return size;
+       }
+
+       if (!chan) {
+               dev_err(&perf->ntb->dev, "DMA engine does not exist\n");
+               return -EINVAL;
+       }
+
+       device = chan->device;
+       src_off = (size_t)src & ~PAGE_MASK;
+       dst_off = (size_t)dst & ~PAGE_MASK;
+
+       if (!is_dma_copy_aligned(device, src_off, dst_off, size))
+               return -ENODEV;
+
+       vbase = (u64)(u64 *)mw->vbase;
+       dst_vaddr = (u64)(u64 *)dst;
+       dst_phys = mw->phys_addr + (dst_vaddr - vbase);
+
+       unmap = dmaengine_get_unmap_data(device->dev, 1, GFP_NOWAIT);
+       if (!unmap)
+               return -ENOMEM;
+
+       unmap->len = size;
+       unmap->addr[0] = dma_map_page(device->dev, virt_to_page(src),
+                                     src_off, size, DMA_TO_DEVICE);
+       if (dma_mapping_error(device->dev, unmap->addr[0]))
+               goto err_get_unmap;
+
+       unmap->to_cnt = 1;
+
+       do {
+               txd = device->device_prep_dma_memcpy(chan, dst_phys,
+                                                    unmap->addr[0],
+                                                    size, DMA_PREP_INTERRUPT);
+               if (!txd) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(DMA_OUT_RESOURCE_TO);
+               }
+       } while (!txd && (++retries < DMA_RETRIES));
+
+       if (!txd) {
+               pctx->dma_prep_err++;
+               goto err_get_unmap;
+       }
+
+       txd->callback = perf_copy_callback;
+       txd->callback_param = pctx;
+       dma_set_unmap(txd, unmap);
+
+       cookie = dmaengine_submit(txd);
+       if (dma_submit_error(cookie))
+               goto err_set_unmap;
+
+       atomic_inc(&pctx->dma_sync);
+       dma_async_issue_pending(chan);
+
+       return size;
+
+err_set_unmap:
+       dmaengine_unmap_put(unmap);
+err_get_unmap:
+       dmaengine_unmap_put(unmap);
+       return 0;
+}
+
+static int perf_move_data(struct pthr_ctx *pctx, char *dst, char *src,
+                         u64 buf_size, u64 win_size, u64 total)
+{
+       int chunks, total_chunks, i;
+       int copied_chunks = 0;
+       u64 copied = 0, result;
+       char *tmp = dst;
+       u64 perf, diff_us;
+       ktime_t kstart, kstop, kdiff;
+
+       chunks = div64_u64(win_size, buf_size);
+       total_chunks = div64_u64(total, buf_size);
+       kstart = ktime_get();
+
+       for (i = 0; i < total_chunks; i++) {
+               result = perf_copy(pctx, tmp, src, buf_size);
+               copied += result;
+               copied_chunks++;
+               if (copied_chunks == chunks) {
+                       tmp = dst;
+                       copied_chunks = 0;
+               } else
+                       tmp += buf_size;
+
+               /* Probably should schedule every 4GB to prevent soft hang. */
+               if (((copied % SZ_4G) == 0) && !use_dma) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(1);
+               }
+       }
+
+       if (use_dma) {
+               pr_info("%s: All DMA descriptors submitted\n", current->comm);
+               while (atomic_read(&pctx->dma_sync) != 0)
+                       msleep(20);
+       }
+
+       kstop = ktime_get();
+       kdiff = ktime_sub(kstop, kstart);
+       diff_us = ktime_to_us(kdiff);
+
+       pr_info("%s: copied %llu bytes\n", current->comm, copied);
+
+       pr_info("%s: lasted %llu usecs\n", current->comm, diff_us);
+
+       perf = div64_u64(copied, diff_us);
+
+       pr_info("%s: MBytes/s: %llu\n", current->comm, perf);
+
+       return 0;
+}
+
+static bool perf_dma_filter_fn(struct dma_chan *chan, void *node)
+{
+       return dev_to_node(&chan->dev->device) == (int)(unsigned long)node;
+}
+
+static int ntb_perf_thread(void *data)
+{
+       struct pthr_ctx *pctx = data;
+       struct perf_ctx *perf = pctx->perf;
+       struct pci_dev *pdev = perf->ntb->pdev;
+       struct perf_mw *mw = &perf->mw;
+       char *dst;
+       u64 win_size, buf_size, total;
+       void *src;
+       int rc, node, i;
+       struct dma_chan *dma_chan = NULL;
+
+       pr_info("kthread %s starting...\n", current->comm);
+
+       node = dev_to_node(&pdev->dev);
+
+       if (use_dma && !pctx->dma_chan) {
+               dma_cap_mask_t dma_mask;
+
+               dma_cap_zero(dma_mask);
+               dma_cap_set(DMA_MEMCPY, dma_mask);
+               dma_chan = dma_request_channel(dma_mask, perf_dma_filter_fn,
+                                              (void *)(unsigned long)node);
+               if (!dma_chan) {
+                       pr_warn("%s: cannot acquire DMA channel, quitting\n",
+                               current->comm);
+                       return -ENODEV;
+               }
+               pctx->dma_chan = dma_chan;
+       }
+
+       for (i = 0; i < MAX_SRCS; i++) {
+               pctx->srcs[i] = kmalloc_node(MAX_TEST_SIZE, GFP_KERNEL, node);
+               if (!pctx->srcs[i]) {
+                       rc = -ENOMEM;
+                       goto err;
+               }
+       }
+
+       win_size = mw->phys_size;
+       buf_size = 1ULL << seg_order;
+       total = 1ULL << run_order;
+
+       if (buf_size > MAX_TEST_SIZE)
+               buf_size = MAX_TEST_SIZE;
+
+       dst = (char *)mw->vbase;
+
+       atomic_inc(&perf->tsync);
+       while (atomic_read(&perf->tsync) != perf->perf_threads)
+               schedule();
+
+       src = pctx->srcs[pctx->src_idx];
+       pctx->src_idx = (pctx->src_idx + 1) & (MAX_SRCS - 1);
+
+       rc = perf_move_data(pctx, dst, src, buf_size, win_size, total);
+
+       atomic_dec(&perf->tsync);
+
+       if (rc < 0) {
+               pr_err("%s: failed\n", current->comm);
+               rc = -ENXIO;
+               goto err;
+       }
+
+       for (i = 0; i < MAX_SRCS; i++) {
+               kfree(pctx->srcs[i]);
+               pctx->srcs[i] = NULL;
+       }
+
+       return 0;
+
+err:
+       for (i = 0; i < MAX_SRCS; i++) {
+               kfree(pctx->srcs[i]);
+               pctx->srcs[i] = NULL;
+       }
+
+       if (dma_chan) {
+               dma_release_channel(dma_chan);
+               pctx->dma_chan = NULL;
+       }
+
+       return rc;
+}
+
+static void perf_free_mw(struct perf_ctx *perf)
+{
+       struct perf_mw *mw = &perf->mw;
+       struct pci_dev *pdev = perf->ntb->pdev;
+
+       if (!mw->virt_addr)
+               return;
+
+       ntb_mw_clear_trans(perf->ntb, 0);
+       dma_free_coherent(&pdev->dev, mw->buf_size,
+                         mw->virt_addr, mw->dma_addr);
+       mw->xlat_size = 0;
+       mw->buf_size = 0;
+       mw->virt_addr = NULL;
+}
+
+static int perf_set_mw(struct perf_ctx *perf, resource_size_t size)
+{
+       struct perf_mw *mw = &perf->mw;
+       size_t xlat_size, buf_size;
+
+       if (!size)
+               return -EINVAL;
+
+       xlat_size = round_up(size, mw->xlat_align_size);
+       buf_size = round_up(size, mw->xlat_align);
+
+       if (mw->xlat_size == xlat_size)
+               return 0;
+
+       if (mw->buf_size)
+               perf_free_mw(perf);
+
+       mw->xlat_size = xlat_size;
+       mw->buf_size = buf_size;
+
+       mw->virt_addr = dma_alloc_coherent(&perf->ntb->pdev->dev, buf_size,
+                                          &mw->dma_addr, GFP_KERNEL);
+       if (!mw->virt_addr) {
+               mw->xlat_size = 0;
+               mw->buf_size = 0;
+       }
+
+       return 0;
+}
+
+static void perf_link_work(struct work_struct *work)
+{
+       struct perf_ctx *perf =
+               container_of(work, struct perf_ctx, link_work.work);
+       struct ntb_dev *ndev = perf->ntb;
+       struct pci_dev *pdev = ndev->pdev;
+       u32 val;
+       u64 size;
+       int rc;
+
+       dev_dbg(&perf->ntb->pdev->dev, "%s called\n", __func__);
+
+       size = perf->mw.phys_size;
+       ntb_peer_spad_write(ndev, MW_SZ_HIGH, upper_32_bits(size));
+       ntb_peer_spad_write(ndev, MW_SZ_LOW, lower_32_bits(size));
+       ntb_peer_spad_write(ndev, VERSION, PERF_VERSION);
+
+       /* now read what peer wrote */
+       val = ntb_spad_read(ndev, VERSION);
+       if (val != PERF_VERSION) {
+               dev_dbg(&pdev->dev, "Remote version = %#x\n", val);
+               goto out;
+       }
+
+       val = ntb_spad_read(ndev, MW_SZ_HIGH);
+       size = (u64)val << 32;
+
+       val = ntb_spad_read(ndev, MW_SZ_LOW);
+       size |= val;
+
+       dev_dbg(&pdev->dev, "Remote MW size = %#llx\n", size);
+
+       rc = perf_set_mw(perf, size);
+       if (rc)
+               goto out1;
+
+       perf->link_is_up = true;
+
+       return;
+
+out1:
+       perf_free_mw(perf);
+
+out:
+       if (ntb_link_is_up(ndev, NULL, NULL) == 1)
+               schedule_delayed_work(&perf->link_work,
+                                     msecs_to_jiffies(PERF_LINK_DOWN_TIMEOUT));
+}
+
+static void perf_link_cleanup(struct work_struct *work)
+{
+       struct perf_ctx *perf = container_of(work,
+                                            struct perf_ctx,
+                                            link_cleanup);
+
+       dev_dbg(&perf->ntb->pdev->dev, "%s called\n", __func__);
+
+       if (!perf->link_is_up)
+               cancel_delayed_work_sync(&perf->link_work);
+}
+
+static int perf_setup_mw(struct ntb_dev *ntb, struct perf_ctx *perf)
+{
+       struct perf_mw *mw;
+       int rc;
+
+       mw = &perf->mw;
+
+       rc = ntb_mw_get_range(ntb, 0, &mw->phys_addr, &mw->phys_size,
+                             &mw->xlat_align, &mw->xlat_align_size);
+       if (rc)
+               return rc;
+
+       perf->mw.vbase = ioremap_wc(mw->phys_addr, mw->phys_size);
+       if (!mw->vbase)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static ssize_t debugfs_run_read(struct file *filp, char __user *ubuf,
+                               size_t count, loff_t *offp)
+{
+       struct perf_ctx *perf = filp->private_data;
+       char *buf;
+       ssize_t ret, out_offset;
+
+       if (!perf)
+               return 0;
+
+       buf = kmalloc(64, GFP_KERNEL);
+       out_offset = snprintf(buf, 64, "%d\n", perf->run);
+       ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset);
+       kfree(buf);
+
+       return ret;
+}
+
+static ssize_t debugfs_run_write(struct file *filp, const char __user *ubuf,
+                                size_t count, loff_t *offp)
+{
+       struct perf_ctx *perf = filp->private_data;
+       int node, i;
+
+       if (!perf->link_is_up)
+               return 0;
+
+       if (perf->perf_threads == 0)
+               return 0;
+
+       if (atomic_read(&perf->tsync) == 0)
+               perf->run = false;
+
+       if (perf->run) {
+               /* lets stop the threads */
+               perf->run = false;
+               for (i = 0; i < MAX_THREADS; i++) {
+                       if (perf->pthr_ctx[i].thread) {
+                               kthread_stop(perf->pthr_ctx[i].thread);
+                               perf->pthr_ctx[i].thread = NULL;
+                       } else
+                               break;
+               }
+       } else {
+               perf->run = true;
+
+               if (perf->perf_threads > MAX_THREADS) {
+                       perf->perf_threads = MAX_THREADS;
+                       pr_info("Reset total threads to: %u\n", MAX_THREADS);
+               }
+
+               /* no greater than 1M */
+               if (seg_order > MAX_SEG_ORDER) {
+                       seg_order = MAX_SEG_ORDER;
+                       pr_info("Fix seg_order to %u\n", seg_order);
+               }
+
+               if (run_order < seg_order) {
+                       run_order = seg_order;
+                       pr_info("Fix run_order to %u\n", run_order);
+               }
+
+               node = dev_to_node(&perf->ntb->pdev->dev);
+               /* launch kernel thread */
+               for (i = 0; i < perf->perf_threads; i++) {
+                       struct pthr_ctx *pctx;
+
+                       pctx = &perf->pthr_ctx[i];
+                       atomic_set(&pctx->dma_sync, 0);
+                       pctx->perf = perf;
+                       pctx->thread =
+                               kthread_create_on_node(ntb_perf_thread,
+                                                      (void *)pctx,
+                                                      node, "ntb_perf %d", i);
+                       if (pctx->thread)
+                               wake_up_process(pctx->thread);
+                       else {
+                               perf->run = false;
+                               for (i = 0; i < MAX_THREADS; i++) {
+                                       if (pctx->thread) {
+                                               kthread_stop(pctx->thread);
+                                               pctx->thread = NULL;
+                                       }
+                               }
+                       }
+
+                       if (perf->run == false)
+                               return -ENXIO;
+               }
+
+       }
+
+       return count;
+}
+
+static const struct file_operations ntb_perf_debugfs_run = {
+       .owner = THIS_MODULE,
+       .open = simple_open,
+       .read = debugfs_run_read,
+       .write = debugfs_run_write,
+};
+
+static int perf_debugfs_setup(struct perf_ctx *perf)
+{
+       struct pci_dev *pdev = perf->ntb->pdev;
+
+       if (!debugfs_initialized())
+               return -ENODEV;
+
+       if (!perf_debugfs_dir) {
+               perf_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+               if (!perf_debugfs_dir)
+                       return -ENODEV;
+       }
+
+       perf->debugfs_node_dir = debugfs_create_dir(pci_name(pdev),
+                                                   perf_debugfs_dir);
+       if (!perf->debugfs_node_dir)
+               return -ENODEV;
+
+       perf->debugfs_run = debugfs_create_file("run", S_IRUSR | S_IWUSR,
+                                               perf->debugfs_node_dir, perf,
+                                               &ntb_perf_debugfs_run);
+       if (!perf->debugfs_run)
+               return -ENODEV;
+
+       perf->debugfs_threads = debugfs_create_u8("threads", S_IRUSR | S_IWUSR,
+                                                 perf->debugfs_node_dir,
+                                                 &perf->perf_threads);
+       if (!perf->debugfs_threads)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int perf_probe(struct ntb_client *client, struct ntb_dev *ntb)
+{
+       struct pci_dev *pdev = ntb->pdev;
+       struct perf_ctx *perf;
+       int node;
+       int rc = 0;
+
+       node = dev_to_node(&pdev->dev);
+
+       perf = kzalloc_node(sizeof(*perf), GFP_KERNEL, node);
+       if (!perf) {
+               rc = -ENOMEM;
+               goto err_perf;
+       }
+
+       perf->ntb = ntb;
+       perf->perf_threads = 1;
+       atomic_set(&perf->tsync, 0);
+       perf->run = false;
+       spin_lock_init(&perf->db_lock);
+       perf_setup_mw(ntb, perf);
+       INIT_DELAYED_WORK(&perf->link_work, perf_link_work);
+       INIT_WORK(&perf->link_cleanup, perf_link_cleanup);
+
+       rc = ntb_set_ctx(ntb, perf, &perf_ops);
+       if (rc)
+               goto err_ctx;
+
+       perf->link_is_up = false;
+       ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO);
+       ntb_link_event(ntb);
+
+       rc = perf_debugfs_setup(perf);
+       if (rc)
+               goto err_ctx;
+
+       return 0;
+
+err_ctx:
+       cancel_delayed_work_sync(&perf->link_work);
+       cancel_work_sync(&perf->link_cleanup);
+       kfree(perf);
+err_perf:
+       return rc;
+}
+
+static void perf_remove(struct ntb_client *client, struct ntb_dev *ntb)
+{
+       struct perf_ctx *perf = ntb->ctx;
+       int i;
+
+       dev_dbg(&perf->ntb->dev, "%s called\n", __func__);
+
+       cancel_delayed_work_sync(&perf->link_work);
+       cancel_work_sync(&perf->link_cleanup);
+
+       ntb_clear_ctx(ntb);
+       ntb_link_disable(ntb);
+
+       debugfs_remove_recursive(perf_debugfs_dir);
+       perf_debugfs_dir = NULL;
+
+       if (use_dma) {
+               for (i = 0; i < MAX_THREADS; i++) {
+                       struct pthr_ctx *pctx = &perf->pthr_ctx[i];
+
+                       if (pctx->dma_chan)
+                               dma_release_channel(pctx->dma_chan);
+               }
+       }
+
+       kfree(perf);
+}
+
+static struct ntb_client perf_client = {
+       .ops = {
+               .probe = perf_probe,
+               .remove = perf_remove,
+       },
+};
+module_ntb_client(perf_client);
index 002a94a..5d62373 100644 (file)
@@ -8,3 +8,14 @@ config BLK_DEV_NVME
 
          To compile this driver as a module, choose M here: the
          module will be called nvme.
+
+config BLK_DEV_NVME_SCSI
+       bool "SCSI emulation for NVMe device nodes"
+       depends on BLK_DEV_NVME
+       ---help---
+         This adds support for the SG_IO ioctl on the NVMe character
+         and block devices nodes, as well a a translation for a small
+         number of selected SCSI commands to NVMe commands to the NVMe
+         driver.  If you don't know what this means you probably want
+         to say N here, and if you know what it means you probably
+         want to say N as well.
index a5fe239..51bf908 100644 (file)
@@ -1,5 +1,6 @@
 
 obj-$(CONFIG_BLK_DEV_NVME)     += nvme.o
 
-lightnvm-$(CONFIG_NVM) := lightnvm.o
-nvme-y         += pci.o scsi.o $(lightnvm-y)
+lightnvm-$(CONFIG_NVM)                 := lightnvm.o
+nvme-y                                 += core.o pci.o $(lightnvm-y)
+nvme-$(CONFIG_BLK_DEV_NVME_SCSI)        += scsi.o
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
new file mode 100644 (file)
index 0000000..c5bf001
--- /dev/null
@@ -0,0 +1,1472 @@
+/*
+ * NVM Express device driver
+ * Copyright (c) 2011-2014, Intel Corporation.
+ *
+ * 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/blkdev.h>
+#include <linux/blk-mq.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list_sort.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pr.h>
+#include <linux/ptrace.h>
+#include <linux/nvme_ioctl.h>
+#include <linux/t10-pi.h>
+#include <scsi/sg.h>
+#include <asm/unaligned.h>
+
+#include "nvme.h"
+
+#define NVME_MINORS            (1U << MINORBITS)
+
+static int nvme_major;
+module_param(nvme_major, int, 0);
+
+static int nvme_char_major;
+module_param(nvme_char_major, int, 0);
+
+static LIST_HEAD(nvme_ctrl_list);
+DEFINE_SPINLOCK(dev_list_lock);
+
+static struct class *nvme_class;
+
+static void nvme_free_ns(struct kref *kref)
+{
+       struct nvme_ns *ns = container_of(kref, struct nvme_ns, kref);
+
+       if (ns->type == NVME_NS_LIGHTNVM)
+               nvme_nvm_unregister(ns->queue, ns->disk->disk_name);
+
+       spin_lock(&dev_list_lock);
+       ns->disk->private_data = NULL;
+       spin_unlock(&dev_list_lock);
+
+       nvme_put_ctrl(ns->ctrl);
+       put_disk(ns->disk);
+       kfree(ns);
+}
+
+static void nvme_put_ns(struct nvme_ns *ns)
+{
+       kref_put(&ns->kref, nvme_free_ns);
+}
+
+static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk)
+{
+       struct nvme_ns *ns;
+
+       spin_lock(&dev_list_lock);
+       ns = disk->private_data;
+       if (ns && !kref_get_unless_zero(&ns->kref))
+               ns = NULL;
+       spin_unlock(&dev_list_lock);
+
+       return ns;
+}
+
+void nvme_requeue_req(struct request *req)
+{
+       unsigned long flags;
+
+       blk_mq_requeue_request(req);
+       spin_lock_irqsave(req->q->queue_lock, flags);
+       if (!blk_queue_stopped(req->q))
+               blk_mq_kick_requeue_list(req->q);
+       spin_unlock_irqrestore(req->q->queue_lock, flags);
+}
+
+struct request *nvme_alloc_request(struct request_queue *q,
+               struct nvme_command *cmd, unsigned int flags)
+{
+       bool write = cmd->common.opcode & 1;
+       struct request *req;
+
+       req = blk_mq_alloc_request(q, write, flags);
+       if (IS_ERR(req))
+               return req;
+
+       req->cmd_type = REQ_TYPE_DRV_PRIV;
+       req->cmd_flags |= REQ_FAILFAST_DRIVER;
+       req->__data_len = 0;
+       req->__sector = (sector_t) -1;
+       req->bio = req->biotail = NULL;
+
+       req->cmd = (unsigned char *)cmd;
+       req->cmd_len = sizeof(struct nvme_command);
+       req->special = (void *)0;
+
+       return req;
+}
+
+/*
+ * Returns 0 on success.  If the result is negative, it's a Linux error code;
+ * if the result is positive, it's an NVM Express status code
+ */
+int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+               void *buffer, unsigned bufflen, u32 *result, unsigned timeout)
+{
+       struct request *req;
+       int ret;
+
+       req = nvme_alloc_request(q, cmd, 0);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       req->timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+       if (buffer && bufflen) {
+               ret = blk_rq_map_kern(q, req, buffer, bufflen, GFP_KERNEL);
+               if (ret)
+                       goto out;
+       }
+
+       blk_execute_rq(req->q, NULL, req, 0);
+       if (result)
+               *result = (u32)(uintptr_t)req->special;
+       ret = req->errors;
+ out:
+       blk_mq_free_request(req);
+       return ret;
+}
+
+int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+               void *buffer, unsigned bufflen)
+{
+       return __nvme_submit_sync_cmd(q, cmd, buffer, bufflen, NULL, 0);
+}
+
+int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+               void __user *ubuffer, unsigned bufflen,
+               void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
+               u32 *result, unsigned timeout)
+{
+       bool write = cmd->common.opcode & 1;
+       struct nvme_ns *ns = q->queuedata;
+       struct gendisk *disk = ns ? ns->disk : NULL;
+       struct request *req;
+       struct bio *bio = NULL;
+       void *meta = NULL;
+       int ret;
+
+       req = nvme_alloc_request(q, cmd, 0);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       req->timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+       if (ubuffer && bufflen) {
+               ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
+                               GFP_KERNEL);
+               if (ret)
+                       goto out;
+               bio = req->bio;
+
+               if (!disk)
+                       goto submit;
+               bio->bi_bdev = bdget_disk(disk, 0);
+               if (!bio->bi_bdev) {
+                       ret = -ENODEV;
+                       goto out_unmap;
+               }
+
+               if (meta_buffer) {
+                       struct bio_integrity_payload *bip;
+
+                       meta = kmalloc(meta_len, GFP_KERNEL);
+                       if (!meta) {
+                               ret = -ENOMEM;
+                               goto out_unmap;
+                       }
+
+                       if (write) {
+                               if (copy_from_user(meta, meta_buffer,
+                                               meta_len)) {
+                                       ret = -EFAULT;
+                                       goto out_free_meta;
+                               }
+                       }
+
+                       bip = bio_integrity_alloc(bio, GFP_KERNEL, 1);
+                       if (IS_ERR(bip)) {
+                               ret = PTR_ERR(bip);
+                               goto out_free_meta;
+                       }
+
+                       bip->bip_iter.bi_size = meta_len;
+                       bip->bip_iter.bi_sector = meta_seed;
+
+                       ret = bio_integrity_add_page(bio, virt_to_page(meta),
+                                       meta_len, offset_in_page(meta));
+                       if (ret != meta_len) {
+                               ret = -ENOMEM;
+                               goto out_free_meta;
+                       }
+               }
+       }
+ submit:
+       blk_execute_rq(req->q, disk, req, 0);
+       ret = req->errors;
+       if (result)
+               *result = (u32)(uintptr_t)req->special;
+       if (meta && !ret && !write) {
+               if (copy_to_user(meta_buffer, meta, meta_len))
+                       ret = -EFAULT;
+       }
+ out_free_meta:
+       kfree(meta);
+ out_unmap:
+       if (bio) {
+               if (disk && bio->bi_bdev)
+                       bdput(bio->bi_bdev);
+               blk_rq_unmap_user(bio);
+       }
+ out:
+       blk_mq_free_request(req);
+       return ret;
+}
+
+int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+               void __user *ubuffer, unsigned bufflen, u32 *result,
+               unsigned timeout)
+{
+       return __nvme_submit_user_cmd(q, cmd, ubuffer, bufflen, NULL, 0, 0,
+                       result, timeout);
+}
+
+int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id)
+{
+       struct nvme_command c = { };
+       int error;
+
+       /* gcc-4.4.4 (at least) has issues with initializers and anon unions */
+       c.identify.opcode = nvme_admin_identify;
+       c.identify.cns = cpu_to_le32(1);
+
+       *id = kmalloc(sizeof(struct nvme_id_ctrl), GFP_KERNEL);
+       if (!*id)
+               return -ENOMEM;
+
+       error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
+                       sizeof(struct nvme_id_ctrl));
+       if (error)
+               kfree(*id);
+       return error;
+}
+
+static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *ns_list)
+{
+       struct nvme_command c = { };
+
+       c.identify.opcode = nvme_admin_identify;
+       c.identify.cns = cpu_to_le32(2);
+       c.identify.nsid = cpu_to_le32(nsid);
+       return nvme_submit_sync_cmd(dev->admin_q, &c, ns_list, 0x1000);
+}
+
+int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid,
+               struct nvme_id_ns **id)
+{
+       struct nvme_command c = { };
+       int error;
+
+       /* gcc-4.4.4 (at least) has issues with initializers and anon unions */
+       c.identify.opcode = nvme_admin_identify,
+       c.identify.nsid = cpu_to_le32(nsid),
+
+       *id = kmalloc(sizeof(struct nvme_id_ns), GFP_KERNEL);
+       if (!*id)
+               return -ENOMEM;
+
+       error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
+                       sizeof(struct nvme_id_ns));
+       if (error)
+               kfree(*id);
+       return error;
+}
+
+int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid,
+                                       dma_addr_t dma_addr, u32 *result)
+{
+       struct nvme_command c;
+
+       memset(&c, 0, sizeof(c));
+       c.features.opcode = nvme_admin_get_features;
+       c.features.nsid = cpu_to_le32(nsid);
+       c.features.prp1 = cpu_to_le64(dma_addr);
+       c.features.fid = cpu_to_le32(fid);
+
+       return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0, result, 0);
+}
+
+int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
+                                       dma_addr_t dma_addr, u32 *result)
+{
+       struct nvme_command c;
+
+       memset(&c, 0, sizeof(c));
+       c.features.opcode = nvme_admin_set_features;
+       c.features.prp1 = cpu_to_le64(dma_addr);
+       c.features.fid = cpu_to_le32(fid);
+       c.features.dword11 = cpu_to_le32(dword11);
+
+       return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0, result, 0);
+}
+
+int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log)
+{
+       struct nvme_command c = { };
+       int error;
+
+       c.common.opcode = nvme_admin_get_log_page,
+       c.common.nsid = cpu_to_le32(0xFFFFFFFF),
+       c.common.cdw10[0] = cpu_to_le32(
+                       (((sizeof(struct nvme_smart_log) / 4) - 1) << 16) |
+                        NVME_LOG_SMART),
+
+       *log = kmalloc(sizeof(struct nvme_smart_log), GFP_KERNEL);
+       if (!*log)
+               return -ENOMEM;
+
+       error = nvme_submit_sync_cmd(dev->admin_q, &c, *log,
+                       sizeof(struct nvme_smart_log));
+       if (error)
+               kfree(*log);
+       return error;
+}
+
+int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count)
+{
+       u32 q_count = (*count - 1) | ((*count - 1) << 16);
+       u32 result;
+       int status, nr_io_queues;
+
+       status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, 0,
+                       &result);
+       if (status)
+               return status;
+
+       nr_io_queues = min(result & 0xffff, result >> 16) + 1;
+       *count = min(*count, nr_io_queues);
+       return 0;
+}
+
+static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+{
+       struct nvme_user_io io;
+       struct nvme_command c;
+       unsigned length, meta_len;
+       void __user *metadata;
+
+       if (copy_from_user(&io, uio, sizeof(io)))
+               return -EFAULT;
+
+       switch (io.opcode) {
+       case nvme_cmd_write:
+       case nvme_cmd_read:
+       case nvme_cmd_compare:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       length = (io.nblocks + 1) << ns->lba_shift;
+       meta_len = (io.nblocks + 1) * ns->ms;
+       metadata = (void __user *)(uintptr_t)io.metadata;
+
+       if (ns->ext) {
+               length += meta_len;
+               meta_len = 0;
+       } else if (meta_len) {
+               if ((io.metadata & 3) || !io.metadata)
+                       return -EINVAL;
+       }
+
+       memset(&c, 0, sizeof(c));
+       c.rw.opcode = io.opcode;
+       c.rw.flags = io.flags;
+       c.rw.nsid = cpu_to_le32(ns->ns_id);
+       c.rw.slba = cpu_to_le64(io.slba);
+       c.rw.length = cpu_to_le16(io.nblocks);
+       c.rw.control = cpu_to_le16(io.control);
+       c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
+       c.rw.reftag = cpu_to_le32(io.reftag);
+       c.rw.apptag = cpu_to_le16(io.apptag);
+       c.rw.appmask = cpu_to_le16(io.appmask);
+
+       return __nvme_submit_user_cmd(ns->queue, &c,
+                       (void __user *)(uintptr_t)io.addr, length,
+                       metadata, meta_len, io.slba, NULL, 0);
+}
+
+static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+                       struct nvme_passthru_cmd __user *ucmd)
+{
+       struct nvme_passthru_cmd cmd;
+       struct nvme_command c;
+       unsigned timeout = 0;
+       int status;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
+               return -EFAULT;
+
+       memset(&c, 0, sizeof(c));
+       c.common.opcode = cmd.opcode;
+       c.common.flags = cmd.flags;
+       c.common.nsid = cpu_to_le32(cmd.nsid);
+       c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
+       c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
+       c.common.cdw10[0] = cpu_to_le32(cmd.cdw10);
+       c.common.cdw10[1] = cpu_to_le32(cmd.cdw11);
+       c.common.cdw10[2] = cpu_to_le32(cmd.cdw12);
+       c.common.cdw10[3] = cpu_to_le32(cmd.cdw13);
+       c.common.cdw10[4] = cpu_to_le32(cmd.cdw14);
+       c.common.cdw10[5] = cpu_to_le32(cmd.cdw15);
+
+       if (cmd.timeout_ms)
+               timeout = msecs_to_jiffies(cmd.timeout_ms);
+
+       status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+                       (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+                       &cmd.result, timeout);
+       if (status >= 0) {
+               if (put_user(cmd.result, &ucmd->result))
+                       return -EFAULT;
+       }
+
+       return status;
+}
+
+static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
+               unsigned int cmd, unsigned long arg)
+{
+       struct nvme_ns *ns = bdev->bd_disk->private_data;
+
+       switch (cmd) {
+       case NVME_IOCTL_ID:
+               force_successful_syscall_return();
+               return ns->ns_id;
+       case NVME_IOCTL_ADMIN_CMD:
+               return nvme_user_cmd(ns->ctrl, NULL, (void __user *)arg);
+       case NVME_IOCTL_IO_CMD:
+               return nvme_user_cmd(ns->ctrl, ns, (void __user *)arg);
+       case NVME_IOCTL_SUBMIT_IO:
+               return nvme_submit_io(ns, (void __user *)arg);
+#ifdef CONFIG_BLK_DEV_NVME_SCSI
+       case SG_GET_VERSION_NUM:
+               return nvme_sg_get_version_num((void __user *)arg);
+       case SG_IO:
+               return nvme_sg_io(ns, (void __user *)arg);
+#endif
+       default:
+               return -ENOTTY;
+       }
+}
+
+#ifdef CONFIG_COMPAT
+static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode,
+                       unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case SG_IO:
+               return -ENOIOCTLCMD;
+       }
+       return nvme_ioctl(bdev, mode, cmd, arg);
+}
+#else
+#define nvme_compat_ioctl      NULL
+#endif
+
+static int nvme_open(struct block_device *bdev, fmode_t mode)
+{
+       return nvme_get_ns_from_disk(bdev->bd_disk) ? 0 : -ENXIO;
+}
+
+static void nvme_release(struct gendisk *disk, fmode_t mode)
+{
+       nvme_put_ns(disk->private_data);
+}
+
+static int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+       /* some standard values */
+       geo->heads = 1 << 6;
+       geo->sectors = 1 << 5;
+       geo->cylinders = get_capacity(bdev->bd_disk) >> 11;
+       return 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+static void nvme_init_integrity(struct nvme_ns *ns)
+{
+       struct blk_integrity integrity;
+
+       switch (ns->pi_type) {
+       case NVME_NS_DPS_PI_TYPE3:
+               integrity.profile = &t10_pi_type3_crc;
+               break;
+       case NVME_NS_DPS_PI_TYPE1:
+       case NVME_NS_DPS_PI_TYPE2:
+               integrity.profile = &t10_pi_type1_crc;
+               break;
+       default:
+               integrity.profile = NULL;
+               break;
+       }
+       integrity.tuple_size = ns->ms;
+       blk_integrity_register(ns->disk, &integrity);
+       blk_queue_max_integrity_segments(ns->queue, 1);
+}
+#else
+static void nvme_init_integrity(struct nvme_ns *ns)
+{
+}
+#endif /* CONFIG_BLK_DEV_INTEGRITY */
+
+static void nvme_config_discard(struct nvme_ns *ns)
+{
+       u32 logical_block_size = queue_logical_block_size(ns->queue);
+       ns->queue->limits.discard_zeroes_data = 0;
+       ns->queue->limits.discard_alignment = logical_block_size;
+       ns->queue->limits.discard_granularity = logical_block_size;
+       blk_queue_max_discard_sectors(ns->queue, 0xffffffff);
+       queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue);
+}
+
+static int nvme_revalidate_disk(struct gendisk *disk)
+{
+       struct nvme_ns *ns = disk->private_data;
+       struct nvme_id_ns *id;
+       u8 lbaf, pi_type;
+       u16 old_ms;
+       unsigned short bs;
+
+       if (nvme_identify_ns(ns->ctrl, ns->ns_id, &id)) {
+               dev_warn(ns->ctrl->dev, "%s: Identify failure nvme%dn%d\n",
+                               __func__, ns->ctrl->instance, ns->ns_id);
+               return -ENODEV;
+       }
+       if (id->ncap == 0) {
+               kfree(id);
+               return -ENODEV;
+       }
+
+       if (nvme_nvm_ns_supported(ns, id) && ns->type != NVME_NS_LIGHTNVM) {
+               if (nvme_nvm_register(ns->queue, disk->disk_name)) {
+                       dev_warn(ns->ctrl->dev,
+                               "%s: LightNVM init failure\n", __func__);
+                       kfree(id);
+                       return -ENODEV;
+               }
+               ns->type = NVME_NS_LIGHTNVM;
+       }
+
+       if (ns->ctrl->vs >= NVME_VS(1, 1))
+               memcpy(ns->eui, id->eui64, sizeof(ns->eui));
+       if (ns->ctrl->vs >= NVME_VS(1, 2))
+               memcpy(ns->uuid, id->nguid, sizeof(ns->uuid));
+
+       old_ms = ns->ms;
+       lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK;
+       ns->lba_shift = id->lbaf[lbaf].ds;
+       ns->ms = le16_to_cpu(id->lbaf[lbaf].ms);
+       ns->ext = ns->ms && (id->flbas & NVME_NS_FLBAS_META_EXT);
+
+       /*
+        * If identify namespace failed, use default 512 byte block size so
+        * block layer can use before failing read/write for 0 capacity.
+        */
+       if (ns->lba_shift == 0)
+               ns->lba_shift = 9;
+       bs = 1 << ns->lba_shift;
+       /* XXX: PI implementation requires metadata equal t10 pi tuple size */
+       pi_type = ns->ms == sizeof(struct t10_pi_tuple) ?
+                                       id->dps & NVME_NS_DPS_PI_MASK : 0;
+
+       blk_mq_freeze_queue(disk->queue);
+       if (blk_get_integrity(disk) && (ns->pi_type != pi_type ||
+                               ns->ms != old_ms ||
+                               bs != queue_logical_block_size(disk->queue) ||
+                               (ns->ms && ns->ext)))
+               blk_integrity_unregister(disk);
+
+       ns->pi_type = pi_type;
+       blk_queue_logical_block_size(ns->queue, bs);
+
+       if (ns->ms && !blk_get_integrity(disk) && !ns->ext)
+               nvme_init_integrity(ns);
+       if (ns->ms && !(ns->ms == 8 && ns->pi_type) && !blk_get_integrity(disk))
+               set_capacity(disk, 0);
+       else
+               set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9));
+
+       if (ns->ctrl->oncs & NVME_CTRL_ONCS_DSM)
+               nvme_config_discard(ns);
+       blk_mq_unfreeze_queue(disk->queue);
+
+       kfree(id);
+       return 0;
+}
+
+static char nvme_pr_type(enum pr_type type)
+{
+       switch (type) {
+       case PR_WRITE_EXCLUSIVE:
+               return 1;
+       case PR_EXCLUSIVE_ACCESS:
+               return 2;
+       case PR_WRITE_EXCLUSIVE_REG_ONLY:
+               return 3;
+       case PR_EXCLUSIVE_ACCESS_REG_ONLY:
+               return 4;
+       case PR_WRITE_EXCLUSIVE_ALL_REGS:
+               return 5;
+       case PR_EXCLUSIVE_ACCESS_ALL_REGS:
+               return 6;
+       default:
+               return 0;
+       }
+};
+
+static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
+                               u64 key, u64 sa_key, u8 op)
+{
+       struct nvme_ns *ns = bdev->bd_disk->private_data;
+       struct nvme_command c;
+       u8 data[16] = { 0, };
+
+       put_unaligned_le64(key, &data[0]);
+       put_unaligned_le64(sa_key, &data[8]);
+
+       memset(&c, 0, sizeof(c));
+       c.common.opcode = op;
+       c.common.nsid = cpu_to_le32(ns->ns_id);
+       c.common.cdw10[0] = cpu_to_le32(cdw10);
+
+       return nvme_submit_sync_cmd(ns->queue, &c, data, 16);
+}
+
+static int nvme_pr_register(struct block_device *bdev, u64 old,
+               u64 new, unsigned flags)
+{
+       u32 cdw10;
+
+       if (flags & ~PR_FL_IGNORE_KEY)
+               return -EOPNOTSUPP;
+
+       cdw10 = old ? 2 : 0;
+       cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0;
+       cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */
+       return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register);
+}
+
+static int nvme_pr_reserve(struct block_device *bdev, u64 key,
+               enum pr_type type, unsigned flags)
+{
+       u32 cdw10;
+
+       if (flags & ~PR_FL_IGNORE_KEY)
+               return -EOPNOTSUPP;
+
+       cdw10 = nvme_pr_type(type) << 8;
+       cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0);
+       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire);
+}
+
+static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
+               enum pr_type type, bool abort)
+{
+       u32 cdw10 = nvme_pr_type(type) << 8 | abort ? 2 : 1;
+       return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire);
+}
+
+static int nvme_pr_clear(struct block_device *bdev, u64 key)
+{
+       u32 cdw10 = 1 | (key ? 1 << 3 : 0);
+       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
+}
+
+static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
+{
+       u32 cdw10 = nvme_pr_type(type) << 8 | key ? 1 << 3 : 0;
+       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+}
+
+static const struct pr_ops nvme_pr_ops = {
+       .pr_register    = nvme_pr_register,
+       .pr_reserve     = nvme_pr_reserve,
+       .pr_release     = nvme_pr_release,
+       .pr_preempt     = nvme_pr_preempt,
+       .pr_clear       = nvme_pr_clear,
+};
+
+static const struct block_device_operations nvme_fops = {
+       .owner          = THIS_MODULE,
+       .ioctl          = nvme_ioctl,
+       .compat_ioctl   = nvme_compat_ioctl,
+       .open           = nvme_open,
+       .release        = nvme_release,
+       .getgeo         = nvme_getgeo,
+       .revalidate_disk= nvme_revalidate_disk,
+       .pr_ops         = &nvme_pr_ops,
+};
+
+static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
+{
+       unsigned long timeout =
+               ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
+       u32 csts, bit = enabled ? NVME_CSTS_RDY : 0;
+       int ret;
+
+       while ((ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) == 0) {
+               if ((csts & NVME_CSTS_RDY) == bit)
+                       break;
+
+               msleep(100);
+               if (fatal_signal_pending(current))
+                       return -EINTR;
+               if (time_after(jiffies, timeout)) {
+                       dev_err(ctrl->dev,
+                               "Device not ready; aborting %s\n", enabled ?
+                                               "initialisation" : "reset");
+                       return -ENODEV;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * If the device has been passed off to us in an enabled state, just clear
+ * the enabled bit.  The spec says we should set the 'shutdown notification
+ * bits', but doing so may cause the device to complete commands to the
+ * admin queue ... and we don't know what memory that might be pointing at!
+ */
+int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
+{
+       int ret;
+
+       ctrl->ctrl_config &= ~NVME_CC_SHN_MASK;
+       ctrl->ctrl_config &= ~NVME_CC_ENABLE;
+
+       ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
+       if (ret)
+               return ret;
+       return nvme_wait_ready(ctrl, cap, false);
+}
+
+int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
+{
+       /*
+        * Default to a 4K page size, with the intention to update this
+        * path in the future to accomodate architectures with differing
+        * kernel and IO page sizes.
+        */
+       unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12, page_shift = 12;
+       int ret;
+
+       if (page_shift < dev_page_min) {
+               dev_err(ctrl->dev,
+                       "Minimum device page size %u too large for host (%u)\n",
+                       1 << dev_page_min, 1 << page_shift);
+               return -ENODEV;
+       }
+
+       ctrl->page_size = 1 << page_shift;
+
+       ctrl->ctrl_config = NVME_CC_CSS_NVM;
+       ctrl->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT;
+       ctrl->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE;
+       ctrl->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
+       ctrl->ctrl_config |= NVME_CC_ENABLE;
+
+       ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
+       if (ret)
+               return ret;
+       return nvme_wait_ready(ctrl, cap, true);
+}
+
+int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl)
+{
+       unsigned long timeout = SHUTDOWN_TIMEOUT + jiffies;
+       u32 csts;
+       int ret;
+
+       ctrl->ctrl_config &= ~NVME_CC_SHN_MASK;
+       ctrl->ctrl_config |= NVME_CC_SHN_NORMAL;
+
+       ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
+       if (ret)
+               return ret;
+
+       while ((ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) == 0) {
+               if ((csts & NVME_CSTS_SHST_MASK) == NVME_CSTS_SHST_CMPLT)
+                       break;
+
+               msleep(100);
+               if (fatal_signal_pending(current))
+                       return -EINTR;
+               if (time_after(jiffies, timeout)) {
+                       dev_err(ctrl->dev,
+                               "Device shutdown incomplete; abort shutdown\n");
+                       return -ENODEV;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Initialize the cached copies of the Identify data and various controller
+ * register in our nvme_ctrl structure.  This should be called as soon as
+ * the admin queue is fully up and running.
+ */
+int nvme_init_identify(struct nvme_ctrl *ctrl)
+{
+       struct nvme_id_ctrl *id;
+       u64 cap;
+       int ret, page_shift;
+
+       ret = ctrl->ops->reg_read32(ctrl, NVME_REG_VS, &ctrl->vs);
+       if (ret) {
+               dev_err(ctrl->dev, "Reading VS failed (%d)\n", ret);
+               return ret;
+       }
+
+       ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &cap);
+       if (ret) {
+               dev_err(ctrl->dev, "Reading CAP failed (%d)\n", ret);
+               return ret;
+       }
+       page_shift = NVME_CAP_MPSMIN(cap) + 12;
+
+       if (ctrl->vs >= NVME_VS(1, 1))
+               ctrl->subsystem = NVME_CAP_NSSRC(cap);
+
+       ret = nvme_identify_ctrl(ctrl, &id);
+       if (ret) {
+               dev_err(ctrl->dev, "Identify Controller failed (%d)\n", ret);
+               return -EIO;
+       }
+
+       ctrl->oncs = le16_to_cpup(&id->oncs);
+       atomic_set(&ctrl->abort_limit, id->acl + 1);
+       ctrl->vwc = id->vwc;
+       memcpy(ctrl->serial, id->sn, sizeof(id->sn));
+       memcpy(ctrl->model, id->mn, sizeof(id->mn));
+       memcpy(ctrl->firmware_rev, id->fr, sizeof(id->fr));
+       if (id->mdts)
+               ctrl->max_hw_sectors = 1 << (id->mdts + page_shift - 9);
+       else
+               ctrl->max_hw_sectors = UINT_MAX;
+
+       if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && id->vs[3]) {
+               unsigned int max_hw_sectors;
+
+               ctrl->stripe_size = 1 << (id->vs[3] + page_shift);
+               max_hw_sectors = ctrl->stripe_size >> (page_shift - 9);
+               if (ctrl->max_hw_sectors) {
+                       ctrl->max_hw_sectors = min(max_hw_sectors,
+                                                       ctrl->max_hw_sectors);
+               } else {
+                       ctrl->max_hw_sectors = max_hw_sectors;
+               }
+       }
+
+       kfree(id);
+       return 0;
+}
+
+static int nvme_dev_open(struct inode *inode, struct file *file)
+{
+       struct nvme_ctrl *ctrl;
+       int instance = iminor(inode);
+       int ret = -ENODEV;
+
+       spin_lock(&dev_list_lock);
+       list_for_each_entry(ctrl, &nvme_ctrl_list, node) {
+               if (ctrl->instance != instance)
+                       continue;
+
+               if (!ctrl->admin_q) {
+                       ret = -EWOULDBLOCK;
+                       break;
+               }
+               if (!kref_get_unless_zero(&ctrl->kref))
+                       break;
+               file->private_data = ctrl;
+               ret = 0;
+               break;
+       }
+       spin_unlock(&dev_list_lock);
+
+       return ret;
+}
+
+static int nvme_dev_release(struct inode *inode, struct file *file)
+{
+       nvme_put_ctrl(file->private_data);
+       return 0;
+}
+
+static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
+{
+       struct nvme_ns *ns;
+       int ret;
+
+       mutex_lock(&ctrl->namespaces_mutex);
+       if (list_empty(&ctrl->namespaces)) {
+               ret = -ENOTTY;
+               goto out_unlock;
+       }
+
+       ns = list_first_entry(&ctrl->namespaces, struct nvme_ns, list);
+       if (ns != list_last_entry(&ctrl->namespaces, struct nvme_ns, list)) {
+               dev_warn(ctrl->dev,
+                       "NVME_IOCTL_IO_CMD not supported when multiple namespaces present!\n");
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
+       dev_warn(ctrl->dev,
+               "using deprecated NVME_IOCTL_IO_CMD ioctl on the char device!\n");
+       kref_get(&ns->kref);
+       mutex_unlock(&ctrl->namespaces_mutex);
+
+       ret = nvme_user_cmd(ctrl, ns, argp);
+       nvme_put_ns(ns);
+       return ret;
+
+out_unlock:
+       mutex_unlock(&ctrl->namespaces_mutex);
+       return ret;
+}
+
+static long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+               unsigned long arg)
+{
+       struct nvme_ctrl *ctrl = file->private_data;
+       void __user *argp = (void __user *)arg;
+
+       switch (cmd) {
+       case NVME_IOCTL_ADMIN_CMD:
+               return nvme_user_cmd(ctrl, NULL, argp);
+       case NVME_IOCTL_IO_CMD:
+               return nvme_dev_user_cmd(ctrl, argp);
+       case NVME_IOCTL_RESET:
+               dev_warn(ctrl->dev, "resetting controller\n");
+               return ctrl->ops->reset_ctrl(ctrl);
+       case NVME_IOCTL_SUBSYS_RESET:
+               return nvme_reset_subsystem(ctrl);
+       default:
+               return -ENOTTY;
+       }
+}
+
+static const struct file_operations nvme_dev_fops = {
+       .owner          = THIS_MODULE,
+       .open           = nvme_dev_open,
+       .release        = nvme_dev_release,
+       .unlocked_ioctl = nvme_dev_ioctl,
+       .compat_ioctl   = nvme_dev_ioctl,
+};
+
+static ssize_t nvme_sysfs_reset(struct device *dev,
+                               struct device_attribute *attr, const char *buf,
+                               size_t count)
+{
+       struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+       int ret;
+
+       ret = ctrl->ops->reset_ctrl(ctrl);
+       if (ret < 0)
+               return ret;
+       return count;
+}
+static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
+
+static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
+                                                               char *buf)
+{
+       struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+       return sprintf(buf, "%pU\n", ns->uuid);
+}
+static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL);
+
+static ssize_t eui_show(struct device *dev, struct device_attribute *attr,
+                                                               char *buf)
+{
+       struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+       return sprintf(buf, "%8phd\n", ns->eui);
+}
+static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL);
+
+static ssize_t nsid_show(struct device *dev, struct device_attribute *attr,
+                                                               char *buf)
+{
+       struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+       return sprintf(buf, "%d\n", ns->ns_id);
+}
+static DEVICE_ATTR(nsid, S_IRUGO, nsid_show, NULL);
+
+static struct attribute *nvme_ns_attrs[] = {
+       &dev_attr_uuid.attr,
+       &dev_attr_eui.attr,
+       &dev_attr_nsid.attr,
+       NULL,
+};
+
+static umode_t nvme_attrs_are_visible(struct kobject *kobj,
+               struct attribute *a, int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+
+       if (a == &dev_attr_uuid.attr) {
+               if (!memchr_inv(ns->uuid, 0, sizeof(ns->uuid)))
+                       return 0;
+       }
+       if (a == &dev_attr_eui.attr) {
+               if (!memchr_inv(ns->eui, 0, sizeof(ns->eui)))
+                       return 0;
+       }
+       return a->mode;
+}
+
+static const struct attribute_group nvme_ns_attr_group = {
+       .attrs          = nvme_ns_attrs,
+       .is_visible     = nvme_attrs_are_visible,
+};
+
+#define nvme_show_function(field)                                              \
+static ssize_t  field##_show(struct device *dev,                               \
+                           struct device_attribute *attr, char *buf)           \
+{                                                                              \
+        struct nvme_ctrl *ctrl = dev_get_drvdata(dev);                         \
+        return sprintf(buf, "%.*s\n", (int)sizeof(ctrl->field), ctrl->field);  \
+}                                                                              \
+static DEVICE_ATTR(field, S_IRUGO, field##_show, NULL);
+
+nvme_show_function(model);
+nvme_show_function(serial);
+nvme_show_function(firmware_rev);
+
+static struct attribute *nvme_dev_attrs[] = {
+       &dev_attr_reset_controller.attr,
+       &dev_attr_model.attr,
+       &dev_attr_serial.attr,
+       &dev_attr_firmware_rev.attr,
+       NULL
+};
+
+static struct attribute_group nvme_dev_attrs_group = {
+       .attrs = nvme_dev_attrs,
+};
+
+static const struct attribute_group *nvme_dev_attr_groups[] = {
+       &nvme_dev_attrs_group,
+       NULL,
+};
+
+static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+       struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
+       struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
+
+       return nsa->ns_id - nsb->ns_id;
+}
+
+static struct nvme_ns *nvme_find_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+{
+       struct nvme_ns *ns;
+
+       lockdep_assert_held(&ctrl->namespaces_mutex);
+
+       list_for_each_entry(ns, &ctrl->namespaces, list) {
+               if (ns->ns_id == nsid)
+                       return ns;
+               if (ns->ns_id > nsid)
+                       break;
+       }
+       return NULL;
+}
+
+static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+{
+       struct nvme_ns *ns;
+       struct gendisk *disk;
+       int node = dev_to_node(ctrl->dev);
+
+       lockdep_assert_held(&ctrl->namespaces_mutex);
+
+       ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
+       if (!ns)
+               return;
+
+       ns->queue = blk_mq_init_queue(ctrl->tagset);
+       if (IS_ERR(ns->queue))
+               goto out_free_ns;
+       queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue);
+       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue);
+       ns->queue->queuedata = ns;
+       ns->ctrl = ctrl;
+
+       disk = alloc_disk_node(0, node);
+       if (!disk)
+               goto out_free_queue;
+
+       kref_init(&ns->kref);
+       ns->ns_id = nsid;
+       ns->disk = disk;
+       ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */
+
+       blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
+       if (ctrl->max_hw_sectors) {
+               blk_queue_max_hw_sectors(ns->queue, ctrl->max_hw_sectors);
+               blk_queue_max_segments(ns->queue,
+                       (ctrl->max_hw_sectors / (ctrl->page_size >> 9)) + 1);
+       }
+       if (ctrl->stripe_size)
+               blk_queue_chunk_sectors(ns->queue, ctrl->stripe_size >> 9);
+       if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
+               blk_queue_flush(ns->queue, REQ_FLUSH | REQ_FUA);
+       blk_queue_virt_boundary(ns->queue, ctrl->page_size - 1);
+
+       disk->major = nvme_major;
+       disk->first_minor = 0;
+       disk->fops = &nvme_fops;
+       disk->private_data = ns;
+       disk->queue = ns->queue;
+       disk->driverfs_dev = ctrl->device;
+       disk->flags = GENHD_FL_EXT_DEVT;
+       sprintf(disk->disk_name, "nvme%dn%d", ctrl->instance, nsid);
+
+       if (nvme_revalidate_disk(ns->disk))
+               goto out_free_disk;
+
+       list_add_tail(&ns->list, &ctrl->namespaces);
+       kref_get(&ctrl->kref);
+       if (ns->type == NVME_NS_LIGHTNVM)
+               return;
+
+       add_disk(ns->disk);
+       if (sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
+                                       &nvme_ns_attr_group))
+               pr_warn("%s: failed to create sysfs group for identification\n",
+                       ns->disk->disk_name);
+       return;
+ out_free_disk:
+       kfree(disk);
+ out_free_queue:
+       blk_cleanup_queue(ns->queue);
+ out_free_ns:
+       kfree(ns);
+}
+
+static void nvme_ns_remove(struct nvme_ns *ns)
+{
+       bool kill = nvme_io_incapable(ns->ctrl) &&
+                       !blk_queue_dying(ns->queue);
+
+       lockdep_assert_held(&ns->ctrl->namespaces_mutex);
+
+       if (kill) {
+               blk_set_queue_dying(ns->queue);
+
+               /*
+                * The controller was shutdown first if we got here through
+                * device removal. The shutdown may requeue outstanding
+                * requests. These need to be aborted immediately so
+                * del_gendisk doesn't block indefinitely for their completion.
+                */
+               blk_mq_abort_requeue_list(ns->queue);
+       }
+       if (ns->disk->flags & GENHD_FL_UP) {
+               if (blk_get_integrity(ns->disk))
+                       blk_integrity_unregister(ns->disk);
+               sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
+                                       &nvme_ns_attr_group);
+               del_gendisk(ns->disk);
+       }
+       if (kill || !blk_queue_dying(ns->queue)) {
+               blk_mq_abort_requeue_list(ns->queue);
+               blk_cleanup_queue(ns->queue);
+       }
+       list_del_init(&ns->list);
+       nvme_put_ns(ns);
+}
+
+static void nvme_validate_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+{
+       struct nvme_ns *ns;
+
+       ns = nvme_find_ns(ctrl, nsid);
+       if (ns) {
+               if (revalidate_disk(ns->disk))
+                       nvme_ns_remove(ns);
+       } else
+               nvme_alloc_ns(ctrl, nsid);
+}
+
+static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
+{
+       struct nvme_ns *ns;
+       __le32 *ns_list;
+       unsigned i, j, nsid, prev = 0, num_lists = DIV_ROUND_UP(nn, 1024);
+       int ret = 0;
+
+       ns_list = kzalloc(0x1000, GFP_KERNEL);
+       if (!ns_list)
+               return -ENOMEM;
+
+       for (i = 0; i < num_lists; i++) {
+               ret = nvme_identify_ns_list(ctrl, prev, ns_list);
+               if (ret)
+                       goto out;
+
+               for (j = 0; j < min(nn, 1024U); j++) {
+                       nsid = le32_to_cpu(ns_list[j]);
+                       if (!nsid)
+                               goto out;
+
+                       nvme_validate_ns(ctrl, nsid);
+
+                       while (++prev < nsid) {
+                               ns = nvme_find_ns(ctrl, prev);
+                               if (ns)
+                                       nvme_ns_remove(ns);
+                       }
+               }
+               nn -= j;
+       }
+ out:
+       kfree(ns_list);
+       return ret;
+}
+
+static void __nvme_scan_namespaces(struct nvme_ctrl *ctrl, unsigned nn)
+{
+       struct nvme_ns *ns, *next;
+       unsigned i;
+
+       lockdep_assert_held(&ctrl->namespaces_mutex);
+
+       for (i = 1; i <= nn; i++)
+               nvme_validate_ns(ctrl, i);
+
+       list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
+               if (ns->ns_id > nn)
+                       nvme_ns_remove(ns);
+       }
+}
+
+void nvme_scan_namespaces(struct nvme_ctrl *ctrl)
+{
+       struct nvme_id_ctrl *id;
+       unsigned nn;
+
+       if (nvme_identify_ctrl(ctrl, &id))
+               return;
+
+       mutex_lock(&ctrl->namespaces_mutex);
+       nn = le32_to_cpu(id->nn);
+       if (ctrl->vs >= NVME_VS(1, 1) &&
+           !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)) {
+               if (!nvme_scan_ns_list(ctrl, nn))
+                       goto done;
+       }
+       __nvme_scan_namespaces(ctrl, le32_to_cpup(&id->nn));
+ done:
+       list_sort(NULL, &ctrl->namespaces, ns_cmp);
+       mutex_unlock(&ctrl->namespaces_mutex);
+       kfree(id);
+}
+
+void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
+{
+       struct nvme_ns *ns, *next;
+
+       mutex_lock(&ctrl->namespaces_mutex);
+       list_for_each_entry_safe(ns, next, &ctrl->namespaces, list)
+               nvme_ns_remove(ns);
+       mutex_unlock(&ctrl->namespaces_mutex);
+}
+
+static DEFINE_IDA(nvme_instance_ida);
+
+static int nvme_set_instance(struct nvme_ctrl *ctrl)
+{
+       int instance, error;
+
+       do {
+               if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
+                       return -ENODEV;
+
+               spin_lock(&dev_list_lock);
+               error = ida_get_new(&nvme_instance_ida, &instance);
+               spin_unlock(&dev_list_lock);
+       } while (error == -EAGAIN);
+
+       if (error)
+               return -ENODEV;
+
+       ctrl->instance = instance;
+       return 0;
+}
+
+static void nvme_release_instance(struct nvme_ctrl *ctrl)
+{
+       spin_lock(&dev_list_lock);
+       ida_remove(&nvme_instance_ida, ctrl->instance);
+       spin_unlock(&dev_list_lock);
+}
+
+void nvme_uninit_ctrl(struct nvme_ctrl *ctrl)
+ {
+       device_destroy(nvme_class, MKDEV(nvme_char_major, ctrl->instance));
+
+       spin_lock(&dev_list_lock);
+       list_del(&ctrl->node);
+       spin_unlock(&dev_list_lock);
+}
+
+static void nvme_free_ctrl(struct kref *kref)
+{
+       struct nvme_ctrl *ctrl = container_of(kref, struct nvme_ctrl, kref);
+
+       put_device(ctrl->device);
+       nvme_release_instance(ctrl);
+
+       ctrl->ops->free_ctrl(ctrl);
+}
+
+void nvme_put_ctrl(struct nvme_ctrl *ctrl)
+{
+       kref_put(&ctrl->kref, nvme_free_ctrl);
+}
+
+/*
+ * Initialize a NVMe controller structures.  This needs to be called during
+ * earliest initialization so that we have the initialized structured around
+ * during probing.
+ */
+int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
+               const struct nvme_ctrl_ops *ops, unsigned long quirks)
+{
+       int ret;
+
+       INIT_LIST_HEAD(&ctrl->namespaces);
+       mutex_init(&ctrl->namespaces_mutex);
+       kref_init(&ctrl->kref);
+       ctrl->dev = dev;
+       ctrl->ops = ops;
+       ctrl->quirks = quirks;
+
+       ret = nvme_set_instance(ctrl);
+       if (ret)
+               goto out;
+
+       ctrl->device = device_create_with_groups(nvme_class, ctrl->dev,
+                               MKDEV(nvme_char_major, ctrl->instance),
+                               dev, nvme_dev_attr_groups,
+                               "nvme%d", ctrl->instance);
+       if (IS_ERR(ctrl->device)) {
+               ret = PTR_ERR(ctrl->device);
+               goto out_release_instance;
+       }
+       get_device(ctrl->device);
+       dev_set_drvdata(ctrl->device, ctrl);
+
+       spin_lock(&dev_list_lock);
+       list_add_tail(&ctrl->node, &nvme_ctrl_list);
+       spin_unlock(&dev_list_lock);
+
+       return 0;
+out_release_instance:
+       nvme_release_instance(ctrl);
+out:
+       return ret;
+}
+
+void nvme_stop_queues(struct nvme_ctrl *ctrl)
+{
+       struct nvme_ns *ns;
+
+       mutex_lock(&ctrl->namespaces_mutex);
+       list_for_each_entry(ns, &ctrl->namespaces, list) {
+               spin_lock_irq(ns->queue->queue_lock);
+               queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue);
+               spin_unlock_irq(ns->queue->queue_lock);
+
+               blk_mq_cancel_requeue_work(ns->queue);
+               blk_mq_stop_hw_queues(ns->queue);
+       }
+       mutex_unlock(&ctrl->namespaces_mutex);
+}
+
+void nvme_start_queues(struct nvme_ctrl *ctrl)
+{
+       struct nvme_ns *ns;
+
+       mutex_lock(&ctrl->namespaces_mutex);
+       list_for_each_entry(ns, &ctrl->namespaces, list) {
+               queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue);
+               blk_mq_start_stopped_hw_queues(ns->queue, true);
+               blk_mq_kick_requeue_list(ns->queue);
+       }
+       mutex_unlock(&ctrl->namespaces_mutex);
+}
+
+int __init nvme_core_init(void)
+{
+       int result;
+
+       result = register_blkdev(nvme_major, "nvme");
+       if (result < 0)
+               return result;
+       else if (result > 0)
+               nvme_major = result;
+
+       result = __register_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme",
+                                                       &nvme_dev_fops);
+       if (result < 0)
+               goto unregister_blkdev;
+       else if (result > 0)
+               nvme_char_major = result;
+
+       nvme_class = class_create(THIS_MODULE, "nvme");
+       if (IS_ERR(nvme_class)) {
+               result = PTR_ERR(nvme_class);
+               goto unregister_chrdev;
+       }
+
+       return 0;
+
+ unregister_chrdev:
+       __unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
+ unregister_blkdev:
+       unregister_blkdev(nvme_major, "nvme");
+       return result;
+}
+
+void nvme_core_exit(void)
+{
+       unregister_blkdev(nvme_major, "nvme");
+       class_destroy(nvme_class);
+       __unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
+}
index 1af54ea..5cd3725 100644 (file)
@@ -146,6 +146,16 @@ struct nvme_nvm_command {
        };
 };
 
+struct nvme_nvm_lp_mlc {
+       __u16                   num_pairs;
+       __u8                    pairs[886];
+};
+
+struct nvme_nvm_lp_tbl {
+       __u8                    id[8];
+       struct nvme_nvm_lp_mlc  mlc;
+};
+
 struct nvme_nvm_id_group {
        __u8                    mtype;
        __u8                    fmtype;
@@ -169,7 +179,8 @@ struct nvme_nvm_id_group {
        __le32                  mpos;
        __le32                  mccap;
        __le16                  cpar;
-       __u8                    reserved[906];
+       __u8                    reserved[10];
+       struct nvme_nvm_lp_tbl lptbl;
 } __packed;
 
 struct nvme_nvm_addr_format {
@@ -266,6 +277,15 @@ static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
                dst->mccap = le32_to_cpu(src->mccap);
 
                dst->cpar = le16_to_cpu(src->cpar);
+
+               if (dst->fmtype == NVM_ID_FMTYPE_MLC) {
+                       memcpy(dst->lptbl.id, src->lptbl.id, 8);
+                       dst->lptbl.mlc.num_pairs =
+                                       le16_to_cpu(src->lptbl.mlc.num_pairs);
+                       /* 4 bits per pair */
+                       memcpy(dst->lptbl.mlc.pairs, src->lptbl.mlc.pairs,
+                                               dst->lptbl.mlc.num_pairs >> 1);
+               }
        }
 
        return 0;
@@ -274,7 +294,6 @@ static int init_grps(struct nvm_id *nvm_id, struct nvme_nvm_id *nvme_nvm_id)
 static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
 {
        struct nvme_ns *ns = nvmdev->q->queuedata;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_id *nvme_nvm_id;
        struct nvme_nvm_command c = {};
        int ret;
@@ -287,7 +306,7 @@ static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id)
        if (!nvme_nvm_id)
                return -ENOMEM;
 
-       ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+       ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
                                nvme_nvm_id, sizeof(struct nvme_nvm_id));
        if (ret) {
                ret = -EIO;
@@ -312,9 +331,8 @@ static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
                                nvm_l2p_update_fn *update_l2p, void *priv)
 {
        struct nvme_ns *ns = nvmdev->q->queuedata;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_command c = {};
-       u32 len = queue_max_hw_sectors(dev->admin_q) << 9;
+       u32 len = queue_max_hw_sectors(ns->ctrl->admin_q) << 9;
        u32 nlb_pr_rq = len / sizeof(u64);
        u64 cmd_slba = slba;
        void *entries;
@@ -332,10 +350,10 @@ static int nvme_nvm_get_l2p_tbl(struct nvm_dev *nvmdev, u64 slba, u32 nlb,
                c.l2p.slba = cpu_to_le64(cmd_slba);
                c.l2p.nlb = cpu_to_le32(cmd_nlb);
 
-               ret = nvme_submit_sync_cmd(dev->admin_q,
+               ret = nvme_submit_sync_cmd(ns->ctrl->admin_q,
                                (struct nvme_command *)&c, entries, len);
                if (ret) {
-                       dev_err(dev->dev, "L2P table transfer failed (%d)\n",
+                       dev_err(ns->ctrl->dev, "L2P table transfer failed (%d)\n",
                                                                        ret);
                        ret = -EIO;
                        goto out;
@@ -361,7 +379,7 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
 {
        struct request_queue *q = nvmdev->q;
        struct nvme_ns *ns = q->queuedata;
-       struct nvme_dev *dev = ns->dev;
+       struct nvme_ctrl *ctrl = ns->ctrl;
        struct nvme_nvm_command c = {};
        struct nvme_nvm_bb_tbl *bb_tbl;
        int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blocks;
@@ -375,41 +393,36 @@ static int nvme_nvm_get_bb_tbl(struct nvm_dev *nvmdev, struct ppa_addr ppa,
        if (!bb_tbl)
                return -ENOMEM;
 
-       ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+       ret = nvme_submit_sync_cmd(ctrl->admin_q, (struct nvme_command *)&c,
                                                                bb_tbl, tblsz);
        if (ret) {
-               dev_err(dev->dev, "get bad block table failed (%d)\n", ret);
+               dev_err(ctrl->dev, "get bad block table failed (%d)\n", ret);
                ret = -EIO;
                goto out;
        }
 
        if (bb_tbl->tblid[0] != 'B' || bb_tbl->tblid[1] != 'B' ||
                bb_tbl->tblid[2] != 'L' || bb_tbl->tblid[3] != 'T') {
-               dev_err(dev->dev, "bbt format mismatch\n");
+               dev_err(ctrl->dev, "bbt format mismatch\n");
                ret = -EINVAL;
                goto out;
        }
 
        if (le16_to_cpu(bb_tbl->verid) != 1) {
                ret = -EINVAL;
-               dev_err(dev->dev, "bbt version not supported\n");
+               dev_err(ctrl->dev, "bbt version not supported\n");
                goto out;
        }
 
        if (le32_to_cpu(bb_tbl->tblks) != nr_blocks) {
                ret = -EINVAL;
-               dev_err(dev->dev, "bbt unsuspected blocks returned (%u!=%u)",
+               dev_err(ctrl->dev, "bbt unsuspected blocks returned (%u!=%u)",
                                        le32_to_cpu(bb_tbl->tblks), nr_blocks);
                goto out;
        }
 
        ppa = dev_to_generic_addr(nvmdev, ppa);
        ret = update_bbtbl(ppa, nr_blocks, bb_tbl->blk, priv);
-       if (ret) {
-               ret = -EINTR;
-               goto out;
-       }
-
 out:
        kfree(bb_tbl);
        return ret;
@@ -419,7 +432,6 @@ static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct nvm_rq *rqd,
                                                                int type)
 {
        struct nvme_ns *ns = nvmdev->q->queuedata;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_nvm_command c = {};
        int ret = 0;
 
@@ -429,10 +441,10 @@ static int nvme_nvm_set_bb_tbl(struct nvm_dev *nvmdev, struct nvm_rq *rqd,
        c.set_bb.nlb = cpu_to_le16(rqd->nr_pages - 1);
        c.set_bb.value = type;
 
-       ret = nvme_submit_sync_cmd(dev->admin_q, (struct nvme_command *)&c,
+       ret = nvme_submit_sync_cmd(ns->ctrl->admin_q, (struct nvme_command *)&c,
                                                                NULL, 0);
        if (ret)
-               dev_err(dev->dev, "set bad block table failed (%d)\n", ret);
+               dev_err(ns->ctrl->dev, "set bad block table failed (%d)\n", ret);
        return ret;
 }
 
@@ -453,11 +465,8 @@ static inline void nvme_nvm_rqtocmd(struct request *rq, struct nvm_rq *rqd,
 static void nvme_nvm_end_io(struct request *rq, int error)
 {
        struct nvm_rq *rqd = rq->end_io_data;
-       struct nvm_dev *dev = rqd->dev;
 
-       if (dev->mt && dev->mt->end_io(rqd, error))
-               pr_err("nvme: err status: %x result: %lx\n",
-                               rq->errors, (unsigned long)rq->special);
+       nvm_end_io(rqd, error);
 
        kfree(rq->cmd);
        blk_mq_free_request(rq);
@@ -520,9 +529,8 @@ static int nvme_nvm_erase_block(struct nvm_dev *dev, struct nvm_rq *rqd)
 static void *nvme_nvm_create_dma_pool(struct nvm_dev *nvmdev, char *name)
 {
        struct nvme_ns *ns = nvmdev->q->queuedata;
-       struct nvme_dev *dev = ns->dev;
 
-       return dma_pool_create(name, dev->dev, PAGE_SIZE, PAGE_SIZE, 0);
+       return dma_pool_create(name, ns->ctrl->dev, PAGE_SIZE, PAGE_SIZE, 0);
 }
 
 static void nvme_nvm_destroy_dma_pool(void *pool)
@@ -580,8 +588,9 @@ void nvme_nvm_unregister(struct request_queue *q, char *disk_name)
 
 int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id)
 {
-       struct nvme_dev *dev = ns->dev;
-       struct pci_dev *pdev = to_pci_dev(dev->dev);
+       struct nvme_ctrl *ctrl = ns->ctrl;
+       /* XXX: this is poking into PCI structures from generic code! */
+       struct pci_dev *pdev = to_pci_dev(ctrl->dev);
 
        /* QEMU NVMe simulator - PCI ID + Vendor specific bit */
        if (pdev->vendor == PCI_VENDOR_ID_CNEX &&
index 044253d..4fb5bb7 100644 (file)
 #include <linux/kref.h>
 #include <linux/blk-mq.h>
 
+enum {
+       /*
+        * Driver internal status code for commands that were cancelled due
+        * to timeouts or controller shutdown.  The value is negative so
+        * that it a) doesn't overlap with the unsigned hardware error codes,
+        * and b) can easily be tested for.
+        */
+       NVME_SC_CANCELLED               = -EINTR,
+};
+
 extern unsigned char nvme_io_timeout;
 #define NVME_IO_TIMEOUT        (nvme_io_timeout * HZ)
 
+extern unsigned char admin_timeout;
+#define ADMIN_TIMEOUT  (admin_timeout * HZ)
+
+extern unsigned char shutdown_timeout;
+#define SHUTDOWN_TIMEOUT       (shutdown_timeout * HZ)
+
 enum {
        NVME_NS_LBA             = 0,
        NVME_NS_LIGHTNVM        = 1,
 };
 
 /*
- * Represents an NVM Express device.  Each nvme_dev is a PCI function.
+ * List of workarounds for devices that required behavior not specified in
+ * the standard.
  */
-struct nvme_dev {
-       struct list_head node;
-       struct nvme_queue **queues;
+enum nvme_quirks {
+       /*
+        * Prefers I/O aligned to a stripe size specified in a vendor
+        * specific Identify field.
+        */
+       NVME_QUIRK_STRIPE_SIZE                  = (1 << 0),
+
+       /*
+        * The controller doesn't handle Identify value others than 0 or 1
+        * correctly.
+        */
+       NVME_QUIRK_IDENTIFY_CNS                 = (1 << 1),
+};
+
+struct nvme_ctrl {
+       const struct nvme_ctrl_ops *ops;
        struct request_queue *admin_q;
-       struct blk_mq_tag_set tagset;
-       struct blk_mq_tag_set admin_tagset;
-       u32 __iomem *dbs;
        struct device *dev;
-       struct dma_pool *prp_page_pool;
-       struct dma_pool *prp_small_pool;
+       struct kref kref;
        int instance;
-       unsigned queue_count;
-       unsigned online_queues;
-       unsigned max_qid;
-       int q_depth;
-       u32 db_stride;
-       u32 ctrl_config;
-       struct msix_entry *entry;
-       struct nvme_bar __iomem *bar;
+       struct blk_mq_tag_set *tagset;
        struct list_head namespaces;
-       struct kref kref;
-       struct device *device;
-       struct work_struct reset_work;
-       struct work_struct probe_work;
-       struct work_struct scan_work;
+       struct mutex namespaces_mutex;
+       struct device *device;  /* char device */
+       struct list_head node;
+
        char name[12];
        char serial[20];
        char model[40];
        char firmware_rev[8];
-       bool subsystem;
+
+       u32 ctrl_config;
+
+       u32 page_size;
        u32 max_hw_sectors;
        u32 stripe_size;
-       u32 page_size;
-       void __iomem *cmb;
-       dma_addr_t cmb_dma_addr;
-       u64 cmb_size;
-       u32 cmbsz;
        u16 oncs;
-       u16 abort_limit;
+       atomic_t abort_limit;
        u8 event_limit;
        u8 vwc;
+       u32 vs;
+       bool subsystem;
+       unsigned long quirks;
 };
 
 /*
@@ -79,11 +98,14 @@ struct nvme_dev {
 struct nvme_ns {
        struct list_head list;
 
-       struct nvme_dev *dev;
+       struct nvme_ctrl *ctrl;
        struct request_queue *queue;
        struct gendisk *disk;
        struct kref kref;
 
+       u8 eui[8];
+       u8 uuid[16];
+
        unsigned ns_id;
        int lba_shift;
        u16 ms;
@@ -94,41 +116,156 @@ struct nvme_ns {
        u32 mode_select_block_len;
 };
 
-/*
- * The nvme_iod describes the data in an I/O, including the list of PRP
- * entries.  You can't see it in this data structure because C doesn't let
- * me express that.  Use nvme_alloc_iod to ensure there's enough space
- * allocated to store the PRP list.
- */
-struct nvme_iod {
-       unsigned long private;  /* For the use of the submitter of the I/O */
-       int npages;             /* In the PRP list. 0 means small pool in use */
-       int offset;             /* Of PRP list */
-       int nents;              /* Used in scatterlist */
-       int length;             /* Of data, in bytes */
-       dma_addr_t first_dma;
-       struct scatterlist meta_sg[1]; /* metadata requires single contiguous buffer */
-       struct scatterlist sg[0];
+struct nvme_ctrl_ops {
+       int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
+       int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
+       int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
+       bool (*io_incapable)(struct nvme_ctrl *ctrl);
+       int (*reset_ctrl)(struct nvme_ctrl *ctrl);
+       void (*free_ctrl)(struct nvme_ctrl *ctrl);
 };
 
+static inline bool nvme_ctrl_ready(struct nvme_ctrl *ctrl)
+{
+       u32 val = 0;
+
+       if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
+               return false;
+       return val & NVME_CSTS_RDY;
+}
+
+static inline bool nvme_io_incapable(struct nvme_ctrl *ctrl)
+{
+       u32 val = 0;
+
+       if (ctrl->ops->io_incapable(ctrl))
+               return false;
+       if (ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &val))
+               return false;
+       return val & NVME_CSTS_CFS;
+}
+
+static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
+{
+       if (!ctrl->subsystem)
+               return -ENOTTY;
+       return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
+}
+
 static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector)
 {
        return (sector >> (ns->lba_shift - 9));
 }
 
+static inline void nvme_setup_flush(struct nvme_ns *ns,
+               struct nvme_command *cmnd)
+{
+       memset(cmnd, 0, sizeof(*cmnd));
+       cmnd->common.opcode = nvme_cmd_flush;
+       cmnd->common.nsid = cpu_to_le32(ns->ns_id);
+}
+
+static inline void nvme_setup_rw(struct nvme_ns *ns, struct request *req,
+               struct nvme_command *cmnd)
+{
+       u16 control = 0;
+       u32 dsmgmt = 0;
+
+       if (req->cmd_flags & REQ_FUA)
+               control |= NVME_RW_FUA;
+       if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
+               control |= NVME_RW_LR;
+
+       if (req->cmd_flags & REQ_RAHEAD)
+               dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH;
+
+       memset(cmnd, 0, sizeof(*cmnd));
+       cmnd->rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read);
+       cmnd->rw.command_id = req->tag;
+       cmnd->rw.nsid = cpu_to_le32(ns->ns_id);
+       cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
+       cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
+
+       if (ns->ms) {
+               switch (ns->pi_type) {
+               case NVME_NS_DPS_PI_TYPE3:
+                       control |= NVME_RW_PRINFO_PRCHK_GUARD;
+                       break;
+               case NVME_NS_DPS_PI_TYPE1:
+               case NVME_NS_DPS_PI_TYPE2:
+                       control |= NVME_RW_PRINFO_PRCHK_GUARD |
+                                       NVME_RW_PRINFO_PRCHK_REF;
+                       cmnd->rw.reftag = cpu_to_le32(
+                                       nvme_block_nr(ns, blk_rq_pos(req)));
+                       break;
+               }
+               if (!blk_integrity_rq(req))
+                       control |= NVME_RW_PRINFO_PRACT;
+       }
+
+       cmnd->rw.control = cpu_to_le16(control);
+       cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
+}
+
+
+static inline int nvme_error_status(u16 status)
+{
+       switch (status & 0x7ff) {
+       case NVME_SC_SUCCESS:
+               return 0;
+       case NVME_SC_CAP_EXCEEDED:
+               return -ENOSPC;
+       default:
+               return -EIO;
+       }
+}
+
+static inline bool nvme_req_needs_retry(struct request *req, u16 status)
+{
+       return !(status & NVME_SC_DNR || blk_noretry_request(req)) &&
+               (jiffies - req->start_time) < req->timeout;
+}
+
+int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
+int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
+int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
+int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
+               const struct nvme_ctrl_ops *ops, unsigned long quirks);
+void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
+void nvme_put_ctrl(struct nvme_ctrl *ctrl);
+int nvme_init_identify(struct nvme_ctrl *ctrl);
+
+void nvme_scan_namespaces(struct nvme_ctrl *ctrl);
+void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
+
+void nvme_stop_queues(struct nvme_ctrl *ctrl);
+void nvme_start_queues(struct nvme_ctrl *ctrl);
+
+struct request *nvme_alloc_request(struct request_queue *q,
+               struct nvme_command *cmd, unsigned int flags);
+void nvme_requeue_req(struct request *req);
 int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
                void *buf, unsigned bufflen);
 int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
-               void *buffer, void __user *ubuffer, unsigned bufflen,
+               void *buffer, unsigned bufflen,  u32 *result, unsigned timeout);
+int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+               void __user *ubuffer, unsigned bufflen, u32 *result,
+               unsigned timeout);
+int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
+               void __user *ubuffer, unsigned bufflen,
+               void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
                u32 *result, unsigned timeout);
-int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id);
-int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid,
+int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id);
+int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid,
                struct nvme_id_ns **id);
-int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log);
-int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
+int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log);
+int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid,
                        dma_addr_t dma_addr, u32 *result);
-int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
+int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
                        dma_addr_t dma_addr, u32 *result);
+int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count);
+
+extern spinlock_t dev_list_lock;
 
 struct sg_io_hdr;
 
@@ -154,4 +291,7 @@ static inline int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *i
 }
 #endif /* CONFIG_NVM */
 
+int __init nvme_core_init(void);
+void nvme_core_exit(void);
+
 #endif /* _NVME_H */
index f5c0e26..72ef832 100644 (file)
@@ -12,6 +12,7 @@
  * more details.
  */
 
+#include <linux/aer.h>
 #include <linux/bitops.h>
 #include <linux/blkdev.h>
 #include <linux/blk-mq.h>
 #include <linux/kdev_t.h>
 #include <linux/kthread.h>
 #include <linux/kernel.h>
-#include <linux/list_sort.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/poison.h>
 #include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/t10-pi.h>
 #include <linux/types.h>
-#include <linux/pr.h>
-#include <scsi/sg.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <asm/unaligned.h>
 
-#include <uapi/linux/nvme_ioctl.h>
 #include "nvme.h"
 
-#define NVME_MINORS            (1U << MINORBITS)
 #define NVME_Q_DEPTH           1024
 #define NVME_AQ_DEPTH          256
 #define SQ_SIZE(depth)         (depth * sizeof(struct nvme_command))
 #define CQ_SIZE(depth)         (depth * sizeof(struct nvme_completion))
-#define ADMIN_TIMEOUT          (admin_timeout * HZ)
-#define SHUTDOWN_TIMEOUT       (shutdown_timeout * HZ)
+               
+/*
+ * We handle AEN commands ourselves and don't even let the
+ * block layer know about them.
+ */
+#define NVME_NR_AEN_COMMANDS   1
+#define NVME_AQ_BLKMQ_DEPTH    (NVME_AQ_DEPTH - NVME_NR_AEN_COMMANDS)
 
-static unsigned char admin_timeout = 60;
+unsigned char admin_timeout = 60;
 module_param(admin_timeout, byte, 0644);
 MODULE_PARM_DESC(admin_timeout, "timeout in seconds for admin commands");
 
@@ -63,16 +65,10 @@ unsigned char nvme_io_timeout = 30;
 module_param_named(io_timeout, nvme_io_timeout, byte, 0644);
 MODULE_PARM_DESC(io_timeout, "timeout in seconds for I/O");
 
-static unsigned char shutdown_timeout = 5;
+unsigned char shutdown_timeout = 5;
 module_param(shutdown_timeout, byte, 0644);
 MODULE_PARM_DESC(shutdown_timeout, "timeout in seconds for controller shutdown");
 
-static int nvme_major;
-module_param(nvme_major, int, 0);
-
-static int nvme_char_major;
-module_param(nvme_char_major, int, 0);
-
 static int use_threaded_interrupts;
 module_param(use_threaded_interrupts, int, 0);
 
@@ -80,28 +76,60 @@ static bool use_cmb_sqes = true;
 module_param(use_cmb_sqes, bool, 0644);
 MODULE_PARM_DESC(use_cmb_sqes, "use controller's memory buffer for I/O SQes");
 
-static DEFINE_SPINLOCK(dev_list_lock);
 static LIST_HEAD(dev_list);
 static struct task_struct *nvme_thread;
 static struct workqueue_struct *nvme_workq;
 static wait_queue_head_t nvme_kthread_wait;
 
-static struct class *nvme_class;
+struct nvme_dev;
+struct nvme_queue;
 
-static int __nvme_reset(struct nvme_dev *dev);
 static int nvme_reset(struct nvme_dev *dev);
 static void nvme_process_cq(struct nvme_queue *nvmeq);
-static void nvme_dead_ctrl(struct nvme_dev *dev);
+static void nvme_remove_dead_ctrl(struct nvme_dev *dev);
+static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown);
 
-struct async_cmd_info {
-       struct kthread_work work;
-       struct kthread_worker *worker;
-       struct request *req;
-       u32 result;
-       int status;
-       void *ctx;
+/*
+ * Represents an NVM Express device.  Each nvme_dev is a PCI function.
+ */
+struct nvme_dev {
+       struct list_head node;
+       struct nvme_queue **queues;
+       struct blk_mq_tag_set tagset;
+       struct blk_mq_tag_set admin_tagset;
+       u32 __iomem *dbs;
+       struct device *dev;
+       struct dma_pool *prp_page_pool;
+       struct dma_pool *prp_small_pool;
+       unsigned queue_count;
+       unsigned online_queues;
+       unsigned max_qid;
+       int q_depth;
+       u32 db_stride;
+       struct msix_entry *entry;
+       void __iomem *bar;
+       struct work_struct reset_work;
+       struct work_struct scan_work;
+       struct work_struct remove_work;
+       struct mutex shutdown_lock;
+       bool subsystem;
+       void __iomem *cmb;
+       dma_addr_t cmb_dma_addr;
+       u64 cmb_size;
+       u32 cmbsz;
+       unsigned long flags;
+
+#define NVME_CTRL_RESETTING    0
+
+       struct nvme_ctrl ctrl;
+       struct completion ioq_wait;
 };
 
+static inline struct nvme_dev *to_nvme_dev(struct nvme_ctrl *ctrl)
+{
+       return container_of(ctrl, struct nvme_dev, ctrl);
+}
+
 /*
  * An NVM Express queue.  Each device has at least two (one for admin
  * commands and one for I/O commands).
@@ -126,7 +154,24 @@ struct nvme_queue {
        u16 qid;
        u8 cq_phase;
        u8 cqe_seen;
-       struct async_cmd_info cmdinfo;
+};
+
+/*
+ * The nvme_iod describes the data in an I/O, including the list of PRP
+ * entries.  You can't see it in this data structure because C doesn't let
+ * me express that.  Use nvme_init_iod to ensure there's enough space
+ * allocated to store the PRP list.
+ */
+struct nvme_iod {
+       struct nvme_queue *nvmeq;
+       int aborted;
+       int npages;             /* In the PRP list. 0 means small pool in use */
+       int nents;              /* Used in scatterlist */
+       int length;             /* Of data, in bytes */
+       dma_addr_t first_dma;
+       struct scatterlist meta_sg; /* metadata requires single contiguous buffer */
+       struct scatterlist *sg;
+       struct scatterlist inline_sg[0];
 };
 
 /*
@@ -148,23 +193,11 @@ static inline void _nvme_check_size(void)
        BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
 }
 
-typedef void (*nvme_completion_fn)(struct nvme_queue *, void *,
-                                               struct nvme_completion *);
-
-struct nvme_cmd_info {
-       nvme_completion_fn fn;
-       void *ctx;
-       int aborted;
-       struct nvme_queue *nvmeq;
-       struct nvme_iod iod[0];
-};
-
 /*
  * Max size of iod being embedded in the request payload
  */
 #define NVME_INT_PAGES         2
-#define NVME_INT_BYTES(dev)    (NVME_INT_PAGES * (dev)->page_size)
-#define NVME_INT_MASK          0x01
+#define NVME_INT_BYTES(dev)    (NVME_INT_PAGES * (dev)->ctrl.page_size)
 
 /*
  * Will slightly overestimate the number of pages needed.  This is OK
@@ -173,19 +206,22 @@ struct nvme_cmd_info {
  */
 static int nvme_npages(unsigned size, struct nvme_dev *dev)
 {
-       unsigned nprps = DIV_ROUND_UP(size + dev->page_size, dev->page_size);
+       unsigned nprps = DIV_ROUND_UP(size + dev->ctrl.page_size,
+                                     dev->ctrl.page_size);
        return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
 }
 
-static unsigned int nvme_cmd_size(struct nvme_dev *dev)
+static unsigned int nvme_iod_alloc_size(struct nvme_dev *dev,
+               unsigned int size, unsigned int nseg)
 {
-       unsigned int ret = sizeof(struct nvme_cmd_info);
-
-       ret += sizeof(struct nvme_iod);
-       ret += sizeof(__le64 *) * nvme_npages(NVME_INT_BYTES(dev), dev);
-       ret += sizeof(struct scatterlist) * NVME_INT_PAGES;
+       return sizeof(__le64 *) * nvme_npages(size, dev) +
+                       sizeof(struct scatterlist) * nseg;
+}
 
-       return ret;
+static unsigned int nvme_cmd_size(struct nvme_dev *dev)
+{
+       return sizeof(struct nvme_iod) +
+               nvme_iod_alloc_size(dev, NVME_INT_BYTES(dev), NVME_INT_PAGES);
 }
 
 static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
@@ -215,11 +251,11 @@ static int nvme_admin_init_request(void *data, struct request *req,
                                unsigned int numa_node)
 {
        struct nvme_dev *dev = data;
-       struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
        struct nvme_queue *nvmeq = dev->queues[0];
 
        BUG_ON(!nvmeq);
-       cmd->nvmeq = nvmeq;
+       iod->nvmeq = nvmeq;
        return 0;
 }
 
@@ -242,148 +278,36 @@ static int nvme_init_request(void *data, struct request *req,
                                unsigned int numa_node)
 {
        struct nvme_dev *dev = data;
-       struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
        struct nvme_queue *nvmeq = dev->queues[hctx_idx + 1];
 
        BUG_ON(!nvmeq);
-       cmd->nvmeq = nvmeq;
+       iod->nvmeq = nvmeq;
        return 0;
 }
 
-static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx,
-                               nvme_completion_fn handler)
+static void nvme_complete_async_event(struct nvme_dev *dev,
+               struct nvme_completion *cqe)
 {
-       cmd->fn = handler;
-       cmd->ctx = ctx;
-       cmd->aborted = 0;
-       blk_mq_start_request(blk_mq_rq_from_pdu(cmd));
-}
-
-static void *iod_get_private(struct nvme_iod *iod)
-{
-       return (void *) (iod->private & ~0x1UL);
-}
-
-/*
- * If bit 0 is set, the iod is embedded in the request payload.
- */
-static bool iod_should_kfree(struct nvme_iod *iod)
-{
-       return (iod->private & NVME_INT_MASK) == 0;
-}
-
-/* Special values must be less than 0x1000 */
-#define CMD_CTX_BASE           ((void *)POISON_POINTER_DELTA)
-#define CMD_CTX_CANCELLED      (0x30C + CMD_CTX_BASE)
-#define CMD_CTX_COMPLETED      (0x310 + CMD_CTX_BASE)
-#define CMD_CTX_INVALID                (0x314 + CMD_CTX_BASE)
-
-static void special_completion(struct nvme_queue *nvmeq, void *ctx,
-                                               struct nvme_completion *cqe)
-{
-       if (ctx == CMD_CTX_CANCELLED)
-               return;
-       if (ctx == CMD_CTX_COMPLETED) {
-               dev_warn(nvmeq->q_dmadev,
-                               "completed id %d twice on queue %d\n",
-                               cqe->command_id, le16_to_cpup(&cqe->sq_id));
-               return;
-       }
-       if (ctx == CMD_CTX_INVALID) {
-               dev_warn(nvmeq->q_dmadev,
-                               "invalid id %d completed on queue %d\n",
-                               cqe->command_id, le16_to_cpup(&cqe->sq_id));
-               return;
-       }
-       dev_warn(nvmeq->q_dmadev, "Unknown special completion %p\n", ctx);
-}
-
-static void *cancel_cmd_info(struct nvme_cmd_info *cmd, nvme_completion_fn *fn)
-{
-       void *ctx;
-
-       if (fn)
-               *fn = cmd->fn;
-       ctx = cmd->ctx;
-       cmd->fn = special_completion;
-       cmd->ctx = CMD_CTX_CANCELLED;
-       return ctx;
-}
-
-static void async_req_completion(struct nvme_queue *nvmeq, void *ctx,
-                                               struct nvme_completion *cqe)
-{
-       u32 result = le32_to_cpup(&cqe->result);
-       u16 status = le16_to_cpup(&cqe->status) >> 1;
+       u16 status = le16_to_cpu(cqe->status) >> 1;
+       u32 result = le32_to_cpu(cqe->result);
 
        if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ)
-               ++nvmeq->dev->event_limit;
+               ++dev->ctrl.event_limit;
        if (status != NVME_SC_SUCCESS)
                return;
 
        switch (result & 0xff07) {
        case NVME_AER_NOTICE_NS_CHANGED:
-               dev_info(nvmeq->q_dmadev, "rescanning\n");
-               schedule_work(&nvmeq->dev->scan_work);
+               dev_info(dev->dev, "rescanning\n");
+               queue_work(nvme_workq, &dev->scan_work);
        default:
-               dev_warn(nvmeq->q_dmadev, "async event result %08x\n", result);
-       }
-}
-
-static void abort_completion(struct nvme_queue *nvmeq, void *ctx,
-                                               struct nvme_completion *cqe)
-{
-       struct request *req = ctx;
-
-       u16 status = le16_to_cpup(&cqe->status) >> 1;
-       u32 result = le32_to_cpup(&cqe->result);
-
-       blk_mq_free_request(req);
-
-       dev_warn(nvmeq->q_dmadev, "Abort status:%x result:%x", status, result);
-       ++nvmeq->dev->abort_limit;
-}
-
-static void async_completion(struct nvme_queue *nvmeq, void *ctx,
-                                               struct nvme_completion *cqe)
-{
-       struct async_cmd_info *cmdinfo = ctx;
-       cmdinfo->result = le32_to_cpup(&cqe->result);
-       cmdinfo->status = le16_to_cpup(&cqe->status) >> 1;
-       queue_kthread_work(cmdinfo->worker, &cmdinfo->work);
-       blk_mq_free_request(cmdinfo->req);
-}
-
-static inline struct nvme_cmd_info *get_cmd_from_tag(struct nvme_queue *nvmeq,
-                                 unsigned int tag)
-{
-       struct request *req = blk_mq_tag_to_rq(*nvmeq->tags, tag);
-
-       return blk_mq_rq_to_pdu(req);
-}
-
-/*
- * Called with local interrupts disabled and the q_lock held.  May not sleep.
- */
-static void *nvme_finish_cmd(struct nvme_queue *nvmeq, int tag,
-                                               nvme_completion_fn *fn)
-{
-       struct nvme_cmd_info *cmd = get_cmd_from_tag(nvmeq, tag);
-       void *ctx;
-       if (tag >= nvmeq->q_depth) {
-               *fn = special_completion;
-               return CMD_CTX_INVALID;
+               dev_warn(dev->dev, "async event result %08x\n", result);
        }
-       if (fn)
-               *fn = cmd->fn;
-       ctx = cmd->ctx;
-       cmd->fn = special_completion;
-       cmd->ctx = CMD_CTX_COMPLETED;
-       return ctx;
 }
 
 /**
- * nvme_submit_cmd() - Copy a command into a queue and ring the doorbell
+ * __nvme_submit_cmd() - Copy a command into a queue and ring the doorbell
  * @nvmeq: The queue to use
  * @cmd: The command to send
  *
@@ -405,69 +329,44 @@ static void __nvme_submit_cmd(struct nvme_queue *nvmeq,
        nvmeq->sq_tail = tail;
 }
 
-static void nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&nvmeq->q_lock, flags);
-       __nvme_submit_cmd(nvmeq, cmd);
-       spin_unlock_irqrestore(&nvmeq->q_lock, flags);
-}
-
-static __le64 **iod_list(struct nvme_iod *iod)
-{
-       return ((void *)iod) + iod->offset;
-}
-
-static inline void iod_init(struct nvme_iod *iod, unsigned nbytes,
-                           unsigned nseg, unsigned long private)
-{
-       iod->private = private;
-       iod->offset = offsetof(struct nvme_iod, sg[nseg]);
-       iod->npages = -1;
-       iod->length = nbytes;
-       iod->nents = 0;
-}
-
-static struct nvme_iod *
-__nvme_alloc_iod(unsigned nseg, unsigned bytes, struct nvme_dev *dev,
-                unsigned long priv, gfp_t gfp)
+static __le64 **iod_list(struct request *req)
 {
-       struct nvme_iod *iod = kmalloc(sizeof(struct nvme_iod) +
-                               sizeof(__le64 *) * nvme_npages(bytes, dev) +
-                               sizeof(struct scatterlist) * nseg, gfp);
-
-       if (iod)
-               iod_init(iod, bytes, nseg, priv);
-
-       return iod;
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       return (__le64 **)(iod->sg + req->nr_phys_segments);
 }
 
-static struct nvme_iod *nvme_alloc_iod(struct request *rq, struct nvme_dev *dev,
-                                      gfp_t gfp)
+static int nvme_init_iod(struct request *rq, struct nvme_dev *dev)
 {
-       unsigned size = !(rq->cmd_flags & REQ_DISCARD) ? blk_rq_bytes(rq) :
-                                                sizeof(struct nvme_dsm_range);
-       struct nvme_iod *iod;
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(rq);
+       int nseg = rq->nr_phys_segments;
+       unsigned size;
 
-       if (rq->nr_phys_segments <= NVME_INT_PAGES &&
-           size <= NVME_INT_BYTES(dev)) {
-               struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(rq);
+       if (rq->cmd_flags & REQ_DISCARD)
+               size = sizeof(struct nvme_dsm_range);
+       else
+               size = blk_rq_bytes(rq);
 
-               iod = cmd->iod;
-               iod_init(iod, size, rq->nr_phys_segments,
-                               (unsigned long) rq | NVME_INT_MASK);
-               return iod;
+       if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) {
+               iod->sg = kmalloc(nvme_iod_alloc_size(dev, size, nseg), GFP_ATOMIC);
+               if (!iod->sg)
+                       return BLK_MQ_RQ_QUEUE_BUSY;
+       } else {
+               iod->sg = iod->inline_sg;
        }
 
-       return __nvme_alloc_iod(rq->nr_phys_segments, size, dev,
-                               (unsigned long) rq, gfp);
+       iod->aborted = 0;
+       iod->npages = -1;
+       iod->nents = 0;
+       iod->length = size;
+       return 0;
 }
 
-static void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod)
+static void nvme_free_iod(struct nvme_dev *dev, struct request *req)
 {
-       const int last_prp = dev->page_size / 8 - 1;
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       const int last_prp = dev->ctrl.page_size / 8 - 1;
        int i;
-       __le64 **list = iod_list(iod);
+       __le64 **list = iod_list(req);
        dma_addr_t prp_dma = iod->first_dma;
 
        if (iod->npages == 0)
@@ -479,20 +378,8 @@ static void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod)
                prp_dma = next_prp_dma;
        }
 
-       if (iod_should_kfree(iod))
-               kfree(iod);
-}
-
-static int nvme_error_status(u16 status)
-{
-       switch (status & 0x7ff) {
-       case NVME_SC_SUCCESS:
-               return 0;
-       case NVME_SC_CAP_EXCEEDED:
-               return -ENOSPC;
-       default:
-               return -EIO;
-       }
+       if (iod->sg != iod->inline_sg)
+               kfree(iod->sg);
 }
 
 #ifdef CONFIG_BLK_DEV_INTEGRITY
@@ -549,27 +436,6 @@ static void nvme_dif_remap(struct request *req,
        }
        kunmap_atomic(pmap);
 }
-
-static void nvme_init_integrity(struct nvme_ns *ns)
-{
-       struct blk_integrity integrity;
-
-       switch (ns->pi_type) {
-       case NVME_NS_DPS_PI_TYPE3:
-               integrity.profile = &t10_pi_type3_crc;
-               break;
-       case NVME_NS_DPS_PI_TYPE1:
-       case NVME_NS_DPS_PI_TYPE2:
-               integrity.profile = &t10_pi_type1_crc;
-               break;
-       default:
-               integrity.profile = NULL;
-               break;
-       }
-       integrity.tuple_size = ns->ms;
-       blk_integrity_register(ns->disk, &integrity);
-       blk_queue_max_integrity_segments(ns->queue, 1);
-}
 #else /* CONFIG_BLK_DEV_INTEGRITY */
 static void nvme_dif_remap(struct request *req,
                        void (*dif_swap)(u32 p, u32 v, struct t10_pi_tuple *pi))
@@ -581,91 +447,27 @@ static void nvme_dif_prep(u32 p, u32 v, struct t10_pi_tuple *pi)
 static void nvme_dif_complete(u32 p, u32 v, struct t10_pi_tuple *pi)
 {
 }
-static void nvme_init_integrity(struct nvme_ns *ns)
-{
-}
 #endif
 
-static void req_completion(struct nvme_queue *nvmeq, void *ctx,
-                                               struct nvme_completion *cqe)
-{
-       struct nvme_iod *iod = ctx;
-       struct request *req = iod_get_private(iod);
-       struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
-       u16 status = le16_to_cpup(&cqe->status) >> 1;
-       bool requeue = false;
-       int error = 0;
-
-       if (unlikely(status)) {
-               if (!(status & NVME_SC_DNR || blk_noretry_request(req))
-                   && (jiffies - req->start_time) < req->timeout) {
-                       unsigned long flags;
-
-                       requeue = true;
-                       blk_mq_requeue_request(req);
-                       spin_lock_irqsave(req->q->queue_lock, flags);
-                       if (!blk_queue_stopped(req->q))
-                               blk_mq_kick_requeue_list(req->q);
-                       spin_unlock_irqrestore(req->q->queue_lock, flags);
-                       goto release_iod;
-               }
-
-               if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
-                       if (cmd_rq->ctx == CMD_CTX_CANCELLED)
-                               error = -EINTR;
-                       else
-                               error = status;
-               } else {
-                       error = nvme_error_status(status);
-               }
-       }
-
-       if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
-               u32 result = le32_to_cpup(&cqe->result);
-               req->special = (void *)(uintptr_t)result;
-       }
-
-       if (cmd_rq->aborted)
-               dev_warn(nvmeq->dev->dev,
-                       "completing aborted command with status:%04x\n",
-                       error);
-
-release_iod:
-       if (iod->nents) {
-               dma_unmap_sg(nvmeq->dev->dev, iod->sg, iod->nents,
-                       rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-               if (blk_integrity_rq(req)) {
-                       if (!rq_data_dir(req))
-                               nvme_dif_remap(req, nvme_dif_complete);
-                       dma_unmap_sg(nvmeq->dev->dev, iod->meta_sg, 1,
-                               rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-               }
-       }
-       nvme_free_iod(nvmeq->dev, iod);
-
-       if (likely(!requeue))
-               blk_mq_complete_request(req, error);
-}
-
-/* length is in bytes.  gfp flags indicates whether we may sleep. */
-static int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod,
-               int total_len, gfp_t gfp)
+static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req,
+               int total_len)
 {
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
        struct dma_pool *pool;
        int length = total_len;
        struct scatterlist *sg = iod->sg;
        int dma_len = sg_dma_len(sg);
        u64 dma_addr = sg_dma_address(sg);
-       u32 page_size = dev->page_size;
+       u32 page_size = dev->ctrl.page_size;
        int offset = dma_addr & (page_size - 1);
        __le64 *prp_list;
-       __le64 **list = iod_list(iod);
+       __le64 **list = iod_list(req);
        dma_addr_t prp_dma;
        int nprps, i;
 
        length -= (page_size - offset);
        if (length <= 0)
-               return total_len;
+               return true;
 
        dma_len -= (page_size - offset);
        if (dma_len) {
@@ -678,7 +480,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod,
 
        if (length <= page_size) {
                iod->first_dma = dma_addr;
-               return total_len;
+               return true;
        }
 
        nprps = DIV_ROUND_UP(length, page_size);
@@ -690,11 +492,11 @@ static int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod,
                iod->npages = 1;
        }
 
-       prp_list = dma_pool_alloc(pool, gfp, &prp_dma);
+       prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
        if (!prp_list) {
                iod->first_dma = dma_addr;
                iod->npages = -1;
-               return (total_len - length) + page_size;
+               return false;
        }
        list[0] = prp_list;
        iod->first_dma = prp_dma;
@@ -702,9 +504,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod,
        for (;;) {
                if (i == page_size >> 3) {
                        __le64 *old_prp_list = prp_list;
-                       prp_list = dma_pool_alloc(pool, gfp, &prp_dma);
+                       prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
                        if (!prp_list)
-                               return total_len - length;
+                               return false;
                        list[iod->npages++] = prp_list;
                        prp_list[0] = old_prp_list[i - 1];
                        old_prp_list[i - 1] = cpu_to_le64(prp_dma);
@@ -724,115 +526,105 @@ static int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod,
                dma_len = sg_dma_len(sg);
        }
 
-       return total_len;
+       return true;
 }
 
-static void nvme_submit_priv(struct nvme_queue *nvmeq, struct request *req,
-               struct nvme_iod *iod)
+static int nvme_map_data(struct nvme_dev *dev, struct request *req,
+               struct nvme_command *cmnd)
 {
-       struct nvme_command cmnd;
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       struct request_queue *q = req->q;
+       enum dma_data_direction dma_dir = rq_data_dir(req) ?
+                       DMA_TO_DEVICE : DMA_FROM_DEVICE;
+       int ret = BLK_MQ_RQ_QUEUE_ERROR;
 
-       memcpy(&cmnd, req->cmd, sizeof(cmnd));
-       cmnd.rw.command_id = req->tag;
-       if (req->nr_phys_segments) {
-               cmnd.rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
-               cmnd.rw.prp2 = cpu_to_le64(iod->first_dma);
-       }
+       sg_init_table(iod->sg, req->nr_phys_segments);
+       iod->nents = blk_rq_map_sg(q, req, iod->sg);
+       if (!iod->nents)
+               goto out;
 
-       __nvme_submit_cmd(nvmeq, &cmnd);
-}
+       ret = BLK_MQ_RQ_QUEUE_BUSY;
+       if (!dma_map_sg(dev->dev, iod->sg, iod->nents, dma_dir))
+               goto out;
 
-/*
- * We reuse the small pool to allocate the 16-byte range here as it is not
- * worth having a special pool for these or additional cases to handle freeing
- * the iod.
- */
-static void nvme_submit_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns,
-               struct request *req, struct nvme_iod *iod)
-{
-       struct nvme_dsm_range *range =
-                               (struct nvme_dsm_range *)iod_list(iod)[0];
-       struct nvme_command cmnd;
+       if (!nvme_setup_prps(dev, req, blk_rq_bytes(req)))
+               goto out_unmap;
 
-       range->cattr = cpu_to_le32(0);
-       range->nlb = cpu_to_le32(blk_rq_bytes(req) >> ns->lba_shift);
-       range->slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
+       ret = BLK_MQ_RQ_QUEUE_ERROR;
+       if (blk_integrity_rq(req)) {
+               if (blk_rq_count_integrity_sg(q, req->bio) != 1)
+                       goto out_unmap;
 
-       memset(&cmnd, 0, sizeof(cmnd));
-       cmnd.dsm.opcode = nvme_cmd_dsm;
-       cmnd.dsm.command_id = req->tag;
-       cmnd.dsm.nsid = cpu_to_le32(ns->ns_id);
-       cmnd.dsm.prp1 = cpu_to_le64(iod->first_dma);
-       cmnd.dsm.nr = 0;
-       cmnd.dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD);
+               sg_init_table(&iod->meta_sg, 1);
+               if (blk_rq_map_integrity_sg(q, req->bio, &iod->meta_sg) != 1)
+                       goto out_unmap;
 
-       __nvme_submit_cmd(nvmeq, &cmnd);
-}
+               if (rq_data_dir(req))
+                       nvme_dif_remap(req, nvme_dif_prep);
 
-static void nvme_submit_flush(struct nvme_queue *nvmeq, struct nvme_ns *ns,
-                                                               int cmdid)
-{
-       struct nvme_command cmnd;
+               if (!dma_map_sg(dev->dev, &iod->meta_sg, 1, dma_dir))
+                       goto out_unmap;
+       }
 
-       memset(&cmnd, 0, sizeof(cmnd));
-       cmnd.common.opcode = nvme_cmd_flush;
-       cmnd.common.command_id = cmdid;
-       cmnd.common.nsid = cpu_to_le32(ns->ns_id);
+       cmnd->rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
+       cmnd->rw.prp2 = cpu_to_le64(iod->first_dma);
+       if (blk_integrity_rq(req))
+               cmnd->rw.metadata = cpu_to_le64(sg_dma_address(&iod->meta_sg));
+       return BLK_MQ_RQ_QUEUE_OK;
 
-       __nvme_submit_cmd(nvmeq, &cmnd);
+out_unmap:
+       dma_unmap_sg(dev->dev, iod->sg, iod->nents, dma_dir);
+out:
+       return ret;
 }
 
-static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod,
-                                                       struct nvme_ns *ns)
+static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
 {
-       struct request *req = iod_get_private(iod);
-       struct nvme_command cmnd;
-       u16 control = 0;
-       u32 dsmgmt = 0;
-
-       if (req->cmd_flags & REQ_FUA)
-               control |= NVME_RW_FUA;
-       if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
-               control |= NVME_RW_LR;
-
-       if (req->cmd_flags & REQ_RAHEAD)
-               dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH;
-
-       memset(&cmnd, 0, sizeof(cmnd));
-       cmnd.rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read);
-       cmnd.rw.command_id = req->tag;
-       cmnd.rw.nsid = cpu_to_le32(ns->ns_id);
-       cmnd.rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
-       cmnd.rw.prp2 = cpu_to_le64(iod->first_dma);
-       cmnd.rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
-       cmnd.rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
-
-       if (ns->ms) {
-               switch (ns->pi_type) {
-               case NVME_NS_DPS_PI_TYPE3:
-                       control |= NVME_RW_PRINFO_PRCHK_GUARD;
-                       break;
-               case NVME_NS_DPS_PI_TYPE1:
-               case NVME_NS_DPS_PI_TYPE2:
-                       control |= NVME_RW_PRINFO_PRCHK_GUARD |
-                                       NVME_RW_PRINFO_PRCHK_REF;
-                       cmnd.rw.reftag = cpu_to_le32(
-                                       nvme_block_nr(ns, blk_rq_pos(req)));
-                       break;
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       enum dma_data_direction dma_dir = rq_data_dir(req) ?
+                       DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+       if (iod->nents) {
+               dma_unmap_sg(dev->dev, iod->sg, iod->nents, dma_dir);
+               if (blk_integrity_rq(req)) {
+                       if (!rq_data_dir(req))
+                               nvme_dif_remap(req, nvme_dif_complete);
+                       dma_unmap_sg(dev->dev, &iod->meta_sg, 1, dma_dir);
                }
-               if (blk_integrity_rq(req))
-                       cmnd.rw.metadata =
-                               cpu_to_le64(sg_dma_address(iod->meta_sg));
-               else
-                       control |= NVME_RW_PRINFO_PRACT;
        }
 
-       cmnd.rw.control = cpu_to_le16(control);
-       cmnd.rw.dsmgmt = cpu_to_le32(dsmgmt);
+       nvme_free_iod(dev, req);
+}
 
-       __nvme_submit_cmd(nvmeq, &cmnd);
+/*
+ * We reuse the small pool to allocate the 16-byte range here as it is not
+ * worth having a special pool for these or additional cases to handle freeing
+ * the iod.
+ */
+static int nvme_setup_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns,
+               struct request *req, struct nvme_command *cmnd)
+{
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       struct nvme_dsm_range *range;
 
-       return 0;
+       range = dma_pool_alloc(nvmeq->dev->prp_small_pool, GFP_ATOMIC,
+                                               &iod->first_dma);
+       if (!range)
+               return BLK_MQ_RQ_QUEUE_BUSY;
+       iod_list(req)[0] = (__le64 *)range;
+       iod->npages = 0;
+
+       range->cattr = cpu_to_le32(0);
+       range->nlb = cpu_to_le32(blk_rq_bytes(req) >> ns->lba_shift);
+       range->slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req)));
+
+       memset(cmnd, 0, sizeof(*cmnd));
+       cmnd->dsm.opcode = nvme_cmd_dsm;
+       cmnd->dsm.nsid = cpu_to_le32(ns->ns_id);
+       cmnd->dsm.prp1 = cpu_to_le64(iod->first_dma);
+       cmnd->dsm.nr = 0;
+       cmnd->dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD);
+       return BLK_MQ_RQ_QUEUE_OK;
 }
 
 /*
@@ -845,9 +637,8 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
        struct nvme_queue *nvmeq = hctx->driver_data;
        struct nvme_dev *dev = nvmeq->dev;
        struct request *req = bd->rq;
-       struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
-       struct nvme_iod *iod;
-       enum dma_data_direction dma_dir;
+       struct nvme_command cmnd;
+       int ret = BLK_MQ_RQ_QUEUE_OK;
 
        /*
         * If formated with metadata, require the block layer provide a buffer
@@ -857,91 +648,72 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
        if (ns && ns->ms && !blk_integrity_rq(req)) {
                if (!(ns->pi_type && ns->ms == 8) &&
                                        req->cmd_type != REQ_TYPE_DRV_PRIV) {
-                       blk_mq_complete_request(req, -EFAULT);
+                       blk_mq_end_request(req, -EFAULT);
                        return BLK_MQ_RQ_QUEUE_OK;
                }
        }
 
-       iod = nvme_alloc_iod(req, dev, GFP_ATOMIC);
-       if (!iod)
-               return BLK_MQ_RQ_QUEUE_BUSY;
+       ret = nvme_init_iod(req, dev);
+       if (ret)
+               return ret;
 
        if (req->cmd_flags & REQ_DISCARD) {
-               void *range;
-               /*
-                * We reuse the small pool to allocate the 16-byte range here
-                * as it is not worth having a special pool for these or
-                * additional cases to handle freeing the iod.
-                */
-               range = dma_pool_alloc(dev->prp_small_pool, GFP_ATOMIC,
-                                               &iod->first_dma);
-               if (!range)
-                       goto retry_cmd;
-               iod_list(iod)[0] = (__le64 *)range;
-               iod->npages = 0;
-       } else if (req->nr_phys_segments) {
-               dma_dir = rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+               ret = nvme_setup_discard(nvmeq, ns, req, &cmnd);
+       } else {
+               if (req->cmd_type == REQ_TYPE_DRV_PRIV)
+                       memcpy(&cmnd, req->cmd, sizeof(cmnd));
+               else if (req->cmd_flags & REQ_FLUSH)
+                       nvme_setup_flush(ns, &cmnd);
+               else
+                       nvme_setup_rw(ns, req, &cmnd);
+
+               if (req->nr_phys_segments)
+                       ret = nvme_map_data(dev, req, &cmnd);
+       }
 
-               sg_init_table(iod->sg, req->nr_phys_segments);
-               iod->nents = blk_rq_map_sg(req->q, req, iod->sg);
-               if (!iod->nents)
-                       goto error_cmd;
+       if (ret)
+               goto out;
 
-               if (!dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir))
-                       goto retry_cmd;
+       cmnd.common.command_id = req->tag;
+       blk_mq_start_request(req);
 
-               if (blk_rq_bytes(req) !=
-                    nvme_setup_prps(dev, iod, blk_rq_bytes(req), GFP_ATOMIC)) {
-                       dma_unmap_sg(dev->dev, iod->sg, iod->nents, dma_dir);
-                       goto retry_cmd;
-               }
-               if (blk_integrity_rq(req)) {
-                       if (blk_rq_count_integrity_sg(req->q, req->bio) != 1) {
-                               dma_unmap_sg(dev->dev, iod->sg, iod->nents,
-                                               dma_dir);
-                               goto error_cmd;
-                       }
+       spin_lock_irq(&nvmeq->q_lock);
+       __nvme_submit_cmd(nvmeq, &cmnd);
+       nvme_process_cq(nvmeq);
+       spin_unlock_irq(&nvmeq->q_lock);
+       return BLK_MQ_RQ_QUEUE_OK;
+out:
+       nvme_free_iod(dev, req);
+       return ret;
+}
 
-                       sg_init_table(iod->meta_sg, 1);
-                       if (blk_rq_map_integrity_sg(
-                                       req->q, req->bio, iod->meta_sg) != 1) {
-                               dma_unmap_sg(dev->dev, iod->sg, iod->nents,
-                                               dma_dir);
-                               goto error_cmd;
-                       }
+static void nvme_complete_rq(struct request *req)
+{
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       struct nvme_dev *dev = iod->nvmeq->dev;
+       int error = 0;
 
-                       if (rq_data_dir(req))
-                               nvme_dif_remap(req, nvme_dif_prep);
+       nvme_unmap_data(dev, req);
 
-                       if (!dma_map_sg(nvmeq->q_dmadev, iod->meta_sg, 1, dma_dir)) {
-                               dma_unmap_sg(dev->dev, iod->sg, iod->nents,
-                                               dma_dir);
-                               goto error_cmd;
-                       }
+       if (unlikely(req->errors)) {
+               if (nvme_req_needs_retry(req, req->errors)) {
+                       nvme_requeue_req(req);
+                       return;
                }
-       }
 
-       nvme_set_info(cmd, iod, req_completion);
-       spin_lock_irq(&nvmeq->q_lock);
-       if (req->cmd_type == REQ_TYPE_DRV_PRIV)
-               nvme_submit_priv(nvmeq, req, iod);
-       else if (req->cmd_flags & REQ_DISCARD)
-               nvme_submit_discard(nvmeq, ns, req, iod);
-       else if (req->cmd_flags & REQ_FLUSH)
-               nvme_submit_flush(nvmeq, ns, req->tag);
-       else
-               nvme_submit_iod(nvmeq, iod, ns);
+               if (req->cmd_type == REQ_TYPE_DRV_PRIV)
+                       error = req->errors;
+               else
+                       error = nvme_error_status(req->errors);
+       }
 
-       nvme_process_cq(nvmeq);
-       spin_unlock_irq(&nvmeq->q_lock);
-       return BLK_MQ_RQ_QUEUE_OK;
+       if (unlikely(iod->aborted)) {
+               dev_warn(dev->dev,
+                       "completing aborted command with status: %04x\n",
+                       req->errors);
+       }
 
- error_cmd:
-       nvme_free_iod(dev, iod);
-       return BLK_MQ_RQ_QUEUE_ERROR;
- retry_cmd:
-       nvme_free_iod(dev, iod);
-       return BLK_MQ_RQ_QUEUE_BUSY;
+       blk_mq_end_request(req, error);
 }
 
 static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag)
@@ -952,20 +724,47 @@ static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag)
        phase = nvmeq->cq_phase;
 
        for (;;) {
-               void *ctx;
-               nvme_completion_fn fn;
                struct nvme_completion cqe = nvmeq->cqes[head];
-               if ((le16_to_cpu(cqe.status) & 1) != phase)
+               u16 status = le16_to_cpu(cqe.status);
+               struct request *req;
+
+               if ((status & 1) != phase)
                        break;
                nvmeq->sq_head = le16_to_cpu(cqe.sq_head);
                if (++head == nvmeq->q_depth) {
                        head = 0;
                        phase = !phase;
                }
+
                if (tag && *tag == cqe.command_id)
                        *tag = -1;
-               ctx = nvme_finish_cmd(nvmeq, cqe.command_id, &fn);
-               fn(nvmeq, ctx, &cqe);
+
+               if (unlikely(cqe.command_id >= nvmeq->q_depth)) {
+                       dev_warn(nvmeq->q_dmadev,
+                               "invalid id %d completed on queue %d\n",
+                               cqe.command_id, le16_to_cpu(cqe.sq_id));
+                       continue;
+               }
+
+               /*
+                * AEN requests are special as they don't time out and can
+                * survive any kind of queue freeze and often don't respond to
+                * aborts.  We don't even bother to allocate a struct request
+                * for them but rather special case them here.
+                */
+               if (unlikely(nvmeq->qid == 0 &&
+                               cqe.command_id >= NVME_AQ_BLKMQ_DEPTH)) {
+                       nvme_complete_async_event(nvmeq->dev, &cqe);
+                       continue;
+               }
+
+               req = blk_mq_tag_to_rq(*nvmeq->tags, cqe.command_id);
+               if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
+                       u32 result = le32_to_cpu(cqe.result);
+                       req->special = (void *)(uintptr_t)result;
+               }
+               blk_mq_complete_request(req, status >> 1);
+
        }
 
        /* If the controller ignores the cq head doorbell and continuously
@@ -1028,127 +827,30 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, unsigned int tag)
        return 0;
 }
 
-/*
- * Returns 0 on success.  If the result is negative, it's a Linux error code;
- * if the result is positive, it's an NVM Express status code
- */
-int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
-               void *buffer, void __user *ubuffer, unsigned bufflen,
-               u32 *result, unsigned timeout)
+static void nvme_submit_async_event(struct nvme_dev *dev)
 {
-       bool write = cmd->common.opcode & 1;
-       struct bio *bio = NULL;
-       struct request *req;
-       int ret;
-
-       req = blk_mq_alloc_request(q, write, 0);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       struct nvme_command c;
 
-       req->cmd_type = REQ_TYPE_DRV_PRIV;
-       req->cmd_flags |= REQ_FAILFAST_DRIVER;
-       req->__data_len = 0;
-       req->__sector = (sector_t) -1;
-       req->bio = req->biotail = NULL;
-
-       req->timeout = timeout ? timeout : ADMIN_TIMEOUT;
-
-       req->cmd = (unsigned char *)cmd;
-       req->cmd_len = sizeof(struct nvme_command);
-       req->special = (void *)0;
-
-       if (buffer && bufflen) {
-               ret = blk_rq_map_kern(q, req, buffer, bufflen,
-                                     __GFP_DIRECT_RECLAIM);
-               if (ret)
-                       goto out;
-       } else if (ubuffer && bufflen) {
-               ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
-                                     __GFP_DIRECT_RECLAIM);
-               if (ret)
-                       goto out;
-               bio = req->bio;
-       }
+       memset(&c, 0, sizeof(c));
+       c.common.opcode = nvme_admin_async_event;
+       c.common.command_id = NVME_AQ_BLKMQ_DEPTH + --dev->ctrl.event_limit;
 
-       blk_execute_rq(req->q, NULL, req, 0);
-       if (bio)
-               blk_rq_unmap_user(bio);
-       if (result)
-               *result = (u32)(uintptr_t)req->special;
-       ret = req->errors;
- out:
-       blk_mq_free_request(req);
-       return ret;
+       __nvme_submit_cmd(dev->queues[0], &c);
 }
 
-int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
-               void *buffer, unsigned bufflen)
+static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
 {
-       return __nvme_submit_sync_cmd(q, cmd, buffer, NULL, bufflen, NULL, 0);
+       struct nvme_command c;
+
+       memset(&c, 0, sizeof(c));
+       c.delete_queue.opcode = opcode;
+       c.delete_queue.qid = cpu_to_le16(id);
+
+       return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
 }
 
-static int nvme_submit_async_admin_req(struct nvme_dev *dev)
-{
-       struct nvme_queue *nvmeq = dev->queues[0];
-       struct nvme_command c;
-       struct nvme_cmd_info *cmd_info;
-       struct request *req;
-
-       req = blk_mq_alloc_request(dev->admin_q, WRITE,
-                       BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->cmd_flags |= REQ_NO_TIMEOUT;
-       cmd_info = blk_mq_rq_to_pdu(req);
-       nvme_set_info(cmd_info, NULL, async_req_completion);
-
-       memset(&c, 0, sizeof(c));
-       c.common.opcode = nvme_admin_async_event;
-       c.common.command_id = req->tag;
-
-       blk_mq_free_request(req);
-       __nvme_submit_cmd(nvmeq, &c);
-       return 0;
-}
-
-static int nvme_submit_admin_async_cmd(struct nvme_dev *dev,
-                       struct nvme_command *cmd,
-                       struct async_cmd_info *cmdinfo, unsigned timeout)
-{
-       struct nvme_queue *nvmeq = dev->queues[0];
-       struct request *req;
-       struct nvme_cmd_info *cmd_rq;
-
-       req = blk_mq_alloc_request(dev->admin_q, WRITE, 0);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->timeout = timeout;
-       cmd_rq = blk_mq_rq_to_pdu(req);
-       cmdinfo->req = req;
-       nvme_set_info(cmd_rq, cmdinfo, async_completion);
-       cmdinfo->status = -EINTR;
-
-       cmd->common.command_id = req->tag;
-
-       nvme_submit_cmd(nvmeq, cmd);
-       return 0;
-}
-
-static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
-{
-       struct nvme_command c;
-
-       memset(&c, 0, sizeof(c));
-       c.delete_queue.opcode = opcode;
-       c.delete_queue.qid = cpu_to_le16(id);
-
-       return nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
-}
-
-static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
-                                               struct nvme_queue *nvmeq)
+static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
+                                               struct nvme_queue *nvmeq)
 {
        struct nvme_command c;
        int flags = NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED;
@@ -1165,7 +867,7 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
        c.create_cq.cq_flags = cpu_to_le16(flags);
        c.create_cq.irq_vector = cpu_to_le16(nvmeq->cq_vector);
 
-       return nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
+       return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
 }
 
 static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid,
@@ -1186,7 +888,7 @@ static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid,
        c.create_sq.sq_flags = cpu_to_le16(flags);
        c.create_sq.cqid = cpu_to_le16(qid);
 
-       return nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
+       return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
 }
 
 static int adapter_delete_cq(struct nvme_dev *dev, u16 cqid)
@@ -1199,195 +901,111 @@ static int adapter_delete_sq(struct nvme_dev *dev, u16 sqid)
        return adapter_delete_queue(dev, nvme_admin_delete_sq, sqid);
 }
 
-int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id)
+static void abort_endio(struct request *req, int error)
 {
-       struct nvme_command c = { };
-       int error;
-
-       /* gcc-4.4.4 (at least) has issues with initializers and anon unions */
-       c.identify.opcode = nvme_admin_identify;
-       c.identify.cns = cpu_to_le32(1);
-
-       *id = kmalloc(sizeof(struct nvme_id_ctrl), GFP_KERNEL);
-       if (!*id)
-               return -ENOMEM;
-
-       error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
-                       sizeof(struct nvme_id_ctrl));
-       if (error)
-               kfree(*id);
-       return error;
-}
-
-int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid,
-               struct nvme_id_ns **id)
-{
-       struct nvme_command c = { };
-       int error;
-
-       /* gcc-4.4.4 (at least) has issues with initializers and anon unions */
-       c.identify.opcode = nvme_admin_identify,
-       c.identify.nsid = cpu_to_le32(nsid),
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       struct nvme_queue *nvmeq = iod->nvmeq;
+       u32 result = (u32)(uintptr_t)req->special;
+       u16 status = req->errors;
 
-       *id = kmalloc(sizeof(struct nvme_id_ns), GFP_KERNEL);
-       if (!*id)
-               return -ENOMEM;
-
-       error = nvme_submit_sync_cmd(dev->admin_q, &c, *id,
-                       sizeof(struct nvme_id_ns));
-       if (error)
-               kfree(*id);
-       return error;
-}
-
-int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
-                                       dma_addr_t dma_addr, u32 *result)
-{
-       struct nvme_command c;
-
-       memset(&c, 0, sizeof(c));
-       c.features.opcode = nvme_admin_get_features;
-       c.features.nsid = cpu_to_le32(nsid);
-       c.features.prp1 = cpu_to_le64(dma_addr);
-       c.features.fid = cpu_to_le32(fid);
-
-       return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, NULL, 0,
-                       result, 0);
-}
-
-int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
-                                       dma_addr_t dma_addr, u32 *result)
-{
-       struct nvme_command c;
-
-       memset(&c, 0, sizeof(c));
-       c.features.opcode = nvme_admin_set_features;
-       c.features.prp1 = cpu_to_le64(dma_addr);
-       c.features.fid = cpu_to_le32(fid);
-       c.features.dword11 = cpu_to_le32(dword11);
-
-       return __nvme_submit_sync_cmd(dev->admin_q, &c, NULL, NULL, 0,
-                       result, 0);
-}
-
-int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log)
-{
-       struct nvme_command c = { };
-       int error;
-
-       c.common.opcode = nvme_admin_get_log_page,
-       c.common.nsid = cpu_to_le32(0xFFFFFFFF),
-       c.common.cdw10[0] = cpu_to_le32(
-                       (((sizeof(struct nvme_smart_log) / 4) - 1) << 16) |
-                        NVME_LOG_SMART),
-
-       *log = kmalloc(sizeof(struct nvme_smart_log), GFP_KERNEL);
-       if (!*log)
-               return -ENOMEM;
+       dev_warn(nvmeq->q_dmadev, "Abort status:%x result:%x", status, result);
+       atomic_inc(&nvmeq->dev->ctrl.abort_limit);
 
-       error = nvme_submit_sync_cmd(dev->admin_q, &c, *log,
-                       sizeof(struct nvme_smart_log));
-       if (error)
-               kfree(*log);
-       return error;
+       blk_mq_free_request(req);
 }
 
-/**
- * nvme_abort_req - Attempt aborting a request
- *
- * Schedule controller reset if the command was already aborted once before and
- * still hasn't been returned to the driver, or if this is the admin queue.
- */
-static void nvme_abort_req(struct request *req)
+static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
 {
-       struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
-       struct nvme_queue *nvmeq = cmd_rq->nvmeq;
+       struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+       struct nvme_queue *nvmeq = iod->nvmeq;
        struct nvme_dev *dev = nvmeq->dev;
        struct request *abort_req;
-       struct nvme_cmd_info *abort_cmd;
        struct nvme_command cmd;
 
-       if (!nvmeq->qid || cmd_rq->aborted) {
-               spin_lock(&dev_list_lock);
-               if (!__nvme_reset(dev)) {
-                       dev_warn(dev->dev,
-                                "I/O %d QID %d timeout, reset controller\n",
-                                req->tag, nvmeq->qid);
-               }
-               spin_unlock(&dev_list_lock);
-               return;
+       /*
+        * Shutdown immediately if controller times out while starting. The
+        * reset work will see the pci device disabled when it gets the forced
+        * cancellation error. All outstanding requests are completed on
+        * shutdown, so we return BLK_EH_HANDLED.
+        */
+       if (test_bit(NVME_CTRL_RESETTING, &dev->flags)) {
+               dev_warn(dev->dev,
+                        "I/O %d QID %d timeout, disable controller\n",
+                        req->tag, nvmeq->qid);
+               nvme_dev_disable(dev, false);
+               req->errors = NVME_SC_CANCELLED;
+               return BLK_EH_HANDLED;
        }
 
-       if (!dev->abort_limit)
-               return;
+       /*
+        * Shutdown the controller immediately and schedule a reset if the
+        * command was already aborted once before and still hasn't been
+        * returned to the driver, or if this is the admin queue.
+        */
+       if (!nvmeq->qid || iod->aborted) {
+               dev_warn(dev->dev,
+                        "I/O %d QID %d timeout, reset controller\n",
+                        req->tag, nvmeq->qid);
+               nvme_dev_disable(dev, false);
+               queue_work(nvme_workq, &dev->reset_work);
 
-       abort_req = blk_mq_alloc_request(dev->admin_q, WRITE,
-                       BLK_MQ_REQ_NOWAIT);
-       if (IS_ERR(abort_req))
-               return;
+               /*
+                * Mark the request as handled, since the inline shutdown
+                * forces all outstanding requests to complete.
+                */
+               req->errors = NVME_SC_CANCELLED;
+               return BLK_EH_HANDLED;
+       }
 
-       abort_cmd = blk_mq_rq_to_pdu(abort_req);
-       nvme_set_info(abort_cmd, abort_req, abort_completion);
+       iod->aborted = 1;
+
+       if (atomic_dec_return(&dev->ctrl.abort_limit) < 0) {
+               atomic_inc(&dev->ctrl.abort_limit);
+               return BLK_EH_RESET_TIMER;
+       }
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.abort.opcode = nvme_admin_abort_cmd;
        cmd.abort.cid = req->tag;
        cmd.abort.sqid = cpu_to_le16(nvmeq->qid);
-       cmd.abort.command_id = abort_req->tag;
 
-       --dev->abort_limit;
-       cmd_rq->aborted = 1;
+       dev_warn(nvmeq->q_dmadev, "I/O %d QID %d timeout, aborting\n",
+                                req->tag, nvmeq->qid);
+
+       abort_req = nvme_alloc_request(dev->ctrl.admin_q, &cmd,
+                       BLK_MQ_REQ_NOWAIT);
+       if (IS_ERR(abort_req)) {
+               atomic_inc(&dev->ctrl.abort_limit);
+               return BLK_EH_RESET_TIMER;
+       }
+
+       abort_req->timeout = ADMIN_TIMEOUT;
+       abort_req->end_io_data = NULL;
+       blk_execute_rq_nowait(abort_req->q, NULL, abort_req, 0, abort_endio);
 
-       dev_warn(nvmeq->q_dmadev, "Aborting I/O %d QID %d\n", req->tag,
-                                                       nvmeq->qid);
-       nvme_submit_cmd(dev->queues[0], &cmd);
+       /*
+        * The aborted req will be completed on receiving the abort req.
+        * We enable the timer again. If hit twice, it'll cause a device reset,
+        * as the device then is in a faulty state.
+        */
+       return BLK_EH_RESET_TIMER;
 }
 
 static void nvme_cancel_queue_ios(struct request *req, void *data, bool reserved)
 {
        struct nvme_queue *nvmeq = data;
-       void *ctx;
-       nvme_completion_fn fn;
-       struct nvme_cmd_info *cmd;
-       struct nvme_completion cqe;
+       int status;
 
        if (!blk_mq_request_started(req))
                return;
 
-       cmd = blk_mq_rq_to_pdu(req);
-
-       if (cmd->ctx == CMD_CTX_CANCELLED)
-               return;
+       dev_warn(nvmeq->q_dmadev,
+                "Cancelling I/O %d QID %d\n", req->tag, nvmeq->qid);
 
+       status = NVME_SC_ABORT_REQ;
        if (blk_queue_dying(req->q))
-               cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1);
-       else
-               cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1);
-
-
-       dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n",
-                                               req->tag, nvmeq->qid);
-       ctx = cancel_cmd_info(cmd, &fn);
-       fn(nvmeq, ctx, &cqe);
-}
-
-static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
-{
-       struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
-       struct nvme_queue *nvmeq = cmd->nvmeq;
-
-       dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag,
-                                                       nvmeq->qid);
-       spin_lock_irq(&nvmeq->q_lock);
-       nvme_abort_req(req);
-       spin_unlock_irq(&nvmeq->q_lock);
-
-       /*
-        * The aborted req will be completed on receiving the abort req.
-        * We enable the timer again. If hit twice, it'll cause a device reset,
-        * as the device then is in a faulty state.
-        */
-       return BLK_EH_RESET_TIMER;
+               status |= NVME_SC_DNR;
+       blk_mq_complete_request(req, status);
 }
 
 static void nvme_free_queue(struct nvme_queue *nvmeq)
@@ -1430,8 +1048,8 @@ static int nvme_suspend_queue(struct nvme_queue *nvmeq)
        nvmeq->cq_vector = -1;
        spin_unlock_irq(&nvmeq->q_lock);
 
-       if (!nvmeq->qid && nvmeq->dev->admin_q)
-               blk_mq_freeze_queue_start(nvmeq->dev->admin_q);
+       if (!nvmeq->qid && nvmeq->dev->ctrl.admin_q)
+               blk_mq_stop_hw_queues(nvmeq->dev->ctrl.admin_q);
 
        irq_set_affinity_hint(vector, NULL);
        free_irq(vector, nvmeq);
@@ -1447,21 +1065,20 @@ static void nvme_clear_queue(struct nvme_queue *nvmeq)
        spin_unlock_irq(&nvmeq->q_lock);
 }
 
-static void nvme_disable_queue(struct nvme_dev *dev, int qid)
+static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown)
 {
-       struct nvme_queue *nvmeq = dev->queues[qid];
+       struct nvme_queue *nvmeq = dev->queues[0];
 
        if (!nvmeq)
                return;
        if (nvme_suspend_queue(nvmeq))
                return;
 
-       /* Don't tell the adapter to delete the admin queue.
-        * Don't tell a removed adapter to delete IO queues. */
-       if (qid && readl(&dev->bar->csts) != -1) {
-               adapter_delete_sq(dev, qid);
-               adapter_delete_cq(dev, qid);
-       }
+       if (shutdown)
+               nvme_shutdown_ctrl(&dev->ctrl);
+       else
+               nvme_disable_ctrl(&dev->ctrl, lo_hi_readq(
+                                               dev->bar + NVME_REG_CAP));
 
        spin_lock_irq(&nvmeq->q_lock);
        nvme_process_cq(nvmeq);
@@ -1472,11 +1089,12 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,
                                int entry_size)
 {
        int q_depth = dev->q_depth;
-       unsigned q_size_aligned = roundup(q_depth * entry_size, dev->page_size);
+       unsigned q_size_aligned = roundup(q_depth * entry_size,
+                                         dev->ctrl.page_size);
 
        if (q_size_aligned * nr_io_queues > dev->cmb_size) {
                u64 mem_per_q = div_u64(dev->cmb_size, nr_io_queues);
-               mem_per_q = round_down(mem_per_q, dev->page_size);
+               mem_per_q = round_down(mem_per_q, dev->ctrl.page_size);
                q_depth = div_u64(mem_per_q, entry_size);
 
                /*
@@ -1495,8 +1113,8 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
                                int qid, int depth)
 {
        if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) {
-               unsigned offset = (qid - 1) *
-                                       roundup(SQ_SIZE(depth), dev->page_size);
+               unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth),
+                                                     dev->ctrl.page_size);
                nvmeq->sq_dma_addr = dev->cmb_dma_addr + offset;
                nvmeq->sq_cmds_io = dev->cmb + offset;
        } else {
@@ -1527,7 +1145,7 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
        nvmeq->q_dmadev = dev->dev;
        nvmeq->dev = dev;
        snprintf(nvmeq->irqname, sizeof(nvmeq->irqname), "nvme%dq%d",
-                       dev->instance, qid);
+                       dev->ctrl.instance, qid);
        spin_lock_init(&nvmeq->q_lock);
        nvmeq->cq_head = 0;
        nvmeq->cq_phase = 1;
@@ -1604,79 +1222,9 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
        return result;
 }
 
-static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled)
-{
-       unsigned long timeout;
-       u32 bit = enabled ? NVME_CSTS_RDY : 0;
-
-       timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
-
-       while ((readl(&dev->bar->csts) & NVME_CSTS_RDY) != bit) {
-               msleep(100);
-               if (fatal_signal_pending(current))
-                       return -EINTR;
-               if (time_after(jiffies, timeout)) {
-                       dev_err(dev->dev,
-                               "Device not ready; aborting %s\n", enabled ?
-                                               "initialisation" : "reset");
-                       return -ENODEV;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * If the device has been passed off to us in an enabled state, just clear
- * the enabled bit.  The spec says we should set the 'shutdown notification
- * bits', but doing so may cause the device to complete commands to the
- * admin queue ... and we don't know what memory that might be pointing at!
- */
-static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap)
-{
-       dev->ctrl_config &= ~NVME_CC_SHN_MASK;
-       dev->ctrl_config &= ~NVME_CC_ENABLE;
-       writel(dev->ctrl_config, &dev->bar->cc);
-
-       return nvme_wait_ready(dev, cap, false);
-}
-
-static int nvme_enable_ctrl(struct nvme_dev *dev, u64 cap)
-{
-       dev->ctrl_config &= ~NVME_CC_SHN_MASK;
-       dev->ctrl_config |= NVME_CC_ENABLE;
-       writel(dev->ctrl_config, &dev->bar->cc);
-
-       return nvme_wait_ready(dev, cap, true);
-}
-
-static int nvme_shutdown_ctrl(struct nvme_dev *dev)
-{
-       unsigned long timeout;
-
-       dev->ctrl_config &= ~NVME_CC_SHN_MASK;
-       dev->ctrl_config |= NVME_CC_SHN_NORMAL;
-
-       writel(dev->ctrl_config, &dev->bar->cc);
-
-       timeout = SHUTDOWN_TIMEOUT + jiffies;
-       while ((readl(&dev->bar->csts) & NVME_CSTS_SHST_MASK) !=
-                                                       NVME_CSTS_SHST_CMPLT) {
-               msleep(100);
-               if (fatal_signal_pending(current))
-                       return -EINTR;
-               if (time_after(jiffies, timeout)) {
-                       dev_err(dev->dev,
-                               "Device shutdown incomplete; abort shutdown\n");
-                       return -ENODEV;
-               }
-       }
-
-       return 0;
-}
-
 static struct blk_mq_ops nvme_mq_admin_ops = {
        .queue_rq       = nvme_queue_rq,
+       .complete       = nvme_complete_rq,
        .map_queue      = blk_mq_map_queue,
        .init_hctx      = nvme_admin_init_hctx,
        .exit_hctx      = nvme_admin_exit_hctx,
@@ -1686,6 +1234,7 @@ static struct blk_mq_ops nvme_mq_admin_ops = {
 
 static struct blk_mq_ops nvme_mq_ops = {
        .queue_rq       = nvme_queue_rq,
+       .complete       = nvme_complete_rq,
        .map_queue      = blk_mq_map_queue,
        .init_hctx      = nvme_init_hctx,
        .init_request   = nvme_init_request,
@@ -1695,19 +1244,23 @@ static struct blk_mq_ops nvme_mq_ops = {
 
 static void nvme_dev_remove_admin(struct nvme_dev *dev)
 {
-       if (dev->admin_q && !blk_queue_dying(dev->admin_q)) {
-               blk_cleanup_queue(dev->admin_q);
+       if (dev->ctrl.admin_q && !blk_queue_dying(dev->ctrl.admin_q)) {
+               blk_cleanup_queue(dev->ctrl.admin_q);
                blk_mq_free_tag_set(&dev->admin_tagset);
        }
 }
 
 static int nvme_alloc_admin_tags(struct nvme_dev *dev)
 {
-       if (!dev->admin_q) {
+       if (!dev->ctrl.admin_q) {
                dev->admin_tagset.ops = &nvme_mq_admin_ops;
                dev->admin_tagset.nr_hw_queues = 1;
-               dev->admin_tagset.queue_depth = NVME_AQ_DEPTH - 1;
-               dev->admin_tagset.reserved_tags = 1;
+
+               /*
+                * Subtract one to leave an empty queue entry for 'Full Queue'
+                * condition. See NVM-Express 1.2 specification, section 4.1.2.
+                */
+               dev->admin_tagset.queue_depth = NVME_AQ_BLKMQ_DEPTH - 1;
                dev->admin_tagset.timeout = ADMIN_TIMEOUT;
                dev->admin_tagset.numa_node = dev_to_node(dev->dev);
                dev->admin_tagset.cmd_size = nvme_cmd_size(dev);
@@ -1716,18 +1269,18 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
                if (blk_mq_alloc_tag_set(&dev->admin_tagset))
                        return -ENOMEM;
 
-               dev->admin_q = blk_mq_init_queue(&dev->admin_tagset);
-               if (IS_ERR(dev->admin_q)) {
+               dev->ctrl.admin_q = blk_mq_init_queue(&dev->admin_tagset);
+               if (IS_ERR(dev->ctrl.admin_q)) {
                        blk_mq_free_tag_set(&dev->admin_tagset);
                        return -ENOMEM;
                }
-               if (!blk_get_queue(dev->admin_q)) {
+               if (!blk_get_queue(dev->ctrl.admin_q)) {
                        nvme_dev_remove_admin(dev);
-                       dev->admin_q = NULL;
+                       dev->ctrl.admin_q = NULL;
                        return -ENODEV;
                }
        } else
-               blk_mq_unfreeze_queue(dev->admin_q);
+               blk_mq_start_stopped_hw_queues(dev->ctrl.admin_q, true);
 
        return 0;
 }
@@ -1736,31 +1289,17 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
 {
        int result;
        u32 aqa;
-       u64 cap = lo_hi_readq(&dev->bar->cap);
+       u64 cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
        struct nvme_queue *nvmeq;
-       /*
-        * default to a 4K page size, with the intention to update this
-        * path in the future to accomodate architectures with differing
-        * kernel and IO page sizes.
-        */
-       unsigned page_shift = 12;
-       unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
-
-       if (page_shift < dev_page_min) {
-               dev_err(dev->dev,
-                               "Minimum device page size (%u) too large for "
-                               "host (%u)\n", 1 << dev_page_min,
-                               1 << page_shift);
-               return -ENODEV;
-       }
 
-       dev->subsystem = readl(&dev->bar->vs) >= NVME_VS(1, 1) ?
+       dev->subsystem = readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 1) ?
                                                NVME_CAP_NSSRC(cap) : 0;
 
-       if (dev->subsystem && (readl(&dev->bar->csts) & NVME_CSTS_NSSRO))
-               writel(NVME_CSTS_NSSRO, &dev->bar->csts);
+       if (dev->subsystem &&
+           (readl(dev->bar + NVME_REG_CSTS) & NVME_CSTS_NSSRO))
+               writel(NVME_CSTS_NSSRO, dev->bar + NVME_REG_CSTS);
 
-       result = nvme_disable_ctrl(dev, cap);
+       result = nvme_disable_ctrl(&dev->ctrl, cap);
        if (result < 0)
                return result;
 
@@ -1774,18 +1313,11 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
        aqa = nvmeq->q_depth - 1;
        aqa |= aqa << 16;
 
-       dev->page_size = 1 << page_shift;
-
-       dev->ctrl_config = NVME_CC_CSS_NVM;
-       dev->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT;
-       dev->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE;
-       dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
-
-       writel(aqa, &dev->bar->aqa);
-       lo_hi_writeq(nvmeq->sq_dma_addr, &dev->bar->asq);
-       lo_hi_writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
+       writel(aqa, dev->bar + NVME_REG_AQA);
+       lo_hi_writeq(nvmeq->sq_dma_addr, dev->bar + NVME_REG_ASQ);
+       lo_hi_writeq(nvmeq->cq_dma_addr, dev->bar + NVME_REG_ACQ);
 
-       result = nvme_enable_ctrl(dev, cap);
+       result = nvme_enable_ctrl(&dev->ctrl, cap);
        if (result)
                goto free_nvmeq;
 
@@ -1803,406 +1335,6 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
        return result;
 }
 
-static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
-{
-       struct nvme_dev *dev = ns->dev;
-       struct nvme_user_io io;
-       struct nvme_command c;
-       unsigned length, meta_len;
-       int status, write;
-       dma_addr_t meta_dma = 0;
-       void *meta = NULL;
-       void __user *metadata;
-
-       if (copy_from_user(&io, uio, sizeof(io)))
-               return -EFAULT;
-
-       switch (io.opcode) {
-       case nvme_cmd_write:
-       case nvme_cmd_read:
-       case nvme_cmd_compare:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       length = (io.nblocks + 1) << ns->lba_shift;
-       meta_len = (io.nblocks + 1) * ns->ms;
-       metadata = (void __user *)(uintptr_t)io.metadata;
-       write = io.opcode & 1;
-
-       if (ns->ext) {
-               length += meta_len;
-               meta_len = 0;
-       }
-       if (meta_len) {
-               if (((io.metadata & 3) || !io.metadata) && !ns->ext)
-                       return -EINVAL;
-
-               meta = dma_alloc_coherent(dev->dev, meta_len,
-                                               &meta_dma, GFP_KERNEL);
-
-               if (!meta) {
-                       status = -ENOMEM;
-                       goto unmap;
-               }
-               if (write) {
-                       if (copy_from_user(meta, metadata, meta_len)) {
-                               status = -EFAULT;
-                               goto unmap;
-                       }
-               }
-       }
-
-       memset(&c, 0, sizeof(c));
-       c.rw.opcode = io.opcode;
-       c.rw.flags = io.flags;
-       c.rw.nsid = cpu_to_le32(ns->ns_id);
-       c.rw.slba = cpu_to_le64(io.slba);
-       c.rw.length = cpu_to_le16(io.nblocks);
-       c.rw.control = cpu_to_le16(io.control);
-       c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
-       c.rw.reftag = cpu_to_le32(io.reftag);
-       c.rw.apptag = cpu_to_le16(io.apptag);
-       c.rw.appmask = cpu_to_le16(io.appmask);
-       c.rw.metadata = cpu_to_le64(meta_dma);
-
-       status = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
-                       (void __user *)(uintptr_t)io.addr, length, NULL, 0);
- unmap:
-       if (meta) {
-               if (status == NVME_SC_SUCCESS && !write) {
-                       if (copy_to_user(metadata, meta, meta_len))
-                               status = -EFAULT;
-               }
-               dma_free_coherent(dev->dev, meta_len, meta, meta_dma);
-       }
-       return status;
-}
-
-static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns,
-                       struct nvme_passthru_cmd __user *ucmd)
-{
-       struct nvme_passthru_cmd cmd;
-       struct nvme_command c;
-       unsigned timeout = 0;
-       int status;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-       if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
-               return -EFAULT;
-
-       memset(&c, 0, sizeof(c));
-       c.common.opcode = cmd.opcode;
-       c.common.flags = cmd.flags;
-       c.common.nsid = cpu_to_le32(cmd.nsid);
-       c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
-       c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
-       c.common.cdw10[0] = cpu_to_le32(cmd.cdw10);
-       c.common.cdw10[1] = cpu_to_le32(cmd.cdw11);
-       c.common.cdw10[2] = cpu_to_le32(cmd.cdw12);
-       c.common.cdw10[3] = cpu_to_le32(cmd.cdw13);
-       c.common.cdw10[4] = cpu_to_le32(cmd.cdw14);
-       c.common.cdw10[5] = cpu_to_le32(cmd.cdw15);
-
-       if (cmd.timeout_ms)
-               timeout = msecs_to_jiffies(cmd.timeout_ms);
-
-       status = __nvme_submit_sync_cmd(ns ? ns->queue : dev->admin_q, &c,
-                       NULL, (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
-                       &cmd.result, timeout);
-       if (status >= 0) {
-               if (put_user(cmd.result, &ucmd->result))
-                       return -EFAULT;
-       }
-
-       return status;
-}
-
-static int nvme_subsys_reset(struct nvme_dev *dev)
-{
-       if (!dev->subsystem)
-               return -ENOTTY;
-
-       writel(0x4E564D65, &dev->bar->nssr); /* "NVMe" */
-       return 0;
-}
-
-static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
-                                                       unsigned long arg)
-{
-       struct nvme_ns *ns = bdev->bd_disk->private_data;
-
-       switch (cmd) {
-       case NVME_IOCTL_ID:
-               force_successful_syscall_return();
-               return ns->ns_id;
-       case NVME_IOCTL_ADMIN_CMD:
-               return nvme_user_cmd(ns->dev, NULL, (void __user *)arg);
-       case NVME_IOCTL_IO_CMD:
-               return nvme_user_cmd(ns->dev, ns, (void __user *)arg);
-       case NVME_IOCTL_SUBMIT_IO:
-               return nvme_submit_io(ns, (void __user *)arg);
-       case SG_GET_VERSION_NUM:
-               return nvme_sg_get_version_num((void __user *)arg);
-       case SG_IO:
-               return nvme_sg_io(ns, (void __user *)arg);
-       default:
-               return -ENOTTY;
-       }
-}
-
-#ifdef CONFIG_COMPAT
-static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode,
-                                       unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case SG_IO:
-               return -ENOIOCTLCMD;
-       }
-       return nvme_ioctl(bdev, mode, cmd, arg);
-}
-#else
-#define nvme_compat_ioctl      NULL
-#endif
-
-static void nvme_free_dev(struct kref *kref);
-static void nvme_free_ns(struct kref *kref)
-{
-       struct nvme_ns *ns = container_of(kref, struct nvme_ns, kref);
-
-       if (ns->type == NVME_NS_LIGHTNVM)
-               nvme_nvm_unregister(ns->queue, ns->disk->disk_name);
-
-       spin_lock(&dev_list_lock);
-       ns->disk->private_data = NULL;
-       spin_unlock(&dev_list_lock);
-
-       kref_put(&ns->dev->kref, nvme_free_dev);
-       put_disk(ns->disk);
-       kfree(ns);
-}
-
-static int nvme_open(struct block_device *bdev, fmode_t mode)
-{
-       int ret = 0;
-       struct nvme_ns *ns;
-
-       spin_lock(&dev_list_lock);
-       ns = bdev->bd_disk->private_data;
-       if (!ns)
-               ret = -ENXIO;
-       else if (!kref_get_unless_zero(&ns->kref))
-               ret = -ENXIO;
-       spin_unlock(&dev_list_lock);
-
-       return ret;
-}
-
-static void nvme_release(struct gendisk *disk, fmode_t mode)
-{
-       struct nvme_ns *ns = disk->private_data;
-       kref_put(&ns->kref, nvme_free_ns);
-}
-
-static int nvme_getgeo(struct block_device *bd, struct hd_geometry *geo)
-{
-       /* some standard values */
-       geo->heads = 1 << 6;
-       geo->sectors = 1 << 5;
-       geo->cylinders = get_capacity(bd->bd_disk) >> 11;
-       return 0;
-}
-
-static void nvme_config_discard(struct nvme_ns *ns)
-{
-       u32 logical_block_size = queue_logical_block_size(ns->queue);
-       ns->queue->limits.discard_zeroes_data = 0;
-       ns->queue->limits.discard_alignment = logical_block_size;
-       ns->queue->limits.discard_granularity = logical_block_size;
-       blk_queue_max_discard_sectors(ns->queue, 0xffffffff);
-       queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue);
-}
-
-static int nvme_revalidate_disk(struct gendisk *disk)
-{
-       struct nvme_ns *ns = disk->private_data;
-       struct nvme_dev *dev = ns->dev;
-       struct nvme_id_ns *id;
-       u8 lbaf, pi_type;
-       u16 old_ms;
-       unsigned short bs;
-
-       if (nvme_identify_ns(dev, ns->ns_id, &id)) {
-               dev_warn(dev->dev, "%s: Identify failure nvme%dn%d\n", __func__,
-                                               dev->instance, ns->ns_id);
-               return -ENODEV;
-       }
-       if (id->ncap == 0) {
-               kfree(id);
-               return -ENODEV;
-       }
-
-       if (nvme_nvm_ns_supported(ns, id) && ns->type != NVME_NS_LIGHTNVM) {
-               if (nvme_nvm_register(ns->queue, disk->disk_name)) {
-                       dev_warn(dev->dev,
-                               "%s: LightNVM init failure\n", __func__);
-                       kfree(id);
-                       return -ENODEV;
-               }
-               ns->type = NVME_NS_LIGHTNVM;
-       }
-
-       old_ms = ns->ms;
-       lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK;
-       ns->lba_shift = id->lbaf[lbaf].ds;
-       ns->ms = le16_to_cpu(id->lbaf[lbaf].ms);
-       ns->ext = ns->ms && (id->flbas & NVME_NS_FLBAS_META_EXT);
-
-       /*
-        * If identify namespace failed, use default 512 byte block size so
-        * block layer can use before failing read/write for 0 capacity.
-        */
-       if (ns->lba_shift == 0)
-               ns->lba_shift = 9;
-       bs = 1 << ns->lba_shift;
-
-       /* XXX: PI implementation requires metadata equal t10 pi tuple size */
-       pi_type = ns->ms == sizeof(struct t10_pi_tuple) ?
-                                       id->dps & NVME_NS_DPS_PI_MASK : 0;
-
-       blk_mq_freeze_queue(disk->queue);
-       if (blk_get_integrity(disk) && (ns->pi_type != pi_type ||
-                               ns->ms != old_ms ||
-                               bs != queue_logical_block_size(disk->queue) ||
-                               (ns->ms && ns->ext)))
-               blk_integrity_unregister(disk);
-
-       ns->pi_type = pi_type;
-       blk_queue_logical_block_size(ns->queue, bs);
-
-       if (ns->ms && !ns->ext)
-               nvme_init_integrity(ns);
-
-       if ((ns->ms && !(ns->ms == 8 && ns->pi_type) &&
-                                               !blk_get_integrity(disk)) ||
-                                               ns->type == NVME_NS_LIGHTNVM)
-               set_capacity(disk, 0);
-       else
-               set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9));
-
-       if (dev->oncs & NVME_CTRL_ONCS_DSM)
-               nvme_config_discard(ns);
-       blk_mq_unfreeze_queue(disk->queue);
-
-       kfree(id);
-       return 0;
-}
-
-static char nvme_pr_type(enum pr_type type)
-{
-       switch (type) {
-       case PR_WRITE_EXCLUSIVE:
-               return 1;
-       case PR_EXCLUSIVE_ACCESS:
-               return 2;
-       case PR_WRITE_EXCLUSIVE_REG_ONLY:
-               return 3;
-       case PR_EXCLUSIVE_ACCESS_REG_ONLY:
-               return 4;
-       case PR_WRITE_EXCLUSIVE_ALL_REGS:
-               return 5;
-       case PR_EXCLUSIVE_ACCESS_ALL_REGS:
-               return 6;
-       default:
-               return 0;
-       }
-};
-
-static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
-                               u64 key, u64 sa_key, u8 op)
-{
-       struct nvme_ns *ns = bdev->bd_disk->private_data;
-       struct nvme_command c;
-       u8 data[16] = { 0, };
-
-       put_unaligned_le64(key, &data[0]);
-       put_unaligned_le64(sa_key, &data[8]);
-
-       memset(&c, 0, sizeof(c));
-       c.common.opcode = op;
-       c.common.nsid = cpu_to_le32(ns->ns_id);
-       c.common.cdw10[0] = cpu_to_le32(cdw10);
-
-       return nvme_submit_sync_cmd(ns->queue, &c, data, 16);
-}
-
-static int nvme_pr_register(struct block_device *bdev, u64 old,
-               u64 new, unsigned flags)
-{
-       u32 cdw10;
-
-       if (flags & ~PR_FL_IGNORE_KEY)
-               return -EOPNOTSUPP;
-
-       cdw10 = old ? 2 : 0;
-       cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0;
-       cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */
-       return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register);
-}
-
-static int nvme_pr_reserve(struct block_device *bdev, u64 key,
-               enum pr_type type, unsigned flags)
-{
-       u32 cdw10;
-
-       if (flags & ~PR_FL_IGNORE_KEY)
-               return -EOPNOTSUPP;
-
-       cdw10 = nvme_pr_type(type) << 8;
-       cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0);
-       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire);
-}
-
-static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
-               enum pr_type type, bool abort)
-{
-       u32 cdw10 = nvme_pr_type(type) << 8 | abort ? 2 : 1;
-       return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire);
-}
-
-static int nvme_pr_clear(struct block_device *bdev, u64 key)
-{
-       u32 cdw10 = 1 | (key ? 1 << 3 : 0);
-       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
-}
-
-static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
-{
-       u32 cdw10 = nvme_pr_type(type) << 8 | key ? 1 << 3 : 0;
-       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
-}
-
-static const struct pr_ops nvme_pr_ops = {
-       .pr_register    = nvme_pr_register,
-       .pr_reserve     = nvme_pr_reserve,
-       .pr_release     = nvme_pr_release,
-       .pr_preempt     = nvme_pr_preempt,
-       .pr_clear       = nvme_pr_clear,
-};
-
-static const struct block_device_operations nvme_fops = {
-       .owner          = THIS_MODULE,
-       .ioctl          = nvme_ioctl,
-       .compat_ioctl   = nvme_compat_ioctl,
-       .open           = nvme_open,
-       .release        = nvme_release,
-       .getgeo         = nvme_getgeo,
-       .revalidate_disk= nvme_revalidate_disk,
-       .pr_ops         = &nvme_pr_ops,
-};
-
 static int nvme_kthread(void *data)
 {
        struct nvme_dev *dev, *next;
@@ -2212,14 +1344,20 @@ static int nvme_kthread(void *data)
                spin_lock(&dev_list_lock);
                list_for_each_entry_safe(dev, next, &dev_list, node) {
                        int i;
-                       u32 csts = readl(&dev->bar->csts);
+                       u32 csts = readl(dev->bar + NVME_REG_CSTS);
+
+                       /*
+                        * Skip controllers currently under reset.
+                        */
+                       if (work_pending(&dev->reset_work) || work_busy(&dev->reset_work))
+                               continue;
 
                        if ((dev->subsystem && (csts & NVME_CSTS_NSSRO)) ||
                                                        csts & NVME_CSTS_CFS) {
-                               if (!__nvme_reset(dev)) {
+                               if (queue_work(nvme_workq, &dev->reset_work)) {
                                        dev_warn(dev->dev,
                                                "Failed status: %x, reset controller\n",
-                                               readl(&dev->bar->csts));
+                                               readl(dev->bar + NVME_REG_CSTS));
                                }
                                continue;
                        }
@@ -2230,11 +1368,8 @@ static int nvme_kthread(void *data)
                                spin_lock_irq(&nvmeq->q_lock);
                                nvme_process_cq(nvmeq);
 
-                               while ((i == 0) && (dev->event_limit > 0)) {
-                                       if (nvme_submit_async_admin_req(dev))
-                                               break;
-                                       dev->event_limit--;
-                               }
+                               while (i == 0 && dev->ctrl.event_limit > 0)
+                                       nvme_submit_async_event(dev);
                                spin_unlock_irq(&nvmeq->q_lock);
                        }
                }
@@ -2244,127 +1379,33 @@ static int nvme_kthread(void *data)
        return 0;
 }
 
-static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
-{
-       struct nvme_ns *ns;
-       struct gendisk *disk;
-       int node = dev_to_node(dev->dev);
-
-       ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
-       if (!ns)
-               return;
-
-       ns->queue = blk_mq_init_queue(&dev->tagset);
-       if (IS_ERR(ns->queue))
-               goto out_free_ns;
-       queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue);
-       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue);
-       ns->dev = dev;
-       ns->queue->queuedata = ns;
-
-       disk = alloc_disk_node(0, node);
-       if (!disk)
-               goto out_free_queue;
-
-       kref_init(&ns->kref);
-       ns->ns_id = nsid;
-       ns->disk = disk;
-       ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */
-       list_add_tail(&ns->list, &dev->namespaces);
-
-       blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
-       if (dev->max_hw_sectors) {
-               blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors);
-               blk_queue_max_segments(ns->queue,
-                       (dev->max_hw_sectors / (dev->page_size >> 9)) + 1);
-       }
-       if (dev->stripe_size)
-               blk_queue_chunk_sectors(ns->queue, dev->stripe_size >> 9);
-       if (dev->vwc & NVME_CTRL_VWC_PRESENT)
-               blk_queue_flush(ns->queue, REQ_FLUSH | REQ_FUA);
-       blk_queue_virt_boundary(ns->queue, dev->page_size - 1);
-
-       disk->major = nvme_major;
-       disk->first_minor = 0;
-       disk->fops = &nvme_fops;
-       disk->private_data = ns;
-       disk->queue = ns->queue;
-       disk->driverfs_dev = dev->device;
-       disk->flags = GENHD_FL_EXT_DEVT;
-       sprintf(disk->disk_name, "nvme%dn%d", dev->instance, nsid);
-
-       /*
-        * Initialize capacity to 0 until we establish the namespace format and
-        * setup integrity extentions if necessary. The revalidate_disk after
-        * add_disk allows the driver to register with integrity if the format
-        * requires it.
-        */
-       set_capacity(disk, 0);
-       if (nvme_revalidate_disk(ns->disk))
-               goto out_free_disk;
-
-       kref_get(&dev->kref);
-       if (ns->type != NVME_NS_LIGHTNVM) {
-               add_disk(ns->disk);
-               if (ns->ms) {
-                       struct block_device *bd = bdget_disk(ns->disk, 0);
-                       if (!bd)
-                               return;
-                       if (blkdev_get(bd, FMODE_READ, NULL)) {
-                               bdput(bd);
-                               return;
-                       }
-                       blkdev_reread_part(bd);
-                       blkdev_put(bd, FMODE_READ);
-               }
-       }
-       return;
- out_free_disk:
-       kfree(disk);
-       list_del(&ns->list);
- out_free_queue:
-       blk_cleanup_queue(ns->queue);
- out_free_ns:
-       kfree(ns);
-}
-
-/*
- * Create I/O queues.  Failing to create an I/O queue is not an issue,
- * we can continue with less than the desired amount of queues, and
- * even a controller without I/O queues an still be used to issue
- * admin commands.  This might be useful to upgrade a buggy firmware
- * for example.
- */
-static void nvme_create_io_queues(struct nvme_dev *dev)
+static int nvme_create_io_queues(struct nvme_dev *dev)
 {
        unsigned i;
+       int ret = 0;
 
-       for (i = dev->queue_count; i <= dev->max_qid; i++)
-               if (!nvme_alloc_queue(dev, i, dev->q_depth))
+       for (i = dev->queue_count; i <= dev->max_qid; i++) {
+               if (!nvme_alloc_queue(dev, i, dev->q_depth)) {
+                       ret = -ENOMEM;
                        break;
+               }
+       }
 
-       for (i = dev->online_queues; i <= dev->queue_count - 1; i++)
-               if (nvme_create_queue(dev->queues[i], i)) {
+       for (i = dev->online_queues; i <= dev->queue_count - 1; i++) {
+               ret = nvme_create_queue(dev->queues[i], i);
+               if (ret) {
                        nvme_free_queues(dev, i);
                        break;
                }
-}
-
-static int set_queue_count(struct nvme_dev *dev, int count)
-{
-       int status;
-       u32 result;
-       u32 q_count = (count - 1) | ((count - 1) << 16);
-
-       status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES, q_count, 0,
-                                                               &result);
-       if (status < 0)
-               return status;
-       if (status > 0) {
-               dev_err(dev->dev, "Could not set queue count (%d)\n", status);
-               return 0;
        }
-       return min(result & 0xffff, result >> 16) + 1;
+
+       /*
+        * Ignore failing Create SQ/CQ commands, we can continue with less
+        * than the desired aount of queues, and even a controller without
+        * I/O queues an still be used to issue admin commands.  This might
+        * be useful to upgrade a buggy firmware for example.
+        */
+       return ret >= 0 ? 0 : ret;
 }
 
 static void __iomem *nvme_map_cmb(struct nvme_dev *dev)
@@ -2379,11 +1420,11 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev)
        if (!use_cmb_sqes)
                return NULL;
 
-       dev->cmbsz = readl(&dev->bar->cmbsz);
+       dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ);
        if (!(NVME_CMB_SZ(dev->cmbsz)))
                return NULL;
 
-       cmbloc = readl(&dev->bar->cmbloc);
+       cmbloc = readl(dev->bar + NVME_REG_CMBLOC);
 
        szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz));
        size = szu * NVME_CMB_SZ(dev->cmbsz);
@@ -2431,11 +1472,20 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        int result, i, vecs, nr_io_queues, size;
 
        nr_io_queues = num_possible_cpus();
-       result = set_queue_count(dev, nr_io_queues);
-       if (result <= 0)
+       result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues);
+       if (result < 0)
                return result;
-       if (result < nr_io_queues)
-               nr_io_queues = result;
+
+       /*
+        * Degraded controllers might return an error when setting the queue
+        * count.  We still want to be able to bring them online and offer
+        * access to the admin queue, as that might be only way to fix them up.
+        */
+       if (result > 0) {
+               dev_err(dev->dev, "Could not set queue count (%d)\n", result);
+               nr_io_queues = 0;
+               result = 0;
+       }
 
        if (dev->cmb && NVME_CMB_SQS(dev->cmbsz)) {
                result = nvme_cmb_qdepth(dev, nr_io_queues,
@@ -2457,7 +1507,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
                                return -ENOMEM;
                        size = db_bar_size(dev, nr_io_queues);
                } while (1);
-               dev->dbs = ((void __iomem *)dev->bar) + 4096;
+               dev->dbs = dev->bar + 4096;
                adminq->q_db = dev->dbs;
        }
 
@@ -2501,115 +1551,115 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
 
        /* Free previously allocated queues that are no longer usable */
        nvme_free_queues(dev, nr_io_queues + 1);
-       nvme_create_io_queues(dev);
-
-       return 0;
+       return nvme_create_io_queues(dev);
 
  free_queues:
        nvme_free_queues(dev, 1);
        return result;
 }
 
-static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
+static void nvme_set_irq_hints(struct nvme_dev *dev)
 {
-       struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
-       struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
+       struct nvme_queue *nvmeq;
+       int i;
 
-       return nsa->ns_id - nsb->ns_id;
-}
+       for (i = 0; i < dev->online_queues; i++) {
+               nvmeq = dev->queues[i];
 
-static struct nvme_ns *nvme_find_ns(struct nvme_dev *dev, unsigned nsid)
-{
-       struct nvme_ns *ns;
+               if (!nvmeq->tags || !(*nvmeq->tags))
+                       continue;
 
-       list_for_each_entry(ns, &dev->namespaces, list) {
-               if (ns->ns_id == nsid)
-                       return ns;
-               if (ns->ns_id > nsid)
-                       break;
+               irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector,
+                                       blk_mq_tags_cpumask(*nvmeq->tags));
        }
-       return NULL;
 }
 
-static inline bool nvme_io_incapable(struct nvme_dev *dev)
+static void nvme_dev_scan(struct work_struct *work)
 {
-       return (!dev->bar || readl(&dev->bar->csts) & NVME_CSTS_CFS ||
-                                                       dev->online_queues < 2);
+       struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work);
+
+       if (!dev->tagset.tags)
+               return;
+       nvme_scan_namespaces(&dev->ctrl);
+       nvme_set_irq_hints(dev);
 }
 
-static void nvme_ns_remove(struct nvme_ns *ns)
+static void nvme_del_queue_end(struct request *req, int error)
 {
-       bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
-
-       if (kill) {
-               blk_set_queue_dying(ns->queue);
+       struct nvme_queue *nvmeq = req->end_io_data;
 
-               /*
-                * The controller was shutdown first if we got here through
-                * device removal. The shutdown may requeue outstanding
-                * requests. These need to be aborted immediately so
-                * del_gendisk doesn't block indefinitely for their completion.
-                */
-               blk_mq_abort_requeue_list(ns->queue);
-       }
-       if (ns->disk->flags & GENHD_FL_UP)
-               del_gendisk(ns->disk);
-       if (kill || !blk_queue_dying(ns->queue)) {
-               blk_mq_abort_requeue_list(ns->queue);
-               blk_cleanup_queue(ns->queue);
-       }
-       list_del_init(&ns->list);
-       kref_put(&ns->kref, nvme_free_ns);
+       blk_mq_free_request(req);
+       complete(&nvmeq->dev->ioq_wait);
 }
 
-static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn)
+static void nvme_del_cq_end(struct request *req, int error)
 {
-       struct nvme_ns *ns, *next;
-       unsigned i;
+       struct nvme_queue *nvmeq = req->end_io_data;
 
-       for (i = 1; i <= nn; i++) {
-               ns = nvme_find_ns(dev, i);
-               if (ns) {
-                       if (revalidate_disk(ns->disk))
-                               nvme_ns_remove(ns);
-               } else
-                       nvme_alloc_ns(dev, i);
-       }
-       list_for_each_entry_safe(ns, next, &dev->namespaces, list) {
-               if (ns->ns_id > nn)
-                       nvme_ns_remove(ns);
+       if (!error) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&nvmeq->q_lock, flags);
+               nvme_process_cq(nvmeq);
+               spin_unlock_irqrestore(&nvmeq->q_lock, flags);
        }
-       list_sort(NULL, &dev->namespaces, ns_cmp);
+
+       nvme_del_queue_end(req, error);
 }
 
-static void nvme_set_irq_hints(struct nvme_dev *dev)
+static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
 {
-       struct nvme_queue *nvmeq;
-       int i;
+       struct request_queue *q = nvmeq->dev->ctrl.admin_q;
+       struct request *req;
+       struct nvme_command cmd;
 
-       for (i = 0; i < dev->online_queues; i++) {
-               nvmeq = dev->queues[i];
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.delete_queue.opcode = opcode;
+       cmd.delete_queue.qid = cpu_to_le16(nvmeq->qid);
 
-               if (!nvmeq->tags || !(*nvmeq->tags))
-                       continue;
+       req = nvme_alloc_request(q, &cmd, BLK_MQ_REQ_NOWAIT);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
 
-               irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector,
-                                       blk_mq_tags_cpumask(*nvmeq->tags));
-       }
+       req->timeout = ADMIN_TIMEOUT;
+       req->end_io_data = nvmeq;
+
+       blk_execute_rq_nowait(q, NULL, req, false,
+                       opcode == nvme_admin_delete_cq ?
+                               nvme_del_cq_end : nvme_del_queue_end);
+       return 0;
 }
 
-static void nvme_dev_scan(struct work_struct *work)
+static void nvme_disable_io_queues(struct nvme_dev *dev)
 {
-       struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work);
-       struct nvme_id_ctrl *ctrl;
+       int pass;
+       unsigned long timeout;
+       u8 opcode = nvme_admin_delete_sq;
 
-       if (!dev->tagset.tags)
-               return;
-       if (nvme_identify_ctrl(dev, &ctrl))
-               return;
-       nvme_scan_namespaces(dev, le32_to_cpup(&ctrl->nn));
-       kfree(ctrl);
-       nvme_set_irq_hints(dev);
+       for (pass = 0; pass < 2; pass++) {
+               int sent = 0, i = dev->queue_count - 1;
+
+               reinit_completion(&dev->ioq_wait);
+ retry:
+               timeout = ADMIN_TIMEOUT;
+               for (; i > 0; i--) {
+                       struct nvme_queue *nvmeq = dev->queues[i];
+
+                       if (!pass)
+                               nvme_suspend_queue(nvmeq);
+                       if (nvme_delete_queue(nvmeq, opcode))
+                               break;
+                       ++sent;
+               }
+               while (sent--) {
+                       timeout = wait_for_completion_io_timeout(&dev->ioq_wait, timeout);
+                       if (timeout == 0)
+                               return;
+                       if (i)
+                               goto retry;
+               }
+               opcode = nvme_admin_delete_cq;
+       }
 }
 
 /*
@@ -2620,42 +1670,7 @@ static void nvme_dev_scan(struct work_struct *work)
  */
 static int nvme_dev_add(struct nvme_dev *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev->dev);
-       int res;
-       struct nvme_id_ctrl *ctrl;
-       int shift = NVME_CAP_MPSMIN(lo_hi_readq(&dev->bar->cap)) + 12;
-
-       res = nvme_identify_ctrl(dev, &ctrl);
-       if (res) {
-               dev_err(dev->dev, "Identify Controller failed (%d)\n", res);
-               return -EIO;
-       }
-
-       dev->oncs = le16_to_cpup(&ctrl->oncs);
-       dev->abort_limit = ctrl->acl + 1;
-       dev->vwc = ctrl->vwc;
-       memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn));
-       memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn));
-       memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
-       if (ctrl->mdts)
-               dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9);
-       else
-               dev->max_hw_sectors = UINT_MAX;
-       if ((pdev->vendor == PCI_VENDOR_ID_INTEL) &&
-                       (pdev->device == 0x0953) && ctrl->vs[3]) {
-               unsigned int max_hw_sectors;
-
-               dev->stripe_size = 1 << (ctrl->vs[3] + shift);
-               max_hw_sectors = dev->stripe_size >> (shift - 9);
-               if (dev->max_hw_sectors) {
-                       dev->max_hw_sectors = min(max_hw_sectors,
-                                                       dev->max_hw_sectors);
-               } else
-                       dev->max_hw_sectors = max_hw_sectors;
-       }
-       kfree(ctrl);
-
-       if (!dev->tagset.tags) {
+       if (!dev->ctrl.tagset) {
                dev->tagset.ops = &nvme_mq_ops;
                dev->tagset.nr_hw_queues = dev->online_queues - 1;
                dev->tagset.timeout = NVME_IO_TIMEOUT;
@@ -2668,8 +1683,9 @@ static int nvme_dev_add(struct nvme_dev *dev)
 
                if (blk_mq_alloc_tag_set(&dev->tagset))
                        return 0;
+               dev->ctrl.tagset = &dev->tagset;
        }
-       schedule_work(&dev->scan_work);
+       queue_work(nvme_workq, &dev->scan_work);
        return 0;
 }
 
@@ -2699,7 +1715,7 @@ static int nvme_dev_map(struct nvme_dev *dev)
        if (!dev->bar)
                goto disable;
 
-       if (readl(&dev->bar->csts) == -1) {
+       if (readl(dev->bar + NVME_REG_CSTS) == -1) {
                result = -ENODEV;
                goto unmap;
        }
@@ -2714,10 +1730,11 @@ static int nvme_dev_map(struct nvme_dev *dev)
                        goto unmap;
        }
 
-       cap = lo_hi_readq(&dev->bar->cap);
+       cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
+
        dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH);
        dev->db_stride = 1 << NVME_CAP_STRIDE(cap);
-       dev->dbs = ((void __iomem *)dev->bar) + 4096;
+       dev->dbs = dev->bar + 4096;
 
        /*
         * Temporary fix for the Apple controller found in the MacBook8,1 and
@@ -2730,9 +1747,11 @@ static int nvme_dev_map(struct nvme_dev *dev)
                        dev->q_depth);
        }
 
-       if (readl(&dev->bar->vs) >= NVME_VS(1, 2))
+       if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2))
                dev->cmb = nvme_map_cmb(dev);
 
+       pci_enable_pcie_error_reporting(pdev);
+       pci_save_state(pdev);
        return 0;
 
  unmap:
@@ -2760,152 +1779,34 @@ static void nvme_dev_unmap(struct nvme_dev *dev)
                pci_release_regions(pdev);
        }
 
-       if (pci_is_enabled(pdev))
+       if (pci_is_enabled(pdev)) {
+               pci_disable_pcie_error_reporting(pdev);
                pci_disable_device(pdev);
-}
-
-struct nvme_delq_ctx {
-       struct task_struct *waiter;
-       struct kthread_worker *worker;
-       atomic_t refcount;
-};
-
-static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)
-{
-       dq->waiter = current;
-       mb();
-
-       for (;;) {
-               set_current_state(TASK_KILLABLE);
-               if (!atomic_read(&dq->refcount))
-                       break;
-               if (!schedule_timeout(ADMIN_TIMEOUT) ||
-                                       fatal_signal_pending(current)) {
-                       /*
-                        * Disable the controller first since we can't trust it
-                        * at this point, but leave the admin queue enabled
-                        * until all queue deletion requests are flushed.
-                        * FIXME: This may take a while if there are more h/w
-                        * queues than admin tags.
-                        */
-                       set_current_state(TASK_RUNNING);
-                       nvme_disable_ctrl(dev, lo_hi_readq(&dev->bar->cap));
-                       nvme_clear_queue(dev->queues[0]);
-                       flush_kthread_worker(dq->worker);
-                       nvme_disable_queue(dev, 0);
-                       return;
-               }
        }
-       set_current_state(TASK_RUNNING);
-}
-
-static void nvme_put_dq(struct nvme_delq_ctx *dq)
-{
-       atomic_dec(&dq->refcount);
-       if (dq->waiter)
-               wake_up_process(dq->waiter);
-}
-
-static struct nvme_delq_ctx *nvme_get_dq(struct nvme_delq_ctx *dq)
-{
-       atomic_inc(&dq->refcount);
-       return dq;
-}
-
-static void nvme_del_queue_end(struct nvme_queue *nvmeq)
-{
-       struct nvme_delq_ctx *dq = nvmeq->cmdinfo.ctx;
-       nvme_put_dq(dq);
-
-       spin_lock_irq(&nvmeq->q_lock);
-       nvme_process_cq(nvmeq);
-       spin_unlock_irq(&nvmeq->q_lock);
-}
-
-static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode,
-                                               kthread_work_func_t fn)
-{
-       struct nvme_command c;
-
-       memset(&c, 0, sizeof(c));
-       c.delete_queue.opcode = opcode;
-       c.delete_queue.qid = cpu_to_le16(nvmeq->qid);
-
-       init_kthread_work(&nvmeq->cmdinfo.work, fn);
-       return nvme_submit_admin_async_cmd(nvmeq->dev, &c, &nvmeq->cmdinfo,
-                                                               ADMIN_TIMEOUT);
-}
-
-static void nvme_del_cq_work_handler(struct kthread_work *work)
-{
-       struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
-                                                       cmdinfo.work);
-       nvme_del_queue_end(nvmeq);
-}
-
-static int nvme_delete_cq(struct nvme_queue *nvmeq)
-{
-       return adapter_async_del_queue(nvmeq, nvme_admin_delete_cq,
-                                               nvme_del_cq_work_handler);
 }
 
-static void nvme_del_sq_work_handler(struct kthread_work *work)
+static int nvme_dev_list_add(struct nvme_dev *dev)
 {
-       struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
-                                                       cmdinfo.work);
-       int status = nvmeq->cmdinfo.status;
-
-       if (!status)
-               status = nvme_delete_cq(nvmeq);
-       if (status)
-               nvme_del_queue_end(nvmeq);
-}
-
-static int nvme_delete_sq(struct nvme_queue *nvmeq)
-{
-       return adapter_async_del_queue(nvmeq, nvme_admin_delete_sq,
-                                               nvme_del_sq_work_handler);
-}
-
-static void nvme_del_queue_start(struct kthread_work *work)
-{
-       struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
-                                                       cmdinfo.work);
-       if (nvme_delete_sq(nvmeq))
-               nvme_del_queue_end(nvmeq);
-}
+       bool start_thread = false;
 
-static void nvme_disable_io_queues(struct nvme_dev *dev)
-{
-       int i;
-       DEFINE_KTHREAD_WORKER_ONSTACK(worker);
-       struct nvme_delq_ctx dq;
-       struct task_struct *kworker_task = kthread_run(kthread_worker_fn,
-                                       &worker, "nvme%d", dev->instance);
-
-       if (IS_ERR(kworker_task)) {
-               dev_err(dev->dev,
-                       "Failed to create queue del task\n");
-               for (i = dev->queue_count - 1; i > 0; i--)
-                       nvme_disable_queue(dev, i);
-               return;
+       spin_lock(&dev_list_lock);
+       if (list_empty(&dev_list) && IS_ERR_OR_NULL(nvme_thread)) {
+               start_thread = true;
+               nvme_thread = NULL;
        }
+       list_add(&dev->node, &dev_list);
+       spin_unlock(&dev_list_lock);
 
-       dq.waiter = NULL;
-       atomic_set(&dq.refcount, 0);
-       dq.worker = &worker;
-       for (i = dev->queue_count - 1; i > 0; i--) {
-               struct nvme_queue *nvmeq = dev->queues[i];
+       if (start_thread) {
+               nvme_thread = kthread_run(nvme_kthread, NULL, "nvme");
+               wake_up_all(&nvme_kthread_wait);
+       } else
+               wait_event_killable(nvme_kthread_wait, nvme_thread);
 
-               if (nvme_suspend_queue(nvmeq))
-                       continue;
-               nvmeq->cmdinfo.ctx = nvme_get_dq(&dq);
-               nvmeq->cmdinfo.worker = dq.worker;
-               init_kthread_work(&nvmeq->cmdinfo.work, nvme_del_queue_start);
-               queue_kthread_work(dq.worker, &nvmeq->cmdinfo.work);
-       }
-       nvme_wait_dq(&dq, dev);
-       kthread_stop(kworker_task);
+       if (IS_ERR_OR_NULL(nvme_thread))
+               return nvme_thread ? PTR_ERR(nvme_thread) : -EINTR;
+
+       return 0;
 }
 
 /*
@@ -2928,44 +1829,17 @@ static void nvme_dev_list_remove(struct nvme_dev *dev)
                kthread_stop(tmp);
 }
 
-static void nvme_freeze_queues(struct nvme_dev *dev)
-{
-       struct nvme_ns *ns;
-
-       list_for_each_entry(ns, &dev->namespaces, list) {
-               blk_mq_freeze_queue_start(ns->queue);
-
-               spin_lock_irq(ns->queue->queue_lock);
-               queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue);
-               spin_unlock_irq(ns->queue->queue_lock);
-
-               blk_mq_cancel_requeue_work(ns->queue);
-               blk_mq_stop_hw_queues(ns->queue);
-       }
-}
-
-static void nvme_unfreeze_queues(struct nvme_dev *dev)
-{
-       struct nvme_ns *ns;
-
-       list_for_each_entry(ns, &dev->namespaces, list) {
-               queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue);
-               blk_mq_unfreeze_queue(ns->queue);
-               blk_mq_start_stopped_hw_queues(ns->queue, true);
-               blk_mq_kick_requeue_list(ns->queue);
-       }
-}
-
-static void nvme_dev_shutdown(struct nvme_dev *dev)
+static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
 {
        int i;
        u32 csts = -1;
 
        nvme_dev_list_remove(dev);
 
+       mutex_lock(&dev->shutdown_lock);
        if (dev->bar) {
-               nvme_freeze_queues(dev);
-               csts = readl(&dev->bar->csts);
+               nvme_stop_queues(&dev->ctrl);
+               csts = readl(dev->bar + NVME_REG_CSTS);
        }
        if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) {
                for (i = dev->queue_count - 1; i >= 0; i--) {
@@ -2974,30 +1848,13 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)
                }
        } else {
                nvme_disable_io_queues(dev);
-               nvme_shutdown_ctrl(dev);
-               nvme_disable_queue(dev, 0);
+               nvme_disable_admin_queue(dev, shutdown);
        }
        nvme_dev_unmap(dev);
 
        for (i = dev->queue_count - 1; i >= 0; i--)
                nvme_clear_queue(dev->queues[i]);
-}
-
-static void nvme_dev_remove(struct nvme_dev *dev)
-{
-       struct nvme_ns *ns, *next;
-
-       if (nvme_io_incapable(dev)) {
-               /*
-                * If the device is not capable of IO (surprise hot-removal,
-                * for example), we need to quiesce prior to deleting the
-                * namespaces. This will end outstanding requests and prevent
-                * attempts to sync dirty data.
-                */
-               nvme_dev_shutdown(dev);
-       }
-       list_for_each_entry_safe(ns, next, &dev->namespaces, list)
-               nvme_ns_remove(ns);
+       mutex_unlock(&dev->shutdown_lock);
 }
 
 static int nvme_setup_prp_pools(struct nvme_dev *dev)
@@ -3023,119 +1880,36 @@ static void nvme_release_prp_pools(struct nvme_dev *dev)
        dma_pool_destroy(dev->prp_small_pool);
 }
 
-static DEFINE_IDA(nvme_instance_ida);
-
-static int nvme_set_instance(struct nvme_dev *dev)
-{
-       int instance, error;
-
-       do {
-               if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
-                       return -ENODEV;
-
-               spin_lock(&dev_list_lock);
-               error = ida_get_new(&nvme_instance_ida, &instance);
-               spin_unlock(&dev_list_lock);
-       } while (error == -EAGAIN);
-
-       if (error)
-               return -ENODEV;
-
-       dev->instance = instance;
-       return 0;
-}
-
-static void nvme_release_instance(struct nvme_dev *dev)
-{
-       spin_lock(&dev_list_lock);
-       ida_remove(&nvme_instance_ida, dev->instance);
-       spin_unlock(&dev_list_lock);
-}
-
-static void nvme_free_dev(struct kref *kref)
+static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
 {
-       struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref);
+       struct nvme_dev *dev = to_nvme_dev(ctrl);
 
        put_device(dev->dev);
-       put_device(dev->device);
-       nvme_release_instance(dev);
        if (dev->tagset.tags)
                blk_mq_free_tag_set(&dev->tagset);
-       if (dev->admin_q)
-               blk_put_queue(dev->admin_q);
+       if (dev->ctrl.admin_q)
+               blk_put_queue(dev->ctrl.admin_q);
        kfree(dev->queues);
        kfree(dev->entry);
        kfree(dev);
 }
 
-static int nvme_dev_open(struct inode *inode, struct file *f)
-{
-       struct nvme_dev *dev;
-       int instance = iminor(inode);
-       int ret = -ENODEV;
-
-       spin_lock(&dev_list_lock);
-       list_for_each_entry(dev, &dev_list, node) {
-               if (dev->instance == instance) {
-                       if (!dev->admin_q) {
-                               ret = -EWOULDBLOCK;
-                               break;
-                       }
-                       if (!kref_get_unless_zero(&dev->kref))
-                               break;
-                       f->private_data = dev;
-                       ret = 0;
-                       break;
-               }
-       }
-       spin_unlock(&dev_list_lock);
-
-       return ret;
-}
-
-static int nvme_dev_release(struct inode *inode, struct file *f)
+static void nvme_reset_work(struct work_struct *work)
 {
-       struct nvme_dev *dev = f->private_data;
-       kref_put(&dev->kref, nvme_free_dev);
-       return 0;
-}
+       struct nvme_dev *dev = container_of(work, struct nvme_dev, reset_work);
+       int result;
 
-static long nvme_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
-{
-       struct nvme_dev *dev = f->private_data;
-       struct nvme_ns *ns;
-
-       switch (cmd) {
-       case NVME_IOCTL_ADMIN_CMD:
-               return nvme_user_cmd(dev, NULL, (void __user *)arg);
-       case NVME_IOCTL_IO_CMD:
-               if (list_empty(&dev->namespaces))
-                       return -ENOTTY;
-               ns = list_first_entry(&dev->namespaces, struct nvme_ns, list);
-               return nvme_user_cmd(dev, ns, (void __user *)arg);
-       case NVME_IOCTL_RESET:
-               dev_warn(dev->dev, "resetting controller\n");
-               return nvme_reset(dev);
-       case NVME_IOCTL_SUBSYS_RESET:
-               return nvme_subsys_reset(dev);
-       default:
-               return -ENOTTY;
-       }
-}
+       if (WARN_ON(test_bit(NVME_CTRL_RESETTING, &dev->flags)))
+               goto out;
 
-static const struct file_operations nvme_dev_fops = {
-       .owner          = THIS_MODULE,
-       .open           = nvme_dev_open,
-       .release        = nvme_dev_release,
-       .unlocked_ioctl = nvme_dev_ioctl,
-       .compat_ioctl   = nvme_dev_ioctl,
-};
+       /*
+        * If we're called to reset a live controller first shut it down before
+        * moving on.
+        */
+       if (dev->bar)
+               nvme_dev_disable(dev, false);
 
-static void nvme_probe_work(struct work_struct *work)
-{
-       struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work);
-       bool start_thread = false;
-       int result;
+       set_bit(NVME_CTRL_RESETTING, &dev->flags);
 
        result = nvme_dev_map(dev);
        if (result)
@@ -3145,35 +1919,24 @@ static void nvme_probe_work(struct work_struct *work)
        if (result)
                goto unmap;
 
-       spin_lock(&dev_list_lock);
-       if (list_empty(&dev_list) && IS_ERR_OR_NULL(nvme_thread)) {
-               start_thread = true;
-               nvme_thread = NULL;
-       }
-       list_add(&dev->node, &dev_list);
-       spin_unlock(&dev_list_lock);
-
-       if (start_thread) {
-               nvme_thread = kthread_run(nvme_kthread, NULL, "nvme");
-               wake_up_all(&nvme_kthread_wait);
-       } else
-               wait_event_killable(nvme_kthread_wait, nvme_thread);
-
-       if (IS_ERR_OR_NULL(nvme_thread)) {
-               result = nvme_thread ? PTR_ERR(nvme_thread) : -EINTR;
-               goto disable;
-       }
-
        nvme_init_queue(dev->queues[0], 0);
        result = nvme_alloc_admin_tags(dev);
        if (result)
                goto disable;
 
+       result = nvme_init_identify(&dev->ctrl);
+       if (result)
+               goto free_tags;
+
        result = nvme_setup_io_queues(dev);
        if (result)
                goto free_tags;
 
-       dev->event_limit = 1;
+       dev->ctrl.event_limit = NVME_NR_AEN_COMMANDS;
+
+       result = nvme_dev_list_add(dev);
+       if (result)
+               goto remove;
 
        /*
         * Keep the controller around but remove all namespaces if we don't have
@@ -3181,117 +1944,98 @@ static void nvme_probe_work(struct work_struct *work)
         */
        if (dev->online_queues < 2) {
                dev_warn(dev->dev, "IO queues not created\n");
-               nvme_dev_remove(dev);
+               nvme_remove_namespaces(&dev->ctrl);
        } else {
-               nvme_unfreeze_queues(dev);
+               nvme_start_queues(&dev->ctrl);
                nvme_dev_add(dev);
        }
 
+       clear_bit(NVME_CTRL_RESETTING, &dev->flags);
        return;
 
+ remove:
+       nvme_dev_list_remove(dev);
  free_tags:
        nvme_dev_remove_admin(dev);
-       blk_put_queue(dev->admin_q);
-       dev->admin_q = NULL;
+       blk_put_queue(dev->ctrl.admin_q);
+       dev->ctrl.admin_q = NULL;
        dev->queues[0]->tags = NULL;
  disable:
-       nvme_disable_queue(dev, 0);
-       nvme_dev_list_remove(dev);
+       nvme_disable_admin_queue(dev, false);
  unmap:
        nvme_dev_unmap(dev);
  out:
-       if (!work_busy(&dev->reset_work))
-               nvme_dead_ctrl(dev);
+       nvme_remove_dead_ctrl(dev);
 }
 
-static int nvme_remove_dead_ctrl(void *arg)
+static void nvme_remove_dead_ctrl_work(struct work_struct *work)
 {
-       struct nvme_dev *dev = (struct nvme_dev *)arg;
+       struct nvme_dev *dev = container_of(work, struct nvme_dev, remove_work);
        struct pci_dev *pdev = to_pci_dev(dev->dev);
 
        if (pci_get_drvdata(pdev))
                pci_stop_and_remove_bus_device_locked(pdev);
-       kref_put(&dev->kref, nvme_free_dev);
-       return 0;
+       nvme_put_ctrl(&dev->ctrl);
 }
 
-static void nvme_dead_ctrl(struct nvme_dev *dev)
+static void nvme_remove_dead_ctrl(struct nvme_dev *dev)
 {
-       dev_warn(dev->dev, "Device failed to resume\n");
-       kref_get(&dev->kref);
-       if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d",
-                                               dev->instance))) {
-               dev_err(dev->dev,
-                       "Failed to start controller remove task\n");
-               kref_put(&dev->kref, nvme_free_dev);
-       }
+       dev_warn(dev->dev, "Removing after probe failure\n");
+       kref_get(&dev->ctrl.kref);
+       if (!schedule_work(&dev->remove_work))
+               nvme_put_ctrl(&dev->ctrl);
 }
 
-static void nvme_reset_work(struct work_struct *ws)
+static int nvme_reset(struct nvme_dev *dev)
 {
-       struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work);
-       bool in_probe = work_busy(&dev->probe_work);
-
-       nvme_dev_shutdown(dev);
+       if (!dev->ctrl.admin_q || blk_queue_dying(dev->ctrl.admin_q))
+               return -ENODEV;
 
-       /* Synchronize with device probe so that work will see failure status
-        * and exit gracefully without trying to schedule another reset */
-       flush_work(&dev->probe_work);
+       if (!queue_work(nvme_workq, &dev->reset_work))
+               return -EBUSY;
 
-       /* Fail this device if reset occured during probe to avoid
-        * infinite initialization loops. */
-       if (in_probe) {
-               nvme_dead_ctrl(dev);
-               return;
-       }
-       /* Schedule device resume asynchronously so the reset work is available
-        * to cleanup errors that may occur during reinitialization */
-       schedule_work(&dev->probe_work);
+       flush_work(&dev->reset_work);
+       return 0;
 }
 
-static int __nvme_reset(struct nvme_dev *dev)
+static int nvme_pci_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
 {
-       if (work_pending(&dev->reset_work))
-               return -EBUSY;
-       list_del_init(&dev->node);
-       queue_work(nvme_workq, &dev->reset_work);
+       *val = readl(to_nvme_dev(ctrl)->bar + off);
        return 0;
 }
 
-static int nvme_reset(struct nvme_dev *dev)
+static int nvme_pci_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
 {
-       int ret;
-
-       if (!dev->admin_q || blk_queue_dying(dev->admin_q))
-               return -ENODEV;
-
-       spin_lock(&dev_list_lock);
-       ret = __nvme_reset(dev);
-       spin_unlock(&dev_list_lock);
-
-       if (!ret) {
-               flush_work(&dev->reset_work);
-               flush_work(&dev->probe_work);
-               return 0;
-       }
+       writel(val, to_nvme_dev(ctrl)->bar + off);
+       return 0;
+}
 
-       return ret;
+static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
+{
+       *val = readq(to_nvme_dev(ctrl)->bar + off);
+       return 0;
 }
 
-static ssize_t nvme_sysfs_reset(struct device *dev,
-                               struct device_attribute *attr, const char *buf,
-                               size_t count)
+static bool nvme_pci_io_incapable(struct nvme_ctrl *ctrl)
 {
-       struct nvme_dev *ndev = dev_get_drvdata(dev);
-       int ret;
+       struct nvme_dev *dev = to_nvme_dev(ctrl);
 
-       ret = nvme_reset(ndev);
-       if (ret < 0)
-               return ret;
+       return !dev->bar || dev->online_queues < 2;
+}
 
-       return count;
+static int nvme_pci_reset_ctrl(struct nvme_ctrl *ctrl)
+{
+       return nvme_reset(to_nvme_dev(ctrl));
 }
-static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
+
+static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
+       .reg_read32             = nvme_pci_reg_read32,
+       .reg_write32            = nvme_pci_reg_write32,
+       .reg_read64             = nvme_pci_reg_read64,
+       .io_incapable           = nvme_pci_io_incapable,
+       .reset_ctrl             = nvme_pci_reset_ctrl,
+       .free_ctrl              = nvme_pci_free_ctrl,
+};
 
 static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
@@ -3314,46 +2058,30 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (!dev->queues)
                goto free;
 
-       INIT_LIST_HEAD(&dev->namespaces);
-       INIT_WORK(&dev->reset_work, nvme_reset_work);
        dev->dev = get_device(&pdev->dev);
        pci_set_drvdata(pdev, dev);
-       result = nvme_set_instance(dev);
-       if (result)
-               goto put_pci;
+
+       INIT_LIST_HEAD(&dev->node);
+       INIT_WORK(&dev->scan_work, nvme_dev_scan);
+       INIT_WORK(&dev->reset_work, nvme_reset_work);
+       INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
+       mutex_init(&dev->shutdown_lock);
+       init_completion(&dev->ioq_wait);
 
        result = nvme_setup_prp_pools(dev);
        if (result)
-               goto release;
-
-       kref_init(&dev->kref);
-       dev->device = device_create(nvme_class, &pdev->dev,
-                               MKDEV(nvme_char_major, dev->instance),
-                               dev, "nvme%d", dev->instance);
-       if (IS_ERR(dev->device)) {
-               result = PTR_ERR(dev->device);
-               goto release_pools;
-       }
-       get_device(dev->device);
-       dev_set_drvdata(dev->device, dev);
+               goto put_pci;
 
-       result = device_create_file(dev->device, &dev_attr_reset_controller);
+       result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
+                       id->driver_data);
        if (result)
-               goto put_dev;
+               goto release_pools;
 
-       INIT_LIST_HEAD(&dev->node);
-       INIT_WORK(&dev->scan_work, nvme_dev_scan);
-       INIT_WORK(&dev->probe_work, nvme_probe_work);
-       schedule_work(&dev->probe_work);
+       queue_work(nvme_workq, &dev->reset_work);
        return 0;
 
- put_dev:
-       device_destroy(nvme_class, MKDEV(nvme_char_major, dev->instance));
-       put_device(dev->device);
  release_pools:
        nvme_release_prp_pools(dev);
- release:
-       nvme_release_instance(dev);
  put_pci:
        put_device(dev->dev);
  free:
@@ -3368,15 +2096,15 @@ static void nvme_reset_notify(struct pci_dev *pdev, bool prepare)
        struct nvme_dev *dev = pci_get_drvdata(pdev);
 
        if (prepare)
-               nvme_dev_shutdown(dev);
+               nvme_dev_disable(dev, false);
        else
-               schedule_work(&dev->probe_work);
+               queue_work(nvme_workq, &dev->reset_work);
 }
 
 static void nvme_shutdown(struct pci_dev *pdev)
 {
        struct nvme_dev *dev = pci_get_drvdata(pdev);
-       nvme_dev_shutdown(dev);
+       nvme_dev_disable(dev, true);
 }
 
 static void nvme_remove(struct pci_dev *pdev)
@@ -3388,34 +2116,25 @@ static void nvme_remove(struct pci_dev *pdev)
        spin_unlock(&dev_list_lock);
 
        pci_set_drvdata(pdev, NULL);
-       flush_work(&dev->probe_work);
        flush_work(&dev->reset_work);
        flush_work(&dev->scan_work);
-       device_remove_file(dev->device, &dev_attr_reset_controller);
-       nvme_dev_remove(dev);
-       nvme_dev_shutdown(dev);
+       nvme_remove_namespaces(&dev->ctrl);
+       nvme_uninit_ctrl(&dev->ctrl);
+       nvme_dev_disable(dev, true);
        nvme_dev_remove_admin(dev);
-       device_destroy(nvme_class, MKDEV(nvme_char_major, dev->instance));
        nvme_free_queues(dev, 0);
        nvme_release_cmb(dev);
        nvme_release_prp_pools(dev);
-       kref_put(&dev->kref, nvme_free_dev);
+       nvme_put_ctrl(&dev->ctrl);
 }
 
-/* These functions are yet to be implemented */
-#define nvme_error_detected NULL
-#define nvme_dump_registers NULL
-#define nvme_link_reset NULL
-#define nvme_slot_reset NULL
-#define nvme_error_resume NULL
-
 #ifdef CONFIG_PM_SLEEP
 static int nvme_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct nvme_dev *ndev = pci_get_drvdata(pdev);
 
-       nvme_dev_shutdown(ndev);
+       nvme_dev_disable(ndev, true);
        return 0;
 }
 
@@ -3424,17 +2143,53 @@ static int nvme_resume(struct device *dev)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct nvme_dev *ndev = pci_get_drvdata(pdev);
 
-       schedule_work(&ndev->probe_work);
+       queue_work(nvme_workq, &ndev->reset_work);
        return 0;
 }
 #endif
 
 static SIMPLE_DEV_PM_OPS(nvme_dev_pm_ops, nvme_suspend, nvme_resume);
 
+static pci_ers_result_t nvme_error_detected(struct pci_dev *pdev,
+                                               pci_channel_state_t state)
+{
+       struct nvme_dev *dev = pci_get_drvdata(pdev);
+
+       /*
+        * A frozen channel requires a reset. When detected, this method will
+        * shutdown the controller to quiesce. The controller will be restarted
+        * after the slot reset through driver's slot_reset callback.
+        */
+       dev_warn(&pdev->dev, "error detected: state:%d\n", state);
+       switch (state) {
+       case pci_channel_io_normal:
+               return PCI_ERS_RESULT_CAN_RECOVER;
+       case pci_channel_io_frozen:
+               nvme_dev_disable(dev, false);
+               return PCI_ERS_RESULT_NEED_RESET;
+       case pci_channel_io_perm_failure:
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t nvme_slot_reset(struct pci_dev *pdev)
+{
+       struct nvme_dev *dev = pci_get_drvdata(pdev);
+
+       dev_info(&pdev->dev, "restart after slot reset\n");
+       pci_restore_state(pdev);
+       queue_work(nvme_workq, &dev->reset_work);
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void nvme_error_resume(struct pci_dev *pdev)
+{
+       pci_cleanup_aer_uncorrect_error_status(pdev);
+}
+
 static const struct pci_error_handlers nvme_err_handler = {
        .error_detected = nvme_error_detected,
-       .mmio_enabled   = nvme_dump_registers,
-       .link_reset     = nvme_link_reset,
        .slot_reset     = nvme_slot_reset,
        .resume         = nvme_error_resume,
        .reset_notify   = nvme_reset_notify,
@@ -3444,6 +2199,10 @@ static const struct pci_error_handlers nvme_err_handler = {
 #define PCI_CLASS_STORAGE_EXPRESS      0x010802
 
 static const struct pci_device_id nvme_id_table[] = {
+       { PCI_VDEVICE(INTEL, 0x0953),
+               .driver_data = NVME_QUIRK_STRIPE_SIZE, },
+       { PCI_VDEVICE(INTEL, 0x5845),   /* Qemu emulated controller */
+               .driver_data = NVME_QUIRK_IDENTIFY_CNS, },
        { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
        { 0, }
@@ -3468,40 +2227,21 @@ static int __init nvme_init(void)
 
        init_waitqueue_head(&nvme_kthread_wait);
 
-       nvme_workq = create_singlethread_workqueue("nvme");
+       nvme_workq = alloc_workqueue("nvme", WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
        if (!nvme_workq)
                return -ENOMEM;
 
-       result = register_blkdev(nvme_major, "nvme");
+       result = nvme_core_init();
        if (result < 0)
                goto kill_workq;
-       else if (result > 0)
-               nvme_major = result;
-
-       result = __register_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme",
-                                                       &nvme_dev_fops);
-       if (result < 0)
-               goto unregister_blkdev;
-       else if (result > 0)
-               nvme_char_major = result;
-
-       nvme_class = class_create(THIS_MODULE, "nvme");
-       if (IS_ERR(nvme_class)) {
-               result = PTR_ERR(nvme_class);
-               goto unregister_chrdev;
-       }
 
        result = pci_register_driver(&nvme_driver);
        if (result)
-               goto destroy_class;
+               goto core_exit;
        return 0;
 
- destroy_class:
-       class_destroy(nvme_class);
- unregister_chrdev:
-       __unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
- unregister_blkdev:
-       unregister_blkdev(nvme_major, "nvme");
+ core_exit:
+       nvme_core_exit();
  kill_workq:
        destroy_workqueue(nvme_workq);
        return result;
@@ -3510,10 +2250,8 @@ static int __init nvme_init(void)
 static void __exit nvme_exit(void)
 {
        pci_unregister_driver(&nvme_driver);
-       unregister_blkdev(nvme_major, "nvme");
+       nvme_core_exit();
        destroy_workqueue(nvme_workq);
-       class_destroy(nvme_class);
-       __unregister_chrdev(nvme_char_major, 0, NVME_MINORS, "nvme");
        BUG_ON(nvme_thread && !IS_ERR(nvme_thread));
        _nvme_check_size();
 }
index c3d8d38..e947e29 100644 (file)
@@ -524,7 +524,7 @@ static int nvme_trans_standard_inquiry_page(struct nvme_ns *ns,
                                        struct sg_io_hdr *hdr, u8 *inq_response,
                                        int alloc_len)
 {
-       struct nvme_dev *dev = ns->dev;
+       struct nvme_ctrl *ctrl = ns->ctrl;
        struct nvme_id_ns *id_ns;
        int res;
        int nvme_sc;
@@ -532,10 +532,10 @@ static int nvme_trans_standard_inquiry_page(struct nvme_ns *ns,
        u8 resp_data_format = 0x02;
        u8 protect;
        u8 cmdque = 0x01 << 1;
-       u8 fw_offset = sizeof(dev->firmware_rev);
+       u8 fw_offset = sizeof(ctrl->firmware_rev);
 
        /* nvme ns identify - use DPS value for PROTECT field */
-       nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+       nvme_sc = nvme_identify_ns(ctrl, ns->ns_id, &id_ns);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                return res;
@@ -553,12 +553,12 @@ static int nvme_trans_standard_inquiry_page(struct nvme_ns *ns,
        inq_response[5] = protect;      /* sccs=0 | acc=0 | tpgs=0 | pc3=0 */
        inq_response[7] = cmdque;       /* wbus16=0 | sync=0 | vs=0 */
        strncpy(&inq_response[8], "NVMe    ", 8);
-       strncpy(&inq_response[16], dev->model, 16);
+       strncpy(&inq_response[16], ctrl->model, 16);
 
-       while (dev->firmware_rev[fw_offset - 1] == ' ' && fw_offset > 4)
+       while (ctrl->firmware_rev[fw_offset - 1] == ' ' && fw_offset > 4)
                fw_offset--;
        fw_offset -= 4;
-       strncpy(&inq_response[32], dev->firmware_rev + fw_offset, 4);
+       strncpy(&inq_response[32], ctrl->firmware_rev + fw_offset, 4);
 
        xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
        return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
@@ -588,82 +588,113 @@ static int nvme_trans_unit_serial_page(struct nvme_ns *ns,
                                        struct sg_io_hdr *hdr, u8 *inq_response,
                                        int alloc_len)
 {
-       struct nvme_dev *dev = ns->dev;
        int xfer_len;
 
        memset(inq_response, 0, STANDARD_INQUIRY_LENGTH);
        inq_response[1] = INQ_UNIT_SERIAL_NUMBER_PAGE; /* Page Code */
        inq_response[3] = INQ_SERIAL_NUMBER_LENGTH;    /* Page Length */
-       strncpy(&inq_response[4], dev->serial, INQ_SERIAL_NUMBER_LENGTH);
+       strncpy(&inq_response[4], ns->ctrl->serial, INQ_SERIAL_NUMBER_LENGTH);
 
        xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH);
        return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
 }
 
-static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
-                                       u8 *inq_response, int alloc_len)
+static int nvme_fill_device_id_eui64(struct nvme_ns *ns, struct sg_io_hdr *hdr,
+               u8 *inq_response, int alloc_len)
 {
-       struct nvme_dev *dev = ns->dev;
-       int res;
-       int nvme_sc;
-       int xfer_len;
-       __be32 tmp_id = cpu_to_be32(ns->ns_id);
+       struct nvme_id_ns *id_ns;
+       int nvme_sc, res;
+       size_t len;
+       void *eui;
 
-       memset(inq_response, 0, alloc_len);
-       inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;    /* Page Code */
-       if (readl(&dev->bar->vs) >= NVME_VS(1, 1)) {
-               struct nvme_id_ns *id_ns;
-               void *eui;
-               int len;
+       nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
+       res = nvme_trans_status_code(hdr, nvme_sc);
+       if (res)
+               return res;
 
-               nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
-               res = nvme_trans_status_code(hdr, nvme_sc);
-               if (res)
-                       return res;
+       eui = id_ns->eui64;
+       len = sizeof(id_ns->eui64);
 
-               eui = id_ns->eui64;
-               len = sizeof(id_ns->eui64);
-               if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) {
-                       if (bitmap_empty(eui, len * 8)) {
-                               eui = id_ns->nguid;
-                               len = sizeof(id_ns->nguid);
-                       }
-               }
+       if (ns->ctrl->vs >= NVME_VS(1, 2)) {
                if (bitmap_empty(eui, len * 8)) {
-                       kfree(id_ns);
-                       goto scsi_string;
+                       eui = id_ns->nguid;
+                       len = sizeof(id_ns->nguid);
                }
+       }
 
-               inq_response[3] = 4 + len; /* Page Length */
-               /* Designation Descriptor start */
-               inq_response[4] = 0x01;    /* Proto ID=0h | Code set=1h */
-               inq_response[5] = 0x02;    /* PIV=0b | Asso=00b | Designator Type=2h */
-               inq_response[6] = 0x00;    /* Rsvd */
-               inq_response[7] = len;     /* Designator Length */
-               memcpy(&inq_response[8], eui, len);
-               kfree(id_ns);
-       } else {
- scsi_string:
-               if (alloc_len < 72) {
-                       return nvme_trans_completion(hdr,
-                                       SAM_STAT_CHECK_CONDITION,
-                                       ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
-                                       SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
-               }
-               inq_response[3] = 0x48;    /* Page Length */
-               /* Designation Descriptor start */
-               inq_response[4] = 0x03;    /* Proto ID=0h | Code set=3h */
-               inq_response[5] = 0x08;    /* PIV=0b | Asso=00b | Designator Type=8h */
-               inq_response[6] = 0x00;    /* Rsvd */
-               inq_response[7] = 0x44;    /* Designator Length */
-
-               sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor);
-               memcpy(&inq_response[12], dev->model, sizeof(dev->model));
-               sprintf(&inq_response[52], "%04x", tmp_id);
-               memcpy(&inq_response[56], dev->serial, sizeof(dev->serial));
+       if (bitmap_empty(eui, len * 8)) {
+               res = -EOPNOTSUPP;
+               goto out_free_id;
        }
-       xfer_len = alloc_len;
-       return nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
+
+       memset(inq_response, 0, alloc_len);
+       inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;
+       inq_response[3] = 4 + len; /* Page Length */
+
+       /* Designation Descriptor start */
+       inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */
+       inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */
+       inq_response[6] = 0x00; /* Rsvd */
+       inq_response[7] = len;  /* Designator Length */
+       memcpy(&inq_response[8], eui, len);
+
+       res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len);
+out_free_id:
+       kfree(id_ns);
+       return res;
+}
+
+static int nvme_fill_device_id_scsi_string(struct nvme_ns *ns,
+               struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len)
+{
+       struct nvme_ctrl *ctrl = ns->ctrl;
+       struct nvme_id_ctrl *id_ctrl;
+       int nvme_sc, res;
+
+       if (alloc_len < 72) {
+               return nvme_trans_completion(hdr,
+                               SAM_STAT_CHECK_CONDITION,
+                               ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
+                               SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
+       }
+
+       nvme_sc = nvme_identify_ctrl(ctrl, &id_ctrl);
+       res = nvme_trans_status_code(hdr, nvme_sc);
+       if (res)
+               return res;
+
+       memset(inq_response, 0, alloc_len);
+       inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE;
+       inq_response[3] = 0x48; /* Page Length */
+
+       /* Designation Descriptor start */
+       inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */
+       inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */
+       inq_response[6] = 0x00; /* Rsvd */
+       inq_response[7] = 0x44; /* Designator Length */
+
+       sprintf(&inq_response[8], "%04x", le16_to_cpu(id_ctrl->vid));
+       memcpy(&inq_response[12], ctrl->model, sizeof(ctrl->model));
+       sprintf(&inq_response[52], "%04x", cpu_to_be32(ns->ns_id));
+       memcpy(&inq_response[56], ctrl->serial, sizeof(ctrl->serial));
+
+       res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len);
+       kfree(id_ctrl);
+       return res;
+}
+
+static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
+                                       u8 *resp, int alloc_len)
+{
+       int res;
+
+       if (ns->ctrl->vs >= NVME_VS(1, 1)) {
+               res = nvme_fill_device_id_eui64(ns, hdr, resp, alloc_len);
+               if (res != -EOPNOTSUPP)
+                       return res;
+       }
+
+       return nvme_fill_device_id_scsi_string(ns, hdr, resp, alloc_len);
 }
 
 static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
@@ -672,7 +703,7 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        u8 *inq_response;
        int res;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
+       struct nvme_ctrl *ctrl = ns->ctrl;
        struct nvme_id_ctrl *id_ctrl;
        struct nvme_id_ns *id_ns;
        int xfer_len;
@@ -688,7 +719,7 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        if (inq_response == NULL)
                return -ENOMEM;
 
-       nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+       nvme_sc = nvme_identify_ns(ctrl, ns->ns_id, &id_ns);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                goto out_free_inq;
@@ -704,7 +735,7 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        app_chk = protect << 1;
        ref_chk = protect;
 
-       nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
+       nvme_sc = nvme_identify_ctrl(ctrl, &id_ctrl);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                goto out_free_inq;
@@ -815,7 +846,6 @@ static int nvme_trans_log_info_exceptions(struct nvme_ns *ns,
        int res;
        int xfer_len;
        u8 *log_response;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_smart_log *smart_log;
        u8 temp_c;
        u16 temp_k;
@@ -824,7 +854,7 @@ static int nvme_trans_log_info_exceptions(struct nvme_ns *ns,
        if (log_response == NULL)
                return -ENOMEM;
 
-       res = nvme_get_log_page(dev, &smart_log);
+       res = nvme_get_log_page(ns->ctrl, &smart_log);
        if (res < 0)
                goto out_free_response;
 
@@ -862,7 +892,6 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        int res;
        int xfer_len;
        u8 *log_response;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_smart_log *smart_log;
        u32 feature_resp;
        u8 temp_c_cur, temp_c_thresh;
@@ -872,7 +901,7 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        if (log_response == NULL)
                return -ENOMEM;
 
-       res = nvme_get_log_page(dev, &smart_log);
+       res = nvme_get_log_page(ns->ctrl, &smart_log);
        if (res < 0)
                goto out_free_response;
 
@@ -886,7 +915,7 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        kfree(smart_log);
 
        /* Get Features for Temp Threshold */
-       res = nvme_get_features(dev, NVME_FEAT_TEMP_THRESH, 0, 0,
+       res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, 0,
                                                                &feature_resp);
        if (res != NVME_SC_SUCCESS)
                temp_c_thresh = LOG_TEMP_UNKNOWN;
@@ -948,7 +977,6 @@ static int nvme_trans_fill_blk_desc(struct nvme_ns *ns, struct sg_io_hdr *hdr,
 {
        int res;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_id_ns *id_ns;
        u8 flbas;
        u32 lba_length;
@@ -958,7 +986,7 @@ static int nvme_trans_fill_blk_desc(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        else if (llbaa > 0 && len < MODE_PAGE_LLBAA_BLK_DES_LEN)
                return -EINVAL;
 
-       nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+       nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                return res;
@@ -1014,14 +1042,13 @@ static int nvme_trans_fill_caching_page(struct nvme_ns *ns,
 {
        int res = 0;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        u32 feature_resp;
        u8 vwc;
 
        if (len < MODE_PAGE_CACHING_LEN)
                return -EINVAL;
 
-       nvme_sc = nvme_get_features(dev, NVME_FEAT_VOLATILE_WC, 0, 0,
+       nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, 0,
                                                                &feature_resp);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
@@ -1207,12 +1234,11 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
 {
        int res;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_id_ctrl *id_ctrl;
        int lowest_pow_st;      /* max npss = lowest power consumption */
        unsigned ps_desired = 0;
 
-       nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
+       nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                return res;
@@ -1256,7 +1282,7 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
                                SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
                break;
        }
-       nvme_sc = nvme_set_features(dev, NVME_FEAT_POWER_MGMT, ps_desired, 0,
+       nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_POWER_MGMT, ps_desired, 0,
                                    NULL);
        return nvme_trans_status_code(hdr, nvme_sc);
 }
@@ -1280,7 +1306,6 @@ static int nvme_trans_send_download_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr
                                        u8 buffer_id)
 {
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_command c;
 
        if (hdr->iovec_count > 0) {
@@ -1297,7 +1322,7 @@ static int nvme_trans_send_download_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr
        c.dlfw.numd = cpu_to_le32((tot_len/BYTES_TO_DWORDS) - 1);
        c.dlfw.offset = cpu_to_le32(offset/BYTES_TO_DWORDS);
 
-       nvme_sc = __nvme_submit_sync_cmd(dev->admin_q, &c, NULL,
+       nvme_sc = nvme_submit_user_cmd(ns->ctrl->admin_q, &c,
                        hdr->dxferp, tot_len, NULL, 0);
        return nvme_trans_status_code(hdr, nvme_sc);
 }
@@ -1364,14 +1389,13 @@ static int nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr,
 {
        int res = 0;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        unsigned dword11;
 
        switch (page_code) {
        case MODE_PAGE_CACHING:
                dword11 = ((mode_page[2] & CACHING_MODE_PAGE_WCE_MASK) ? 1 : 0);
-               nvme_sc = nvme_set_features(dev, NVME_FEAT_VOLATILE_WC, dword11,
-                                           0, NULL);
+               nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_VOLATILE_WC,
+                                           dword11, 0, NULL);
                res = nvme_trans_status_code(hdr, nvme_sc);
                break;
        case MODE_PAGE_CONTROL:
@@ -1473,7 +1497,6 @@ static int nvme_trans_fmt_set_blk_size_count(struct nvme_ns *ns,
 {
        int res = 0;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        u8 flbas;
 
        /*
@@ -1486,7 +1509,7 @@ static int nvme_trans_fmt_set_blk_size_count(struct nvme_ns *ns,
        if (ns->mode_select_num_blocks == 0 || ns->mode_select_block_len == 0) {
                struct nvme_id_ns *id_ns;
 
-               nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+               nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
                res = nvme_trans_status_code(hdr, nvme_sc);
                if (res)
                        return res;
@@ -1570,7 +1593,6 @@ static int nvme_trans_fmt_send_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr,
 {
        int res;
        int nvme_sc;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_id_ns *id_ns;
        u8 i;
        u8 flbas, nlbaf;
@@ -1579,7 +1601,7 @@ static int nvme_trans_fmt_send_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        struct nvme_command c;
 
        /* Loop thru LBAF's in id_ns to match reqd lbaf, put in cdw10 */
-       nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+       nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                return res;
@@ -1611,7 +1633,7 @@ static int nvme_trans_fmt_send_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        c.format.nsid = cpu_to_le32(ns->ns_id);
        c.format.cdw10 = cpu_to_le32(cdw10);
 
-       nvme_sc = nvme_submit_sync_cmd(dev->admin_q, &c, NULL, 0);
+       nvme_sc = nvme_submit_sync_cmd(ns->ctrl->admin_q, &c, NULL, 0);
        res = nvme_trans_status_code(hdr, nvme_sc);
 
        kfree(id_ns);
@@ -1704,7 +1726,7 @@ static int nvme_trans_do_nvme_io(struct nvme_ns *ns, struct sg_io_hdr *hdr,
                        nvme_sc = NVME_SC_LBA_RANGE;
                        break;
                }
-               nvme_sc = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
+               nvme_sc = nvme_submit_user_cmd(ns->queue, &c,
                                next_mapping_addr, unit_len, NULL, 0);
                if (nvme_sc)
                        break;
@@ -2040,7 +2062,6 @@ static int nvme_trans_read_capacity(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        u32 alloc_len;
        u32 resp_size;
        u32 xfer_len;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_id_ns *id_ns;
        u8 *response;
 
@@ -2052,7 +2073,7 @@ static int nvme_trans_read_capacity(struct nvme_ns *ns, struct sg_io_hdr *hdr,
                resp_size = READ_CAP_10_RESP_SIZE;
        }
 
-       nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns);
+       nvme_sc = nvme_identify_ns(ns->ctrl, ns->ns_id, &id_ns);
        res = nvme_trans_status_code(hdr, nvme_sc);
        if (res)
                return res;     
@@ -2080,7 +2101,6 @@ static int nvme_trans_report_luns(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        int nvme_sc;
        u32 alloc_len, xfer_len, resp_size;
        u8 *response;
-       struct nvme_dev *dev = ns->dev;
        struct nvme_id_ctrl *id_ctrl;
        u32 ll_length, lun_id;
        u8 lun_id_offset = REPORT_LUNS_FIRST_LUN_OFFSET;
@@ -2094,7 +2114,7 @@ static int nvme_trans_report_luns(struct nvme_ns *ns, struct sg_io_hdr *hdr,
        case ALL_LUNS_RETURNED:
        case ALL_WELL_KNOWN_LUNS_RETURNED:
        case RESTRICTED_LUNS_RETURNED:
-               nvme_sc = nvme_identify_ctrl(dev, &id_ctrl);
+               nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl);
                res = nvme_trans_status_code(hdr, nvme_sc);
                if (res)
                        return res;
@@ -2295,9 +2315,7 @@ static int nvme_trans_test_unit_ready(struct nvme_ns *ns,
                                        struct sg_io_hdr *hdr,
                                        u8 *cmd)
 {
-       struct nvme_dev *dev = ns->dev;
-
-       if (!(readl(&dev->bar->csts) & NVME_CSTS_RDY))
+       if (nvme_ctrl_ready(ns->ctrl))
                return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION,
                                            NOT_READY, SCSI_ASC_LUN_NOT_READY,
                                            SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
index dd92c5e..b48ac63 100644 (file)
@@ -138,22 +138,22 @@ static int __oprofilefs_create_file(struct dentry *root, char const *name,
        struct dentry *dentry;
        struct inode *inode;
 
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
        dentry = d_alloc_name(root, name);
        if (!dentry) {
-               mutex_unlock(&d_inode(root)->i_mutex);
+               inode_unlock(d_inode(root));
                return -ENOMEM;
        }
        inode = oprofilefs_get_inode(root->d_sb, S_IFREG | perm);
        if (!inode) {
                dput(dentry);
-               mutex_unlock(&d_inode(root)->i_mutex);
+               inode_unlock(d_inode(root));
                return -ENOMEM;
        }
        inode->i_fop = fops;
        inode->i_private = priv;
        d_add(dentry, inode);
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        return 0;
 }
 
@@ -215,22 +215,22 @@ struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name)
        struct dentry *dentry;
        struct inode *inode;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        dentry = d_alloc_name(parent, name);
        if (!dentry) {
-               mutex_unlock(&d_inode(parent)->i_mutex);
+               inode_unlock(d_inode(parent));
                return NULL;
        }
        inode = oprofilefs_get_inode(parent->d_sb, S_IFDIR | 0755);
        if (!inode) {
                dput(dentry);
-               mutex_unlock(&d_inode(parent)->i_mutex);
+               inode_unlock(d_inode(parent));
                return NULL;
        }
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
        d_add(dentry, inode);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        return dentry;
 }
 
index 8e11fb2..e24b059 100644 (file)
@@ -786,18 +786,27 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
        return CCIO_IOVA(iovp, offset);
 }
 
+
+static dma_addr_t
+ccio_map_page(struct device *dev, struct page *page, unsigned long offset,
+               size_t size, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       return ccio_map_single(dev, page_address(page) + offset, size,
+                       direction);
+}
+
+
 /**
- * ccio_unmap_single - Unmap an address range from the IOMMU.
+ * ccio_unmap_page - Unmap an address range from the IOMMU.
  * @dev: The PCI device.
  * @addr: The start address of the DMA region.
  * @size: The length of the DMA region.
  * @direction: The direction of the DMA transaction (to/from device).
- *
- * This function implements the pci_unmap_single function.
  */
 static void 
-ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size, 
-                 enum dma_data_direction direction)
+ccio_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        struct ioc *ioc;
        unsigned long flags; 
@@ -826,7 +835,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
 }
 
 /**
- * ccio_alloc_consistent - Allocate a consistent DMA mapping.
+ * ccio_alloc - Allocate a consistent DMA mapping.
  * @dev: The PCI device.
  * @size: The length of the DMA region.
  * @dma_handle: The DMA address handed back to the device (not the cpu).
@@ -834,7 +843,8 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
  * This function implements the pci_alloc_consistent function.
  */
 static void * 
-ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
+ccio_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag,
+               struct dma_attrs *attrs)
 {
       void *ret;
 #if 0
@@ -858,7 +868,7 @@ ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, g
 }
 
 /**
- * ccio_free_consistent - Free a consistent DMA mapping.
+ * ccio_free - Free a consistent DMA mapping.
  * @dev: The PCI device.
  * @size: The length of the DMA region.
  * @cpu_addr: The cpu address returned from the ccio_alloc_consistent.
@@ -867,10 +877,10 @@ ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, g
  * This function implements the pci_free_consistent function.
  */
 static void 
-ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr, 
-                    dma_addr_t dma_handle)
+ccio_free(struct device *dev, size_t size, void *cpu_addr,
+               dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
-       ccio_unmap_single(dev, dma_handle, size, 0);
+       ccio_unmap_page(dev, dma_handle, size, 0, NULL);
        free_pages((unsigned long)cpu_addr, get_order(size));
 }
 
@@ -897,7 +907,7 @@ ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr,
  */
 static int
 ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, 
-           enum dma_data_direction direction)
+           enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        struct ioc *ioc;
        int coalesced, filled = 0;
@@ -974,7 +984,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
  */
 static void 
 ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, 
-             enum dma_data_direction direction)
+             enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        struct ioc *ioc;
 
@@ -993,27 +1003,22 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
 #ifdef CCIO_COLLECT_STATS
                ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
 #endif
-               ccio_unmap_single(dev, sg_dma_address(sglist),
-                                 sg_dma_len(sglist), direction);
+               ccio_unmap_page(dev, sg_dma_address(sglist),
+                                 sg_dma_len(sglist), direction, NULL);
                ++sglist;
        }
 
        DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents);
 }
 
-static struct hppa_dma_ops ccio_ops = {
+static struct dma_map_ops ccio_ops = {
        .dma_supported =        ccio_dma_supported,
-       .alloc_consistent =     ccio_alloc_consistent,
-       .alloc_noncoherent =    ccio_alloc_consistent,
-       .free_consistent =      ccio_free_consistent,
-       .map_single =           ccio_map_single,
-       .unmap_single =         ccio_unmap_single,
+       .alloc =                ccio_alloc,
+       .free =                 ccio_free,
+       .map_page =             ccio_map_page,
+       .unmap_page =           ccio_unmap_page,
        .map_sg =               ccio_map_sg,
        .unmap_sg =             ccio_unmap_sg,
-       .dma_sync_single_for_cpu =      NULL,   /* NOP for U2/Uturn */
-       .dma_sync_single_for_device =   NULL,   /* NOP for U2/Uturn */
-       .dma_sync_sg_for_cpu =          NULL,   /* ditto */
-       .dma_sync_sg_for_device =               NULL,   /* ditto */
 };
 
 #ifdef CONFIG_PROC_FS
@@ -1062,7 +1067,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
                           ioc->msingle_calls, ioc->msingle_pages,
                           (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
 
-               /* KLUGE - unmap_sg calls unmap_single for each mapped page */
+               /* KLUGE - unmap_sg calls unmap_page for each mapped page */
                min = ioc->usingle_calls - ioc->usg_calls;
                max = ioc->usingle_pages - ioc->usg_pages;
                seq_printf(m, "pci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
index 225049b..42ec460 100644 (file)
@@ -780,8 +780,18 @@ sba_map_single(struct device *dev, void *addr, size_t size,
 }
 
 
+static dma_addr_t
+sba_map_page(struct device *dev, struct page *page, unsigned long offset,
+               size_t size, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
+{
+       return sba_map_single(dev, page_address(page) + offset, size,
+                       direction);
+}
+
+
 /**
- * sba_unmap_single - unmap one IOVA and free resources
+ * sba_unmap_page - unmap one IOVA and free resources
  * @dev: instance of PCI owned by the driver that's asking.
  * @iova:  IOVA of driver buffer previously mapped.
  * @size:  number of bytes mapped in driver buffer.
@@ -790,8 +800,8 @@ sba_map_single(struct device *dev, void *addr, size_t size,
  * See Documentation/DMA-API-HOWTO.txt
  */
 static void
-sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
-                enum dma_data_direction direction)
+sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
+               enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        struct ioc *ioc;
 #if DELAYED_RESOURCE_CNT > 0
@@ -858,15 +868,15 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
 
 
 /**
- * sba_alloc_consistent - allocate/map shared mem for DMA
+ * sba_alloc - allocate/map shared mem for DMA
  * @hwdev: instance of PCI owned by the driver that's asking.
  * @size:  number of bytes mapped in driver buffer.
  * @dma_handle:  IOVA of new buffer.
  *
  * See Documentation/DMA-API-HOWTO.txt
  */
-static void *sba_alloc_consistent(struct device *hwdev, size_t size,
-                                       dma_addr_t *dma_handle, gfp_t gfp)
+static void *sba_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle,
+               gfp_t gfp, struct dma_attrs *attrs)
 {
        void *ret;
 
@@ -888,7 +898,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
 
 
 /**
- * sba_free_consistent - free/unmap shared mem for DMA
+ * sba_free - free/unmap shared mem for DMA
  * @hwdev: instance of PCI owned by the driver that's asking.
  * @size:  number of bytes mapped in driver buffer.
  * @vaddr:  virtual address IOVA of "consistent" buffer.
@@ -897,10 +907,10 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
  * See Documentation/DMA-API-HOWTO.txt
  */
 static void
-sba_free_consistent(struct device *hwdev, size_t size, void *vaddr,
-                   dma_addr_t dma_handle)
+sba_free(struct device *hwdev, size_t size, void *vaddr,
+                   dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
-       sba_unmap_single(hwdev, dma_handle, size, 0);
+       sba_unmap_page(hwdev, dma_handle, size, 0, NULL);
        free_pages((unsigned long) vaddr, get_order(size));
 }
 
@@ -933,7 +943,7 @@ int dump_run_sg = 0;
  */
 static int
 sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
-          enum dma_data_direction direction)
+          enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        struct ioc *ioc;
        int coalesced, filled = 0;
@@ -1016,7 +1026,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
  */
 static void 
 sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
-            enum dma_data_direction direction)
+            enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        struct ioc *ioc;
 #ifdef ASSERT_PDIR_SANITY
@@ -1040,7 +1050,8 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
 
        while (sg_dma_len(sglist) && nents--) {
 
-               sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
+               sba_unmap_page(dev, sg_dma_address(sglist), sg_dma_len(sglist),
+                               direction, NULL);
 #ifdef SBA_COLLECT_STATS
                ioc->usg_pages += ((sg_dma_address(sglist) & ~IOVP_MASK) + sg_dma_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
                ioc->usingle_calls--;   /* kluge since call is unmap_sg() */
@@ -1058,19 +1069,14 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
 
 }
 
-static struct hppa_dma_ops sba_ops = {
+static struct dma_map_ops sba_ops = {
        .dma_supported =        sba_dma_supported,
-       .alloc_consistent =     sba_alloc_consistent,
-       .alloc_noncoherent =    sba_alloc_consistent,
-       .free_consistent =      sba_free_consistent,
-       .map_single =           sba_map_single,
-       .unmap_single =         sba_unmap_single,
+       .alloc =                sba_alloc,
+       .free =                 sba_free,
+       .map_page =             sba_map_page,
+       .unmap_page =           sba_unmap_page,
        .map_sg =               sba_map_sg,
        .unmap_sg =             sba_unmap_sg,
-       .dma_sync_single_for_cpu =      NULL,
-       .dma_sync_single_for_device =   NULL,
-       .dma_sync_sg_for_cpu =          NULL,
-       .dma_sync_sg_for_device =       NULL,
 };
 
 
index 59ac36f..8c05b5c 100644 (file)
@@ -25,7 +25,7 @@ DEFINE_RAW_SPINLOCK(pci_lock);
 #define PCI_word_BAD (pos & 1)
 #define PCI_dword_BAD (pos & 3)
 
-#define PCI_OP_READ(size,type,len) \
+#define PCI_OP_READ(size, type, len) \
 int pci_bus_read_config_##size \
        (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \
 {                                                                      \
@@ -40,7 +40,7 @@ int pci_bus_read_config_##size \
        return res;                                                     \
 }
 
-#define PCI_OP_WRITE(size,type,len) \
+#define PCI_OP_WRITE(size, type, len) \
 int pci_bus_write_config_##size \
        (struct pci_bus *bus, unsigned int devfn, int pos, type value)  \
 {                                                                      \
@@ -231,7 +231,7 @@ static noinline void pci_wait_cfg(struct pci_dev *dev)
 }
 
 /* Returns 0 on success, negative values indicate error. */
-#define PCI_USER_READ_CONFIG(size,type)                                        \
+#define PCI_USER_READ_CONFIG(size, type)                                       \
 int pci_user_read_config_##size                                                \
        (struct pci_dev *dev, int pos, type *val)                       \
 {                                                                      \
@@ -251,7 +251,7 @@ int pci_user_read_config_##size                                             \
 EXPORT_SYMBOL_GPL(pci_user_read_config_##size);
 
 /* Returns 0 on success, negative values indicate error. */
-#define PCI_USER_WRITE_CONFIG(size,type)                               \
+#define PCI_USER_WRITE_CONFIG(size, type)                              \
 int pci_user_write_config_##size                                       \
        (struct pci_dev *dev, int pos, type val)                        \
 {                                                                      \
index d3346d2..89b3bef 100644 (file)
@@ -140,6 +140,8 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
        type_mask |= IORESOURCE_TYPE_BITS;
 
        pci_bus_for_each_resource(bus, r, i) {
+               resource_size_t min_used = min;
+
                if (!r)
                        continue;
 
@@ -163,12 +165,12 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
                 * overrides "min".
                 */
                if (avail.start)
-                       min = avail.start;
+                       min_used = avail.start;
 
                max = avail.end;
 
                /* Ok, try it out.. */
-               ret = allocate_resource(r, res, size, min, max,
+               ret = allocate_resource(r, res, size, min_used, max,
                                        align, alignf, alignf_data);
                if (ret == 0)
                        return 0;
index c0ad9aa..75a6054 100644 (file)
@@ -49,8 +49,7 @@ config PCI_RCAR_GEN2
 
 config PCI_RCAR_GEN2_PCIE
        bool "Renesas R-Car PCIe controller"
-       depends on ARM
-       depends on ARCH_SHMOBILE || COMPILE_TEST
+       depends on ARCH_SHMOBILE || (ARM && COMPILE_TEST)
        help
          Say Y here if you want PCIe controller support on R-Car Gen2 SoCs.
 
@@ -119,13 +118,11 @@ config PCI_VERSATILE
        depends on ARCH_VERSATILE
 
 config PCIE_IPROC
-       tristate "Broadcom iProc PCIe controller"
-       depends on OF && (ARM || ARM64)
-       default n
+       tristate
        help
          This enables the iProc PCIe core controller support for Broadcom's
-         iProc family of SoCs. An appropriate bus interface driver also needs
-         to be enabled
+         iProc family of SoCs. An appropriate bus interface driver needs
+         to be enabled to select this.
 
 config PCIE_IPROC_PLATFORM
        tristate "Broadcom iProc PCIe platform bus driver"
@@ -148,6 +145,16 @@ config PCIE_IPROC_BCMA
          Say Y here if you want to use the Broadcom iProc PCIe controller
          through the BCMA bus interface
 
+config PCIE_IPROC_MSI
+       bool "Broadcom iProc PCIe MSI support"
+       depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA
+       depends on PCI_MSI
+       select PCI_MSI_IRQ_DOMAIN
+       default ARCH_BCM_IPROC
+       help
+         Say Y here if you want to enable MSI support for Broadcom's iProc
+         PCIe controller
+
 config PCIE_ALTERA
        bool "Altera PCIe controller"
        depends on ARM || NIOS2
@@ -167,10 +174,21 @@ config PCIE_ALTERA_MSI
 
 config PCI_HISI
        depends on OF && ARM64
-       bool "HiSilicon SoC HIP05 PCIe controller"
+       bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers"
        select PCIEPORTBUS
        select PCIE_DW
        help
-         Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+         Say Y here if you want PCIe controller support on HiSilicon
+         Hip05 and Hip06 SoCs
+
+config PCIE_QCOM
+       bool "Qualcomm PCIe controller"
+       depends on ARCH_QCOM && OF
+       select PCIE_DW
+       select PCIEPORTBUS
+       help
+         Say Y here to enable PCIe controller support on Qualcomm SoCs. The
+         PCIe controller uses the Designware core plus Qualcomm-specific
+         hardware wrappers.
 
 endmenu
index 9d4d3c6..7b2f20c 100644 (file)
@@ -15,8 +15,10 @@ obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
 obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
 obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
+obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
 obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
 obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
index 8c36880..923607b 100644 (file)
@@ -302,7 +302,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
        }
 
        ret = devm_request_irq(&pdev->dev, pp->irq,
-                              dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
+                              dra7xx_pcie_msi_irq_handler,
+                              IRQF_SHARED | IRQF_NO_THREAD,
                               "dra7-pcie-msi", pp);
        if (ret) {
                dev_err(&pdev->dev, "failed to request irq\n");
index 01095e1..d997d22 100644 (file)
@@ -522,7 +522,8 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
 
                ret = devm_request_irq(&pdev->dev, pp->msi_irq,
                                        exynos_pcie_msi_irq_handler,
-                                       IRQF_SHARED, "exynos-pcie", pp);
+                                       IRQF_SHARED | IRQF_NO_THREAD,
+                                       "exynos-pcie", pp);
                if (ret) {
                        dev_err(&pdev->dev, "failed to request msi irq\n");
                        return ret;
index 5434c90..1652bc7 100644 (file)
@@ -38,16 +38,7 @@ struct gen_pci_cfg_windows {
        struct gen_pci_cfg_bus_ops              *ops;
 };
 
-/*
- * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
- * sysdata.  Add pci_sys_data as the first element in struct gen_pci so
- * that when we use a gen_pci pointer as sysdata, it is also a pointer to
- * a struct pci_sys_data.
- */
 struct gen_pci {
-#ifdef CONFIG_ARM
-       struct pci_sys_data                     sys;
-#endif
        struct pci_host_bridge                  host;
        struct gen_pci_cfg_windows              cfg;
        struct list_head                        resources;
index 22e8224..fe60096 100644 (file)
@@ -32,7 +32,7 @@
 #define to_imx6_pcie(x)        container_of(x, struct imx6_pcie, pp)
 
 struct imx6_pcie {
-       int                     reset_gpio;
+       struct gpio_desc        *reset_gpio;
        struct clk              *pcie_bus;
        struct clk              *pcie_phy;
        struct clk              *pcie;
@@ -122,7 +122,7 @@ static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
 }
 
 /* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
-static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
+static int pcie_phy_read(void __iomem *dbi_base, int addr, int *data)
 {
        u32 val, phy_ctl;
        int ret;
@@ -287,10 +287,10 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
        usleep_range(200, 500);
 
        /* Some boards don't have PCIe reset GPIO. */
-       if (gpio_is_valid(imx6_pcie->reset_gpio)) {
-               gpio_set_value(imx6_pcie->reset_gpio, 0);
+       if (imx6_pcie->reset_gpio) {
+               gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 0);
                msleep(100);
-               gpio_set_value(imx6_pcie->reset_gpio, 1);
+               gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 1);
        }
        return 0;
 
@@ -537,7 +537,8 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
 
                ret = devm_request_irq(&pdev->dev, pp->msi_irq,
                                       imx6_pcie_msi_handler,
-                                      IRQF_SHARED, "mx6-pcie-msi", pp);
+                                      IRQF_SHARED | IRQF_NO_THREAD,
+                                      "mx6-pcie-msi", pp);
                if (ret) {
                        dev_err(&pdev->dev, "failed to request MSI irq\n");
                        return ret;
@@ -560,7 +561,6 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
 {
        struct imx6_pcie *imx6_pcie;
        struct pcie_port *pp;
-       struct device_node *np = pdev->dev.of_node;
        struct resource *dbi_base;
        int ret;
 
@@ -581,15 +581,8 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
                return PTR_ERR(pp->dbi_base);
 
        /* Fetch GPIOs */
-       imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
-       if (gpio_is_valid(imx6_pcie->reset_gpio)) {
-               ret = devm_gpio_request_one(&pdev->dev, imx6_pcie->reset_gpio,
-                                           GPIOF_OUT_INIT_LOW, "PCIe reset");
-               if (ret) {
-                       dev_err(&pdev->dev, "unable to get reset gpio\n");
-                       return ret;
-               }
-       }
+       imx6_pcie->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
+                                                       GPIOD_OUT_LOW);
 
        /* Fetch clocks */
        imx6_pcie->pcie_phy = devm_clk_get(&pdev->dev, "pcie_phy");
index c4f64bf..9980a4b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
@@ -102,6 +103,8 @@ struct rcar_pci_priv {
        unsigned busnr;
        int irq;
        unsigned long window_size;
+       unsigned long window_addr;
+       unsigned long window_pci;
 };
 
 /* PCI configuration space operations */
@@ -239,8 +242,8 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
               RCAR_PCI_ARBITER_PCIBP_MODE;
        iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
 
-       /* PCI-AHB mapping: 0x40000000 base */
-       iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16,
+       /* PCI-AHB mapping */
+       iowrite32(priv->window_addr | RCAR_PCIAHB_PREFETCH16,
                  reg + RCAR_PCIAHB_WIN1_CTR_REG);
 
        /* AHB-PCI mapping: OHCI/EHCI registers */
@@ -251,7 +254,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
        iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
                  reg + RCAR_AHBPCI_WIN1_CTR_REG);
        /* Set PCI-AHB Window1 address */
-       iowrite32(0x40000000 | PCI_BASE_ADDRESS_MEM_PREFETCH,
+       iowrite32(priv->window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH,
                  reg + PCI_BASE_ADDRESS_1);
        /* Set AHB-PCI bridge PCI communication area address */
        val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
@@ -284,6 +287,64 @@ static struct pci_ops rcar_pci_ops = {
        .write  = pci_generic_config_write,
 };
 
+static int pci_dma_range_parser_init(struct of_pci_range_parser *parser,
+                                    struct device_node *node)
+{
+       const int na = 3, ns = 2;
+       int rlen;
+
+       parser->node = node;
+       parser->pna = of_n_addr_cells(node);
+       parser->np = parser->pna + na + ns;
+
+       parser->range = of_get_property(node, "dma-ranges", &rlen);
+       if (!parser->range)
+               return -ENOENT;
+
+       parser->end = parser->range + rlen / sizeof(__be32);
+       return 0;
+}
+
+static int rcar_pci_parse_map_dma_ranges(struct rcar_pci_priv *pci,
+                                        struct device_node *np)
+{
+       struct of_pci_range range;
+       struct of_pci_range_parser parser;
+       int index = 0;
+
+       /* Failure to parse is ok as we fall back to defaults */
+       if (pci_dma_range_parser_init(&parser, np))
+               return 0;
+
+       /* Get the dma-ranges from DT */
+       for_each_of_pci_range(&parser, &range) {
+               /* Hardware only allows one inbound 32-bit range */
+               if (index)
+                       return -EINVAL;
+
+               pci->window_addr = (unsigned long)range.cpu_addr;
+               pci->window_pci = (unsigned long)range.pci_addr;
+               pci->window_size = (unsigned long)range.size;
+
+               /* Catch HW limitations */
+               if (!(range.flags & IORESOURCE_PREFETCH)) {
+                       dev_err(pci->dev, "window must be prefetchable\n");
+                       return -EINVAL;
+               }
+               if (pci->window_addr) {
+                       u32 lowaddr = 1 << (ffs(pci->window_addr) - 1);
+
+                       if (lowaddr < pci->window_size) {
+                               dev_err(pci->dev, "invalid window size/addr\n");
+                               return -EINVAL;
+                       }
+               }
+               index++;
+       }
+
+       return 0;
+}
+
 static int rcar_pci_probe(struct platform_device *pdev)
 {
        struct resource *cfg_res, *mem_res;
@@ -329,6 +390,9 @@ static int rcar_pci_probe(struct platform_device *pdev)
                return priv->irq;
        }
 
+       /* default window addr and size if not specified in DT */
+       priv->window_addr = 0x40000000;
+       priv->window_pci = 0x40000000;
        priv->window_size = SZ_1G;
 
        if (pdev->dev.of_node) {
@@ -344,6 +408,12 @@ static int rcar_pci_probe(struct platform_device *pdev)
                priv->busnr = busnr.start;
                if (busnr.end != busnr.start)
                        dev_warn(&pdev->dev, "only one bus number supported\n");
+
+               ret = rcar_pci_parse_map_dma_ranges(priv, pdev->dev.of_node);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to parse dma-range\n");
+                       return ret;
+               }
        } else {
                priv->busnr = pdev->id;
        }
@@ -360,6 +430,7 @@ static int rcar_pci_probe(struct platform_device *pdev)
 }
 
 static struct of_device_id rcar_pci_of_match[] = {
+       { .compatible = "renesas,pci-rcar-gen2", },
        { .compatible = "renesas,pci-r8a7790", },
        { .compatible = "renesas,pci-r8a7791", },
        { .compatible = "renesas,pci-r8a7794", },
index 3018ae5..3032311 100644 (file)
@@ -1288,7 +1288,7 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
 
        msi->irq = err;
 
-       err = request_irq(msi->irq, tegra_pcie_msi_irq, 0,
+       err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
                          tegra_msi_irq_chip.name, pcie);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
index 0863d9c..f843a72 100644 (file)
@@ -125,9 +125,6 @@ out_release_res:
        return err;
 }
 
-/* Unused, temporary to satisfy ARM arch code */
-struct pci_sys_data sys;
-
 static int versatile_pci_probe(struct platform_device *pdev)
 {
        struct resource *res;
@@ -208,7 +205,7 @@ static int versatile_pci_probe(struct platform_device *pdev)
        pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
        pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
 
-       bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, &sys, &pci_res);
+       bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, NULL, &pci_res);
        if (!bus)
                return -ENOMEM;
 
index 02a7452..2171682 100644 (file)
@@ -128,32 +128,26 @@ static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
 static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
                               u32 *val)
 {
-       int ret;
-
        if (pp->ops->rd_own_conf)
-               ret = pp->ops->rd_own_conf(pp, where, size, val);
-       else
-               ret = dw_pcie_cfg_read(pp->dbi_base + where, size, val);
+               return pp->ops->rd_own_conf(pp, where, size, val);
 
-       return ret;
+       return dw_pcie_cfg_read(pp->dbi_base + where, size, val);
 }
 
 static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
                               u32 val)
 {
-       int ret;
-
        if (pp->ops->wr_own_conf)
-               ret = pp->ops->wr_own_conf(pp, where, size, val);
-       else
-               ret = dw_pcie_cfg_write(pp->dbi_base + where, size, val);
+               return pp->ops->wr_own_conf(pp, where, size, val);
 
-       return ret;
+       return dw_pcie_cfg_write(pp->dbi_base + where, size, val);
 }
 
 static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
                int type, u64 cpu_addr, u64 pci_addr, u32 size)
 {
+       u32 val;
+
        dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
                          PCIE_ATU_VIEWPORT);
        dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr), PCIE_ATU_LOWER_BASE);
@@ -164,6 +158,12 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
        dw_pcie_writel_rc(pp, upper_32_bits(pci_addr), PCIE_ATU_UPPER_TARGET);
        dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
        dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
+
+       /*
+        * Make sure ATU enable takes effect before any subsequent config
+        * and I/O accesses.
+        */
+       dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
 }
 
 static struct irq_chip dw_msi_irq_chip = {
@@ -384,8 +384,8 @@ int dw_pcie_link_up(struct pcie_port *pp)
 {
        if (pp->ops->link_up)
                return pp->ops->link_up(pp);
-       else
-               return 0;
+
+       return 0;
 }
 
 static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
@@ -571,6 +571,9 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
        u64 cpu_addr;
        void __iomem *va_cfg_base;
 
+       if (pp->ops->rd_other_conf)
+               return pp->ops->rd_other_conf(pp, bus, devfn, where, size, val);
+
        busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
                 PCIE_ATU_FUNC(PCI_FUNC(devfn));
 
@@ -605,6 +608,9 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
        u64 cpu_addr;
        void __iomem *va_cfg_base;
 
+       if (pp->ops->wr_other_conf)
+               return pp->ops->wr_other_conf(pp, bus, devfn, where, size, val);
+
        busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
                 PCIE_ATU_FUNC(PCI_FUNC(devfn));
 
@@ -658,46 +664,30 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
                        int size, u32 *val)
 {
        struct pcie_port *pp = bus->sysdata;
-       int ret;
 
        if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
                *val = 0xffffffff;
                return PCIBIOS_DEVICE_NOT_FOUND;
        }
 
-       if (bus->number != pp->root_bus_nr)
-               if (pp->ops->rd_other_conf)
-                       ret = pp->ops->rd_other_conf(pp, bus, devfn,
-                                               where, size, val);
-               else
-                       ret = dw_pcie_rd_other_conf(pp, bus, devfn,
-                                               where, size, val);
-       else
-               ret = dw_pcie_rd_own_conf(pp, where, size, val);
+       if (bus->number == pp->root_bus_nr)
+               return dw_pcie_rd_own_conf(pp, where, size, val);
 
-       return ret;
+       return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
 }
 
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
                        int where, int size, u32 val)
 {
        struct pcie_port *pp = bus->sysdata;
-       int ret;
 
        if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
-       if (bus->number != pp->root_bus_nr)
-               if (pp->ops->wr_other_conf)
-                       ret = pp->ops->wr_other_conf(pp, bus, devfn,
-                                               where, size, val);
-               else
-                       ret = dw_pcie_wr_other_conf(pp, bus, devfn,
-                                               where, size, val);
-       else
-               ret = dw_pcie_wr_own_conf(pp, where, size, val);
+       if (bus->number == pp->root_bus_nr)
+               return dw_pcie_wr_own_conf(pp, where, size, val);
 
-       return ret;
+       return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
 }
 
 static struct pci_ops dw_pcie_ops = {
index 77f7c66..3e98d4e 100644 (file)
@@ -1,10 +1,11 @@
 /*
- * PCIe host controller driver for HiSilicon Hip05 SoC
+ * PCIe host controller driver for HiSilicon SoCs
  *
  * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
  *
- * Author: Zhou Wang <wangzhou1@hisilicon.com>
- *         Dacai Zhu <zhudacai@hisilicon.com>
+ * Authors: Zhou Wang <wangzhou1@hisilicon.com>
+ *          Dacai Zhu <zhudacai@hisilicon.com>
+ *          Gabriele Paoloni <gabriele.paoloni@huawei.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
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/platform_device.h>
+#include <linux/of_device.h>
 #include <linux/regmap.h>
 
 #include "pcie-designware.h"
 
-#define PCIE_SUBCTRL_SYS_STATE4_REG                     0x6818
-#define PCIE_LTSSM_LINKUP_STATE                         0x11
-#define PCIE_LTSSM_STATE_MASK                           0x3F
+#define PCIE_LTSSM_LINKUP_STATE                                0x11
+#define PCIE_LTSSM_STATE_MASK                          0x3F
+#define PCIE_SUBCTRL_SYS_STATE4_REG                    0x6818
+#define PCIE_SYS_STATE4                                                0x31c
+#define PCIE_HIP06_CTRL_OFF                                    0x1000
 
 #define to_hisi_pcie(x)        container_of(x, struct hisi_pcie, pp)
 
+struct hisi_pcie;
+
+struct pcie_soc_ops {
+       int (*hisi_pcie_link_up)(struct hisi_pcie *pcie);
+};
+
 struct hisi_pcie {
        struct regmap *subctrl;
        void __iomem *reg_base;
        u32 port_id;
        struct pcie_port pp;
+       struct pcie_soc_ops *soc_ops;
 };
 
 static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
@@ -44,7 +55,7 @@ static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
        return readl(pcie->reg_base + reg);
 }
 
-/* Hip05 PCIe host only supports 32-bit config access */
+/* HipXX PCIe host only supports 32-bit config access */
 static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size,
                              u32 *val)
 {
@@ -69,7 +80,7 @@ static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size,
        return PCIBIOS_SUCCESSFUL;
 }
 
-/* Hip05 PCIe host only supports 32-bit config access */
+/* HipXX PCIe host only supports 32-bit config access */
 static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int  size,
                                u32 val)
 {
@@ -96,10 +107,9 @@ static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int  size,
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int hisi_pcie_link_up(struct pcie_port *pp)
+static int hisi_pcie_link_up_hip05(struct hisi_pcie *hisi_pcie)
 {
        u32 val;
-       struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
 
        regmap_read(hisi_pcie->subctrl, PCIE_SUBCTRL_SYS_STATE4_REG +
                    0x100 * hisi_pcie->port_id, &val);
@@ -107,6 +117,23 @@ static int hisi_pcie_link_up(struct pcie_port *pp)
        return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
 }
 
+static int hisi_pcie_link_up_hip06(struct hisi_pcie *hisi_pcie)
+{
+       u32 val;
+
+       val = hisi_pcie_apb_readl(hisi_pcie, PCIE_HIP06_CTRL_OFF +
+                       PCIE_SYS_STATE4);
+
+       return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
+}
+
+static int hisi_pcie_link_up(struct pcie_port *pp)
+{
+       struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+       return hisi_pcie->soc_ops->hisi_pcie_link_up(hisi_pcie);
+}
+
 static struct pcie_host_ops hisi_pcie_host_ops = {
        .rd_own_conf = hisi_pcie_cfg_read,
        .wr_own_conf = hisi_pcie_cfg_write,
@@ -145,7 +172,9 @@ static int hisi_pcie_probe(struct platform_device *pdev)
 {
        struct hisi_pcie *hisi_pcie;
        struct pcie_port *pp;
+       const struct of_device_id *match;
        struct resource *reg;
+       struct device_driver *driver;
        int ret;
 
        hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
@@ -154,6 +183,10 @@ static int hisi_pcie_probe(struct platform_device *pdev)
 
        pp = &hisi_pcie->pp;
        pp->dev = &pdev->dev;
+       driver = (pdev->dev).driver;
+
+       match = of_match_device(driver->of_match_table, &pdev->dev);
+       hisi_pcie->soc_ops = (struct pcie_soc_ops *) match->data;
 
        hisi_pcie->subctrl =
        syscon_regmap_lookup_by_compatible("hisilicon,pcie-sas-subctrl");
@@ -182,11 +215,27 @@ static int hisi_pcie_probe(struct platform_device *pdev)
        return 0;
 }
 
+static struct pcie_soc_ops hip05_ops = {
+               &hisi_pcie_link_up_hip05
+};
+
+static struct pcie_soc_ops hip06_ops = {
+               &hisi_pcie_link_up_hip06
+};
+
 static const struct of_device_id hisi_pcie_of_match[] = {
-       {.compatible = "hisilicon,hip05-pcie",},
+       {
+                       .compatible = "hisilicon,hip05-pcie",
+                       .data       = (void *) &hip05_ops,
+       },
+       {
+                       .compatible = "hisilicon,hip06-pcie",
+                       .data       = (void *) &hip06_ops,
+       },
        {},
 };
 
+
 MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
 
 static struct platform_driver hisi_pcie_driver = {
@@ -198,3 +247,8 @@ static struct platform_driver hisi_pcie_driver = {
 };
 
 module_platform_driver(hisi_pcie_driver);
+
+MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
+MODULE_AUTHOR("Dacai Zhu <zhudacai@hisilicon.com>");
+MODULE_AUTHOR("Gabriele Paoloni <gabriele.paoloni@huawei.com>");
+MODULE_LICENSE("GPL v2");
index 96a7d99..0d7bee4 100644 (file)
@@ -55,6 +55,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
        bcma_set_drvdata(bdev, pcie);
 
        pcie->base = bdev->io_addr;
+       pcie->base_addr = bdev->addr;
 
        res_mem.start = bdev->addr_s[0];
        res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
diff --git a/drivers/pci/host/pcie-iproc-msi.c b/drivers/pci/host/pcie-iproc-msi.c
new file mode 100644 (file)
index 0000000..9a2973b
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation 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/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+
+#include "pcie-iproc.h"
+
+#define IPROC_MSI_INTR_EN_SHIFT        11
+#define IPROC_MSI_INTR_EN              BIT(IPROC_MSI_INTR_EN_SHIFT)
+#define IPROC_MSI_INT_N_EVENT_SHIFT    1
+#define IPROC_MSI_INT_N_EVENT          BIT(IPROC_MSI_INT_N_EVENT_SHIFT)
+#define IPROC_MSI_EQ_EN_SHIFT          0
+#define IPROC_MSI_EQ_EN                BIT(IPROC_MSI_EQ_EN_SHIFT)
+
+#define IPROC_MSI_EQ_MASK              0x3f
+
+/* Max number of GIC interrupts */
+#define NR_HW_IRQS                     6
+
+/* Number of entries in each event queue */
+#define EQ_LEN                         64
+
+/* Size of each event queue memory region */
+#define EQ_MEM_REGION_SIZE             SZ_4K
+
+/* Size of each MSI address region */
+#define MSI_MEM_REGION_SIZE            SZ_4K
+
+enum iproc_msi_reg {
+       IPROC_MSI_EQ_PAGE = 0,
+       IPROC_MSI_EQ_PAGE_UPPER,
+       IPROC_MSI_PAGE,
+       IPROC_MSI_PAGE_UPPER,
+       IPROC_MSI_CTRL,
+       IPROC_MSI_EQ_HEAD,
+       IPROC_MSI_EQ_TAIL,
+       IPROC_MSI_INTS_EN,
+       IPROC_MSI_REG_SIZE,
+};
+
+struct iproc_msi;
+
+/**
+ * iProc MSI group
+ *
+ * One MSI group is allocated per GIC interrupt, serviced by one iProc MSI
+ * event queue.
+ *
+ * @msi: pointer to iProc MSI data
+ * @gic_irq: GIC interrupt
+ * @eq: Event queue number
+ */
+struct iproc_msi_grp {
+       struct iproc_msi *msi;
+       int gic_irq;
+       unsigned int eq;
+};
+
+/**
+ * iProc event queue based MSI
+ *
+ * Only meant to be used on platforms without MSI support integrated into the
+ * GIC.
+ *
+ * @pcie: pointer to iProc PCIe data
+ * @reg_offsets: MSI register offsets
+ * @grps: MSI groups
+ * @nr_irqs: number of total interrupts connected to GIC
+ * @nr_cpus: number of toal CPUs
+ * @has_inten_reg: indicates the MSI interrupt enable register needs to be
+ * set explicitly (required for some legacy platforms)
+ * @bitmap: MSI vector bitmap
+ * @bitmap_lock: lock to protect access to the MSI bitmap
+ * @nr_msi_vecs: total number of MSI vectors
+ * @inner_domain: inner IRQ domain
+ * @msi_domain: MSI IRQ domain
+ * @nr_eq_region: required number of 4K aligned memory region for MSI event
+ * queues
+ * @nr_msi_region: required number of 4K aligned address region for MSI posted
+ * writes
+ * @eq_cpu: pointer to allocated memory region for MSI event queues
+ * @eq_dma: DMA address of MSI event queues
+ * @msi_addr: MSI address
+ */
+struct iproc_msi {
+       struct iproc_pcie *pcie;
+       const u16 (*reg_offsets)[IPROC_MSI_REG_SIZE];
+       struct iproc_msi_grp *grps;
+       int nr_irqs;
+       int nr_cpus;
+       bool has_inten_reg;
+       unsigned long *bitmap;
+       struct mutex bitmap_lock;
+       unsigned int nr_msi_vecs;
+       struct irq_domain *inner_domain;
+       struct irq_domain *msi_domain;
+       unsigned int nr_eq_region;
+       unsigned int nr_msi_region;
+       void *eq_cpu;
+       dma_addr_t eq_dma;
+       phys_addr_t msi_addr;
+};
+
+static const u16 iproc_msi_reg_paxb[NR_HW_IRQS][IPROC_MSI_REG_SIZE] = {
+       { 0x200, 0x2c0, 0x204, 0x2c4, 0x210, 0x250, 0x254, 0x208 },
+       { 0x200, 0x2c0, 0x204, 0x2c4, 0x214, 0x258, 0x25c, 0x208 },
+       { 0x200, 0x2c0, 0x204, 0x2c4, 0x218, 0x260, 0x264, 0x208 },
+       { 0x200, 0x2c0, 0x204, 0x2c4, 0x21c, 0x268, 0x26c, 0x208 },
+       { 0x200, 0x2c0, 0x204, 0x2c4, 0x220, 0x270, 0x274, 0x208 },
+       { 0x200, 0x2c0, 0x204, 0x2c4, 0x224, 0x278, 0x27c, 0x208 },
+};
+
+static const u16 iproc_msi_reg_paxc[NR_HW_IRQS][IPROC_MSI_REG_SIZE] = {
+       { 0xc00, 0xc04, 0xc08, 0xc0c, 0xc40, 0xc50, 0xc60 },
+       { 0xc10, 0xc14, 0xc18, 0xc1c, 0xc44, 0xc54, 0xc64 },
+       { 0xc20, 0xc24, 0xc28, 0xc2c, 0xc48, 0xc58, 0xc68 },
+       { 0xc30, 0xc34, 0xc38, 0xc3c, 0xc4c, 0xc5c, 0xc6c },
+};
+
+static inline u32 iproc_msi_read_reg(struct iproc_msi *msi,
+                                    enum iproc_msi_reg reg,
+                                    unsigned int eq)
+{
+       struct iproc_pcie *pcie = msi->pcie;
+
+       return readl_relaxed(pcie->base + msi->reg_offsets[eq][reg]);
+}
+
+static inline void iproc_msi_write_reg(struct iproc_msi *msi,
+                                      enum iproc_msi_reg reg,
+                                      int eq, u32 val)
+{
+       struct iproc_pcie *pcie = msi->pcie;
+
+       writel_relaxed(val, pcie->base + msi->reg_offsets[eq][reg]);
+}
+
+static inline u32 hwirq_to_group(struct iproc_msi *msi, unsigned long hwirq)
+{
+       return (hwirq % msi->nr_irqs);
+}
+
+static inline unsigned int iproc_msi_addr_offset(struct iproc_msi *msi,
+                                                unsigned long hwirq)
+{
+       if (msi->nr_msi_region > 1)
+               return hwirq_to_group(msi, hwirq) * MSI_MEM_REGION_SIZE;
+       else
+               return hwirq_to_group(msi, hwirq) * sizeof(u32);
+}
+
+static inline unsigned int iproc_msi_eq_offset(struct iproc_msi *msi, u32 eq)
+{
+       if (msi->nr_eq_region > 1)
+               return eq * EQ_MEM_REGION_SIZE;
+       else
+               return eq * EQ_LEN * sizeof(u32);
+}
+
+static struct irq_chip iproc_msi_irq_chip = {
+       .name = "iProc-MSI",
+};
+
+static struct msi_domain_info iproc_msi_domain_info = {
+       .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+               MSI_FLAG_PCI_MSIX,
+       .chip = &iproc_msi_irq_chip,
+};
+
+/*
+ * In iProc PCIe core, each MSI group is serviced by a GIC interrupt and a
+ * dedicated event queue.  Each MSI group can support up to 64 MSI vectors.
+ *
+ * The number of MSI groups varies between different iProc SoCs.  The total
+ * number of CPU cores also varies.  To support MSI IRQ affinity, we
+ * distribute GIC interrupts across all available CPUs.  MSI vector is moved
+ * from one GIC interrupt to another to steer to the target CPU.
+ *
+ * Assuming:
+ * - the number of MSI groups is M
+ * - the number of CPU cores is N
+ * - M is always a multiple of N
+ *
+ * Total number of raw MSI vectors = M * 64
+ * Total number of supported MSI vectors = (M * 64) / N
+ */
+static inline int hwirq_to_cpu(struct iproc_msi *msi, unsigned long hwirq)
+{
+       return (hwirq % msi->nr_cpus);
+}
+
+static inline unsigned long hwirq_to_canonical_hwirq(struct iproc_msi *msi,
+                                                    unsigned long hwirq)
+{
+       return (hwirq - hwirq_to_cpu(msi, hwirq));
+}
+
+static int iproc_msi_irq_set_affinity(struct irq_data *data,
+                                     const struct cpumask *mask, bool force)
+{
+       struct iproc_msi *msi = irq_data_get_irq_chip_data(data);
+       int target_cpu = cpumask_first(mask);
+       int curr_cpu;
+
+       curr_cpu = hwirq_to_cpu(msi, data->hwirq);
+       if (curr_cpu == target_cpu)
+               return IRQ_SET_MASK_OK_DONE;
+
+       /* steer MSI to the target CPU */
+       data->hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq) + target_cpu;
+
+       return IRQ_SET_MASK_OK;
+}
+
+static void iproc_msi_irq_compose_msi_msg(struct irq_data *data,
+                                         struct msi_msg *msg)
+{
+       struct iproc_msi *msi = irq_data_get_irq_chip_data(data);
+       dma_addr_t addr;
+
+       addr = msi->msi_addr + iproc_msi_addr_offset(msi, data->hwirq);
+       msg->address_lo = lower_32_bits(addr);
+       msg->address_hi = upper_32_bits(addr);
+       msg->data = data->hwirq;
+}
+
+static struct irq_chip iproc_msi_bottom_irq_chip = {
+       .name = "MSI",
+       .irq_set_affinity = iproc_msi_irq_set_affinity,
+       .irq_compose_msi_msg = iproc_msi_irq_compose_msi_msg,
+};
+
+static int iproc_msi_irq_domain_alloc(struct irq_domain *domain,
+                                     unsigned int virq, unsigned int nr_irqs,
+                                     void *args)
+{
+       struct iproc_msi *msi = domain->host_data;
+       int hwirq;
+
+       mutex_lock(&msi->bitmap_lock);
+
+       /* Allocate 'nr_cpus' number of MSI vectors each time */
+       hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0,
+                                          msi->nr_cpus, 0);
+       if (hwirq < msi->nr_msi_vecs) {
+               bitmap_set(msi->bitmap, hwirq, msi->nr_cpus);
+       } else {
+               mutex_unlock(&msi->bitmap_lock);
+               return -ENOSPC;
+       }
+
+       mutex_unlock(&msi->bitmap_lock);
+
+       irq_domain_set_info(domain, virq, hwirq, &iproc_msi_bottom_irq_chip,
+                           domain->host_data, handle_simple_irq, NULL, NULL);
+
+       return 0;
+}
+
+static void iproc_msi_irq_domain_free(struct irq_domain *domain,
+                                     unsigned int virq, unsigned int nr_irqs)
+{
+       struct irq_data *data = irq_domain_get_irq_data(domain, virq);
+       struct iproc_msi *msi = irq_data_get_irq_chip_data(data);
+       unsigned int hwirq;
+
+       mutex_lock(&msi->bitmap_lock);
+
+       hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq);
+       bitmap_clear(msi->bitmap, hwirq, msi->nr_cpus);
+
+       mutex_unlock(&msi->bitmap_lock);
+
+       irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+       .alloc = iproc_msi_irq_domain_alloc,
+       .free = iproc_msi_irq_domain_free,
+};
+
+static inline u32 decode_msi_hwirq(struct iproc_msi *msi, u32 eq, u32 head)
+{
+       u32 *msg, hwirq;
+       unsigned int offs;
+
+       offs = iproc_msi_eq_offset(msi, eq) + head * sizeof(u32);
+       msg = (u32 *)(msi->eq_cpu + offs);
+       hwirq = *msg & IPROC_MSI_EQ_MASK;
+
+       /*
+        * Since we have multiple hwirq mapped to a single MSI vector,
+        * now we need to derive the hwirq at CPU0.  It can then be used to
+        * mapped back to virq.
+        */
+       return hwirq_to_canonical_hwirq(msi, hwirq);
+}
+
+static void iproc_msi_handler(struct irq_desc *desc)
+{
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct iproc_msi_grp *grp;
+       struct iproc_msi *msi;
+       struct iproc_pcie *pcie;
+       u32 eq, head, tail, nr_events;
+       unsigned long hwirq;
+       int virq;
+
+       chained_irq_enter(chip, desc);
+
+       grp = irq_desc_get_handler_data(desc);
+       msi = grp->msi;
+       pcie = msi->pcie;
+       eq = grp->eq;
+
+       /*
+        * iProc MSI event queue is tracked by head and tail pointers.  Head
+        * pointer indicates the next entry (MSI data) to be consumed by SW in
+        * the queue and needs to be updated by SW.  iProc MSI core uses the
+        * tail pointer as the next data insertion point.
+        *
+        * Entries between head and tail pointers contain valid MSI data.  MSI
+        * data is guaranteed to be in the event queue memory before the tail
+        * pointer is updated by the iProc MSI core.
+        */
+       head = iproc_msi_read_reg(msi, IPROC_MSI_EQ_HEAD,
+                                 eq) & IPROC_MSI_EQ_MASK;
+       do {
+               tail = iproc_msi_read_reg(msi, IPROC_MSI_EQ_TAIL,
+                                         eq) & IPROC_MSI_EQ_MASK;
+
+               /*
+                * Figure out total number of events (MSI data) to be
+                * processed.
+                */
+               nr_events = (tail < head) ?
+                       (EQ_LEN - (head - tail)) : (tail - head);
+               if (!nr_events)
+                       break;
+
+               /* process all outstanding events */
+               while (nr_events--) {
+                       hwirq = decode_msi_hwirq(msi, eq, head);
+                       virq = irq_find_mapping(msi->inner_domain, hwirq);
+                       generic_handle_irq(virq);
+
+                       head++;
+                       head %= EQ_LEN;
+               }
+
+               /*
+                * Now all outstanding events have been processed.  Update the
+                * head pointer.
+                */
+               iproc_msi_write_reg(msi, IPROC_MSI_EQ_HEAD, eq, head);
+
+               /*
+                * Now go read the tail pointer again to see if there are new
+                * oustanding events that came in during the above window.
+                */
+       } while (true);
+
+       chained_irq_exit(chip, desc);
+}
+
+static void iproc_msi_enable(struct iproc_msi *msi)
+{
+       int i, eq;
+       u32 val;
+
+       /* Program memory region for each event queue */
+       for (i = 0; i < msi->nr_eq_region; i++) {
+               dma_addr_t addr = msi->eq_dma + (i * EQ_MEM_REGION_SIZE);
+
+               iproc_msi_write_reg(msi, IPROC_MSI_EQ_PAGE, i,
+                                   lower_32_bits(addr));
+               iproc_msi_write_reg(msi, IPROC_MSI_EQ_PAGE_UPPER, i,
+                                   upper_32_bits(addr));
+       }
+
+       /* Program address region for MSI posted writes */
+       for (i = 0; i < msi->nr_msi_region; i++) {
+               phys_addr_t addr = msi->msi_addr + (i * MSI_MEM_REGION_SIZE);
+
+               iproc_msi_write_reg(msi, IPROC_MSI_PAGE, i,
+                                   lower_32_bits(addr));
+               iproc_msi_write_reg(msi, IPROC_MSI_PAGE_UPPER, i,
+                                   upper_32_bits(addr));
+       }
+
+       for (eq = 0; eq < msi->nr_irqs; eq++) {
+               /* Enable MSI event queue */
+               val = IPROC_MSI_INTR_EN | IPROC_MSI_INT_N_EVENT |
+                       IPROC_MSI_EQ_EN;
+               iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
+
+               /*
+                * Some legacy platforms require the MSI interrupt enable
+                * register to be set explicitly.
+                */
+               if (msi->has_inten_reg) {
+                       val = iproc_msi_read_reg(msi, IPROC_MSI_INTS_EN, eq);
+                       val |= BIT(eq);
+                       iproc_msi_write_reg(msi, IPROC_MSI_INTS_EN, eq, val);
+               }
+       }
+}
+
+static void iproc_msi_disable(struct iproc_msi *msi)
+{
+       u32 eq, val;
+
+       for (eq = 0; eq < msi->nr_irqs; eq++) {
+               if (msi->has_inten_reg) {
+                       val = iproc_msi_read_reg(msi, IPROC_MSI_INTS_EN, eq);
+                       val &= ~BIT(eq);
+                       iproc_msi_write_reg(msi, IPROC_MSI_INTS_EN, eq, val);
+               }
+
+               val = iproc_msi_read_reg(msi, IPROC_MSI_CTRL, eq);
+               val &= ~(IPROC_MSI_INTR_EN | IPROC_MSI_INT_N_EVENT |
+                        IPROC_MSI_EQ_EN);
+               iproc_msi_write_reg(msi, IPROC_MSI_CTRL, eq, val);
+       }
+}
+
+static int iproc_msi_alloc_domains(struct device_node *node,
+                                  struct iproc_msi *msi)
+{
+       msi->inner_domain = irq_domain_add_linear(NULL, msi->nr_msi_vecs,
+                                                 &msi_domain_ops, msi);
+       if (!msi->inner_domain)
+               return -ENOMEM;
+
+       msi->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node),
+                                                   &iproc_msi_domain_info,
+                                                   msi->inner_domain);
+       if (!msi->msi_domain) {
+               irq_domain_remove(msi->inner_domain);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void iproc_msi_free_domains(struct iproc_msi *msi)
+{
+       if (msi->msi_domain)
+               irq_domain_remove(msi->msi_domain);
+
+       if (msi->inner_domain)
+               irq_domain_remove(msi->inner_domain);
+}
+
+static void iproc_msi_irq_free(struct iproc_msi *msi, unsigned int cpu)
+{
+       int i;
+
+       for (i = cpu; i < msi->nr_irqs; i += msi->nr_cpus) {
+               irq_set_chained_handler_and_data(msi->grps[i].gic_irq,
+                                                NULL, NULL);
+       }
+}
+
+static int iproc_msi_irq_setup(struct iproc_msi *msi, unsigned int cpu)
+{
+       int i, ret;
+       cpumask_var_t mask;
+       struct iproc_pcie *pcie = msi->pcie;
+
+       for (i = cpu; i < msi->nr_irqs; i += msi->nr_cpus) {
+               irq_set_chained_handler_and_data(msi->grps[i].gic_irq,
+                                                iproc_msi_handler,
+                                                &msi->grps[i]);
+               /* Dedicate GIC interrupt to each CPU core */
+               if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
+                       cpumask_clear(mask);
+                       cpumask_set_cpu(cpu, mask);
+                       ret = irq_set_affinity(msi->grps[i].gic_irq, mask);
+                       if (ret)
+                               dev_err(pcie->dev,
+                                       "failed to set affinity for IRQ%d\n",
+                                       msi->grps[i].gic_irq);
+                       free_cpumask_var(mask);
+               } else {
+                       dev_err(pcie->dev, "failed to alloc CPU mask\n");
+                       ret = -EINVAL;
+               }
+
+               if (ret) {
+                       /* Free all configured/unconfigured IRQs */
+                       iproc_msi_irq_free(msi, cpu);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node)
+{
+       struct iproc_msi *msi;
+       int i, ret;
+       unsigned int cpu;
+
+       if (!of_device_is_compatible(node, "brcm,iproc-msi"))
+               return -ENODEV;
+
+       if (!of_find_property(node, "msi-controller", NULL))
+               return -ENODEV;
+
+       if (pcie->msi)
+               return -EBUSY;
+
+       msi = devm_kzalloc(pcie->dev, sizeof(*msi), GFP_KERNEL);
+       if (!msi)
+               return -ENOMEM;
+
+       msi->pcie = pcie;
+       pcie->msi = msi;
+       msi->msi_addr = pcie->base_addr;
+       mutex_init(&msi->bitmap_lock);
+       msi->nr_cpus = num_possible_cpus();
+
+       msi->nr_irqs = of_irq_count(node);
+       if (!msi->nr_irqs) {
+               dev_err(pcie->dev, "found no MSI GIC interrupt\n");
+               return -ENODEV;
+       }
+
+       if (msi->nr_irqs > NR_HW_IRQS) {
+               dev_warn(pcie->dev, "too many MSI GIC interrupts defined %d\n",
+                        msi->nr_irqs);
+               msi->nr_irqs = NR_HW_IRQS;
+       }
+
+       if (msi->nr_irqs < msi->nr_cpus) {
+               dev_err(pcie->dev,
+                       "not enough GIC interrupts for MSI affinity\n");
+               return -EINVAL;
+       }
+
+       if (msi->nr_irqs % msi->nr_cpus != 0) {
+               msi->nr_irqs -= msi->nr_irqs % msi->nr_cpus;
+               dev_warn(pcie->dev, "Reducing number of interrupts to %d\n",
+                        msi->nr_irqs);
+       }
+
+       switch (pcie->type) {
+       case IPROC_PCIE_PAXB:
+               msi->reg_offsets = iproc_msi_reg_paxb;
+               msi->nr_eq_region = 1;
+               msi->nr_msi_region = 1;
+               break;
+       case IPROC_PCIE_PAXC:
+               msi->reg_offsets = iproc_msi_reg_paxc;
+               msi->nr_eq_region = msi->nr_irqs;
+               msi->nr_msi_region = msi->nr_irqs;
+               break;
+       default:
+               dev_err(pcie->dev, "incompatible iProc PCIe interface\n");
+               return -EINVAL;
+       }
+
+       if (of_find_property(node, "brcm,pcie-msi-inten", NULL))
+               msi->has_inten_reg = true;
+
+       msi->nr_msi_vecs = msi->nr_irqs * EQ_LEN;
+       msi->bitmap = devm_kcalloc(pcie->dev, BITS_TO_LONGS(msi->nr_msi_vecs),
+                                  sizeof(*msi->bitmap), GFP_KERNEL);
+       if (!msi->bitmap)
+               return -ENOMEM;
+
+       msi->grps = devm_kcalloc(pcie->dev, msi->nr_irqs, sizeof(*msi->grps),
+                                GFP_KERNEL);
+       if (!msi->grps)
+               return -ENOMEM;
+
+       for (i = 0; i < msi->nr_irqs; i++) {
+               unsigned int irq = irq_of_parse_and_map(node, i);
+
+               if (!irq) {
+                       dev_err(pcie->dev, "unable to parse/map interrupt\n");
+                       ret = -ENODEV;
+                       goto free_irqs;
+               }
+               msi->grps[i].gic_irq = irq;
+               msi->grps[i].msi = msi;
+               msi->grps[i].eq = i;
+       }
+
+       /* Reserve memory for event queue and make sure memories are zeroed */
+       msi->eq_cpu = dma_zalloc_coherent(pcie->dev,
+                                         msi->nr_eq_region * EQ_MEM_REGION_SIZE,
+                                         &msi->eq_dma, GFP_KERNEL);
+       if (!msi->eq_cpu) {
+               ret = -ENOMEM;
+               goto free_irqs;
+       }
+
+       ret = iproc_msi_alloc_domains(node, msi);
+       if (ret) {
+               dev_err(pcie->dev, "failed to create MSI domains\n");
+               goto free_eq_dma;
+       }
+
+       for_each_online_cpu(cpu) {
+               ret = iproc_msi_irq_setup(msi, cpu);
+               if (ret)
+                       goto free_msi_irq;
+       }
+
+       iproc_msi_enable(msi);
+
+       return 0;
+
+free_msi_irq:
+       for_each_online_cpu(cpu)
+               iproc_msi_irq_free(msi, cpu);
+       iproc_msi_free_domains(msi);
+
+free_eq_dma:
+       dma_free_coherent(pcie->dev, msi->nr_eq_region * EQ_MEM_REGION_SIZE,
+                         msi->eq_cpu, msi->eq_dma);
+
+free_irqs:
+       for (i = 0; i < msi->nr_irqs; i++) {
+               if (msi->grps[i].gic_irq)
+                       irq_dispose_mapping(msi->grps[i].gic_irq);
+       }
+       pcie->msi = NULL;
+       return ret;
+}
+EXPORT_SYMBOL(iproc_msi_init);
+
+void iproc_msi_exit(struct iproc_pcie *pcie)
+{
+       struct iproc_msi *msi = pcie->msi;
+       unsigned int i, cpu;
+
+       if (!msi)
+               return;
+
+       iproc_msi_disable(msi);
+
+       for_each_online_cpu(cpu)
+               iproc_msi_irq_free(msi, cpu);
+
+       iproc_msi_free_domains(msi);
+
+       dma_free_coherent(pcie->dev, msi->nr_eq_region * EQ_MEM_REGION_SIZE,
+                         msi->eq_cpu, msi->eq_dma);
+
+       for (i = 0; i < msi->nr_irqs; i++) {
+               if (msi->grps[i].gic_irq)
+                       irq_dispose_mapping(msi->grps[i].gic_irq);
+       }
+}
+EXPORT_SYMBOL(iproc_msi_exit);
index c9550dc..1738c52 100644 (file)
 
 #include "pcie-iproc.h"
 
+static const struct of_device_id iproc_pcie_of_match_table[] = {
+       {
+               .compatible = "brcm,iproc-pcie",
+               .data = (int *)IPROC_PCIE_PAXB,
+       }, {
+               .compatible = "brcm,iproc-pcie-paxc",
+               .data = (int *)IPROC_PCIE_PAXC,
+       },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
+
 static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *of_id;
        struct iproc_pcie *pcie;
        struct device_node *np = pdev->dev.of_node;
        struct resource reg;
@@ -35,11 +48,16 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
        LIST_HEAD(res);
        int ret;
 
+       of_id = of_match_device(iproc_pcie_of_match_table, &pdev->dev);
+       if (!of_id)
+               return -EINVAL;
+
        pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL);
        if (!pcie)
                return -ENOMEM;
 
        pcie->dev = &pdev->dev;
+       pcie->type = (enum iproc_pcie_type)of_id->data;
        platform_set_drvdata(pdev, pcie);
 
        ret = of_address_to_resource(np, 0, &reg);
@@ -53,6 +71,7 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
                dev_err(pcie->dev, "unable to map controller registers\n");
                return -ENOMEM;
        }
+       pcie->base_addr = reg.start;
 
        if (of_property_read_bool(np, "brcm,pcie-ob")) {
                u32 val;
@@ -114,12 +133,6 @@ static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
        return iproc_pcie_remove(pcie);
 }
 
-static const struct of_device_id iproc_pcie_of_match_table[] = {
-       { .compatible = "brcm,iproc-pcie", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
-
 static struct platform_driver iproc_pcie_pltfm_driver = {
        .driver = {
                .name = "iproc-pcie",
index eac719a..5816bce 100644 (file)
 
 #include "pcie-iproc.h"
 
-#define CLK_CONTROL_OFFSET           0x000
 #define EP_PERST_SOURCE_SELECT_SHIFT 2
 #define EP_PERST_SOURCE_SELECT       BIT(EP_PERST_SOURCE_SELECT_SHIFT)
 #define EP_MODE_SURVIVE_PERST_SHIFT  1
 #define EP_MODE_SURVIVE_PERST        BIT(EP_MODE_SURVIVE_PERST_SHIFT)
 #define RC_PCIE_RST_OUTPUT_SHIFT     0
 #define RC_PCIE_RST_OUTPUT           BIT(RC_PCIE_RST_OUTPUT_SHIFT)
+#define PAXC_RESET_MASK              0x7f
 
-#define CFG_IND_ADDR_OFFSET          0x120
 #define CFG_IND_ADDR_MASK            0x00001ffc
 
-#define CFG_IND_DATA_OFFSET          0x124
-
-#define CFG_ADDR_OFFSET              0x1f8
 #define CFG_ADDR_BUS_NUM_SHIFT       20
 #define CFG_ADDR_BUS_NUM_MASK        0x0ff00000
 #define CFG_ADDR_DEV_NUM_SHIFT       15
 #define CFG_ADDR_CFG_TYPE_SHIFT      0
 #define CFG_ADDR_CFG_TYPE_MASK       0x00000003
 
-#define CFG_DATA_OFFSET              0x1fc
-
-#define SYS_RC_INTX_EN               0x330
 #define SYS_RC_INTX_MASK             0xf
 
-#define PCIE_LINK_STATUS_OFFSET      0xf0c
 #define PCIE_PHYLINKUP_SHIFT         3
 #define PCIE_PHYLINKUP               BIT(PCIE_PHYLINKUP_SHIFT)
 #define PCIE_DL_ACTIVE_SHIFT         2
 #define OARR_SIZE_CFG_SHIFT          1
 #define OARR_SIZE_CFG                BIT(OARR_SIZE_CFG_SHIFT)
 
-#define OARR_LO(window)              (0xd20 + (window) * 8)
-#define OARR_HI(window)              (0xd24 + (window) * 8)
-#define OMAP_LO(window)              (0xd40 + (window) * 8)
-#define OMAP_HI(window)              (0xd44 + (window) * 8)
-
 #define MAX_NUM_OB_WINDOWS           2
+#define MAX_NUM_PAXC_PF              4
+
+#define IPROC_PCIE_REG_INVALID 0xffff
+
+enum iproc_pcie_reg {
+       IPROC_PCIE_CLK_CTRL = 0,
+       IPROC_PCIE_CFG_IND_ADDR,
+       IPROC_PCIE_CFG_IND_DATA,
+       IPROC_PCIE_CFG_ADDR,
+       IPROC_PCIE_CFG_DATA,
+       IPROC_PCIE_INTX_EN,
+       IPROC_PCIE_OARR_LO,
+       IPROC_PCIE_OARR_HI,
+       IPROC_PCIE_OMAP_LO,
+       IPROC_PCIE_OMAP_HI,
+       IPROC_PCIE_LINK_STATUS,
+};
+
+/* iProc PCIe PAXB registers */
+static const u16 iproc_pcie_reg_paxb[] = {
+       [IPROC_PCIE_CLK_CTRL]     = 0x000,
+       [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
+       [IPROC_PCIE_CFG_IND_DATA] = 0x124,
+       [IPROC_PCIE_CFG_ADDR]     = 0x1f8,
+       [IPROC_PCIE_CFG_DATA]     = 0x1fc,
+       [IPROC_PCIE_INTX_EN]      = 0x330,
+       [IPROC_PCIE_OARR_LO]      = 0xd20,
+       [IPROC_PCIE_OARR_HI]      = 0xd24,
+       [IPROC_PCIE_OMAP_LO]      = 0xd40,
+       [IPROC_PCIE_OMAP_HI]      = 0xd44,
+       [IPROC_PCIE_LINK_STATUS]  = 0xf0c,
+};
+
+/* iProc PCIe PAXC v1 registers */
+static const u16 iproc_pcie_reg_paxc[] = {
+       [IPROC_PCIE_CLK_CTRL]     = 0x000,
+       [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
+       [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
+       [IPROC_PCIE_CFG_ADDR]     = 0x1f8,
+       [IPROC_PCIE_CFG_DATA]     = 0x1fc,
+       [IPROC_PCIE_INTX_EN]      = IPROC_PCIE_REG_INVALID,
+       [IPROC_PCIE_OARR_LO]      = IPROC_PCIE_REG_INVALID,
+       [IPROC_PCIE_OARR_HI]      = IPROC_PCIE_REG_INVALID,
+       [IPROC_PCIE_OMAP_LO]      = IPROC_PCIE_REG_INVALID,
+       [IPROC_PCIE_OMAP_HI]      = IPROC_PCIE_REG_INVALID,
+       [IPROC_PCIE_LINK_STATUS]  = IPROC_PCIE_REG_INVALID,
+};
 
 static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
 {
@@ -91,6 +125,65 @@ static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
        return pcie;
 }
 
+static inline bool iproc_pcie_reg_is_invalid(u16 reg_offset)
+{
+       return !!(reg_offset == IPROC_PCIE_REG_INVALID);
+}
+
+static inline u16 iproc_pcie_reg_offset(struct iproc_pcie *pcie,
+                                       enum iproc_pcie_reg reg)
+{
+       return pcie->reg_offsets[reg];
+}
+
+static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie,
+                                     enum iproc_pcie_reg reg)
+{
+       u16 offset = iproc_pcie_reg_offset(pcie, reg);
+
+       if (iproc_pcie_reg_is_invalid(offset))
+               return 0;
+
+       return readl(pcie->base + offset);
+}
+
+static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie,
+                                       enum iproc_pcie_reg reg, u32 val)
+{
+       u16 offset = iproc_pcie_reg_offset(pcie, reg);
+
+       if (iproc_pcie_reg_is_invalid(offset))
+               return;
+
+       writel(val, pcie->base + offset);
+}
+
+static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
+                                      enum iproc_pcie_reg reg,
+                                      unsigned window, u32 val)
+{
+       u16 offset = iproc_pcie_reg_offset(pcie, reg);
+
+       if (iproc_pcie_reg_is_invalid(offset))
+               return;
+
+       writel(val, pcie->base + offset + (window * 8));
+}
+
+static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie,
+                                             unsigned int slot,
+                                             unsigned int fn)
+{
+       if (slot > 0)
+               return false;
+
+       /* PAXC can only support limited number of functions */
+       if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF)
+               return false;
+
+       return true;
+}
+
 /**
  * Note access to the configuration registers are protected at the higher layer
  * by 'pci_lock' in drivers/pci/access.c
@@ -104,28 +197,34 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
        unsigned fn = PCI_FUNC(devfn);
        unsigned busno = bus->number;
        u32 val;
+       u16 offset;
+
+       if (!iproc_pcie_device_is_valid(pcie, slot, fn))
+               return NULL;
 
        /* root complex access */
        if (busno == 0) {
-               if (slot >= 1)
+               iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
+                                    where & CFG_IND_ADDR_MASK);
+               offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
+               if (iproc_pcie_reg_is_invalid(offset))
                        return NULL;
-               writel(where & CFG_IND_ADDR_MASK,
-                      pcie->base + CFG_IND_ADDR_OFFSET);
-               return (pcie->base + CFG_IND_DATA_OFFSET);
+               else
+                       return (pcie->base + offset);
        }
 
-       if (fn > 1)
-               return NULL;
-
        /* EP device access */
        val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
                (slot << CFG_ADDR_DEV_NUM_SHIFT) |
                (fn << CFG_ADDR_FUNC_NUM_SHIFT) |
                (where & CFG_ADDR_REG_NUM_MASK) |
                (1 & CFG_ADDR_CFG_TYPE_MASK);
-       writel(val, pcie->base + CFG_ADDR_OFFSET);
-
-       return (pcie->base + CFG_DATA_OFFSET);
+       iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val);
+       offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA);
+       if (iproc_pcie_reg_is_invalid(offset))
+               return NULL;
+       else
+               return (pcie->base + offset);
 }
 
 static struct pci_ops iproc_pcie_ops = {
@@ -138,18 +237,29 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)
 {
        u32 val;
 
+       if (pcie->type == IPROC_PCIE_PAXC) {
+               val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
+               val &= ~PAXC_RESET_MASK;
+               iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
+               udelay(100);
+               val |= PAXC_RESET_MASK;
+               iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
+               udelay(100);
+               return;
+       }
+
        /*
         * Select perst_b signal as reset source. Put the device into reset,
         * and then bring it out of reset
         */
-       val = readl(pcie->base + CLK_CONTROL_OFFSET);
+       val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
        val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
                ~RC_PCIE_RST_OUTPUT;
-       writel(val, pcie->base + CLK_CONTROL_OFFSET);
+       iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
        udelay(250);
 
        val |= RC_PCIE_RST_OUTPUT;
-       writel(val, pcie->base + CLK_CONTROL_OFFSET);
+       iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
        msleep(100);
 }
 
@@ -160,7 +270,14 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
        u16 pos, link_status;
        bool link_is_active = false;
 
-       val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
+       /*
+        * PAXC connects to emulated endpoint devices directly and does not
+        * have a Serdes.  Therefore skip the link detection logic here.
+        */
+       if (pcie->type == IPROC_PCIE_PAXC)
+               return 0;
+
+       val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
        if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
                dev_err(pcie->dev, "PHY or data link is INACTIVE!\n");
                return -ENODEV;
@@ -221,7 +338,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
 
 static void iproc_pcie_enable(struct iproc_pcie *pcie)
 {
-       writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN);
+       iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK);
 }
 
 /**
@@ -245,7 +362,7 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
 
        if (size > max_size) {
                dev_err(pcie->dev,
-                       "res size 0x%pap exceeds max supported size 0x%llx\n",
+                       "res size %pap exceeds max supported size 0x%llx\n",
                        &size, max_size);
                return -EINVAL;
        }
@@ -272,11 +389,15 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
        axi_addr -= ob->axi_offset;
 
        for (i = 0; i < MAX_NUM_OB_WINDOWS; i++) {
-               writel(lower_32_bits(axi_addr) | OARR_VALID |
-                      (ob->set_oarr_size ? 1 : 0), pcie->base + OARR_LO(i));
-               writel(upper_32_bits(axi_addr), pcie->base + OARR_HI(i));
-               writel(lower_32_bits(pci_addr), pcie->base + OMAP_LO(i));
-               writel(upper_32_bits(pci_addr), pcie->base + OMAP_HI(i));
+               iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_LO, i,
+                                   lower_32_bits(axi_addr) | OARR_VALID |
+                                   (ob->set_oarr_size ? 1 : 0));
+               iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_HI, i,
+                                   upper_32_bits(axi_addr));
+               iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_LO, i,
+                                   lower_32_bits(pci_addr));
+               iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_HI, i,
+                                   upper_32_bits(pci_addr));
 
                size -= ob->window_size;
                if (size == 0)
@@ -319,6 +440,26 @@ static int iproc_pcie_map_ranges(struct iproc_pcie *pcie,
        return 0;
 }
 
+static int iproc_pcie_msi_enable(struct iproc_pcie *pcie)
+{
+       struct device_node *msi_node;
+
+       msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0);
+       if (!msi_node)
+               return -ENODEV;
+
+       /*
+        * If another MSI controller is being used, the call below should fail
+        * but that is okay
+        */
+       return iproc_msi_init(pcie, msi_node);
+}
+
+static void iproc_pcie_msi_disable(struct iproc_pcie *pcie)
+{
+       iproc_msi_exit(pcie);
+}
+
 int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 {
        int ret;
@@ -340,6 +481,19 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
                goto err_exit_phy;
        }
 
+       switch (pcie->type) {
+       case IPROC_PCIE_PAXB:
+               pcie->reg_offsets = iproc_pcie_reg_paxb;
+               break;
+       case IPROC_PCIE_PAXC:
+               pcie->reg_offsets = iproc_pcie_reg_paxc;
+               break;
+       default:
+               dev_err(pcie->dev, "incompatible iProc PCIe interface\n");
+               ret = -EINVAL;
+               goto err_power_off_phy;
+       }
+
        iproc_pcie_reset(pcie);
 
        if (pcie->need_ob_cfg) {
@@ -373,6 +527,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 
        iproc_pcie_enable(pcie);
 
+       if (IS_ENABLED(CONFIG_PCI_MSI))
+               if (iproc_pcie_msi_enable(pcie))
+                       dev_info(pcie->dev, "not using iProc MSI\n");
+
        pci_scan_child_bus(bus);
        pci_assign_unassigned_bus_resources(bus);
        pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
@@ -397,6 +555,8 @@ int iproc_pcie_remove(struct iproc_pcie *pcie)
        pci_stop_root_bus(pcie->root_bus);
        pci_remove_root_bus(pcie->root_bus);
 
+       iproc_pcie_msi_disable(pcie);
+
        phy_power_off(pcie->phy);
        phy_exit(pcie->phy);
 
index d3dc940..e84d93c 100644 (file)
 #ifndef _PCIE_IPROC_H
 #define _PCIE_IPROC_H
 
+/**
+ * iProc PCIe interface type
+ *
+ * PAXB is the wrapper used in root complex that can be connected to an
+ * external endpoint device.
+ *
+ * PAXC is the wrapper used in root complex dedicated for internal emulated
+ * endpoint devices.
+ */
+enum iproc_pcie_type {
+       IPROC_PCIE_PAXB = 0,
+       IPROC_PCIE_PAXC,
+};
+
 /**
  * iProc PCIe outbound mapping
  * @set_oarr_size: indicates the OARR size bit needs to be set
@@ -27,21 +41,30 @@ struct iproc_pcie_ob {
        resource_size_t window_size;
 };
 
+struct iproc_msi;
+
 /**
  * iProc PCIe device
+ *
  * @dev: pointer to device data structure
+ * @type: iProc PCIe interface type
+ * @reg_offsets: register offsets
  * @base: PCIe host controller I/O register base
+ * @base_addr: PCIe host controller register base physical address
  * @sysdata: Per PCI controller data (ARM-specific)
  * @root_bus: pointer to root bus
  * @phy: optional PHY device that controls the Serdes
- * @irqs: interrupt IDs
  * @map_irq: function callback to map interrupts
- * @need_ob_cfg: indidates SW needs to configure the outbound mapping window
+ * @need_ob_cfg: indicates SW needs to configure the outbound mapping window
  * @ob: outbound mapping parameters
+ * @msi: MSI data
  */
 struct iproc_pcie {
        struct device *dev;
+       enum iproc_pcie_type type;
+       const u16 *reg_offsets;
        void __iomem *base;
+       phys_addr_t base_addr;
 #ifdef CONFIG_ARM
        struct pci_sys_data sysdata;
 #endif
@@ -50,9 +73,24 @@ struct iproc_pcie {
        int (*map_irq)(const struct pci_dev *, u8, u8);
        bool need_ob_cfg;
        struct iproc_pcie_ob ob;
+       struct iproc_msi *msi;
 };
 
 int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res);
 int iproc_pcie_remove(struct iproc_pcie *pcie);
 
+#ifdef CONFIG_PCIE_IPROC_MSI
+int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
+void iproc_msi_exit(struct iproc_pcie *pcie);
+#else
+static inline int iproc_msi_init(struct iproc_pcie *pcie,
+                                struct device_node *node)
+{
+       return -ENODEV;
+}
+static inline void iproc_msi_exit(struct iproc_pcie *pcie)
+{
+}
+#endif
+
 #endif /* _PCIE_IPROC_H */
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
new file mode 100644 (file)
index 0000000..e845fba
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright 2015 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+
+#define PCIE20_PARF_PHY_CTRL                   0x40
+#define PCIE20_PARF_PHY_REFCLK                 0x4C
+#define PCIE20_PARF_DBI_BASE_ADDR              0x168
+#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16c
+#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
+
+#define PCIE20_ELBI_SYS_CTRL                   0x04
+#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE         BIT(0)
+
+#define PCIE20_CAP                             0x70
+
+#define PERST_DELAY_US                         1000
+
+struct qcom_pcie_resources_v0 {
+       struct clk *iface_clk;
+       struct clk *core_clk;
+       struct clk *phy_clk;
+       struct reset_control *pci_reset;
+       struct reset_control *axi_reset;
+       struct reset_control *ahb_reset;
+       struct reset_control *por_reset;
+       struct reset_control *phy_reset;
+       struct regulator *vdda;
+       struct regulator *vdda_phy;
+       struct regulator *vdda_refclk;
+};
+
+struct qcom_pcie_resources_v1 {
+       struct clk *iface;
+       struct clk *aux;
+       struct clk *master_bus;
+       struct clk *slave_bus;
+       struct reset_control *core;
+       struct regulator *vdda;
+};
+
+union qcom_pcie_resources {
+       struct qcom_pcie_resources_v0 v0;
+       struct qcom_pcie_resources_v1 v1;
+};
+
+struct qcom_pcie;
+
+struct qcom_pcie_ops {
+       int (*get_resources)(struct qcom_pcie *pcie);
+       int (*init)(struct qcom_pcie *pcie);
+       void (*deinit)(struct qcom_pcie *pcie);
+};
+
+struct qcom_pcie {
+       struct pcie_port pp;
+       struct device *dev;
+       union qcom_pcie_resources res;
+       void __iomem *parf;
+       void __iomem *dbi;
+       void __iomem *elbi;
+       struct phy *phy;
+       struct gpio_desc *reset;
+       struct qcom_pcie_ops *ops;
+};
+
+#define to_qcom_pcie(x)                container_of(x, struct qcom_pcie, pp)
+
+static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
+{
+       gpiod_set_value(pcie->reset, 1);
+       usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
+}
+
+static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
+{
+       gpiod_set_value(pcie->reset, 0);
+       usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
+}
+
+static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
+{
+       struct pcie_port *pp = arg;
+
+       return dw_handle_msi_irq(pp);
+}
+
+static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
+{
+       struct device *dev = pcie->dev;
+       unsigned int retries = 0;
+       u32 val;
+
+       if (dw_pcie_link_up(&pcie->pp))
+               return 0;
+
+       /* enable link training */
+       val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
+       val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
+       writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
+
+       do {
+               if (dw_pcie_link_up(&pcie->pp))
+                       return 0;
+               usleep_range(250, 1000);
+       } while (retries < 200);
+
+       dev_warn(dev, "phy link never came up\n");
+
+       return -ETIMEDOUT;
+}
+
+static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie)
+{
+       struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
+       struct device *dev = pcie->dev;
+
+       res->vdda = devm_regulator_get(dev, "vdda");
+       if (IS_ERR(res->vdda))
+               return PTR_ERR(res->vdda);
+
+       res->vdda_phy = devm_regulator_get(dev, "vdda_phy");
+       if (IS_ERR(res->vdda_phy))
+               return PTR_ERR(res->vdda_phy);
+
+       res->vdda_refclk = devm_regulator_get(dev, "vdda_refclk");
+       if (IS_ERR(res->vdda_refclk))
+               return PTR_ERR(res->vdda_refclk);
+
+       res->iface_clk = devm_clk_get(dev, "iface");
+       if (IS_ERR(res->iface_clk))
+               return PTR_ERR(res->iface_clk);
+
+       res->core_clk = devm_clk_get(dev, "core");
+       if (IS_ERR(res->core_clk))
+               return PTR_ERR(res->core_clk);
+
+       res->phy_clk = devm_clk_get(dev, "phy");
+       if (IS_ERR(res->phy_clk))
+               return PTR_ERR(res->phy_clk);
+
+       res->pci_reset = devm_reset_control_get(dev, "pci");
+       if (IS_ERR(res->pci_reset))
+               return PTR_ERR(res->pci_reset);
+
+       res->axi_reset = devm_reset_control_get(dev, "axi");
+       if (IS_ERR(res->axi_reset))
+               return PTR_ERR(res->axi_reset);
+
+       res->ahb_reset = devm_reset_control_get(dev, "ahb");
+       if (IS_ERR(res->ahb_reset))
+               return PTR_ERR(res->ahb_reset);
+
+       res->por_reset = devm_reset_control_get(dev, "por");
+       if (IS_ERR(res->por_reset))
+               return PTR_ERR(res->por_reset);
+
+       res->phy_reset = devm_reset_control_get(dev, "phy");
+       if (IS_ERR(res->phy_reset))
+               return PTR_ERR(res->phy_reset);
+
+       return 0;
+}
+
+static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie)
+{
+       struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
+       struct device *dev = pcie->dev;
+
+       res->vdda = devm_regulator_get(dev, "vdda");
+       if (IS_ERR(res->vdda))
+               return PTR_ERR(res->vdda);
+
+       res->iface = devm_clk_get(dev, "iface");
+       if (IS_ERR(res->iface))
+               return PTR_ERR(res->iface);
+
+       res->aux = devm_clk_get(dev, "aux");
+       if (IS_ERR(res->aux))
+               return PTR_ERR(res->aux);
+
+       res->master_bus = devm_clk_get(dev, "master_bus");
+       if (IS_ERR(res->master_bus))
+               return PTR_ERR(res->master_bus);
+
+       res->slave_bus = devm_clk_get(dev, "slave_bus");
+       if (IS_ERR(res->slave_bus))
+               return PTR_ERR(res->slave_bus);
+
+       res->core = devm_reset_control_get(dev, "core");
+       if (IS_ERR(res->core))
+               return PTR_ERR(res->core);
+
+       return 0;
+}
+
+static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie)
+{
+       struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
+
+       reset_control_assert(res->pci_reset);
+       reset_control_assert(res->axi_reset);
+       reset_control_assert(res->ahb_reset);
+       reset_control_assert(res->por_reset);
+       reset_control_assert(res->pci_reset);
+       clk_disable_unprepare(res->iface_clk);
+       clk_disable_unprepare(res->core_clk);
+       clk_disable_unprepare(res->phy_clk);
+       regulator_disable(res->vdda);
+       regulator_disable(res->vdda_phy);
+       regulator_disable(res->vdda_refclk);
+}
+
+static int qcom_pcie_init_v0(struct qcom_pcie *pcie)
+{
+       struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
+       struct device *dev = pcie->dev;
+       u32 val;
+       int ret;
+
+       ret = regulator_enable(res->vdda);
+       if (ret) {
+               dev_err(dev, "cannot enable vdda regulator\n");
+               return ret;
+       }
+
+       ret = regulator_enable(res->vdda_refclk);
+       if (ret) {
+               dev_err(dev, "cannot enable vdda_refclk regulator\n");
+               goto err_refclk;
+       }
+
+       ret = regulator_enable(res->vdda_phy);
+       if (ret) {
+               dev_err(dev, "cannot enable vdda_phy regulator\n");
+               goto err_vdda_phy;
+       }
+
+       ret = reset_control_assert(res->ahb_reset);
+       if (ret) {
+               dev_err(dev, "cannot assert ahb reset\n");
+               goto err_assert_ahb;
+       }
+
+       ret = clk_prepare_enable(res->iface_clk);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable iface clock\n");
+               goto err_assert_ahb;
+       }
+
+       ret = clk_prepare_enable(res->phy_clk);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable phy clock\n");
+               goto err_clk_phy;
+       }
+
+       ret = clk_prepare_enable(res->core_clk);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable core clock\n");
+               goto err_clk_core;
+       }
+
+       ret = reset_control_deassert(res->ahb_reset);
+       if (ret) {
+               dev_err(dev, "cannot deassert ahb reset\n");
+               goto err_deassert_ahb;
+       }
+
+       /* enable PCIe clocks and resets */
+       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val &= ~BIT(0);
+       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+       /* enable external reference clock */
+       val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
+       val |= BIT(16);
+       writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
+
+       ret = reset_control_deassert(res->phy_reset);
+       if (ret) {
+               dev_err(dev, "cannot deassert phy reset\n");
+               return ret;
+       }
+
+       ret = reset_control_deassert(res->pci_reset);
+       if (ret) {
+               dev_err(dev, "cannot deassert pci reset\n");
+               return ret;
+       }
+
+       ret = reset_control_deassert(res->por_reset);
+       if (ret) {
+               dev_err(dev, "cannot deassert por reset\n");
+               return ret;
+       }
+
+       ret = reset_control_deassert(res->axi_reset);
+       if (ret) {
+               dev_err(dev, "cannot deassert axi reset\n");
+               return ret;
+       }
+
+       /* wait for clock acquisition */
+       usleep_range(1000, 1500);
+
+       return 0;
+
+err_deassert_ahb:
+       clk_disable_unprepare(res->core_clk);
+err_clk_core:
+       clk_disable_unprepare(res->phy_clk);
+err_clk_phy:
+       clk_disable_unprepare(res->iface_clk);
+err_assert_ahb:
+       regulator_disable(res->vdda_phy);
+err_vdda_phy:
+       regulator_disable(res->vdda_refclk);
+err_refclk:
+       regulator_disable(res->vdda);
+
+       return ret;
+}
+
+static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie)
+{
+       struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
+
+       reset_control_assert(res->core);
+       clk_disable_unprepare(res->slave_bus);
+       clk_disable_unprepare(res->master_bus);
+       clk_disable_unprepare(res->iface);
+       clk_disable_unprepare(res->aux);
+       regulator_disable(res->vdda);
+}
+
+static int qcom_pcie_init_v1(struct qcom_pcie *pcie)
+{
+       struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
+       struct device *dev = pcie->dev;
+       int ret;
+
+       ret = reset_control_deassert(res->core);
+       if (ret) {
+               dev_err(dev, "cannot deassert core reset\n");
+               return ret;
+       }
+
+       ret = clk_prepare_enable(res->aux);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable aux clock\n");
+               goto err_res;
+       }
+
+       ret = clk_prepare_enable(res->iface);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable iface clock\n");
+               goto err_aux;
+       }
+
+       ret = clk_prepare_enable(res->master_bus);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable master_bus clock\n");
+               goto err_iface;
+       }
+
+       ret = clk_prepare_enable(res->slave_bus);
+       if (ret) {
+               dev_err(dev, "cannot prepare/enable slave_bus clock\n");
+               goto err_master;
+       }
+
+       ret = regulator_enable(res->vdda);
+       if (ret) {
+               dev_err(dev, "cannot enable vdda regulator\n");
+               goto err_slave;
+       }
+
+       /* change DBI base address */
+       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+
+       if (IS_ENABLED(CONFIG_PCI_MSI)) {
+               u32 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+
+               val |= BIT(31);
+               writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+       }
+
+       return 0;
+err_slave:
+       clk_disable_unprepare(res->slave_bus);
+err_master:
+       clk_disable_unprepare(res->master_bus);
+err_iface:
+       clk_disable_unprepare(res->iface);
+err_aux:
+       clk_disable_unprepare(res->aux);
+err_res:
+       reset_control_assert(res->core);
+
+       return ret;
+}
+
+static int qcom_pcie_link_up(struct pcie_port *pp)
+{
+       struct qcom_pcie *pcie = to_qcom_pcie(pp);
+       u16 val = readw(pcie->dbi + PCIE20_CAP + PCI_EXP_LNKSTA);
+
+       return !!(val & PCI_EXP_LNKSTA_DLLLA);
+}
+
+static void qcom_pcie_host_init(struct pcie_port *pp)
+{
+       struct qcom_pcie *pcie = to_qcom_pcie(pp);
+       int ret;
+
+       qcom_ep_reset_assert(pcie);
+
+       ret = pcie->ops->init(pcie);
+       if (ret)
+               goto err_deinit;
+
+       ret = phy_power_on(pcie->phy);
+       if (ret)
+               goto err_deinit;
+
+       dw_pcie_setup_rc(pp);
+
+       if (IS_ENABLED(CONFIG_PCI_MSI))
+               dw_pcie_msi_init(pp);
+
+       qcom_ep_reset_deassert(pcie);
+
+       ret = qcom_pcie_establish_link(pcie);
+       if (ret)
+               goto err;
+
+       return;
+err:
+       qcom_ep_reset_assert(pcie);
+       phy_power_off(pcie->phy);
+err_deinit:
+       pcie->ops->deinit(pcie);
+}
+
+static int qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
+                                u32 *val)
+{
+       /* the device class is not reported correctly from the register */
+       if (where == PCI_CLASS_REVISION && size == 4) {
+               *val = readl(pp->dbi_base + PCI_CLASS_REVISION);
+               *val &= 0xff;   /* keep revision id */
+               *val |= PCI_CLASS_BRIDGE_PCI << 16;
+               return PCIBIOS_SUCCESSFUL;
+       }
+
+       return dw_pcie_cfg_read(pp->dbi_base + where, size, val);
+}
+
+static struct pcie_host_ops qcom_pcie_dw_ops = {
+       .link_up = qcom_pcie_link_up,
+       .host_init = qcom_pcie_host_init,
+       .rd_own_conf = qcom_pcie_rd_own_conf,
+};
+
+static const struct qcom_pcie_ops ops_v0 = {
+       .get_resources = qcom_pcie_get_resources_v0,
+       .init = qcom_pcie_init_v0,
+       .deinit = qcom_pcie_deinit_v0,
+};
+
+static const struct qcom_pcie_ops ops_v1 = {
+       .get_resources = qcom_pcie_get_resources_v1,
+       .init = qcom_pcie_init_v1,
+       .deinit = qcom_pcie_deinit_v1,
+};
+
+static int qcom_pcie_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct qcom_pcie *pcie;
+       struct pcie_port *pp;
+       int ret;
+
+       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+       if (!pcie)
+               return -ENOMEM;
+
+       pcie->ops = (struct qcom_pcie_ops *)of_device_get_match_data(dev);
+       pcie->dev = dev;
+
+       pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
+       if (IS_ERR(pcie->reset))
+               return PTR_ERR(pcie->reset);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
+       pcie->parf = devm_ioremap_resource(dev, res);
+       if (IS_ERR(pcie->parf))
+               return PTR_ERR(pcie->parf);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+       pcie->dbi = devm_ioremap_resource(dev, res);
+       if (IS_ERR(pcie->dbi))
+               return PTR_ERR(pcie->dbi);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
+       pcie->elbi = devm_ioremap_resource(dev, res);
+       if (IS_ERR(pcie->elbi))
+               return PTR_ERR(pcie->elbi);
+
+       pcie->phy = devm_phy_optional_get(dev, "pciephy");
+       if (IS_ERR(pcie->phy))
+               return PTR_ERR(pcie->phy);
+
+       ret = pcie->ops->get_resources(pcie);
+       if (ret)
+               return ret;
+
+       pp = &pcie->pp;
+       pp->dev = dev;
+       pp->dbi_base = pcie->dbi;
+       pp->root_bus_nr = -1;
+       pp->ops = &qcom_pcie_dw_ops;
+
+       if (IS_ENABLED(CONFIG_PCI_MSI)) {
+               pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+               if (pp->msi_irq < 0)
+                       return pp->msi_irq;
+
+               ret = devm_request_irq(dev, pp->msi_irq,
+                                      qcom_pcie_msi_irq_handler,
+                                      IRQF_SHARED, "qcom-pcie-msi", pp);
+               if (ret) {
+                       dev_err(dev, "cannot request msi irq\n");
+                       return ret;
+               }
+       }
+
+       ret = phy_init(pcie->phy);
+       if (ret)
+               return ret;
+
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+               dev_err(dev, "cannot initialize host\n");
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, pcie);
+
+       return 0;
+}
+
+static int qcom_pcie_remove(struct platform_device *pdev)
+{
+       struct qcom_pcie *pcie = platform_get_drvdata(pdev);
+
+       qcom_ep_reset_assert(pcie);
+       phy_power_off(pcie->phy);
+       phy_exit(pcie->phy);
+       pcie->ops->deinit(pcie);
+
+       return 0;
+}
+
+static const struct of_device_id qcom_pcie_match[] = {
+       { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 },
+       { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 },
+       { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 },
+       { }
+};
+MODULE_DEVICE_TABLE(of, qcom_pcie_match);
+
+static struct platform_driver qcom_pcie_driver = {
+       .probe = qcom_pcie_probe,
+       .remove = qcom_pcie_remove,
+       .driver = {
+               .name = "qcom-pcie",
+               .of_match_table = qcom_pcie_match,
+       },
+};
+
+module_platform_driver(qcom_pcie_driver);
+
+MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
+MODULE_DESCRIPTION("Qualcomm PCIe root complex driver");
+MODULE_LICENSE("GPL v2");
index f4fa6c5..4edb518 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/of_platform.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #define DRV_NAME "rcar-pcie"
 #define H1_PCIEPHYDOUTR                0x040014
 #define H1_PCIEPHYSR           0x040018
 
+/* R-Car Gen2 PHY */
+#define GEN2_PCIEPHYADDR       0x780
+#define GEN2_PCIEPHYDATA       0x784
+#define GEN2_PCIEPHYCTRL       0x78c
+
 #define INT_PCI_MSI_NR 32
 
 #define RCONF(x)       (PCICONF(0)+(x))
 #define RCAR_PCI_MAX_RESOURCES 4
 #define MAX_NR_INBOUND_MAPS 6
 
-static unsigned long global_io_offset;
-
 struct rcar_msi {
        DECLARE_BITMAP(used, INT_PCI_MSI_NR);
        struct irq_domain *domain;
@@ -126,20 +130,10 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip)
 }
 
 /* Structure representing the PCIe interface */
-/*
- * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
- * sysdata.  Add pci_sys_data as the first element in struct gen_pci so
- * that when we use a gen_pci pointer as sysdata, it is also a pointer to
- * a struct pci_sys_data.
- */
 struct rcar_pcie {
-#ifdef CONFIG_ARM
-       struct pci_sys_data     sys;
-#endif
        struct device           *dev;
        void __iomem            *base;
-       struct resource         res[RCAR_PCI_MAX_RESOURCES];
-       struct resource         busn;
+       struct list_head        resources;
        int                     root_bus_nr;
        struct clk              *clk;
        struct clk              *bus_clk;
@@ -323,10 +317,9 @@ static struct pci_ops rcar_pcie_ops = {
        .write  = rcar_pcie_write_conf,
 };
 
-static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
+static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie,
+                                  struct resource *res)
 {
-       struct resource *res = &pcie->res[win];
-
        /* Setup PCIe address space mappings for each resource */
        resource_size_t size;
        resource_size_t res_start;
@@ -359,31 +352,33 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
        rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
 }
 
-static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pcie)
+static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci)
 {
-       struct resource *res;
-       int i;
-
-       pcie->root_bus_nr = pcie->busn.start;
+       struct resource_entry *win;
+       int i = 0;
 
        /* Setup PCI resources */
-       for (i = 0; i < RCAR_PCI_MAX_RESOURCES; i++) {
+       resource_list_for_each_entry(win, &pci->resources) {
+               struct resource *res = win->res;
 
-               res = &pcie->res[i];
                if (!res->flags)
                        continue;
 
-               rcar_pcie_setup_window(i, pcie);
-
-               if (res->flags & IORESOURCE_IO) {
-                       phys_addr_t io_start = pci_pio_to_address(res->start);
-                       pci_ioremap_io(global_io_offset, io_start);
-                       global_io_offset += SZ_64K;
+               switch (resource_type(res)) {
+               case IORESOURCE_IO:
+               case IORESOURCE_MEM:
+                       rcar_pcie_setup_window(i, pci, res);
+                       i++;
+                       break;
+               case IORESOURCE_BUS:
+                       pci->root_bus_nr = res->start;
+                       break;
+               default:
+                       continue;
                }
 
                pci_add_resource(resource, res);
        }
-       pci_add_resource(resource, &pcie->busn);
 
        return 1;
 }
@@ -578,6 +573,26 @@ static int rcar_pcie_hw_init_h1(struct rcar_pcie *pcie)
        return -ETIMEDOUT;
 }
 
+static int rcar_pcie_hw_init_gen2(struct rcar_pcie *pcie)
+{
+       /*
+        * These settings come from the R-Car Series, 2nd Generation User's
+        * Manual, section 50.3.1 (2) Initialization of the physical layer.
+        */
+       rcar_pci_write_reg(pcie, 0x000f0030, GEN2_PCIEPHYADDR);
+       rcar_pci_write_reg(pcie, 0x00381203, GEN2_PCIEPHYDATA);
+       rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
+       rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
+
+       rcar_pci_write_reg(pcie, 0x000f0054, GEN2_PCIEPHYADDR);
+       /* The following value is for DC connection, no termination resistor */
+       rcar_pci_write_reg(pcie, 0x13802007, GEN2_PCIEPHYDATA);
+       rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
+       rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
+
+       return rcar_pcie_hw_init(pcie);
+}
+
 static int rcar_msi_alloc(struct rcar_msi *chip)
 {
        int msi;
@@ -720,14 +735,16 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
 
        /* Two irqs are for MSI, but they are also used for non-MSI irqs */
        err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
-                              IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
+                              IRQF_SHARED | IRQF_NO_THREAD,
+                              rcar_msi_irq_chip.name, pcie);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
                goto err;
        }
 
        err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
-                              IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
+                              IRQF_SHARED | IRQF_NO_THREAD,
+                              rcar_msi_irq_chip.name, pcie);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
                goto err;
@@ -917,20 +934,71 @@ static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie *pcie,
 
 static const struct of_device_id rcar_pcie_of_match[] = {
        { .compatible = "renesas,pcie-r8a7779", .data = rcar_pcie_hw_init_h1 },
-       { .compatible = "renesas,pcie-r8a7790", .data = rcar_pcie_hw_init },
-       { .compatible = "renesas,pcie-r8a7791", .data = rcar_pcie_hw_init },
+       { .compatible = "renesas,pcie-rcar-gen2", .data = rcar_pcie_hw_init_gen2 },
+       { .compatible = "renesas,pcie-r8a7790", .data = rcar_pcie_hw_init_gen2 },
+       { .compatible = "renesas,pcie-r8a7791", .data = rcar_pcie_hw_init_gen2 },
+       { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init },
        {},
 };
 MODULE_DEVICE_TABLE(of, rcar_pcie_of_match);
 
+static void rcar_pcie_release_of_pci_ranges(struct rcar_pcie *pci)
+{
+       pci_free_resource_list(&pci->resources);
+}
+
+static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
+{
+       int err;
+       struct device *dev = pci->dev;
+       struct device_node *np = dev->of_node;
+       resource_size_t iobase;
+       struct resource_entry *win;
+
+       err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase);
+       if (err)
+               return err;
+
+       resource_list_for_each_entry(win, &pci->resources) {
+               struct resource *parent, *res = win->res;
+
+               switch (resource_type(res)) {
+               case IORESOURCE_IO:
+                       parent = &ioport_resource;
+                       err = pci_remap_iospace(res, iobase);
+                       if (err) {
+                               dev_warn(dev, "error %d: failed to map resource %pR\n",
+                                        err, res);
+                               continue;
+                       }
+                       break;
+               case IORESOURCE_MEM:
+                       parent = &iomem_resource;
+                       break;
+
+               case IORESOURCE_BUS:
+               default:
+                       continue;
+               }
+
+               err = devm_request_resource(dev, parent, res);
+               if (err)
+                       goto out_release_res;
+       }
+
+       return 0;
+
+out_release_res:
+       rcar_pcie_release_of_pci_ranges(pci);
+       return err;
+}
+
 static int rcar_pcie_probe(struct platform_device *pdev)
 {
        struct rcar_pcie *pcie;
        unsigned int data;
-       struct of_pci_range range;
-       struct of_pci_range_parser parser;
        const struct of_device_id *of_id;
-       int err, win = 0;
+       int err;
        int (*hw_init_fn)(struct rcar_pcie *);
 
        pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
@@ -940,16 +1008,9 @@ static int rcar_pcie_probe(struct platform_device *pdev)
        pcie->dev = &pdev->dev;
        platform_set_drvdata(pdev, pcie);
 
-       /* Get the bus range */
-       if (of_pci_parse_bus_range(pdev->dev.of_node, &pcie->busn)) {
-               dev_err(&pdev->dev, "failed to parse bus-range property\n");
-               return -EINVAL;
-       }
+       INIT_LIST_HEAD(&pcie->resources);
 
-       if (of_pci_range_parser_init(&parser, pdev->dev.of_node)) {
-               dev_err(&pdev->dev, "missing ranges property\n");
-               return -EINVAL;
-       }
+       rcar_pcie_parse_request_of_pci_ranges(pcie);
 
        err = rcar_pcie_get_resources(pdev, pcie);
        if (err < 0) {
@@ -957,46 +1018,55 @@ static int rcar_pcie_probe(struct platform_device *pdev)
                return err;
        }
 
-       for_each_of_pci_range(&parser, &range) {
-               err = of_pci_range_to_resource(&range, pdev->dev.of_node,
-                                               &pcie->res[win++]);
-               if (err < 0)
-                       return err;
-
-               if (win > RCAR_PCI_MAX_RESOURCES)
-                       break;
-       }
-
         err = rcar_pcie_parse_map_dma_ranges(pcie, pdev->dev.of_node);
         if (err)
                return err;
 
-       if (IS_ENABLED(CONFIG_PCI_MSI)) {
-               err = rcar_pcie_enable_msi(pcie);
-               if (err < 0) {
-                       dev_err(&pdev->dev,
-                               "failed to enable MSI support: %d\n",
-                               err);
-                       return err;
-               }
-       }
-
        of_id = of_match_device(rcar_pcie_of_match, pcie->dev);
        if (!of_id || !of_id->data)
                return -EINVAL;
        hw_init_fn = of_id->data;
 
+       pm_runtime_enable(pcie->dev);
+       err = pm_runtime_get_sync(pcie->dev);
+       if (err < 0) {
+               dev_err(pcie->dev, "pm_runtime_get_sync failed\n");
+               goto err_pm_disable;
+       }
+
        /* Failure to get a link might just be that no cards are inserted */
        err = hw_init_fn(pcie);
        if (err) {
                dev_info(&pdev->dev, "PCIe link down\n");
-               return 0;
+               err = 0;
+               goto err_pm_put;
        }
 
        data = rcar_pci_read_reg(pcie, MACSR);
        dev_info(&pdev->dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
 
-       return rcar_pcie_enable(pcie);
+       if (IS_ENABLED(CONFIG_PCI_MSI)) {
+               err = rcar_pcie_enable_msi(pcie);
+               if (err < 0) {
+                       dev_err(&pdev->dev,
+                               "failed to enable MSI support: %d\n",
+                               err);
+                       goto err_pm_put;
+               }
+       }
+
+       err = rcar_pcie_enable(pcie);
+       if (err)
+               goto err_pm_put;
+
+       return 0;
+
+err_pm_put:
+       pm_runtime_put(pcie->dev);
+
+err_pm_disable:
+       pm_runtime_disable(pcie->dev);
+       return err;
 }
 
 static struct platform_driver rcar_pcie_driver = {
index b95b756..a6cd823 100644 (file)
@@ -279,7 +279,8 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
                return -ENODEV;
        }
        ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
-                              IRQF_SHARED, "spear1340-pcie", pp);
+                              IRQF_SHARED | IRQF_NO_THREAD,
+                              "spear1340-pcie", pp);
        if (ret) {
                dev_err(dev, "failed to request irq %d\n", pp->irq);
                return ret;
index 3c7a0d5..4cfa463 100644 (file)
@@ -781,7 +781,8 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port)
 
        port->irq = irq_of_parse_and_map(node, 0);
        err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler,
-                              IRQF_SHARED, "xilinx-pcie", port);
+                              IRQF_SHARED | IRQF_NO_THREAD,
+                              "xilinx-pcie", port);
        if (err) {
                dev_err(dev, "unable to request irq %d\n", port->irq);
                return err;
index 876ccc6..a5e66df 100644 (file)
 
 #define MY_NAME        "acpi_pcihp"
 
-#define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __func__ , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+#define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __func__, ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 #define        METHOD_NAME__SUN        "_SUN"
 #define        METHOD_NAME_OSHP        "OSHP"
@@ -132,7 +132,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
 
        while (handle) {
                acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
-               dbg("Trying to get hotplug control for %s \n",
+               dbg("Trying to get hotplug control for %s\n",
                    (char *)string.pointer);
                status = acpi_run_oshp(handle);
                if (ACPI_SUCCESS(status))
index b0e61bf..f0ebc8b 100644 (file)
@@ -181,7 +181,7 @@ struct acpiphp_attention_info
 /* function prototypes */
 
 /* acpiphp_core.c */
-int acpiphp_register_attention(struct acpiphp_attention_info*info);
+int acpiphp_register_attention(struct acpiphp_attention_info *info);
 int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
 int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot, unsigned int sun);
 void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
index e291efc..3c81fc8 100644 (file)
@@ -63,13 +63,13 @@ MODULE_LICENSE("GPL");
 MODULE_PARM_DESC(disable, "disable acpiphp driver");
 module_param_named(disable, acpiphp_disabled, bool, 0444);
 
-static int enable_slot         (struct hotplug_slot *slot);
-static int disable_slot                (struct hotplug_slot *slot);
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int get_power_status    (struct hotplug_slot *slot, u8 *value);
-static int get_attention_status (struct hotplug_slot *slot, u8 *value);
-static int get_latch_status    (struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status  (struct hotplug_slot *slot, u8 *value);
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int set_attention_status(struct hotplug_slot *slot, u8 value);
+static int get_power_status(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
 
 static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
        .enable_slot            = enable_slot,
index ff53856..5f2fda1 100644 (file)
@@ -707,7 +707,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
        unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
 
        list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
-               for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
+               for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
                        struct resource *res = &dev->resource[i];
                        if ((res->flags & type_mask) && !res->start &&
                                        res->end) {
index 6ca2399..2f6d3a1 100644 (file)
@@ -154,7 +154,8 @@ static union apci_descriptor *ibm_slot_from_id(int id)
 ibm_slot_done:
        if (ret) {
                ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
-               memcpy(ret, des, sizeof(union apci_descriptor));
+               if (ret)
+                       memcpy(ret, des, sizeof(union apci_descriptor));
        }
        kfree(table);
        return ret;
@@ -175,8 +176,13 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
        acpi_status stat;
        unsigned long long rc;
        union apci_descriptor *ibm_slot;
+       int id = hpslot_to_sun(slot);
 
-       ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
+       ibm_slot = ibm_slot_from_id(id);
+       if (!ibm_slot) {
+               pr_err("APLS null ACPI descriptor for slot %d\n", id);
+               return -ENODEV;
+       }
 
        pr_debug("%s: set slot %d (%d) attention status to %d\n", __func__,
                        ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
@@ -215,8 +221,13 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
 static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
 {
        union apci_descriptor *ibm_slot;
+       int id = hpslot_to_sun(slot);
 
-       ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
+       ibm_slot = ibm_slot_from_id(id);
+       if (!ibm_slot) {
+               pr_err("APLS null ACPI descriptor for slot %d\n", id);
+               return -ENODEV;
+       }
 
        if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
                *status = 1;
@@ -325,7 +336,7 @@ static int ibm_get_table_from_acpi(char **bufp)
        }
 
        size = 0;
-       for (i=0; i<package->package.count; i++) {
+       for (i = 0; i < package->package.count; i++) {
                memcpy(&lbuf[size],
                                package->package.elements[i].buffer.pointer,
                                package->package.elements[i].buffer.length);
index 6a0ddf7..555bcde 100644 (file)
@@ -52,13 +52,13 @@ struct slot {
 };
 
 struct cpci_hp_controller_ops {
-       int (*query_enum) (void);
-       int (*enable_irq) (void);
-       int (*disable_irq) (void);
-       int (*check_irq) (void *dev_id);
-       int (*hardware_test) (struct slot *slot, u32 value);
-       u8  (*get_power) (struct slot *slot);
-       int (*set_power) (struct slot *slot, int value);
+       int (*query_enum)(void);
+       int (*enable_irq)(void);
+       int (*disable_irq)(void);
+       int (*check_irq)(void *dev_id);
+       int (*hardware_test)(struct slot *slot, u32 value);
+       u8  (*get_power)(struct slot *slot);
+       int (*set_power)(struct slot *slot, int value);
 };
 
 struct cpci_hp_controller {
index 46db293..7d3866c 100644 (file)
 #define dbg(format, arg...)                                    \
        do {                                                    \
                if (cpci_debug)                                 \
-                       printk (KERN_DEBUG "%s: " format "\n",  \
-                               MY_NAME , ## arg);              \
+                       printk(KERN_DEBUG "%s: " format "\n",   \
+                               MY_NAME, ## arg);               \
        } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
 
 /* local variables */
 static DECLARE_RWSEM(list_rwsem);
@@ -238,21 +238,21 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
         * with the pci_hotplug subsystem.
         */
        for (i = first; i <= last; ++i) {
-               slot = kzalloc(sizeof (struct slot), GFP_KERNEL);
+               slot = kzalloc(sizeof(struct slot), GFP_KERNEL);
                if (!slot) {
                        status = -ENOMEM;
                        goto error;
                }
 
                hotplug_slot =
-                       kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
+                       kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
                if (!hotplug_slot) {
                        status = -ENOMEM;
                        goto error_slot;
                }
                slot->hotplug_slot = hotplug_slot;
 
-               info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
+               info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
                if (!info) {
                        status = -ENOMEM;
                        goto error_hpslot;
index 788db48..80c8001 100644 (file)
@@ -38,12 +38,12 @@ extern int cpci_debug;
 #define dbg(format, arg...)                                    \
        do {                                                    \
                if (cpci_debug)                                 \
-                       printk (KERN_DEBUG "%s: " format "\n",  \
-                               MY_NAME , ## arg);              \
+                       printk(KERN_DEBUG "%s: " format "\n",   \
+                               MY_NAME, ## arg);               \
        } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
 
 
 u8 cpci_get_attention_status(struct slot *slot)
index 66b7bbe..88a44a7 100644 (file)
 #define dbg(format, arg...)                                    \
        do {                                                    \
                if (debug)                                      \
-                       printk (KERN_DEBUG "%s: " format "\n",  \
-                               MY_NAME , ## arg);              \
+                       printk(KERN_DEBUG "%s: " format "\n",   \
+                               MY_NAME, ## arg);               \
        } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
 
 /* local variables */
 static bool debug;
@@ -164,7 +164,7 @@ static int __init cpcihp_generic_init(void)
        bus = dev->subordinate;
        pci_dev_put(dev);
 
-       memset(&generic_hpc, 0, sizeof (struct cpci_hp_controller));
+       memset(&generic_hpc, 0, sizeof(struct cpci_hp_controller));
        generic_hpc_ops.query_enum = query_enum;
        generic_hpc.ops = &generic_hpc_ops;
 
index 7ecf34e..5f49c3f 100644 (file)
 #define dbg(format, arg...)                                    \
        do {                                                    \
                if (debug)                                      \
-                       printk (KERN_DEBUG "%s: " format "\n",  \
-                               MY_NAME , ## arg);              \
+                       printk(KERN_DEBUG "%s: " format "\n",   \
+                               MY_NAME, ## arg);               \
        } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
 
 /* local variables */
 static bool debug;
@@ -204,7 +204,7 @@ static int zt5550_hc_disable_irq(void)
        return 0;
 }
 
-static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int zt5550_hc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int status;
 
@@ -214,7 +214,7 @@ static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id
 
        dbg("returned from zt5550_hc_config");
 
-       memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller));
+       memset(&zt5550_hpc, 0, sizeof(struct cpci_hp_controller));
        zt5550_hpc_ops.query_enum = zt5550_hc_query_enum;
        zt5550_hpc.ops = &zt5550_hpc_ops;
        if (!poll) {
index b28b2d2..9103a7b 100644 (file)
 
 #define MY_NAME        "cpqphp"
 
-#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt, MY_NAME, ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 
 
@@ -424,7 +424,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func);
 int cpqhp_hardware_test(struct controller *ctrl, int test_num);
 
 /* resource functions */
-int    cpqhp_resource_sort_and_combine (struct pci_resource **head);
+int    cpqhp_resource_sort_and_combine(struct pci_resource **head);
 
 /* pci functions */
 int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
@@ -685,7 +685,7 @@ static inline int cpq_get_latch_status(struct controller *ctrl,
        u8 hp_slot;
 
        hp_slot = slot->device - ctrl->slot_device_offset;
-       dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
+       dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d\n",
            __func__, slot->device, ctrl->slot_device_offset);
 
        status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
@@ -712,7 +712,7 @@ static inline int get_presence_status(struct controller *ctrl,
 
 static inline int wait_for_ctrl_irq(struct controller *ctrl)
 {
-        DECLARE_WAITQUEUE(wait, current);
+       DECLARE_WAITQUEUE(wait, current);
        int retval = 0;
 
        dbg("%s - start\n", __func__);
index a53084d..74f3a06 100644 (file)
@@ -291,7 +291,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        kfree(slot);
 }
 
-static int ctrl_slot_cleanup (struct controller *ctrl)
+static int ctrl_slot_cleanup(struct controller *ctrl)
 {
        struct slot *old_slot, *next_slot;
 
@@ -301,7 +301,7 @@ static int ctrl_slot_cleanup (struct controller *ctrl)
        while (old_slot) {
                /* memory will be freed by the release_slot callback */
                next_slot = old_slot->next;
-               pci_hp_deregister (old_slot->hotplug_slot);
+               pci_hp_deregister(old_slot->hotplug_slot);
                old_slot = next_slot;
        }
 
@@ -413,9 +413,9 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
        mutex_lock(&ctrl->crit_sect);
 
        if (status == 1)
-               amber_LED_on (ctrl, hp_slot);
+               amber_LED_on(ctrl, hp_slot);
        else if (status == 0)
-               amber_LED_off (ctrl, hp_slot);
+               amber_LED_off(ctrl, hp_slot);
        else {
                /* Done with exclusive hardware access */
                mutex_unlock(&ctrl->crit_sect);
@@ -425,7 +425,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
        set_SOGO(ctrl);
 
        /* Wait for SOBS to be unset */
-       wait_for_ctrl_irq (ctrl);
+       wait_for_ctrl_irq(ctrl);
 
        /* Done with exclusive hardware access */
        mutex_unlock(&ctrl->crit_sect);
@@ -439,7 +439,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
  * @hotplug_slot: slot to change LED on
  * @status: LED control flag
  */
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
 {
        struct pci_func *slot_func;
        struct slot *slot = hotplug_slot->private;
@@ -610,7 +610,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
        u8 ctrl_slot;
        u32 tempdword;
        char name[SLOT_NAME_SIZE];
-       void __iomem *slot_entry= NULL;
+       void __iomem *slot_entry = NULL;
        int result;
 
        dbg("%s\n", __func__);
@@ -755,7 +755,7 @@ static int one_time_init(void)
        if (cpqhp_debug)
                pci_print_IRQ_route();
 
-       dbg("Initialize + Start the notification mechanism \n");
+       dbg("Initialize + Start the notification mechanism\n");
 
        retval = cpqhp_event_start_thread();
        if (retval)
@@ -772,7 +772,7 @@ static int one_time_init(void)
        /* Map rom address */
        cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
        if (!cpqhp_rom_start) {
-               err ("Could not ioremap memory region for ROM\n");
+               err("Could not ioremap memory region for ROM\n");
                retval = -EIO;
                goto error;
        }
@@ -786,7 +786,7 @@ static int one_time_init(void)
        smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
                                        cpqhp_rom_start + ROM_PHY_LEN);
        if (!smbios_table) {
-               err ("Could not find the SMBIOS pointer in memory\n");
+               err("Could not find the SMBIOS pointer in memory\n");
                retval = -EIO;
                goto error_rom_start;
        }
@@ -794,7 +794,7 @@ static int one_time_init(void)
        smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
                                        readw(smbios_table + ST_LENGTH));
        if (!smbios_start) {
-               err ("Could not ioremap memory region taken from SMBIOS values\n");
+               err("Could not ioremap memory region taken from SMBIOS values\n");
                retval = -EIO;
                goto error_smbios_start;
        }
@@ -1181,7 +1181,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * Finish setting up the hot plug ctrl device
         */
        ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
-       dbg("NumSlots %d \n", ctrl->slot_device_offset);
+       dbg("NumSlots %d\n", ctrl->slot_device_offset);
 
        ctrl->next_event = 0;
 
@@ -1198,7 +1198,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
 
        /* set up the interrupt */
-       dbg("HPC interrupt = %d \n", ctrl->interrupt);
+       dbg("HPC interrupt = %d\n", ctrl->interrupt);
        if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
                        IRQF_SHARED, MY_NAME, ctrl)) {
                err("Can't get irq %d for the hotplug pci controller\n",
@@ -1321,7 +1321,7 @@ static void __exit unload_cpqphpd(void)
        while (ctrl) {
                if (ctrl->hpc_reg) {
                        u16 misc;
-                       rc = read_slot_enable (ctrl);
+                       rc = read_slot_enable(ctrl);
 
                        writeb(0, ctrl->hpc_reg + SLOT_SERR);
                        writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
@@ -1361,7 +1361,7 @@ static void __exit unload_cpqphpd(void)
                        kfree(tres);
                }
 
-               kfree (ctrl->pci_bus);
+               kfree(ctrl->pci_bus);
 
                tctrl = ctrl;
                ctrl = ctrl->next;
@@ -1446,7 +1446,7 @@ static int __init cpqhpc_init(void)
 
        cpqhp_debug = debug;
 
-       info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+       info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
        cpqhp_initialize_debugfs();
        result = pci_register_driver(&cpqhpc_driver);
        dbg("pci_register_driver = %d\n", result);
index c5cbefe..a55653b 100644 (file)
@@ -155,7 +155,7 @@ static u8 handle_presence_change(u16 change, struct controller *ctrl)
         * Presence Change
         */
        dbg("cpqsbd:  Presence/Notify input change.\n");
-       dbg("         Changed bits are 0x%4.4x\n", change );
+       dbg("         Changed bits are 0x%4.4x\n", change);
 
        for (hp_slot = 0; hp_slot < 6; hp_slot++) {
                if (change & (0x0101 << hp_slot)) {
@@ -276,9 +276,9 @@ static u8 handle_power_fault(u8 change, struct controller *ctrl)
                                taskInfo->event_type = INT_POWER_FAULT;
 
                                if (ctrl->rev < 4) {
-                                       amber_LED_on (ctrl, hp_slot);
-                                       green_LED_off (ctrl, hp_slot);
-                                       set_SOGO (ctrl);
+                                       amber_LED_on(ctrl, hp_slot);
+                                       green_LED_off(ctrl, hp_slot);
+                                       set_SOGO(ctrl);
 
                                        /* this is a fatal condition, we want
                                         * to crash the machine to protect from
@@ -438,7 +438,7 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h
 
        node = *head;
 
-       if (node->length & (alignment -1)) {
+       if (node->length & (alignment - 1)) {
                /* this one isn't an aligned length, so we'll make a new entry
                 * and split it up.
                 */
@@ -835,13 +835,13 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head)
        if (!(*head))
                return 1;
 
-       dbg("*head->next = %p\n",(*head)->next);
+       dbg("*head->next = %p\n", (*head)->next);
 
        if (!(*head)->next)
                return 0;       /* only one item on the list, already sorted! */
 
-       dbg("*head->base = 0x%x\n",(*head)->base);
-       dbg("*head->next->base = 0x%x\n",(*head)->next->base);
+       dbg("*head->base = 0x%x\n", (*head)->base);
+       dbg("*head->next->base = 0x%x\n", (*head)->next->base);
        while (out_of_order) {
                out_of_order = 0;
 
@@ -917,7 +917,7 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data)
                /* Read to clear posted writes */
                misc = readw(ctrl->hpc_reg + MISC);
 
-               dbg ("%s - waking up\n", __func__);
+               dbg("%s - waking up\n", __func__);
                wake_up_interruptible(&ctrl->queue);
        }
 
@@ -1285,18 +1285,18 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
        /*
         * The board is already on
         */
-       else if (is_slot_enabled (ctrl, hp_slot))
+       else if (is_slot_enabled(ctrl, hp_slot))
                rc = CARD_FUNCTIONING;
        else {
                mutex_lock(&ctrl->crit_sect);
 
                /* turn on board without attaching to the bus */
-               enable_slot_power (ctrl, hp_slot);
+               enable_slot_power(ctrl, hp_slot);
 
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
 
                /* Change bits in slot power register to force another shift out
                 * NOTE: this is to work around the timer bug */
@@ -1307,7 +1307,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
 
                adapter_speed = get_adapter_speed(ctrl, hp_slot);
                if (bus->cur_bus_speed != adapter_speed)
@@ -1315,12 +1315,12 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                                rc = WRONG_BUS_FREQUENCY;
 
                /* turn off board without attaching to the bus */
-               disable_slot_power (ctrl, hp_slot);
+               disable_slot_power(ctrl, hp_slot);
 
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
 
                mutex_unlock(&ctrl->crit_sect);
 
@@ -1329,15 +1329,15 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
                mutex_lock(&ctrl->crit_sect);
 
-               slot_enable (ctrl, hp_slot);
-               green_LED_blink (ctrl, hp_slot);
+               slot_enable(ctrl, hp_slot);
+               green_LED_blink(ctrl, hp_slot);
 
-               amber_LED_off (ctrl, hp_slot);
+               amber_LED_off(ctrl, hp_slot);
 
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
 
                mutex_unlock(&ctrl->crit_sect);
 
@@ -1366,14 +1366,14 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
                        mutex_lock(&ctrl->crit_sect);
 
-                       amber_LED_on (ctrl, hp_slot);
-                       green_LED_off (ctrl, hp_slot);
-                       slot_disable (ctrl, hp_slot);
+                       amber_LED_on(ctrl, hp_slot);
+                       green_LED_off(ctrl, hp_slot);
+                       slot_disable(ctrl, hp_slot);
 
                        set_SOGO(ctrl);
 
                        /* Wait for SOBS to be unset */
-                       wait_for_ctrl_irq (ctrl);
+                       wait_for_ctrl_irq(ctrl);
 
                        mutex_unlock(&ctrl->crit_sect);
 
@@ -1392,14 +1392,14 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
                        mutex_lock(&ctrl->crit_sect);
 
-                       amber_LED_on (ctrl, hp_slot);
-                       green_LED_off (ctrl, hp_slot);
-                       slot_disable (ctrl, hp_slot);
+                       amber_LED_on(ctrl, hp_slot);
+                       green_LED_off(ctrl, hp_slot);
+                       slot_disable(ctrl, hp_slot);
 
                        set_SOGO(ctrl);
 
                        /* Wait for SOBS to be unset */
-                       wait_for_ctrl_irq (ctrl);
+                       wait_for_ctrl_irq(ctrl);
 
                        mutex_unlock(&ctrl->crit_sect);
                }
@@ -1443,7 +1443,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        set_SOGO(ctrl);
 
        /* Wait for SOBS to be unset */
-       wait_for_ctrl_irq (ctrl);
+       wait_for_ctrl_irq(ctrl);
 
        /* Change bits in slot power register to force another shift out
         * NOTE: this is to work around the timer bug
@@ -1455,7 +1455,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        set_SOGO(ctrl);
 
        /* Wait for SOBS to be unset */
-       wait_for_ctrl_irq (ctrl);
+       wait_for_ctrl_irq(ctrl);
 
        adapter_speed = get_adapter_speed(ctrl, hp_slot);
        if (bus->cur_bus_speed != adapter_speed)
@@ -1463,7 +1463,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                        rc = WRONG_BUS_FREQUENCY;
 
        /* turn off board without attaching to the bus */
-       disable_slot_power (ctrl, hp_slot);
+       disable_slot_power(ctrl, hp_slot);
 
        set_SOGO(ctrl);
 
@@ -1484,20 +1484,20 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        dbg("%s: after down\n", __func__);
 
        dbg("%s: before slot_enable\n", __func__);
-       slot_enable (ctrl, hp_slot);
+       slot_enable(ctrl, hp_slot);
 
        dbg("%s: before green_LED_blink\n", __func__);
-       green_LED_blink (ctrl, hp_slot);
+       green_LED_blink(ctrl, hp_slot);
 
        dbg("%s: before amber_LED_blink\n", __func__);
-       amber_LED_off (ctrl, hp_slot);
+       amber_LED_off(ctrl, hp_slot);
 
        dbg("%s: before set_SOGO\n", __func__);
        set_SOGO(ctrl);
 
        /* Wait for SOBS to be unset */
        dbg("%s: before wait_for_ctrl_irq\n", __func__);
-       wait_for_ctrl_irq (ctrl);
+       wait_for_ctrl_irq(ctrl);
        dbg("%s: after wait_for_ctrl_irq\n", __func__);
 
        dbg("%s: before up\n", __func__);
@@ -1520,7 +1520,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        } else {
                /* Get vendor/device ID u32 */
                ctrl->pci_bus->number = func->bus;
-               rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
+               rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
                dbg("%s: pci_read_config_dword returns %d\n", __func__, rc);
                dbg("%s: temp_register is %x\n", __func__, temp_register);
 
@@ -1557,14 +1557,14 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                if (rc) {
                        mutex_lock(&ctrl->crit_sect);
 
-                       amber_LED_on (ctrl, hp_slot);
-                       green_LED_off (ctrl, hp_slot);
-                       slot_disable (ctrl, hp_slot);
+                       amber_LED_on(ctrl, hp_slot);
+                       green_LED_off(ctrl, hp_slot);
+                       slot_disable(ctrl, hp_slot);
 
                        set_SOGO(ctrl);
 
                        /* Wait for SOBS to be unset */
-                       wait_for_ctrl_irq (ctrl);
+                       wait_for_ctrl_irq(ctrl);
 
                        mutex_unlock(&ctrl->crit_sect);
                        return rc;
@@ -1589,25 +1589,25 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
 
                mutex_lock(&ctrl->crit_sect);
 
-               green_LED_on (ctrl, hp_slot);
+               green_LED_on(ctrl, hp_slot);
 
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
 
                mutex_unlock(&ctrl->crit_sect);
        } else {
                mutex_lock(&ctrl->crit_sect);
 
-               amber_LED_on (ctrl, hp_slot);
-               green_LED_off (ctrl, hp_slot);
-               slot_disable (ctrl, hp_slot);
+               amber_LED_on(ctrl, hp_slot);
+               green_LED_off(ctrl, hp_slot);
+               slot_disable(ctrl, hp_slot);
 
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
 
                mutex_unlock(&ctrl->crit_sect);
 
@@ -1672,8 +1672,8 @@ static u32 remove_board(struct pci_func *func, u32 replace_flag, struct controll
 
        mutex_lock(&ctrl->crit_sect);
 
-       green_LED_off (ctrl, hp_slot);
-       slot_disable (ctrl, hp_slot);
+       green_LED_off(ctrl, hp_slot);
+       slot_disable(ctrl, hp_slot);
 
        set_SOGO(ctrl);
 
@@ -1683,7 +1683,7 @@ static u32 remove_board(struct pci_func *func, u32 replace_flag, struct controll
        writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
 
        /* Wait for SOBS to be unset */
-       wait_for_ctrl_irq (ctrl);
+       wait_for_ctrl_irq(ctrl);
 
        mutex_unlock(&ctrl->crit_sect);
 
@@ -1755,7 +1755,7 @@ static int event_thread(void *data)
                if (pushbutton_pending)
                        cpqhp_pushbutton_thread(pushbutton_pending);
                else
-                       for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
+                       for (ctrl = cpqhp_ctrl_list; ctrl; ctrl = ctrl->next)
                                interrupt_event_handler(ctrl);
        }
        dbg("event_thread signals exit\n");
@@ -1766,7 +1766,7 @@ int cpqhp_event_start_thread(void)
 {
        cpqhp_event_thread = kthread_run(event_thread, NULL, "phpd_event");
        if (IS_ERR(cpqhp_event_thread)) {
-               err ("Can't start up our event thread\n");
+               err("Can't start up our event thread\n");
                return PTR_ERR(cpqhp_event_thread);
        }
 
@@ -1794,7 +1794,7 @@ static int update_slot_info(struct controller *ctrl, struct slot *slot)
        info->latch_status = cpq_get_latch_status(ctrl, slot);
        info->adapter_status = get_presence_status(ctrl, slot);
        result = pci_hp_change_slot_info(slot->hotplug_slot, info);
-       kfree (info);
+       kfree(info);
        return result;
 }
 
@@ -1837,23 +1837,23 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        if (p_slot->state == BLINKINGOFF_STATE) {
                                                /* slot is on */
                                                dbg("turn on green LED\n");
-                                               green_LED_on (ctrl, hp_slot);
+                                               green_LED_on(ctrl, hp_slot);
                                        } else if (p_slot->state == BLINKINGON_STATE) {
                                                /* slot is off */
                                                dbg("turn off green LED\n");
-                                               green_LED_off (ctrl, hp_slot);
+                                               green_LED_off(ctrl, hp_slot);
                                        }
 
                                        info(msg_button_cancel, p_slot->number);
 
                                        p_slot->state = STATIC_STATE;
 
-                                       amber_LED_off (ctrl, hp_slot);
+                                       amber_LED_off(ctrl, hp_slot);
 
                                        set_SOGO(ctrl);
 
                                        /* Wait for SOBS to be unset */
-                                       wait_for_ctrl_irq (ctrl);
+                                       wait_for_ctrl_irq(ctrl);
 
                                        mutex_unlock(&ctrl->crit_sect);
                                }
@@ -1861,7 +1861,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
                                        dbg("button release\n");
 
-                                       if (is_slot_enabled (ctrl, hp_slot)) {
+                                       if (is_slot_enabled(ctrl, hp_slot)) {
                                                dbg("slot is on\n");
                                                p_slot->state = BLINKINGOFF_STATE;
                                                info(msg_button_off, p_slot->number);
@@ -1874,13 +1874,13 @@ static void interrupt_event_handler(struct controller *ctrl)
 
                                        dbg("blink green LED and turn off amber\n");
 
-                                       amber_LED_off (ctrl, hp_slot);
-                                       green_LED_blink (ctrl, hp_slot);
+                                       amber_LED_off(ctrl, hp_slot);
+                                       green_LED_blink(ctrl, hp_slot);
 
                                        set_SOGO(ctrl);
 
                                        /* Wait for SOBS to be unset */
-                                       wait_for_ctrl_irq (ctrl);
+                                       wait_for_ctrl_irq(ctrl);
 
                                        mutex_unlock(&ctrl->crit_sect);
                                        init_timer(&p_slot->task_event);
@@ -1940,7 +1940,7 @@ void cpqhp_pushbutton_thread(unsigned long slot)
                dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
                if (!func) {
                        dbg("Error! func NULL in %s\n", __func__);
-                       return ;
+                       return;
                }
 
                if (cpqhp_process_SS(ctrl, func) != 0) {
@@ -1962,7 +1962,7 @@ void cpqhp_pushbutton_thread(unsigned long slot)
                dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
                if (!func) {
                        dbg("Error! func NULL in %s\n", __func__);
-                       return ;
+                       return;
                }
 
                if (ctrl != NULL) {
@@ -1973,7 +1973,7 @@ void cpqhp_pushbutton_thread(unsigned long slot)
                                set_SOGO(ctrl);
 
                                /* Wait for SOBS to be unset */
-                               wait_for_ctrl_irq (ctrl);
+                               wait_for_ctrl_irq(ctrl);
                        }
                }
 
@@ -2086,7 +2086,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
        unsigned int devfn;
        struct slot *p_slot;
        struct pci_bus *pci_bus = ctrl->pci_bus;
-       int physical_slot=0;
+       int physical_slot = 0;
 
        device = func->device;
        func = cpqhp_slot_find(ctrl->bus, device, index++);
@@ -2100,7 +2100,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
                devfn = PCI_DEVFN(func->device, func->function);
 
                /* Check the Class Code */
-               rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+               rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
                if (rc)
                        return rc;
 
@@ -2109,13 +2109,13 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
                        rc = REMOVE_NOT_SUPPORTED;
                } else {
                        /* See if it's a bridge */
-                       rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+                       rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
                        if (rc)
                                return rc;
 
                        /* If it's a bridge, check the VGA Enable bit */
                        if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
-                               rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
+                               rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
                                if (rc)
                                        return rc;
 
@@ -2217,7 +2217,7 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)
                        set_SOGO(ctrl);
 
                        /* Wait for SOGO interrupt */
-                       wait_for_ctrl_irq (ctrl);
+                       wait_for_ctrl_irq(ctrl);
 
                        /* Get ready for next iteration */
                        long_delay((3*HZ)/10);
@@ -2227,7 +2227,7 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)
                        set_SOGO(ctrl);
 
                        /* Wait for SOGO interrupt */
-                       wait_for_ctrl_irq (ctrl);
+                       wait_for_ctrl_irq(ctrl);
 
                        /* Get ready for next iteration */
                        long_delay((3*HZ)/10);
@@ -2243,7 +2243,7 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)
                set_SOGO(ctrl);
 
                /* Wait for SOBS to be unset */
-               wait_for_ctrl_irq (ctrl);
+               wait_for_ctrl_irq(ctrl);
                break;
        case 2:
                /* Do other stuff here! */
@@ -2279,7 +2279,7 @@ static u32 configure_new_device(struct controller  *ctrl, struct pci_func  *func
        dbg("%s\n", __func__);
        /* Check for Multi-function device */
        ctrl->pci_bus->number = func->bus;
-       rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
+       rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
        if (rc) {
                dbg("%s: rc = %d\n", __func__, rc);
                return rc;
@@ -2296,7 +2296,7 @@ static u32 configure_new_device(struct controller  *ctrl, struct pci_func  *func
                rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
 
                if (rc) {
-                       dbg("configure_new_function failed %d\n",rc);
+                       dbg("configure_new_function failed %d\n", rc);
                        index = 0;
 
                        while (new_slot) {
@@ -2317,7 +2317,7 @@ static u32 configure_new_device(struct controller  *ctrl, struct pci_func  *func
                 * and creates a board structure */
 
                while ((function < max_functions) && (!stop_it)) {
-                       pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
+                       pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
 
                        if (ID == 0xFFFFFFFF) {
                                function++;
@@ -2543,10 +2543,10 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 
                /* set Pre Mem base and Limit registers */
                temp_word = p_mem_node->base >> 16;
-               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
 
                temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
-               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
                /* Adjust this to compensate for extra adjustment in first loop
                 */
@@ -2560,7 +2560,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 
                        ID = 0xFFFFFFFF;
                        pci_bus->number = hold_bus_node->base;
-                       pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
+                       pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
                        pci_bus->number = func->bus;
 
                        if (ID != 0xFFFFFFFF) {   /*  device present */
@@ -2579,7 +2579,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                new_slot->status = 0;
 
                                rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
-                               dbg("configure_new_device rc=0x%x\n",rc);
+                               dbg("configure_new_device rc=0x%x\n", rc);
                        }       /* End of IF (device in slot?) */
                }               /* End of FOR loop */
 
@@ -2615,7 +2615,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                        temp_byte = temp_resources.bus_head->base - 1;
 
                        /* set subordinate bus */
-                       rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
+                       rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
 
                        if (temp_resources.bus_head->length == 0) {
                                kfree(temp_resources.bus_head);
@@ -2636,7 +2636,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                hold_IO_node->base = io_node->base + io_node->length;
 
                                temp_byte = (hold_IO_node->base) >> 8;
-                               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
+                               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_IO_BASE, temp_byte);
 
                                return_resource(&(resources->io_head), io_node);
                        }
@@ -2655,13 +2655,13 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                        func->io_head = hold_IO_node;
 
                                        temp_byte = (io_node->base - 1) >> 8;
-                                       rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+                                       rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
 
                                        return_resource(&(resources->io_head), io_node);
                                } else {
                                        /* it doesn't need any IO */
                                        temp_word = 0x0000;
-                                       rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
+                                       rc = pci_bus_write_config_word(pci_bus, devfn, PCI_IO_LIMIT, temp_word);
 
                                        return_resource(&(resources->io_head), io_node);
                                        kfree(hold_IO_node);
@@ -2687,7 +2687,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                hold_mem_node->base = mem_node->base + mem_node->length;
 
                                temp_word = (hold_mem_node->base) >> 16;
-                               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+                               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
 
                                return_resource(&(resources->mem_head), mem_node);
                        }
@@ -2706,14 +2706,14 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 
                                        /* configure end address */
                                        temp_word = (mem_node->base - 1) >> 16;
-                                       rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+                                       rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
 
                                        /* Return unused resources to the pool */
                                        return_resource(&(resources->mem_head), mem_node);
                                } else {
                                        /* it doesn't need any Mem */
                                        temp_word = 0x0000;
-                                       rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+                                       rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
 
                                        return_resource(&(resources->mem_head), mem_node);
                                        kfree(hold_mem_node);
@@ -2739,7 +2739,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
 
                                temp_word = (hold_p_mem_node->base) >> 16;
-                               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+                               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
 
                                return_resource(&(resources->p_mem_head), p_mem_node);
                        }
@@ -2758,13 +2758,13 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                        func->p_mem_head = hold_p_mem_node;
 
                                        temp_word = (p_mem_node->base - 1) >> 16;
-                                       rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+                                       rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
                                        return_resource(&(resources->p_mem_head), p_mem_node);
                                } else {
                                        /* it doesn't need any PMem */
                                        temp_word = 0x0000;
-                                       rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+                                       rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
                                        return_resource(&(resources->p_mem_head), p_mem_node);
                                        kfree(hold_p_mem_node);
@@ -2790,16 +2790,16 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                         *   PCI_COMMAND_INVALIDATE |
                                         *   PCI_COMMAND_PARITY |
                                         *   PCI_COMMAND_SERR */
-               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
+               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
 
                /* set Bridge Control Register */
                command = 0x07;         /* = PCI_BRIDGE_CTL_PARITY |
                                         *   PCI_BRIDGE_CTL_SERR |
                                         *   PCI_BRIDGE_CTL_NO_ISA */
-               rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+               rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
        } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
                /* Standard device */
-               rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+               rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
 
                if (class_code == PCI_BASE_CLASS_DISPLAY) {
                        /* Display (video) adapter (not supported) */
@@ -2810,9 +2810,9 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                        temp_register = 0xFFFFFFFF;
 
                        dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
-                       rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+                       rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
 
-                       rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
+                       rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
                        dbg("CND: base = 0x%x\n", temp_register);
 
                        if (temp_register) {      /* If this register is implemented */
@@ -2891,7 +2891,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                }               /* End of base register loop */
                if (cpqhp_legacy_mode) {
                        /* Figure out which interrupt pin this function uses */
-                       rc = pci_bus_read_config_byte (pci_bus, devfn,
+                       rc = pci_bus_read_config_byte(pci_bus, devfn,
                                PCI_INTERRUPT_PIN, &temp_byte);
 
                        /* If this function needs an interrupt and we are behind
@@ -2905,7 +2905,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                        resources->irqs->barber_pole - 1) & 0x03];
                        } else {
                                /* Program IRQ based on card type */
-                               rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+                               rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
 
                                if (class_code == PCI_BASE_CLASS_STORAGE)
                                        IRQ = cpqhp_disk_irq;
@@ -2914,7 +2914,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                        }
 
                        /* IRQ Line */
-                       rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
+                       rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
                }
 
                if (!behind_bridge) {
@@ -2950,7 +2950,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
                                         *   PCI_COMMAND_INVALIDATE |
                                         *   PCI_COMMAND_PARITY |
                                         *   PCI_COMMAND_SERR */
-               rc = pci_bus_write_config_word (pci_bus, devfn,
+               rc = pci_bus_write_config_word(pci_bus, devfn,
                                        PCI_COMMAND, temp_word);
        } else {                /* End of Not-A-Bridge else */
                /* It's some strange type of PCI adapter (Cardbus?) */
@@ -2961,11 +2961,11 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 
        return 0;
 free_and_out:
-       cpqhp_destroy_resource_list (&temp_resources);
+       cpqhp_destroy_resource_list(&temp_resources);
 
-       return_resource(&(resources-> bus_head), hold_bus_node);
-       return_resource(&(resources-> io_head), hold_IO_node);
-       return_resource(&(resources-> mem_head), hold_mem_node);
-       return_resource(&(resources-> p_mem_head), hold_p_mem_node);
+       return_resource(&(resources->bus_head), hold_bus_node);
+       return_resource(&(resources->io_head), hold_IO_node);
+       return_resource(&(resources->mem_head), hold_mem_node);
+       return_resource(&(resources->p_mem_head), hold_p_mem_node);
        return rc;
 }
index 1e08ff8..c25fc90 100644 (file)
@@ -114,10 +114,10 @@ static u32 add_byte(u32 **p_buffer, u8 value, u32 *used, u32 *avail)
        if ((*used + 1) > *avail)
                return(1);
 
-       *((u8*)*p_buffer) = value;
-       tByte = (u8**)p_buffer;
+       *((u8 *)*p_buffer) = value;
+       tByte = (u8 **)p_buffer;
        (*tByte)++;
-       *used+=1;
+       *used += 1;
        return(0);
 }
 
@@ -129,7 +129,7 @@ static u32 add_dword(u32 **p_buffer, u32 value, u32 *used, u32 *avail)
 
        **p_buffer = value;
        (*p_buffer)++;
-       *used+=4;
+       *used += 4;
        return(0);
 }
 
@@ -141,7 +141,7 @@ static u32 add_dword(u32 **p_buffer, u32 value, u32 *used, u32 *avail)
  *
  * returns 0 for non-Compaq ROM, 1 for Compaq ROM
  */
-static int check_for_compaq_ROM (void __iomem *rom_start)
+static int check_for_compaq_ROM(void __iomem *rom_start)
 {
        u8 temp1, temp2, temp3, temp4, temp5, temp6;
        int result = 0;
@@ -160,12 +160,12 @@ static int check_for_compaq_ROM (void __iomem *rom_start)
            (temp6 == 'Q')) {
                result = 1;
        }
-       dbg ("%s - returned %d\n", __func__, result);
+       dbg("%s - returned %d\n", __func__, result);
        return result;
 }
 
 
-static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
+static u32 access_EV(u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
 {
        unsigned long flags;
        int op = operation;
@@ -197,7 +197,7 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
  *
  * Read the hot plug Resource Table from NVRAM
  */
-static int load_HRT (void __iomem *rom_start)
+static int load_HRT(void __iomem *rom_start)
 {
        u32 available;
        u32 temp_dword;
@@ -232,7 +232,7 @@ static int load_HRT (void __iomem *rom_start)
  *
  * Save the hot plug Resource Table in NVRAM
  */
-static u32 store_HRT (void __iomem *rom_start)
+static u32 store_HRT(void __iomem *rom_start)
 {
        u32 *buffer;
        u32 *pFill;
@@ -252,7 +252,7 @@ static u32 store_HRT (void __iomem *rom_start)
        if (!check_for_compaq_ROM(rom_start))
                return(1);
 
-       buffer = (u32*) evbuffer;
+       buffer = (u32 *) evbuffer;
 
        if (!buffer)
                return(1);
@@ -306,7 +306,7 @@ static u32 store_HRT (void __iomem *rom_start)
                loop = 0;
 
                while (resNode) {
-                       loop ++;
+                       loop++;
 
                        /* base */
                        rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
@@ -331,7 +331,7 @@ static u32 store_HRT (void __iomem *rom_start)
                loop = 0;
 
                while (resNode) {
-                       loop ++;
+                       loop++;
 
                        /* base */
                        rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
@@ -356,7 +356,7 @@ static u32 store_HRT (void __iomem *rom_start)
                loop = 0;
 
                while (resNode) {
-                       loop ++;
+                       loop++;
 
                        /* base */
                        rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
@@ -381,7 +381,7 @@ static u32 store_HRT (void __iomem *rom_start)
                loop = 0;
 
                while (resNode) {
-                       loop ++;
+                       loop++;
 
                        /* base */
                        rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
@@ -408,7 +408,7 @@ static u32 store_HRT (void __iomem *rom_start)
 
        temp_dword = usedbytes;
 
-       rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);
+       rc = access_EV(WRITE_EV, "CQTHPS", (u8 *) buffer, &temp_dword);
 
        dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);
 
@@ -423,7 +423,7 @@ static u32 store_HRT (void __iomem *rom_start)
 }
 
 
-void compaq_nvram_init (void __iomem *rom_start)
+void compaq_nvram_init(void __iomem *rom_start)
 {
        if (rom_start)
                compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
@@ -435,7 +435,7 @@ void compaq_nvram_init (void __iomem *rom_start)
 }
 
 
-int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
+int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl)
 {
        u8 bus, device, function;
        u8 nummem, numpmem, numio, numbus;
@@ -451,7 +451,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
        if (!evbuffer_init) {
                /* Read the resource list information in from NVRAM */
                if (load_HRT(rom_start))
-                       memset (evbuffer, 0, 1024);
+                       memset(evbuffer, 0, 1024);
 
                evbuffer_init = 1;
        }
@@ -472,7 +472,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 
                p_byte += 3;
 
-               if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+               if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
                        return 2;
 
                bus = p_ev_ctrl->bus;
@@ -489,20 +489,20 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
                                return 2;
 
                        /* Skip forward to the next entry */
                        p_byte += (nummem + numpmem + numio + numbus) * 8;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
                                return 2;
 
                        p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
 
                        p_byte += 3;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
                                return 2;
 
                        bus = p_ev_ctrl->bus;
@@ -517,7 +517,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 
                p_byte += 4;
 
-               if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+               if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
                        return 2;
 
                while (nummem--) {
@@ -526,20 +526,20 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                        if (!mem_node)
                                break;
 
-                       mem_node->base = *(u32*)p_byte;
-                       dbg("mem base = %8.8x\n",mem_node->base);
+                       mem_node->base = *(u32 *)p_byte;
+                       dbg("mem base = %8.8x\n", mem_node->base);
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(mem_node);
                                return 2;
                        }
 
-                       mem_node->length = *(u32*)p_byte;
-                       dbg("mem length = %8.8x\n",mem_node->length);
+                       mem_node->length = *(u32 *)p_byte;
+                       dbg("mem length = %8.8x\n", mem_node->length);
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(mem_node);
                                return 2;
                        }
@@ -554,20 +554,20 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                        if (!p_mem_node)
                                break;
 
-                       p_mem_node->base = *(u32*)p_byte;
-                       dbg("pre-mem base = %8.8x\n",p_mem_node->base);
+                       p_mem_node->base = *(u32 *)p_byte;
+                       dbg("pre-mem base = %8.8x\n", p_mem_node->base);
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(p_mem_node);
                                return 2;
                        }
 
-                       p_mem_node->length = *(u32*)p_byte;
-                       dbg("pre-mem length = %8.8x\n",p_mem_node->length);
+                       p_mem_node->length = *(u32 *)p_byte;
+                       dbg("pre-mem length = %8.8x\n", p_mem_node->length);
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(p_mem_node);
                                return 2;
                        }
@@ -582,20 +582,20 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                        if (!io_node)
                                break;
 
-                       io_node->base = *(u32*)p_byte;
-                       dbg("io base = %8.8x\n",io_node->base);
+                       io_node->base = *(u32 *)p_byte;
+                       dbg("io base = %8.8x\n", io_node->base);
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(io_node);
                                return 2;
                        }
 
-                       io_node->length = *(u32*)p_byte;
-                       dbg("io length = %8.8x\n",io_node->length);
+                       io_node->length = *(u32 *)p_byte;
+                       dbg("io length = %8.8x\n", io_node->length);
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(io_node);
                                return 2;
                        }
@@ -610,18 +610,18 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                        if (!bus_node)
                                break;
 
-                       bus_node->base = *(u32*)p_byte;
+                       bus_node->base = *(u32 *)p_byte;
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(bus_node);
                                return 2;
                        }
 
-                       bus_node->length = *(u32*)p_byte;
+                       bus_node->length = *(u32 *)p_byte;
                        p_byte += 4;
 
-                       if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+                       if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
                                kfree(bus_node);
                                return 2;
                        }
@@ -650,7 +650,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 }
 
 
-int compaq_nvram_store (void __iomem *rom_start)
+int compaq_nvram_store(void __iomem *rom_start)
 {
        int rc = 1;
 
index 1c8c2f1..e220d49 100644 (file)
@@ -81,7 +81,7 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom
 }
 
 
-int cpqhp_configure_device (struct controller *ctrl, struct pci_func *func)
+int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
 {
        struct pci_bus *child;
        int num;
@@ -89,7 +89,7 @@ int cpqhp_configure_device (struct controller *ctrl, struct pci_func *func)
        pci_lock_rescan_remove();
 
        if (func->pci_dev == NULL)
-               func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function));
+               func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
 
        /* No pci device, we need to create it then */
        if (func->pci_dev == NULL) {
@@ -128,7 +128,7 @@ int cpqhp_unconfigure_device(struct pci_func *func)
        dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function);
 
        pci_lock_rescan_remove();
-       for (j=0; j<8 ; j++) {
+       for (j = 0; j < 8 ; j++) {
                struct pci_dev *temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
                if (temp) {
                        pci_dev_put(temp);
@@ -143,11 +143,11 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 o
 {
        u32 vendID = 0;
 
-       if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
+       if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
                return -1;
        if (vendID == 0xffffffff)
                return -1;
-       return pci_bus_read_config_dword (bus, devfn, offset, value);
+       return pci_bus_read_config_dword(bus, devfn, offset, value);
 }
 
 
@@ -158,7 +158,7 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 o
  * @dev_num: device number of PCI device
  * @slot: pointer to u8 where slot number will be returned
  */
-int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
+int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
 {
        int rc = 0;
 
@@ -230,7 +230,7 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_
                dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
                /* Yep we got one. bridge ? */
                if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
-                       pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
+                       pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
                        /* XXX: no recursion, wtf? */
                        dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
                        return 0;
@@ -257,16 +257,16 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
                        *bus_num = tbus;
                        *dev_num = tdevice;
                        ctrl->pci_bus->number = tbus;
-                       pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
+                       pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
                        if (!nobridge || (work == 0xffffffff))
                                return 0;
 
                        dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
-                       pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
+                       pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
                        dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
 
                        if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
-                               pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
+                               pci_bus_read_config_byte(ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
                                dbg("Scan bus for Non Bridge: bus %d\n", tbus);
                                if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
                                        *bus_num = tbus;
@@ -280,7 +280,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
 }
 
 
-int cpqhp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot)
+int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot)
 {
        /* plain (bridges allowed) */
        return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);
@@ -419,7 +419,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
                        new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
 
                        for (cloop = 0; cloop < 0x20; cloop++) {
-                               rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
+                               rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) &(new_slot->config_space[cloop]));
                                if (rc)
                                        return rc;
                        }
@@ -465,7 +465,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
  *
  * returns 0 if success
  */
-int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func *new_slot)
+int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot)
 {
        long rc;
        u8 class_code;
@@ -481,7 +481,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func *new_slot)
        ID = 0xFFFFFFFF;
 
        ctrl->pci_bus->number = new_slot->bus;
-       pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
+       pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
 
        if (ID == 0xFFFFFFFF)
                return 2;
@@ -497,7 +497,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func *new_slot)
        while (function < max_functions) {
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
                        /*  Recurse the subordinate bus */
-                       pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
+                       pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
 
                        sub_bus = (int) secondary_bus;
 
@@ -514,7 +514,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func *new_slot)
                new_slot->status = 0;
 
                for (cloop = 0; cloop < 0x20; cloop++)
-                       pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
+                       pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) &(new_slot->config_space[cloop]));
 
                function++;
 
@@ -571,10 +571,10 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
                devfn = PCI_DEVFN(func->device, func->function);
 
                /* Check for Bridge */
-               pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
-                       pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+                       pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 
                        sub_bus = (int) secondary_bus;
 
@@ -595,8 +595,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
                         */
                        for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
                                temp_register = 0xFFFFFFFF;
-                               pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-                               pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+                               pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
+                               pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
                                /* If this register is implemented */
                                if (base) {
                                        if (base & 0x01L) {
@@ -631,8 +631,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
                        /* Figure out IO and memory base lengths */
                        for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
                                temp_register = 0xFFFFFFFF;
-                               pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-                               pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+                               pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
+                               pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
 
                                /* If this register is implemented */
                                if (base) {
@@ -686,7 +686,7 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
  *
  * returns 0 if success
  */
-int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func *func)
+int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func)
 {
        u8 cloop;
        u8 header_type;
@@ -791,7 +791,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func *func)
                        }
                        /* Figure out IO and memory base lengths */
                        for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
-                               pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
+                               pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
 
                                temp_register = 0xFFFFFFFF;
                                pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
@@ -972,13 +972,13 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func)
                 * registers are programmed last
                 */
                for (cloop = 0x3C; cloop > 0; cloop -= 4)
-                       pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
+                       pci_bus_write_config_dword(pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
 
-               pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
                /* If this is a bridge device, restore subordinate devices */
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
-                       pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+                       pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 
                        sub_bus = (int) secondary_bus;
 
@@ -998,7 +998,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func)
                         */
 
                        for (cloop = 16; cloop < 40; cloop += 4) {
-                               pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
+                               pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp);
 
                                if (temp != func->config_space[cloop >> 2]) {
                                        dbg("Config space compare failure!!! offset = %x\n", cloop);
@@ -1050,7 +1050,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
                pci_bus->number = func->bus;
                devfn = PCI_DEVFN(func->device, func->function);
 
-               pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
+               pci_bus_read_config_dword(pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
 
                /* No adapter present */
                if (temp_register == 0xFFFFFFFF)
@@ -1060,14 +1060,14 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
                        return(ADAPTER_NOT_SAME);
 
                /* Check for same revision number and class code */
-               pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
+               pci_bus_read_config_dword(pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
 
                /* Adapter not the same */
                if (temp_register != func->config_space[0x08 >> 2])
                        return(ADAPTER_NOT_SAME);
 
                /* Check for Bridge */
-               pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+               pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
                        /* In order to continue checking, we must program the
@@ -1076,7 +1076,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
                         */
 
                        temp_register = func->config_space[0x18 >> 2];
-                       pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
+                       pci_bus_write_config_dword(pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
 
                        secondary_bus = (temp_register >> 8) & 0xFF;
 
@@ -1094,7 +1094,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
                /* Check to see if it is a standard config header */
                else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
                        /* Check subsystem vendor and ID */
-                       pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
+                       pci_bus_read_config_dword(pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
 
                        if (temp_register != func->config_space[0x2C >> 2]) {
                                /* If it's a SMART-2 and the register isn't
@@ -1108,8 +1108,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
                        /* Figure out IO and memory base lengths */
                        for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
                                temp_register = 0xFFFFFFFF;
-                               pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-                               pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+                               pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
+                               pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
 
                                /* If this register is implemented */
                                if (base) {
@@ -1234,7 +1234,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
        if (rc)
                return rc;
 
-       one_slot = rom_resource_table + sizeof (struct hrt);
+       one_slot = rom_resource_table + sizeof(struct hrt);
 
        i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
        dbg("number_of_entries = %d\n", i);
@@ -1263,12 +1263,12 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
                /* If this entry isn't for our controller's bus, ignore it */
                if (primary_bus != ctrl->bus) {
                        i--;
-                       one_slot += sizeof (struct slot_rt);
+                       one_slot += sizeof(struct slot_rt);
                        continue;
                }
                /* find out if this entry is for an occupied slot */
                ctrl->pci_bus->number = primary_bus;
-               pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
+               pci_bus_read_config_dword(ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
                dbg("temp_D_word = %x\n", temp_dword);
 
                if (temp_dword != 0xFFFFFFFF) {
@@ -1283,7 +1283,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
                        /* If we can't find a match, skip this table entry */
                        if (!func) {
                                i--;
-                               one_slot += sizeof (struct slot_rt);
+                               one_slot += sizeof(struct slot_rt);
                                continue;
                        }
                        /* this may not work and shouldn't be used */
@@ -1395,7 +1395,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
                }
 
                i--;
-               one_slot += sizeof (struct slot_rt);
+               one_slot += sizeof(struct slot_rt);
        }
 
        /* If all of the following fail, we don't have any resources for
@@ -1475,7 +1475,7 @@ int cpqhp_return_board_resources(struct pci_func *func, struct resource_lists *r
  *
  * Puts node back in the resource list pointed to by head
  */
-void cpqhp_destroy_resource_list (struct resource_lists *resources)
+void cpqhp_destroy_resource_list(struct resource_lists *resources)
 {
        struct pci_resource *res, *tres;
 
@@ -1522,7 +1522,7 @@ void cpqhp_destroy_resource_list (struct resource_lists *resources)
  *
  * Puts node back in the resource list pointed to by head
  */
-void cpqhp_destroy_board_resources (struct pci_func *func)
+void cpqhp_destroy_board_resources(struct pci_func *func)
 {
        struct pci_resource *res, *tres;
 
index d81648f..775974d 100644 (file)
@@ -39,7 +39,7 @@
 #include "cpqphp.h"
 
 static DEFINE_MUTEX(cpqphp_mutex);
-static int show_ctrl (struct controller *ctrl, char *buf)
+static int show_ctrl(struct controller *ctrl, char *buf)
 {
        char *out = buf;
        int index;
@@ -77,7 +77,7 @@ static int show_ctrl (struct controller *ctrl, char *buf)
        return out - buf;
 }
 
-static int show_dev (struct controller *ctrl, char *buf)
+static int show_dev(struct controller *ctrl, char *buf)
 {
        char *out = buf;
        int index;
@@ -119,7 +119,7 @@ static int show_dev (struct controller *ctrl, char *buf)
                        out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
                        res = res->next;
                }
-               slot=slot->next;
+               slot = slot->next;
        }
 
        return out - buf;
index e3e46a7..d325683 100644 (file)
@@ -39,11 +39,11 @@ extern int ibmphp_debug;
 #else
        #define MY_NAME THIS_MODULE->name
 #endif
-#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
-#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt, MY_NAME, ## arg); } while (0)
+#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt, MY_NAME, ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 
 /* EBDA stuff */
@@ -603,7 +603,7 @@ void ibmphp_hpc_stop_poll_thread(void);
 #define SLOT_CONNECT(s)        ((u8) ((s & HPC_SLOT_CONNECT) \
        ? HPC_SLOT_DISCONNECTED : HPC_SLOT_CONNECTED))
 
-#define SLOT_ATTN(s,es)        ((u8) ((es & HPC_SLOT_BLINK_ATTN) \
+#define SLOT_ATTN(s, es)       ((u8) ((es & HPC_SLOT_BLINK_ATTN) \
        ? HPC_SLOT_ATTN_BLINK \
        : ((s & HPC_SLOT_ATTN) ? HPC_SLOT_ATTN_ON : HPC_SLOT_ATTN_OFF)))
 
index 1530247..5efd01d 100644 (file)
 #include <asm/io_apic.h>
 #include "ibmphp.h"
 
-#define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
-#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
-#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
-#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
-#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
+#define attn_on(sl)  ibmphp_hpc_writeslot(sl, HPC_SLOT_ATTNON)
+#define attn_off(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_ATTNOFF)
+#define attn_LED_blink(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_BLINKLED)
+#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot(sl, READ_REVLEVEL, rev)
+#define get_hpc_options(sl, opt) ibmphp_hpc_readslot(sl, READ_HPCOPTIONS, opt)
 
 #define DRIVER_VERSION "0.6"
 #define DRIVER_DESC    "IBM Hot Plug PCI Controller Driver"
@@ -52,9 +52,9 @@ int ibmphp_debug;
 
 static bool debug;
 module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
-MODULE_LICENSE ("GPL");
-MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DRIVER_DESC);
 
 struct pci_bus *ibmphp_pci_bus;
 static int max_slots;
@@ -113,14 +113,12 @@ static inline int slot_update(struct slot **sl)
        return rc;
 }
 
-static int __init get_max_slots (void)
+static int __init get_max_slots(void)
 {
        struct slot *slot_cur;
-       struct list_head *tmp;
        u8 slot_count = 0;
 
-       list_for_each(tmp, &ibmphp_slot_head) {
-               slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
+       list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
                /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
                slot_count = max(slot_count, slot_cur->number);
        }
@@ -459,7 +457,7 @@ static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 *value,
                                        *value = SLOT_SPEED(myslot.ext_status);
                        } else
                                *value = MAX_ADAPTER_NONE;
-                }
+               }
        }
 
        if (flag)
@@ -501,16 +499,10 @@ static int get_bus_name(struct hotplug_slot *hotplug_slot, char *value)
 static int __init init_ops(void)
 {
        struct slot *slot_cur;
-       struct list_head *tmp;
        int retval;
        int rc;
 
-       list_for_each(tmp, &ibmphp_slot_head) {
-               slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
-
-               if (!slot_cur)
-                       return -ENODEV;
-
+       list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
                debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
                                                        slot_cur->number);
                if (slot_cur->ctrl->revision == 0xFF)
@@ -620,11 +612,11 @@ int ibmphp_update_slot_info(struct slot *slot_cur)
        info->attention_status = SLOT_ATTN(slot_cur->status,
                                                slot_cur->ext_status);
        info->latch_status = SLOT_LATCH(slot_cur->status);
-        if (!SLOT_PRESENT(slot_cur->status)) {
-                info->adapter_status = 0;
+       if (!SLOT_PRESENT(slot_cur->status)) {
+               info->adapter_status = 0;
 /*             info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
        } else {
-                info->adapter_status = 1;
+               info->adapter_status = 1;
 /*             get_max_adapter_speed_1(slot_cur->hotplug_slot,
                                        &info->max_adapter_speed_status, 0); */
        }
@@ -669,9 +661,7 @@ static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
 {
        struct pci_func *func_cur;
        struct slot *slot_cur;
-       struct list_head *tmp;
-       list_for_each(tmp, &ibmphp_slot_head) {
-               slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
+       list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
                if (slot_cur->func) {
                        func_cur = slot_cur->func;
                        while (func_cur) {
@@ -693,14 +683,12 @@ static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
  *************************************************************/
 static void free_slots(void)
 {
-       struct slot *slot_cur;
-       struct list_head *tmp;
-       struct list_head *next;
+       struct slot *slot_cur, *next;
 
        debug("%s -- enter\n", __func__);
 
-       list_for_each_safe(tmp, next, &ibmphp_slot_head) {
-               slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
+       list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head,
+                                ibm_slot_list) {
                pci_hp_deregister(slot_cur->hotplug_slot);
        }
        debug("%s -- exit\n", __func__);
@@ -866,7 +854,7 @@ static int set_bus(struct slot *slot_cur)
        int retval;
        static struct pci_device_id ciobx[] = {
                { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
-               { },
+               { },
        };
 
        debug("%s - entry slot # %d\n", __func__, slot_cur->number);
@@ -1182,7 +1170,7 @@ error_power:
 * HOT REMOVING ADAPTER CARD                                   *
 * INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
 * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
-          DISABLE POWER ,                                    *
+*              DISABLE POWER ,                               *
 **************************************************************/
 static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
 {
index d9b197d..43e345a 100644 (file)
  */
 
 /* Global lists */
-LIST_HEAD (ibmphp_ebda_pci_rsrc_head);
-LIST_HEAD (ibmphp_slot_head);
+LIST_HEAD(ibmphp_ebda_pci_rsrc_head);
+LIST_HEAD(ibmphp_slot_head);
 
 /* Local variables */
 static struct ebda_hpc_list *hpc_list_ptr;
 static struct ebda_rsrc_list *rsrc_list_ptr;
 static struct rio_table_hdr *rio_table_ptr = NULL;
-static LIST_HEAD (ebda_hpc_head);
-static LIST_HEAD (bus_info_head);
-static LIST_HEAD (rio_vg_head);
-static LIST_HEAD (rio_lo_head);
-static LIST_HEAD (opt_vg_head);
-static LIST_HEAD (opt_lo_head);
+static LIST_HEAD(ebda_hpc_head);
+static LIST_HEAD(bus_info_head);
+static LIST_HEAD(rio_vg_head);
+static LIST_HEAD(rio_lo_head);
+static LIST_HEAD(opt_vg_head);
+static LIST_HEAD(opt_lo_head);
 static void __iomem *io_mem;
 
 /* Local functions */
-static int ebda_rsrc_controller (void);
-static int ebda_rsrc_rsrc (void);
-static int ebda_rio_table (void);
+static int ebda_rsrc_controller(void);
+static int ebda_rsrc_rsrc(void);
+static int ebda_rio_table(void);
 
-static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
+static struct ebda_hpc_list * __init alloc_ebda_hpc_list(void)
 {
        return kzalloc(sizeof(struct ebda_hpc_list), GFP_KERNEL);
 }
 
-static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
+static struct controller *alloc_ebda_hpc(u32 slot_count, u32 bus_count)
 {
        struct controller *controller;
        struct ebda_hpc_slot *slots;
@@ -103,146 +103,146 @@ error:
        return NULL;
 }
 
-static void free_ebda_hpc (struct controller *controller)
+static void free_ebda_hpc(struct controller *controller)
 {
-       kfree (controller->slots);
-       kfree (controller->buses);
-       kfree (controller);
+       kfree(controller->slots);
+       kfree(controller->buses);
+       kfree(controller);
 }
 
-static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
+static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list(void)
 {
        return kzalloc(sizeof(struct ebda_rsrc_list), GFP_KERNEL);
 }
 
-static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
+static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc(void)
 {
        return kzalloc(sizeof(struct ebda_pci_rsrc), GFP_KERNEL);
 }
 
-static void __init print_bus_info (void)
+static void __init print_bus_info(void)
 {
        struct bus_info *ptr;
 
        list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
-               debug ("%s - slot_min = %x\n", __func__, ptr->slot_min);
-               debug ("%s - slot_max = %x\n", __func__, ptr->slot_max);
-               debug ("%s - slot_count = %x\n", __func__, ptr->slot_count);
-               debug ("%s - bus# = %x\n", __func__, ptr->busno);
-               debug ("%s - current_speed = %x\n", __func__, ptr->current_speed);
-               debug ("%s - controller_id = %x\n", __func__, ptr->controller_id);
-
-               debug ("%s - slots_at_33_conv = %x\n", __func__, ptr->slots_at_33_conv);
-               debug ("%s - slots_at_66_conv = %x\n", __func__, ptr->slots_at_66_conv);
-               debug ("%s - slots_at_66_pcix = %x\n", __func__, ptr->slots_at_66_pcix);
-               debug ("%s - slots_at_100_pcix = %x\n", __func__, ptr->slots_at_100_pcix);
-               debug ("%s - slots_at_133_pcix = %x\n", __func__, ptr->slots_at_133_pcix);
+               debug("%s - slot_min = %x\n", __func__, ptr->slot_min);
+               debug("%s - slot_max = %x\n", __func__, ptr->slot_max);
+               debug("%s - slot_count = %x\n", __func__, ptr->slot_count);
+               debug("%s - bus# = %x\n", __func__, ptr->busno);
+               debug("%s - current_speed = %x\n", __func__, ptr->current_speed);
+               debug("%s - controller_id = %x\n", __func__, ptr->controller_id);
+
+               debug("%s - slots_at_33_conv = %x\n", __func__, ptr->slots_at_33_conv);
+               debug("%s - slots_at_66_conv = %x\n", __func__, ptr->slots_at_66_conv);
+               debug("%s - slots_at_66_pcix = %x\n", __func__, ptr->slots_at_66_pcix);
+               debug("%s - slots_at_100_pcix = %x\n", __func__, ptr->slots_at_100_pcix);
+               debug("%s - slots_at_133_pcix = %x\n", __func__, ptr->slots_at_133_pcix);
 
        }
 }
 
-static void print_lo_info (void)
+static void print_lo_info(void)
 {
        struct rio_detail *ptr;
-       debug ("print_lo_info ----\n");
+       debug("print_lo_info ----\n");
        list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) {
-               debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
-               debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
-               debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
-               debug ("%s - first_slot_num = %x\n", __func__, ptr->first_slot_num);
-               debug ("%s - wpindex = %x\n", __func__, ptr->wpindex);
-               debug ("%s - chassis_num = %x\n", __func__, ptr->chassis_num);
+               debug("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
+               debug("%s - rio_type = %x\n", __func__, ptr->rio_type);
+               debug("%s - owner_id = %x\n", __func__, ptr->owner_id);
+               debug("%s - first_slot_num = %x\n", __func__, ptr->first_slot_num);
+               debug("%s - wpindex = %x\n", __func__, ptr->wpindex);
+               debug("%s - chassis_num = %x\n", __func__, ptr->chassis_num);
 
        }
 }
 
-static void print_vg_info (void)
+static void print_vg_info(void)
 {
        struct rio_detail *ptr;
-       debug ("%s ---\n", __func__);
+       debug("%s ---\n", __func__);
        list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) {
-               debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
-               debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
-               debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
-               debug ("%s - first_slot_num = %x\n", __func__, ptr->first_slot_num);
-               debug ("%s - wpindex = %x\n", __func__, ptr->wpindex);
-               debug ("%s - chassis_num = %x\n", __func__, ptr->chassis_num);
+               debug("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
+               debug("%s - rio_type = %x\n", __func__, ptr->rio_type);
+               debug("%s - owner_id = %x\n", __func__, ptr->owner_id);
+               debug("%s - first_slot_num = %x\n", __func__, ptr->first_slot_num);
+               debug("%s - wpindex = %x\n", __func__, ptr->wpindex);
+               debug("%s - chassis_num = %x\n", __func__, ptr->chassis_num);
 
        }
 }
 
-static void __init print_ebda_pci_rsrc (void)
+static void __init print_ebda_pci_rsrc(void)
 {
        struct ebda_pci_rsrc *ptr;
 
        list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) {
-               debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
-                       __func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
+               debug("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
+                       __func__, ptr->rsrc_type, ptr->bus_num, ptr->dev_fun, ptr->start_addr, ptr->end_addr);
        }
 }
 
-static void __init print_ibm_slot (void)
+static void __init print_ibm_slot(void)
 {
        struct slot *ptr;
 
        list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) {
-               debug ("%s - slot_number: %x\n", __func__, ptr->number);
+               debug("%s - slot_number: %x\n", __func__, ptr->number);
        }
 }
 
-static void __init print_opt_vg (void)
+static void __init print_opt_vg(void)
 {
        struct opt_rio *ptr;
-       debug ("%s ---\n", __func__);
+       debug("%s ---\n", __func__);
        list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
-               debug ("%s - rio_type %x\n", __func__, ptr->rio_type);
-               debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num);
-               debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num);
-               debug ("%s - middle_num: %x\n", __func__, ptr->middle_num);
+               debug("%s - rio_type %x\n", __func__, ptr->rio_type);
+               debug("%s - chassis_num: %x\n", __func__, ptr->chassis_num);
+               debug("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num);
+               debug("%s - middle_num: %x\n", __func__, ptr->middle_num);
        }
 }
 
-static void __init print_ebda_hpc (void)
+static void __init print_ebda_hpc(void)
 {
        struct controller *hpc_ptr;
        u16 index;
 
        list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) {
                for (index = 0; index < hpc_ptr->slot_count; index++) {
-                       debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num);
-                       debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num);
-                       debug ("%s - index into ctlr addr: %x\n", __func__, hpc_ptr->slots[index].ctl_index);
-                       debug ("%s - cap of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_cap);
+                       debug("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num);
+                       debug("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num);
+                       debug("%s - index into ctlr addr: %x\n", __func__, hpc_ptr->slots[index].ctl_index);
+                       debug("%s - cap of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_cap);
                }
 
                for (index = 0; index < hpc_ptr->bus_count; index++)
-                       debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __func__, hpc_ptr->buses[index].bus_num);
+                       debug("%s - bus# of each bus controlled by this ctlr: %x\n", __func__, hpc_ptr->buses[index].bus_num);
 
-               debug ("%s - type of hpc: %x\n", __func__, hpc_ptr->ctlr_type);
+               debug("%s - type of hpc: %x\n", __func__, hpc_ptr->ctlr_type);
                switch (hpc_ptr->ctlr_type) {
                case 1:
-                       debug ("%s - bus: %x\n", __func__, hpc_ptr->u.pci_ctlr.bus);
-                       debug ("%s - dev_fun: %x\n", __func__, hpc_ptr->u.pci_ctlr.dev_fun);
-                       debug ("%s - irq: %x\n", __func__, hpc_ptr->irq);
+                       debug("%s - bus: %x\n", __func__, hpc_ptr->u.pci_ctlr.bus);
+                       debug("%s - dev_fun: %x\n", __func__, hpc_ptr->u.pci_ctlr.dev_fun);
+                       debug("%s - irq: %x\n", __func__, hpc_ptr->irq);
                        break;
 
                case 0:
-                       debug ("%s - io_start: %x\n", __func__, hpc_ptr->u.isa_ctlr.io_start);
-                       debug ("%s - io_end: %x\n", __func__, hpc_ptr->u.isa_ctlr.io_end);
-                       debug ("%s - irq: %x\n", __func__, hpc_ptr->irq);
+                       debug("%s - io_start: %x\n", __func__, hpc_ptr->u.isa_ctlr.io_start);
+                       debug("%s - io_end: %x\n", __func__, hpc_ptr->u.isa_ctlr.io_end);
+                       debug("%s - irq: %x\n", __func__, hpc_ptr->irq);
                        break;
 
                case 2:
                case 4:
-                       debug ("%s - wpegbbar: %lx\n", __func__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
-                       debug ("%s - i2c_addr: %x\n", __func__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
-                       debug ("%s - irq: %x\n", __func__, hpc_ptr->irq);
+                       debug("%s - wpegbbar: %lx\n", __func__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
+                       debug("%s - i2c_addr: %x\n", __func__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
+                       debug("%s - irq: %x\n", __func__, hpc_ptr->irq);
                        break;
                }
        }
 }
 
-int __init ibmphp_access_ebda (void)
+int __init ibmphp_access_ebda(void)
 {
        u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz;
        u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base;
@@ -252,12 +252,12 @@ int __init ibmphp_access_ebda (void)
        rio_complete = 0;
        hs_complete = 0;
 
-       io_mem = ioremap ((0x40 << 4) + 0x0e, 2);
-       if (!io_mem )
+       io_mem = ioremap((0x40 << 4) + 0x0e, 2);
+       if (!io_mem)
                return -ENOMEM;
-       ebda_seg = readw (io_mem);
-       iounmap (io_mem);
-       debug ("returned ebda segment: %x\n", ebda_seg);
+       ebda_seg = readw(io_mem);
+       iounmap(io_mem);
+       debug("returned ebda segment: %x\n", ebda_seg);
 
        io_mem = ioremap(ebda_seg<<4, 1);
        if (!io_mem)
@@ -269,7 +269,7 @@ int __init ibmphp_access_ebda (void)
                return -ENOMEM;
 
        io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024));
-       if (!io_mem )
+       if (!io_mem)
                return -ENOMEM;
        next_offset = 0x180;
 
@@ -281,12 +281,12 @@ int __init ibmphp_access_ebda (void)
                         "ibmphp_ebda: next read is beyond ebda_sz\n"))
                        break;
 
-               next_offset = readw (io_mem + offset);  /* offset of next blk */
+               next_offset = readw(io_mem + offset);   /* offset of next blk */
 
                offset += 2;
                if (next_offset == 0)   /* 0 indicate it's last blk */
                        break;
-               blk_id = readw (io_mem + offset);       /* this blk id */
+               blk_id = readw(io_mem + offset);        /* this blk id */
 
                offset += 2;
                /* check if it is hot swap block or rio block */
@@ -294,31 +294,31 @@ int __init ibmphp_access_ebda (void)
                        continue;
                /* found hs table */
                if (blk_id == 0x4853) {
-                       debug ("now enter hot swap block---\n");
-                       debug ("hot blk id: %x\n", blk_id);
-                       format = readb (io_mem + offset);
+                       debug("now enter hot swap block---\n");
+                       debug("hot blk id: %x\n", blk_id);
+                       format = readb(io_mem + offset);
 
                        offset += 1;
                        if (format != 4)
                                goto error_nodev;
-                       debug ("hot blk format: %x\n", format);
+                       debug("hot blk format: %x\n", format);
                        /* hot swap sub blk */
                        base = offset;
 
                        sub_addr = base;
-                       re = readw (io_mem + sub_addr); /* next sub blk */
+                       re = readw(io_mem + sub_addr);  /* next sub blk */
 
                        sub_addr += 2;
-                       rc_id = readw (io_mem + sub_addr);      /* sub blk id */
+                       rc_id = readw(io_mem + sub_addr);       /* sub blk id */
 
                        sub_addr += 2;
                        if (rc_id != 0x5243)
                                goto error_nodev;
                        /* rc sub blk signature  */
-                       num_ctlrs = readb (io_mem + sub_addr);
+                       num_ctlrs = readb(io_mem + sub_addr);
 
                        sub_addr += 1;
-                       hpc_list_ptr = alloc_ebda_hpc_list ();
+                       hpc_list_ptr = alloc_ebda_hpc_list();
                        if (!hpc_list_ptr) {
                                rc = -ENOMEM;
                                goto out;
@@ -326,28 +326,28 @@ int __init ibmphp_access_ebda (void)
                        hpc_list_ptr->format = format;
                        hpc_list_ptr->num_ctlrs = num_ctlrs;
                        hpc_list_ptr->phys_addr = sub_addr;     /*  offset of RSRC_CONTROLLER blk */
-                       debug ("info about hpc descriptor---\n");
-                       debug ("hot blk format: %x\n", format);
-                       debug ("num of controller: %x\n", num_ctlrs);
-                       debug ("offset of hpc data structure entries: %x\n ", sub_addr);
+                       debug("info about hpc descriptor---\n");
+                       debug("hot blk format: %x\n", format);
+                       debug("num of controller: %x\n", num_ctlrs);
+                       debug("offset of hpc data structure entries: %x\n ", sub_addr);
 
                        sub_addr = base + re;   /* re sub blk */
                        /* FIXME: rc is never used/checked */
-                       rc = readw (io_mem + sub_addr); /* next sub blk */
+                       rc = readw(io_mem + sub_addr);  /* next sub blk */
 
                        sub_addr += 2;
-                       re_id = readw (io_mem + sub_addr);      /* sub blk id */
+                       re_id = readw(io_mem + sub_addr);       /* sub blk id */
 
                        sub_addr += 2;
                        if (re_id != 0x5245)
                                goto error_nodev;
 
                        /* signature of re */
-                       num_entries = readw (io_mem + sub_addr);
+                       num_entries = readw(io_mem + sub_addr);
 
                        sub_addr += 2;  /* offset of RSRC_ENTRIES blk */
-                       rsrc_list_ptr = alloc_ebda_rsrc_list ();
-                       if (!rsrc_list_ptr ) {
+                       rsrc_list_ptr = alloc_ebda_rsrc_list();
+                       if (!rsrc_list_ptr) {
                                rc = -ENOMEM;
                                goto out;
                        }
@@ -355,26 +355,26 @@ int __init ibmphp_access_ebda (void)
                        rsrc_list_ptr->num_entries = num_entries;
                        rsrc_list_ptr->phys_addr = sub_addr;
 
-                       debug ("info about rsrc descriptor---\n");
-                       debug ("format: %x\n", format);
-                       debug ("num of rsrc: %x\n", num_entries);
-                       debug ("offset of rsrc data structure entries: %x\n ", sub_addr);
+                       debug("info about rsrc descriptor---\n");
+                       debug("format: %x\n", format);
+                       debug("num of rsrc: %x\n", num_entries);
+                       debug("offset of rsrc data structure entries: %x\n ", sub_addr);
 
                        hs_complete = 1;
                } else {
                /* found rio table, blk_id == 0x4752 */
-                       debug ("now enter io table ---\n");
-                       debug ("rio blk id: %x\n", blk_id);
+                       debug("now enter io table ---\n");
+                       debug("rio blk id: %x\n", blk_id);
 
                        rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL);
                        if (!rio_table_ptr) {
                                rc = -ENOMEM;
                                goto out;
                        }
-                       rio_table_ptr->ver_num = readb (io_mem + offset);
-                       rio_table_ptr->scal_count = readb (io_mem + offset + 1);
-                       rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
-                       rio_table_ptr->offset = offset +3 ;
+                       rio_table_ptr->ver_num = readb(io_mem + offset);
+                       rio_table_ptr->scal_count = readb(io_mem + offset + 1);
+                       rio_table_ptr->riodev_count = readb(io_mem + offset + 2);
+                       rio_table_ptr->offset = offset + 3 ;
 
                        debug("info about rio table hdr ---\n");
                        debug("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ",
@@ -390,28 +390,28 @@ int __init ibmphp_access_ebda (void)
 
        if (rio_table_ptr) {
                if (rio_complete && rio_table_ptr->ver_num == 3) {
-                       rc = ebda_rio_table ();
+                       rc = ebda_rio_table();
                        if (rc)
                                goto out;
                }
        }
-       rc = ebda_rsrc_controller ();
+       rc = ebda_rsrc_controller();
        if (rc)
                goto out;
 
-       rc = ebda_rsrc_rsrc ();
+       rc = ebda_rsrc_rsrc();
        goto out;
 error_nodev:
        rc = -ENODEV;
 out:
-       iounmap (io_mem);
+       iounmap(io_mem);
        return rc;
 }
 
 /*
  * map info of scalability details and rio details from physical address
  */
-static int __init ebda_rio_table (void)
+static int __init ebda_rio_table(void)
 {
        u16 offset;
        u8 i;
@@ -425,39 +425,39 @@ static int __init ebda_rio_table (void)
                rio_detail_ptr = kzalloc(sizeof(struct rio_detail), GFP_KERNEL);
                if (!rio_detail_ptr)
                        return -ENOMEM;
-               rio_detail_ptr->rio_node_id = readb (io_mem + offset);
-               rio_detail_ptr->bbar = readl (io_mem + offset + 1);
-               rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
-               rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
-               rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
-               rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
-               rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
-               rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
-               rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
-               rio_detail_ptr->status = readb (io_mem + offset + 12);
-               rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
-               rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
-//             debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
+               rio_detail_ptr->rio_node_id = readb(io_mem + offset);
+               rio_detail_ptr->bbar = readl(io_mem + offset + 1);
+               rio_detail_ptr->rio_type = readb(io_mem + offset + 5);
+               rio_detail_ptr->owner_id = readb(io_mem + offset + 6);
+               rio_detail_ptr->port0_node_connect = readb(io_mem + offset + 7);
+               rio_detail_ptr->port0_port_connect = readb(io_mem + offset + 8);
+               rio_detail_ptr->port1_node_connect = readb(io_mem + offset + 9);
+               rio_detail_ptr->port1_port_connect = readb(io_mem + offset + 10);
+               rio_detail_ptr->first_slot_num = readb(io_mem + offset + 11);
+               rio_detail_ptr->status = readb(io_mem + offset + 12);
+               rio_detail_ptr->wpindex = readb(io_mem + offset + 13);
+               rio_detail_ptr->chassis_num = readb(io_mem + offset + 14);
+//             debug("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
                //create linked list of chassis
                if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)
-                       list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
+                       list_add(&rio_detail_ptr->rio_detail_list, &rio_vg_head);
                //create linked list of expansion box
                else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)
-                       list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
+                       list_add(&rio_detail_ptr->rio_detail_list, &rio_lo_head);
                else
                        // not in my concern
-                       kfree (rio_detail_ptr);
+                       kfree(rio_detail_ptr);
                offset += 15;
        }
-       print_lo_info ();
-       print_vg_info ();
+       print_lo_info();
+       print_vg_info();
        return 0;
 }
 
 /*
  * reorganizing linked list of chassis
  */
-static struct opt_rio *search_opt_vg (u8 chassis_num)
+static struct opt_rio *search_opt_vg(u8 chassis_num)
 {
        struct opt_rio *ptr;
        list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
@@ -467,13 +467,13 @@ static struct opt_rio *search_opt_vg (u8 chassis_num)
        return NULL;
 }
 
-static int __init combine_wpg_for_chassis (void)
+static int __init combine_wpg_for_chassis(void)
 {
        struct opt_rio *opt_rio_ptr = NULL;
        struct rio_detail *rio_detail_ptr = NULL;
 
        list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) {
-               opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
+               opt_rio_ptr = search_opt_vg(rio_detail_ptr->chassis_num);
                if (!opt_rio_ptr) {
                        opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
                        if (!opt_rio_ptr)
@@ -482,20 +482,20 @@ static int __init combine_wpg_for_chassis (void)
                        opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
                        opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
                        opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
-                       list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
+                       list_add(&opt_rio_ptr->opt_rio_list, &opt_vg_head);
                } else {
-                       opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
-                       opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
+                       opt_rio_ptr->first_slot_num = min(opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
+                       opt_rio_ptr->middle_num = max(opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
                }
        }
-       print_opt_vg ();
+       print_opt_vg();
        return 0;
 }
 
 /*
  * reorganizing linked list of expansion box
  */
-static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
+static struct opt_rio_lo *search_opt_lo(u8 chassis_num)
 {
        struct opt_rio_lo *ptr;
        list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) {
@@ -505,13 +505,13 @@ static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
        return NULL;
 }
 
-static int combine_wpg_for_expansion (void)
+static int combine_wpg_for_expansion(void)
 {
        struct opt_rio_lo *opt_rio_lo_ptr = NULL;
        struct rio_detail *rio_detail_ptr = NULL;
 
        list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) {
-               opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
+               opt_rio_lo_ptr = search_opt_lo(rio_detail_ptr->chassis_num);
                if (!opt_rio_lo_ptr) {
                        opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
                        if (!opt_rio_lo_ptr)
@@ -522,10 +522,10 @@ static int combine_wpg_for_expansion (void)
                        opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
                        opt_rio_lo_ptr->pack_count = 1;
 
-                       list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
+                       list_add(&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
                } else {
-                       opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
-                       opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
+                       opt_rio_lo_ptr->first_slot_num = min(opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
+                       opt_rio_lo_ptr->middle_num = max(opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
                        opt_rio_lo_ptr->pack_count = 2;
                }
        }
@@ -538,7 +538,7 @@ static int combine_wpg_for_expansion (void)
  * Arguments: slot_num, 1st slot number of the chassis we think we are on,
  * var (0 = chassis, 1 = expansion box)
  */
-static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
+static int first_slot_num(u8 slot_num, u8 first_slot, u8 var)
 {
        struct opt_rio *opt_vg_ptr = NULL;
        struct opt_rio_lo *opt_lo_ptr = NULL;
@@ -562,25 +562,25 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
        return rc;
 }
 
-static struct opt_rio_lo *find_rxe_num (u8 slot_num)
+static struct opt_rio_lo *find_rxe_num(u8 slot_num)
 {
        struct opt_rio_lo *opt_lo_ptr;
 
        list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
                //check to see if this slot_num belongs to expansion box
-               if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
+               if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num(slot_num, opt_lo_ptr->first_slot_num, 1)))
                        return opt_lo_ptr;
        }
        return NULL;
 }
 
-static struct opt_rio *find_chassis_num (u8 slot_num)
+static struct opt_rio *find_chassis_num(u8 slot_num)
 {
        struct opt_rio *opt_vg_ptr;
 
        list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
                //check to see if this slot_num belongs to chassis
-               if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
+               if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num(slot_num, opt_vg_ptr->first_slot_num, 0)))
                        return opt_vg_ptr;
        }
        return NULL;
@@ -589,7 +589,7 @@ static struct opt_rio *find_chassis_num (u8 slot_num)
 /* This routine will find out how many slots are in the chassis, so that
  * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
  */
-static u8 calculate_first_slot (u8 slot_num)
+static u8 calculate_first_slot(u8 slot_num)
 {
        u8 first_slot = 1;
        struct slot *slot_cur;
@@ -606,7 +606,7 @@ static u8 calculate_first_slot (u8 slot_num)
 
 #define SLOT_NAME_SIZE 30
 
-static char *create_file_name (struct slot *slot_cur)
+static char *create_file_name(struct slot *slot_cur)
 {
        struct opt_rio *opt_vg_ptr = NULL;
        struct opt_rio_lo *opt_lo_ptr = NULL;
@@ -618,18 +618,18 @@ static char *create_file_name (struct slot *slot_cur)
        u8 flag = 0;
 
        if (!slot_cur) {
-               err ("Structure passed is empty\n");
+               err("Structure passed is empty\n");
                return NULL;
        }
 
        slot_num = slot_cur->number;
 
-       memset (str, 0, sizeof(str));
+       memset(str, 0, sizeof(str));
 
        if (rio_table_ptr) {
                if (rio_table_ptr->ver_num == 3) {
-                       opt_vg_ptr = find_chassis_num (slot_num);
-                       opt_lo_ptr = find_rxe_num (slot_num);
+                       opt_vg_ptr = find_chassis_num(slot_num);
+                       opt_lo_ptr = find_rxe_num(slot_num);
                }
        }
        if (opt_vg_ptr) {
@@ -662,7 +662,7 @@ static char *create_file_name (struct slot *slot_cur)
        }
        if (!flag) {
                if (slot_cur->ctrl->ctlr_type == 4) {
-                       first_slot = calculate_first_slot (slot_num);
+                       first_slot = calculate_first_slot(slot_num);
                        which = 1;
                } else {
                        which = 0;
@@ -698,7 +698,7 @@ static int fillslotinfo(struct hotplug_slot *hotplug_slot)
        hotplug_slot->info->latch_status = SLOT_LATCH(slot->status);
 
        // pci board - present:1 not:0
-       if (SLOT_PRESENT (slot->status))
+       if (SLOT_PRESENT(slot->status))
                hotplug_slot->info->adapter_status = 1;
        else
                hotplug_slot->info->adapter_status = 0;
@@ -729,7 +729,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        /* we don't want to actually remove the resources, since free_resources will do just that */
        ibmphp_unconfigure_card(&slot, -1);
 
-       kfree (slot);
+       kfree(slot);
 }
 
 static struct pci_driver ibmphp_driver;
@@ -739,7 +739,7 @@ static struct pci_driver ibmphp_driver;
  * each hpc from physical address to a list of hot plug controllers based on
  * hpc descriptors.
  */
-static int __init ebda_rsrc_controller (void)
+static int __init ebda_rsrc_controller(void)
 {
        u16 addr, addr_slot, addr_bus;
        u8 ctlr_id, temp, bus_index;
@@ -757,25 +757,25 @@ static int __init ebda_rsrc_controller (void)
        addr = hpc_list_ptr->phys_addr;
        for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
                bus_index = 1;
-               ctlr_id = readb (io_mem + addr);
+               ctlr_id = readb(io_mem + addr);
                addr += 1;
-               slot_num = readb (io_mem + addr);
+               slot_num = readb(io_mem + addr);
 
                addr += 1;
                addr_slot = addr;       /* offset of slot structure */
                addr += (slot_num * 4);
 
-               bus_num = readb (io_mem + addr);
+               bus_num = readb(io_mem + addr);
 
                addr += 1;
                addr_bus = addr;        /* offset of bus */
                addr += (bus_num * 9);  /* offset of ctlr_type */
-               temp = readb (io_mem + addr);
+               temp = readb(io_mem + addr);
 
                addr += 1;
                /* init hpc structure */
-               hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
-               if (!hpc_ptr ) {
+               hpc_ptr = alloc_ebda_hpc(slot_num, bus_num);
+               if (!hpc_ptr) {
                        rc = -ENOMEM;
                        goto error_no_hpc;
                }
@@ -783,23 +783,23 @@ static int __init ebda_rsrc_controller (void)
                hpc_ptr->ctlr_relative_id = ctlr;
                hpc_ptr->slot_count = slot_num;
                hpc_ptr->bus_count = bus_num;
-               debug ("now enter ctlr data structure ---\n");
-               debug ("ctlr id: %x\n", ctlr_id);
-               debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
-               debug ("count of slots controlled by this ctlr: %x\n", slot_num);
-               debug ("count of buses controlled by this ctlr: %x\n", bus_num);
+               debug("now enter ctlr data structure ---\n");
+               debug("ctlr id: %x\n", ctlr_id);
+               debug("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
+               debug("count of slots controlled by this ctlr: %x\n", slot_num);
+               debug("count of buses controlled by this ctlr: %x\n", bus_num);
 
                /* init slot structure, fetch slot, bus, cap... */
                slot_ptr = hpc_ptr->slots;
                for (slot = 0; slot < slot_num; slot++) {
-                       slot_ptr->slot_num = readb (io_mem + addr_slot);
-                       slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num);
-                       slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);
-                       slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num);
+                       slot_ptr->slot_num = readb(io_mem + addr_slot);
+                       slot_ptr->slot_bus_num = readb(io_mem + addr_slot + slot_num);
+                       slot_ptr->ctl_index = readb(io_mem + addr_slot + 2*slot_num);
+                       slot_ptr->slot_cap = readb(io_mem + addr_slot + 3*slot_num);
 
                        // create bus_info lined list --- if only one slot per bus: slot_min = slot_max
 
-                       bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
+                       bus_info_ptr2 = ibmphp_find_same_bus_num(slot_ptr->slot_bus_num);
                        if (!bus_info_ptr2) {
                                bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL);
                                if (!bus_info_ptr1) {
@@ -816,11 +816,11 @@ static int __init ebda_rsrc_controller (void)
 
                                bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
 
-                               list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);
+                               list_add_tail(&bus_info_ptr1->bus_info_list, &bus_info_head);
 
                        } else {
-                               bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num);
-                               bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num);
+                               bus_info_ptr2->slot_min = min(bus_info_ptr2->slot_min, slot_ptr->slot_num);
+                               bus_info_ptr2->slot_max = max(bus_info_ptr2->slot_max, slot_ptr->slot_num);
                                bus_info_ptr2->slot_count += 1;
 
                        }
@@ -834,17 +834,17 @@ static int __init ebda_rsrc_controller (void)
                /* init bus structure */
                bus_ptr = hpc_ptr->buses;
                for (bus = 0; bus < bus_num; bus++) {
-                       bus_ptr->bus_num = readb (io_mem + addr_bus + bus);
-                       bus_ptr->slots_at_33_conv = readb (io_mem + addr_bus + bus_num + 8 * bus);
-                       bus_ptr->slots_at_66_conv = readb (io_mem + addr_bus + bus_num + 8 * bus + 1);
+                       bus_ptr->bus_num = readb(io_mem + addr_bus + bus);
+                       bus_ptr->slots_at_33_conv = readb(io_mem + addr_bus + bus_num + 8 * bus);
+                       bus_ptr->slots_at_66_conv = readb(io_mem + addr_bus + bus_num + 8 * bus + 1);
 
-                       bus_ptr->slots_at_66_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 2);
+                       bus_ptr->slots_at_66_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 2);
 
-                       bus_ptr->slots_at_100_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 3);
+                       bus_ptr->slots_at_100_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 3);
 
-                       bus_ptr->slots_at_133_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 4);
+                       bus_ptr->slots_at_133_pcix = readb(io_mem + addr_bus + bus_num + 8 * bus + 4);
 
-                       bus_info_ptr2 = ibmphp_find_same_bus_num (bus_ptr->bus_num);
+                       bus_info_ptr2 = ibmphp_find_same_bus_num(bus_ptr->bus_num);
                        if (bus_info_ptr2) {
                                bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
                                bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
@@ -859,33 +859,33 @@ static int __init ebda_rsrc_controller (void)
 
                switch (hpc_ptr->ctlr_type) {
                        case 1:
-                               hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
-                               hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
-                               hpc_ptr->irq = readb (io_mem + addr + 2);
+                               hpc_ptr->u.pci_ctlr.bus = readb(io_mem + addr);
+                               hpc_ptr->u.pci_ctlr.dev_fun = readb(io_mem + addr + 1);
+                               hpc_ptr->irq = readb(io_mem + addr + 2);
                                addr += 3;
-                               debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",
+                               debug("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",
                                        hpc_ptr->u.pci_ctlr.bus,
                                        hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
                                break;
 
                        case 0:
-                               hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
-                               hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
-                               if (!request_region (hpc_ptr->u.isa_ctlr.io_start,
+                               hpc_ptr->u.isa_ctlr.io_start = readw(io_mem + addr);
+                               hpc_ptr->u.isa_ctlr.io_end = readw(io_mem + addr + 2);
+                               if (!request_region(hpc_ptr->u.isa_ctlr.io_start,
                                                     (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
                                                     "ibmphp")) {
                                        rc = -ENODEV;
                                        goto error_no_hp_slot;
                                }
-                               hpc_ptr->irq = readb (io_mem + addr + 4);
+                               hpc_ptr->irq = readb(io_mem + addr + 4);
                                addr += 5;
                                break;
 
                        case 2:
                        case 4:
-                               hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
-                               hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
-                               hpc_ptr->irq = readb (io_mem + addr + 5);
+                               hpc_ptr->u.wpeg_ctlr.wpegbbar = readl(io_mem + addr);
+                               hpc_ptr->u.wpeg_ctlr.i2c_addr = readb(io_mem + addr + 4);
+                               hpc_ptr->irq = readb(io_mem + addr + 5);
                                addr += 6;
                                break;
                        default:
@@ -894,8 +894,8 @@ static int __init ebda_rsrc_controller (void)
                }
 
                //reorganize chassis' linked list
-               combine_wpg_for_chassis ();
-               combine_wpg_for_expansion ();
+               combine_wpg_for_chassis();
+               combine_wpg_for_expansion();
                hpc_ptr->revision = 0xff;
                hpc_ptr->options = 0xff;
                hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
@@ -940,7 +940,7 @@ static int __init ebda_rsrc_controller (void)
 
                        tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
 
-                       bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
+                       bus_info_ptr1 = ibmphp_find_same_bus_num(hpc_ptr->slots[index].slot_bus_num);
                        if (!bus_info_ptr1) {
                                kfree(tmp_slot);
                                rc = -ENODEV;
@@ -961,18 +961,18 @@ static int __init ebda_rsrc_controller (void)
                        if (rc)
                                goto error;
 
-                       rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
+                       rc = ibmphp_init_devno((struct slot **) &hp_slot_ptr->private);
                        if (rc)
                                goto error;
                        hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
 
                        // end of registering ibm slot with hotplug core
 
-                       list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
+                       list_add(&((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
                }
 
-               print_bus_info ();
-               list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
+               print_bus_info();
+               list_add(&hpc_ptr->ebda_hpc_list, &ebda_hpc_head);
 
        }                       /* each hpc  */
 
@@ -982,20 +982,20 @@ static int __init ebda_rsrc_controller (void)
                        pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
        }
 
-       print_ebda_hpc ();
-       print_ibm_slot ();
+       print_ebda_hpc();
+       print_ibm_slot();
        return 0;
 
 error:
-       kfree (hp_slot_ptr->private);
+       kfree(hp_slot_ptr->private);
 error_no_slot:
-       kfree (hp_slot_ptr->info);
+       kfree(hp_slot_ptr->info);
 error_no_hp_info:
-       kfree (hp_slot_ptr);
+       kfree(hp_slot_ptr);
 error_no_hp_slot:
-       free_ebda_hpc (hpc_ptr);
+       free_ebda_hpc(hpc_ptr);
 error_no_hpc:
-       iounmap (io_mem);
+       iounmap(io_mem);
        return rc;
 }
 
@@ -1003,7 +1003,7 @@ error_no_hpc:
  * map info (bus, devfun, start addr, end addr..) of i/o, memory,
  * pfm from the physical addr to a list of resource.
  */
-static int __init ebda_rsrc_rsrc (void)
+static int __init ebda_rsrc_rsrc(void)
 {
        u16 addr;
        short rsrc;
@@ -1011,69 +1011,69 @@ static int __init ebda_rsrc_rsrc (void)
        struct ebda_pci_rsrc *rsrc_ptr;
 
        addr = rsrc_list_ptr->phys_addr;
-       debug ("now entering rsrc land\n");
-       debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
+       debug("now entering rsrc land\n");
+       debug("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
 
        for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
-               type = readb (io_mem + addr);
+               type = readb(io_mem + addr);
 
                addr += 1;
                rsrc_type = type & EBDA_RSRC_TYPE_MASK;
 
                if (rsrc_type == EBDA_IO_RSRC_TYPE) {
-                       rsrc_ptr = alloc_ebda_pci_rsrc ();
+                       rsrc_ptr = alloc_ebda_pci_rsrc();
                        if (!rsrc_ptr) {
-                               iounmap (io_mem);
+                               iounmap(io_mem);
                                return -ENOMEM;
                        }
                        rsrc_ptr->rsrc_type = type;
 
-                       rsrc_ptr->bus_num = readb (io_mem + addr);
-                       rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
-                       rsrc_ptr->start_addr = readw (io_mem + addr + 2);
-                       rsrc_ptr->end_addr = readw (io_mem + addr + 4);
+                       rsrc_ptr->bus_num = readb(io_mem + addr);
+                       rsrc_ptr->dev_fun = readb(io_mem + addr + 1);
+                       rsrc_ptr->start_addr = readw(io_mem + addr + 2);
+                       rsrc_ptr->end_addr = readw(io_mem + addr + 4);
                        addr += 6;
 
-                       debug ("rsrc from io type ----\n");
-                       debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
+                       debug("rsrc from io type ----\n");
+                       debug("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
                                rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
 
-                       list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
+                       list_add(&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
                }
 
                if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
-                       rsrc_ptr = alloc_ebda_pci_rsrc ();
-                       if (!rsrc_ptr ) {
-                               iounmap (io_mem);
+                       rsrc_ptr = alloc_ebda_pci_rsrc();
+                       if (!rsrc_ptr) {
+                               iounmap(io_mem);
                                return -ENOMEM;
                        }
                        rsrc_ptr->rsrc_type = type;
 
-                       rsrc_ptr->bus_num = readb (io_mem + addr);
-                       rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
-                       rsrc_ptr->start_addr = readl (io_mem + addr + 2);
-                       rsrc_ptr->end_addr = readl (io_mem + addr + 6);
+                       rsrc_ptr->bus_num = readb(io_mem + addr);
+                       rsrc_ptr->dev_fun = readb(io_mem + addr + 1);
+                       rsrc_ptr->start_addr = readl(io_mem + addr + 2);
+                       rsrc_ptr->end_addr = readl(io_mem + addr + 6);
                        addr += 10;
 
-                       debug ("rsrc from mem or pfm ---\n");
-                       debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
+                       debug("rsrc from mem or pfm ---\n");
+                       debug("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
                                rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
 
-                       list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
+                       list_add(&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
                }
        }
-       kfree (rsrc_list_ptr);
+       kfree(rsrc_list_ptr);
        rsrc_list_ptr = NULL;
-       print_ebda_pci_rsrc ();
+       print_ebda_pci_rsrc();
        return 0;
 }
 
-u16 ibmphp_get_total_controllers (void)
+u16 ibmphp_get_total_controllers(void)
 {
        return hpc_list_ptr->num_ctlrs;
 }
 
-struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
+struct slot *ibmphp_get_slot_from_physical_num(u8 physical_num)
 {
        struct slot *slot;
 
@@ -1090,7 +1090,7 @@ struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
  *     - the total number of the slots based on each bus
  *       (if only one slot per bus slot_min = slot_max )
  */
-struct bus_info *ibmphp_find_same_bus_num (u32 num)
+struct bus_info *ibmphp_find_same_bus_num(u32 num)
 {
        struct bus_info *ptr;
 
@@ -1104,7 +1104,7 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num)
 /*  Finding relative bus number, in order to map corresponding
  *  bus register
  */
-int ibmphp_get_bus_index (u8 num)
+int ibmphp_get_bus_index(u8 num)
 {
        struct bus_info *ptr;
 
@@ -1115,45 +1115,39 @@ int ibmphp_get_bus_index (u8 num)
        return -ENODEV;
 }
 
-void ibmphp_free_bus_info_queue (void)
+void ibmphp_free_bus_info_queue(void)
 {
-       struct bus_info *bus_info;
-       struct list_head *list;
-       struct list_head *next;
+       struct bus_info *bus_info, *next;
 
-       list_for_each_safe (list, next, &bus_info_head ) {
-               bus_info = list_entry (list, struct bus_info, bus_info_list);
+       list_for_each_entry_safe(bus_info, next, &bus_info_head,
+                                bus_info_list) {
                kfree (bus_info);
        }
 }
 
-void ibmphp_free_ebda_hpc_queue (void)
+void ibmphp_free_ebda_hpc_queue(void)
 {
-       struct controller *controller = NULL;
-       struct list_head *list;
-       struct list_head *next;
+       struct controller *controller = NULL, *next;
        int pci_flag = 0;
 
-       list_for_each_safe (list, next, &ebda_hpc_head) {
-               controller = list_entry (list, struct controller, ebda_hpc_list);
+       list_for_each_entry_safe(controller, next, &ebda_hpc_head,
+                                ebda_hpc_list) {
                if (controller->ctlr_type == 0)
-                       release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
+                       release_region(controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
                else if ((controller->ctlr_type == 1) && (!pci_flag)) {
                        ++pci_flag;
-                       pci_unregister_driver (&ibmphp_driver);
+                       pci_unregister_driver(&ibmphp_driver);
                }
-               free_ebda_hpc (controller);
+               free_ebda_hpc(controller);
        }
 }
 
-void ibmphp_free_ebda_pci_rsrc_queue (void)
+void ibmphp_free_ebda_pci_rsrc_queue(void)
 {
-       struct ebda_pci_rsrc *resource;
-       struct list_head *list;
-       struct list_head *next;
+       struct ebda_pci_rsrc *resource, *next;
 
-       list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) {
-               resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+       list_for_each_entry_safe(resource, next, &ibmphp_ebda_pci_rsrc_head,
+                                ebda_pci_rsrc_list) {
                kfree (resource);
                resource = NULL;
        }
@@ -1171,14 +1165,14 @@ static struct pci_device_id id_table[] = {
 
 MODULE_DEVICE_TABLE(pci, id_table);
 
-static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
+static int ibmphp_probe(struct pci_dev *, const struct pci_device_id *);
 static struct pci_driver ibmphp_driver = {
        .name           = "ibmphp",
        .id_table       = id_table,
        .probe          = ibmphp_probe,
 };
 
-int ibmphp_register_pci (void)
+int ibmphp_register_pci(void)
 {
        struct controller *ctrl;
        int rc = 0;
@@ -1191,18 +1185,18 @@ int ibmphp_register_pci (void)
        }
        return rc;
 }
-static int ibmphp_probe (struct pci_dev *dev, const struct pci_device_id *ids)
+static int ibmphp_probe(struct pci_dev *dev, const struct pci_device_id *ids)
 {
        struct controller *ctrl;
 
-       debug ("inside ibmphp_probe\n");
+       debug("inside ibmphp_probe\n");
 
        list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
                if (ctrl->ctlr_type == 1) {
                        if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
                                ctrl->ctrl_dev = dev;
-                               debug ("found device!!!\n");
-                               debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
+                               debug("found device!!!\n");
+                               debug("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
                                return 0;
                        }
                }
index 2208767..a6b458e 100644 (file)
@@ -40,7 +40,7 @@
 #include "ibmphp.h"
 
 static int to_debug = 0;
-#define debug_polling(fmt, arg...)     do { if (to_debug) debug (fmt, arg); } while (0)
+#define debug_polling(fmt, arg...)     do { if (to_debug) debug(fmt, arg); } while (0)
 
 //----------------------------------------------------------------------------
 // timeout values
@@ -110,16 +110,16 @@ static struct task_struct *ibmphp_poll_thread;
 //----------------------------------------------------------------------------
 // local function prototypes
 //----------------------------------------------------------------------------
-static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8);
-static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8);
-static u8 hpc_writecmdtoindex (u8, u8);
-static u8 hpc_readcmdtoindex (u8, u8);
-static void get_hpc_access (void);
-static void free_hpc_access (void);
+static u8 i2c_ctrl_read(struct controller *, void __iomem *, u8);
+static u8 i2c_ctrl_write(struct controller *, void __iomem *, u8, u8);
+static u8 hpc_writecmdtoindex(u8, u8);
+static u8 hpc_readcmdtoindex(u8, u8);
+static void get_hpc_access(void);
+static void free_hpc_access(void);
 static int poll_hpc(void *data);
-static int process_changeinstatus (struct slot *, struct slot *);
-static int process_changeinlatch (u8, u8, struct controller *);
-static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *);
+static int process_changeinstatus(struct slot *, struct slot *);
+static int process_changeinlatch(u8, u8, struct controller *);
+static int hpc_wait_ctlr_notworking(int, struct controller *, void __iomem *, u8 *);
 //----------------------------------------------------------------------------
 
 
@@ -128,16 +128,16 @@ static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u
 *
 * Action:  initialize semaphores and variables
 *---------------------------------------------------------------------*/
-void __init ibmphp_hpc_initvars (void)
+void __init ibmphp_hpc_initvars(void)
 {
-       debug ("%s - Entry\n", __func__);
+       debug("%s - Entry\n", __func__);
 
        mutex_init(&sem_hpcaccess);
        sema_init(&semOperations, 1);
        sema_init(&sem_exit, 0);
        to_debug = 0;
 
-       debug ("%s - Exit\n", __func__);
+       debug("%s - Exit\n", __func__);
 }
 
 /*----------------------------------------------------------------------
@@ -146,7 +146,7 @@ void __init ibmphp_hpc_initvars (void)
 * Action:  read from HPC over I2C
 *
 *---------------------------------------------------------------------*/
-static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
+static u8 i2c_ctrl_read(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
 {
        u8 status;
        int i;
@@ -155,7 +155,7 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
        unsigned long ultemp;
        unsigned long data;     // actual data HILO format
 
-       debug_polling ("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index);
+       debug_polling("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index);
 
        //--------------------------------------------------------------------
        // READ - step 1
@@ -178,28 +178,28 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
                ultemp = ultemp << 8;
                data |= ultemp;
        } else {
-               err ("this controller type is not supported \n");
+               err("this controller type is not supported \n");
                return HPC_ERROR;
        }
 
-       wpg_data = swab32 (data);       // swap data before writing
+       wpg_data = swab32(data);        // swap data before writing
        wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
-       writel (wpg_data, wpg_addr);
+       writel(wpg_data, wpg_addr);
 
        //--------------------------------------------------------------------
        // READ - step 2 : clear the message buffer
        data = 0x00000000;
-       wpg_data = swab32 (data);
+       wpg_data = swab32(data);
        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
-       writel (wpg_data, wpg_addr);
+       writel(wpg_data, wpg_addr);
 
        //--------------------------------------------------------------------
        // READ - step 3 : issue start operation, I2C master control bit 30:ON
        //                 2020 : [20] OR operation at [20] offset 0x20
        data = WPG_I2CMCNTL_STARTOP_MASK;
-       wpg_data = swab32 (data);
+       wpg_data = swab32(data);
        wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
-       writel (wpg_data, wpg_addr);
+       writel(wpg_data, wpg_addr);
 
        //--------------------------------------------------------------------
        // READ - step 4 : wait until start operation bit clears
@@ -207,14 +207,14 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
        while (i) {
                msleep(10);
                wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
-               wpg_data = readl (wpg_addr);
-               data = swab32 (wpg_data);
+               wpg_data = readl(wpg_addr);
+               data = swab32(wpg_data);
                if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
                        break;
                i--;
        }
        if (i == 0) {
-               debug ("%s - Error : WPG timeout\n", __func__);
+               debug("%s - Error : WPG timeout\n", __func__);
                return HPC_ERROR;
        }
        //--------------------------------------------------------------------
@@ -223,26 +223,26 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
        while (i) {
                msleep(10);
                wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
-               wpg_data = readl (wpg_addr);
-               data = swab32 (wpg_data);
-               if (HPC_I2CSTATUS_CHECK (data))
+               wpg_data = readl(wpg_addr);
+               data = swab32(wpg_data);
+               if (HPC_I2CSTATUS_CHECK(data))
                        break;
                i--;
        }
        if (i == 0) {
-               debug ("ctrl_read - Exit Error:I2C timeout\n");
+               debug("ctrl_read - Exit Error:I2C timeout\n");
                return HPC_ERROR;
        }
 
        //--------------------------------------------------------------------
        // READ - step 6 : get DATA
        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
-       wpg_data = readl (wpg_addr);
-       data = swab32 (wpg_data);
+       wpg_data = readl(wpg_addr);
+       data = swab32(wpg_data);
 
        status = (u8) data;
 
-       debug_polling ("%s - Exit index[%x] status[%x]\n", __func__, index, status);
+       debug_polling("%s - Exit index[%x] status[%x]\n", __func__, index, status);
 
        return (status);
 }
@@ -254,7 +254,7 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
 *
 * Return   0 or error codes
 *---------------------------------------------------------------------*/
-static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
+static u8 i2c_ctrl_write(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
 {
        u8 rc;
        void __iomem *wpg_addr; // base addr + offset
@@ -263,7 +263,7 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
        unsigned long data;     // actual data HILO format
        int i;
 
-       debug_polling ("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __func__, WPGBbar, index, cmd);
+       debug_polling("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __func__, WPGBbar, index, cmd);
 
        rc = 0;
        //--------------------------------------------------------------------
@@ -289,28 +289,28 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
                ultemp = ultemp << 8;
                data |= ultemp;
        } else {
-               err ("this controller type is not supported \n");
+               err("this controller type is not supported \n");
                return HPC_ERROR;
        }
 
-       wpg_data = swab32 (data);       // swap data before writing
+       wpg_data = swab32(data);        // swap data before writing
        wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
-       writel (wpg_data, wpg_addr);
+       writel(wpg_data, wpg_addr);
 
        //--------------------------------------------------------------------
        // WRITE - step 2 : clear the message buffer
        data = 0x00000000 | (unsigned long)cmd;
-       wpg_data = swab32 (data);
+       wpg_data = swab32(data);
        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
-       writel (wpg_data, wpg_addr);
+       writel(wpg_data, wpg_addr);
 
        //--------------------------------------------------------------------
        // WRITE - step 3 : issue start operation,I2C master control bit 30:ON
        //                 2020 : [20] OR operation at [20] offset 0x20
        data = WPG_I2CMCNTL_STARTOP_MASK;
-       wpg_data = swab32 (data);
+       wpg_data = swab32(data);
        wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
-       writel (wpg_data, wpg_addr);
+       writel(wpg_data, wpg_addr);
 
        //--------------------------------------------------------------------
        // WRITE - step 4 : wait until start operation bit clears
@@ -318,14 +318,14 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
        while (i) {
                msleep(10);
                wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
-               wpg_data = readl (wpg_addr);
-               data = swab32 (wpg_data);
+               wpg_data = readl(wpg_addr);
+               data = swab32(wpg_data);
                if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
                        break;
                i--;
        }
        if (i == 0) {
-               debug ("%s - Exit Error:WPG timeout\n", __func__);
+               debug("%s - Exit Error:WPG timeout\n", __func__);
                rc = HPC_ERROR;
        }
 
@@ -335,25 +335,25 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8
        while (i) {
                msleep(10);
                wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
-               wpg_data = readl (wpg_addr);
-               data = swab32 (wpg_data);
-               if (HPC_I2CSTATUS_CHECK (data))
+               wpg_data = readl(wpg_addr);
+               data = swab32(wpg_data);
+               if (HPC_I2CSTATUS_CHECK(data))
                        break;
                i--;
        }
        if (i == 0) {
-               debug ("ctrl_read - Error : I2C timeout\n");
+               debug("ctrl_read - Error : I2C timeout\n");
                rc = HPC_ERROR;
        }
 
-       debug_polling ("%s Exit rc[%x]\n", __func__, rc);
+       debug_polling("%s Exit rc[%x]\n", __func__, rc);
        return (rc);
 }
 
 //------------------------------------------------------------
 //  Read from ISA type HPC
 //------------------------------------------------------------
-static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
+static u8 isa_ctrl_read(struct controller *ctlr_ptr, u8 offset)
 {
        u16 start_address;
        u16 end_address;
@@ -361,56 +361,56 @@ static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
 
        start_address = ctlr_ptr->u.isa_ctlr.io_start;
        end_address = ctlr_ptr->u.isa_ctlr.io_end;
-       data = inb (start_address + offset);
+       data = inb(start_address + offset);
        return data;
 }
 
 //--------------------------------------------------------------
 // Write to ISA type HPC
 //--------------------------------------------------------------
-static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
+static void isa_ctrl_write(struct controller *ctlr_ptr, u8 offset, u8 data)
 {
        u16 start_address;
        u16 port_address;
 
        start_address = ctlr_ptr->u.isa_ctlr.io_start;
        port_address = start_address + (u16) offset;
-       outb (data, port_address);
+       outb(data, port_address);
 }
 
-static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
+static u8 pci_ctrl_read(struct controller *ctrl, u8 offset)
 {
        u8 data = 0x00;
-       debug ("inside pci_ctrl_read\n");
+       debug("inside pci_ctrl_read\n");
        if (ctrl->ctrl_dev)
-               pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
+               pci_read_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
        return data;
 }
 
-static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
+static u8 pci_ctrl_write(struct controller *ctrl, u8 offset, u8 data)
 {
        u8 rc = -ENODEV;
-       debug ("inside pci_ctrl_write\n");
+       debug("inside pci_ctrl_write\n");
        if (ctrl->ctrl_dev) {
-               pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
+               pci_write_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
                rc = 0;
        }
        return rc;
 }
 
-static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
+static u8 ctrl_read(struct controller *ctlr, void __iomem *base, u8 offset)
 {
        u8 rc;
        switch (ctlr->ctlr_type) {
        case 0:
-               rc = isa_ctrl_read (ctlr, offset);
+               rc = isa_ctrl_read(ctlr, offset);
                break;
        case 1:
-               rc = pci_ctrl_read (ctlr, offset);
+               rc = pci_ctrl_read(ctlr, offset);
                break;
        case 2:
        case 4:
-               rc = i2c_ctrl_read (ctlr, base, offset);
+               rc = i2c_ctrl_read(ctlr, base, offset);
                break;
        default:
                return -ENODEV;
@@ -418,7 +418,7 @@ static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
        return rc;
 }
 
-static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
+static u8 ctrl_write(struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
 {
        u8 rc = 0;
        switch (ctlr->ctlr_type) {
@@ -426,7 +426,7 @@ static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8
                isa_ctrl_write(ctlr, offset, data);
                break;
        case 1:
-               rc = pci_ctrl_write (ctlr, offset, data);
+               rc = pci_ctrl_write(ctlr, offset, data);
                break;
        case 2:
        case 4:
@@ -444,7 +444,7 @@ static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8
 *
 * Return   index, HPC_ERROR
 *---------------------------------------------------------------------*/
-static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
+static u8 hpc_writecmdtoindex(u8 cmd, u8 index)
 {
        u8 rc;
 
@@ -476,7 +476,7 @@ static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
                break;
 
        default:
-               err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
+               err("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
                rc = HPC_ERROR;
        }
 
@@ -490,7 +490,7 @@ static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
 *
 * Return   index, HPC_ERROR
 *---------------------------------------------------------------------*/
-static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
+static u8 hpc_readcmdtoindex(u8 cmd, u8 index)
 {
        u8 rc;
 
@@ -533,78 +533,77 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
 *
 * Return   0 or error codes
 *---------------------------------------------------------------------*/
-int ibmphp_hpc_readslot (struct slot *pslot, u8 cmd, u8 *pstatus)
+int ibmphp_hpc_readslot(struct slot *pslot, u8 cmd, u8 *pstatus)
 {
        void __iomem *wpg_bbar = NULL;
        struct controller *ctlr_ptr;
-       struct list_head *pslotlist;
        u8 index, status;
        int rc = 0;
        int busindex;
 
-       debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus);
+       debug_polling("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus);
 
        if ((pslot == NULL)
            || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
                rc = -EINVAL;
-               err ("%s - Error invalid pointer, rc[%d]\n", __func__, rc);
+               err("%s - Error invalid pointer, rc[%d]\n", __func__, rc);
                return rc;
        }
 
        if (cmd == READ_BUSSTATUS) {
-               busindex = ibmphp_get_bus_index (pslot->bus);
+               busindex = ibmphp_get_bus_index(pslot->bus);
                if (busindex < 0) {
                        rc = -EINVAL;
-                       err ("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
+                       err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
                        return rc;
                } else
                        index = (u8) busindex;
        } else
                index = pslot->ctlr_index;
 
-       index = hpc_readcmdtoindex (cmd, index);
+       index = hpc_readcmdtoindex(cmd, index);
 
        if (index == HPC_ERROR) {
                rc = -EINVAL;
-               err ("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc);
+               err("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc);
                return rc;
        }
 
        ctlr_ptr = pslot->ctrl;
 
-       get_hpc_access ();
+       get_hpc_access();
 
        //--------------------------------------------------------------------
        // map physical address to logical address
        //--------------------------------------------------------------------
        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-               wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+               wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 
        //--------------------------------------------------------------------
        // check controller status before reading
        //--------------------------------------------------------------------
-       rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
+       rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
        if (!rc) {
                switch (cmd) {
                case READ_ALLSTAT:
                        // update the slot structure
                        pslot->ctrl->status = status;
-                       pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
-                       rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
+                       pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
+                       rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
                                                       &status);
                        if (!rc)
-                               pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
+                               pslot->ext_status = ctrl_read(ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
 
                        break;
 
                case READ_SLOTSTATUS:
                        // DO NOT update the slot structure
-                       *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+                       *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
                        break;
 
                case READ_EXTSLOTSTATUS:
                        // DO NOT update the slot structure
-                       *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+                       *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
                        break;
 
                case READ_CTLRSTATUS:
@@ -613,36 +612,36 @@ int ibmphp_hpc_readslot (struct slot *pslot, u8 cmd, u8 *pstatus)
                        break;
 
                case READ_BUSSTATUS:
-                       pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+                       pslot->busstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
                        break;
                case READ_REVLEVEL:
-                       *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+                       *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
                        break;
                case READ_HPCOPTIONS:
-                       *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+                       *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
                        break;
                case READ_SLOTLATCHLOWREG:
                        // DO NOT update the slot structure
-                       *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+                       *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
                        break;
 
                        // Not used
                case READ_ALLSLOT:
-                       list_for_each (pslotlist, &ibmphp_slot_head) {
-                               pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+                       list_for_each_entry(pslot, &ibmphp_slot_head,
+                                           ibm_slot_list) {
                                index = pslot->ctlr_index;
-                               rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
+                               rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr,
                                                                wpg_bbar, &status);
                                if (!rc) {
-                                       pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
-                                       rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
+                                       pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
+                                       rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT,
                                                                        ctlr_ptr, wpg_bbar, &status);
                                        if (!rc)
                                                pslot->ext_status =
-                                                   ctrl_read (ctlr_ptr, wpg_bbar,
+                                                   ctrl_read(ctlr_ptr, wpg_bbar,
                                                                index + WPG_1ST_EXTSLOT_INDEX);
                                } else {
-                                       err ("%s - Error ctrl_read failed\n", __func__);
+                                       err("%s - Error ctrl_read failed\n", __func__);
                                        rc = -EINVAL;
                                        break;
                                }
@@ -659,11 +658,11 @@ int ibmphp_hpc_readslot (struct slot *pslot, u8 cmd, u8 *pstatus)
 
        // remove physical to logical address mapping
        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-               iounmap (wpg_bbar);
+               iounmap(wpg_bbar);
 
-       free_hpc_access ();
+       free_hpc_access();
 
-       debug_polling ("%s - Exit rc[%d]\n", __func__, rc);
+       debug_polling("%s - Exit rc[%d]\n", __func__, rc);
        return rc;
 }
 
@@ -672,7 +671,7 @@ int ibmphp_hpc_readslot (struct slot *pslot, u8 cmd, u8 *pstatus)
 *
 * Action: issue a WRITE command to HPC
 *---------------------------------------------------------------------*/
-int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)
+int ibmphp_hpc_writeslot(struct slot *pslot, u8 cmd)
 {
        void __iomem *wpg_bbar = NULL;
        struct controller *ctlr_ptr;
@@ -682,55 +681,55 @@ int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)
        int rc = 0;
        int timeout;
 
-       debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd);
+       debug_polling("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd);
        if (pslot == NULL) {
                rc = -EINVAL;
-               err ("%s - Error Exit rc[%d]\n", __func__, rc);
+               err("%s - Error Exit rc[%d]\n", __func__, rc);
                return rc;
        }
 
        if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
                (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
                (cmd == HPC_BUS_133PCIXMODE)) {
-               busindex = ibmphp_get_bus_index (pslot->bus);
+               busindex = ibmphp_get_bus_index(pslot->bus);
                if (busindex < 0) {
                        rc = -EINVAL;
-                       err ("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
+                       err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
                        return rc;
                } else
                        index = (u8) busindex;
        } else
                index = pslot->ctlr_index;
 
-       index = hpc_writecmdtoindex (cmd, index);
+       index = hpc_writecmdtoindex(cmd, index);
 
        if (index == HPC_ERROR) {
                rc = -EINVAL;
-               err ("%s - Error Exit rc[%d]\n", __func__, rc);
+               err("%s - Error Exit rc[%d]\n", __func__, rc);
                return rc;
        }
 
        ctlr_ptr = pslot->ctrl;
 
-       get_hpc_access ();
+       get_hpc_access();
 
        //--------------------------------------------------------------------
        // map physical address to logical address
        //--------------------------------------------------------------------
        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
-               wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+               wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 
-               debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__,
+               debug("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__,
                ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
                ctlr_ptr->u.wpeg_ctlr.i2c_addr);
        }
        //--------------------------------------------------------------------
        // check controller status before writing
        //--------------------------------------------------------------------
-       rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
+       rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
        if (!rc) {
 
-               ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
+               ctrl_write(ctlr_ptr, wpg_bbar, index, cmd);
 
                //--------------------------------------------------------------------
                // check controller is still not working on the command
@@ -738,11 +737,11 @@ int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)
                timeout = CMD_COMPLETE_TOUT_SEC;
                done = 0;
                while (!done) {
-                       rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
+                       rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
                                                        &status);
                        if (!rc) {
-                               if (NEEDTOCHECK_CMDSTATUS (cmd)) {
-                                       if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
+                               if (NEEDTOCHECK_CMDSTATUS(cmd)) {
+                                       if (CTLR_FINISHED(status) == HPC_CTLR_FINISHED_YES)
                                                done = 1;
                                } else
                                        done = 1;
@@ -751,7 +750,7 @@ int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)
                                msleep(1000);
                                if (timeout < 1) {
                                        done = 1;
-                                       err ("%s - Error command complete timeout\n", __func__);
+                                       err("%s - Error command complete timeout\n", __func__);
                                        rc = -EFAULT;
                                } else
                                        timeout--;
@@ -763,10 +762,10 @@ int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)
 
        // remove physical to logical address mapping
        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-               iounmap (wpg_bbar);
-       free_hpc_access ();
+               iounmap(wpg_bbar);
+       free_hpc_access();
 
-       debug_polling ("%s - Exit rc[%d]\n", __func__, rc);
+       debug_polling("%s - Exit rc[%d]\n", __func__, rc);
        return rc;
 }
 
@@ -775,7 +774,7 @@ int ibmphp_hpc_writeslot (struct slot *pslot, u8 cmd)
 *
 * Action: make sure only one process can access HPC at one time
 *---------------------------------------------------------------------*/
-static void get_hpc_access (void)
+static void get_hpc_access(void)
 {
        mutex_lock(&sem_hpcaccess);
 }
@@ -783,7 +782,7 @@ static void get_hpc_access (void)
 /*----------------------------------------------------------------------
 * Name:    free_hpc_access()
 *---------------------------------------------------------------------*/
-void free_hpc_access (void)
+void free_hpc_access(void)
 {
        mutex_unlock(&sem_hpcaccess);
 }
@@ -793,21 +792,21 @@ void free_hpc_access (void)
 *
 * Action: make sure only one process can change the data structure
 *---------------------------------------------------------------------*/
-void ibmphp_lock_operations (void)
+void ibmphp_lock_operations(void)
 {
-       down (&semOperations);
+       down(&semOperations);
        to_debug = 1;
 }
 
 /*----------------------------------------------------------------------
 * Name:    ibmphp_unlock_operations()
 *---------------------------------------------------------------------*/
-void ibmphp_unlock_operations (void)
+void ibmphp_unlock_operations(void)
 {
-       debug ("%s - Entry\n", __func__);
-       up (&semOperations);
+       debug("%s - Entry\n", __func__);
+       up(&semOperations);
        to_debug = 0;
-       debug ("%s - Exit\n", __func__);
+       debug("%s - Exit\n", __func__);
 }
 
 /*----------------------------------------------------------------------
@@ -820,7 +819,6 @@ static int poll_hpc(void *data)
 {
        struct slot myslot;
        struct slot *pslot = NULL;
-       struct list_head *pslotlist;
        int rc;
        int poll_state = POLL_LATCH_REGISTER;
        u8 oldlatchlow = 0x00;
@@ -828,28 +826,28 @@ static int poll_hpc(void *data)
        int poll_count = 0;
        u8 ctrl_count = 0x00;
 
-       debug ("%s - Entry\n", __func__);
+       debug("%s - Entry\n", __func__);
 
        while (!kthread_should_stop()) {
                /* try to get the lock to do some kind of hardware access */
-               down (&semOperations);
+               down(&semOperations);
 
                switch (poll_state) {
                case POLL_LATCH_REGISTER:
                        oldlatchlow = curlatchlow;
                        ctrl_count = 0x00;
-                       list_for_each (pslotlist, &ibmphp_slot_head) {
+                       list_for_each_entry(pslot, &ibmphp_slot_head,
+                                           ibm_slot_list) {
                                if (ctrl_count >= ibmphp_get_total_controllers())
                                        break;
-                               pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
                                        ctrl_count++;
-                                       if (READ_SLOT_LATCH (pslot->ctrl)) {
-                                               rc = ibmphp_hpc_readslot (pslot,
+                                       if (READ_SLOT_LATCH(pslot->ctrl)) {
+                                               rc = ibmphp_hpc_readslot(pslot,
                                                                          READ_SLOTLATCHLOWREG,
                                                                          &curlatchlow);
                                                if (oldlatchlow != curlatchlow)
-                                                       process_changeinlatch (oldlatchlow,
+                                                       process_changeinlatch(oldlatchlow,
                                                                               curlatchlow,
                                                                               pslot->ctrl);
                                        }
@@ -859,25 +857,25 @@ static int poll_hpc(void *data)
                        poll_state = POLL_SLEEP;
                        break;
                case POLL_SLOTS:
-                       list_for_each (pslotlist, &ibmphp_slot_head) {
-                               pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+                       list_for_each_entry(pslot, &ibmphp_slot_head,
+                                           ibm_slot_list) {
                                // make a copy of the old status
-                               memcpy ((void *) &myslot, (void *) pslot,
-                                       sizeof (struct slot));
-                               rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+                               memcpy((void *) &myslot, (void *) pslot,
+                                       sizeof(struct slot));
+                               rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
                                if ((myslot.status != pslot->status)
                                    || (myslot.ext_status != pslot->ext_status))
-                                       process_changeinstatus (pslot, &myslot);
+                                       process_changeinstatus(pslot, &myslot);
                        }
                        ctrl_count = 0x00;
-                       list_for_each (pslotlist, &ibmphp_slot_head) {
+                       list_for_each_entry(pslot, &ibmphp_slot_head,
+                                           ibm_slot_list) {
                                if (ctrl_count >= ibmphp_get_total_controllers())
                                        break;
-                               pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
                                        ctrl_count++;
-                                       if (READ_SLOT_LATCH (pslot->ctrl))
-                                               rc = ibmphp_hpc_readslot (pslot,
+                                       if (READ_SLOT_LATCH(pslot->ctrl))
+                                               rc = ibmphp_hpc_readslot(pslot,
                                                                          READ_SLOTLATCHLOWREG,
                                                                          &curlatchlow);
                                }
@@ -887,13 +885,13 @@ static int poll_hpc(void *data)
                        break;
                case POLL_SLEEP:
                        /* don't sleep with a lock on the hardware */
-                       up (&semOperations);
+                       up(&semOperations);
                        msleep(POLL_INTERVAL_SEC * 1000);
 
                        if (kthread_should_stop())
                                goto out_sleep;
 
-                       down (&semOperations);
+                       down(&semOperations);
 
                        if (poll_count >= POLL_LATCH_CNT) {
                                poll_count = 0;
@@ -903,13 +901,13 @@ static int poll_hpc(void *data)
                        break;
                }
                /* give up the hardware semaphore */
-               up (&semOperations);
+               up(&semOperations);
                /* sleep for a short time just for good measure */
 out_sleep:
                msleep(100);
        }
-       up (&sem_exit);
-       debug ("%s - Exit\n", __func__);
+       up(&sem_exit);
+       debug("%s - Exit\n", __func__);
        return 0;
 }
 
@@ -929,14 +927,14 @@ out_sleep:
 *
 * Notes:
 *---------------------------------------------------------------------*/
-static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
+static int process_changeinstatus(struct slot *pslot, struct slot *poldslot)
 {
        u8 status;
        int rc = 0;
        u8 disable = 0;
        u8 update = 0;
 
-       debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
+       debug("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
 
        // bit 0 - HPC_SLOT_POWER
        if ((pslot->status & 0x01) != (poldslot->status & 0x01))
@@ -958,7 +956,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
        // bit 5 - HPC_SLOT_PWRGD
        if ((pslot->status & 0x20) != (poldslot->status & 0x20))
                // OFF -> ON: ignore, ON -> OFF: disable slot
-               if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status)))
+               if ((poldslot->status & 0x20) && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status)))
                        disable = 1;
 
        // bit 6 - HPC_SLOT_BUS_SPEED
@@ -969,20 +967,20 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
                update = 1;
                // OPEN -> CLOSE
                if (pslot->status & 0x80) {
-                       if (SLOT_PWRGD (pslot->status)) {
+                       if (SLOT_PWRGD(pslot->status)) {
                                // power goes on and off after closing latch
                                // check again to make sure power is still ON
                                msleep(1000);
-                               rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
-                               if (SLOT_PWRGD (status))
+                               rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &status);
+                               if (SLOT_PWRGD(status))
                                        update = 1;
                                else    // overwrite power in pslot to OFF
                                        pslot->status &= ~HPC_SLOT_POWER;
                        }
                }
                // CLOSE -> OPEN
-               else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
-                       && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
+               else if ((SLOT_PWRGD(poldslot->status) == HPC_SLOT_PWRGD_GOOD)
+                       && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status))) {
                        disable = 1;
                }
                // else - ignore
@@ -992,15 +990,15 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
                update = 1;
 
        if (disable) {
-               debug ("process_changeinstatus - disable slot\n");
+               debug("process_changeinstatus - disable slot\n");
                pslot->flag = 0;
-               rc = ibmphp_do_disable_slot (pslot);
+               rc = ibmphp_do_disable_slot(pslot);
        }
 
        if (update || disable)
-               ibmphp_update_slot_info (pslot);
+               ibmphp_update_slot_info(pslot);
 
-       debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);
+       debug("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);
 
        return rc;
 }
@@ -1015,32 +1013,32 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
 * Return   0 or error codes
 * Value:
 *---------------------------------------------------------------------*/
-static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
+static int process_changeinlatch(u8 old, u8 new, struct controller *ctrl)
 {
        struct slot myslot, *pslot;
        u8 i;
        u8 mask;
        int rc = 0;
 
-       debug ("%s - Entry old[%x], new[%x]\n", __func__, old, new);
+       debug("%s - Entry old[%x], new[%x]\n", __func__, old, new);
        // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
 
        for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
                mask = 0x01 << i;
                if ((mask & old) != (mask & new)) {
-                       pslot = ibmphp_get_slot_from_physical_num (i);
+                       pslot = ibmphp_get_slot_from_physical_num(i);
                        if (pslot) {
-                               memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-                               rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
-                               debug ("%s - call process_changeinstatus for slot[%d]\n", __func__, i);
-                               process_changeinstatus (pslot, &myslot);
+                               memcpy((void *) &myslot, (void *) pslot, sizeof(struct slot));
+                               rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
+                               debug("%s - call process_changeinstatus for slot[%d]\n", __func__, i);
+                               process_changeinstatus(pslot, &myslot);
                        } else {
                                rc = -EINVAL;
-                               err ("%s - Error bad pointer for slot[%d]\n", __func__, i);
+                               err("%s - Error bad pointer for slot[%d]\n", __func__, i);
                        }
                }
        }
-       debug ("%s - Exit rc[%d]\n", __func__, rc);
+       debug("%s - Exit rc[%d]\n", __func__, rc);
        return rc;
 }
 
@@ -1049,13 +1047,13 @@ static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
 *
 * Action:  start polling thread
 *---------------------------------------------------------------------*/
-int __init ibmphp_hpc_start_poll_thread (void)
+int __init ibmphp_hpc_start_poll_thread(void)
 {
-       debug ("%s - Entry\n", __func__);
+       debug("%s - Entry\n", __func__);
 
        ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll");
        if (IS_ERR(ibmphp_poll_thread)) {
-               err ("%s - Error, thread not started\n", __func__);
+               err("%s - Error, thread not started\n", __func__);
                return PTR_ERR(ibmphp_poll_thread);
        }
        return 0;
@@ -1066,30 +1064,30 @@ int __init ibmphp_hpc_start_poll_thread (void)
 *
 * Action:  stop polling thread and cleanup
 *---------------------------------------------------------------------*/
-void __exit ibmphp_hpc_stop_poll_thread (void)
+void __exit ibmphp_hpc_stop_poll_thread(void)
 {
-       debug ("%s - Entry\n", __func__);
+       debug("%s - Entry\n", __func__);
 
        kthread_stop(ibmphp_poll_thread);
-       debug ("before locking operations \n");
-       ibmphp_lock_operations ();
-       debug ("after locking operations \n");
+       debug("before locking operations\n");
+       ibmphp_lock_operations();
+       debug("after locking operations\n");
 
        // wait for poll thread to exit
-       debug ("before sem_exit down \n");
-       down (&sem_exit);
-       debug ("after sem_exit down \n");
+       debug("before sem_exit down\n");
+       down(&sem_exit);
+       debug("after sem_exit down\n");
 
        // cleanup
-       debug ("before free_hpc_access \n");
-       free_hpc_access ();
-       debug ("after free_hpc_access \n");
-       ibmphp_unlock_operations ();
-       debug ("after unlock operations \n");
-       up (&sem_exit);
-       debug ("after sem exit up\n");
-
-       debug ("%s - Exit\n", __func__);
+       debug("before free_hpc_access\n");
+       free_hpc_access();
+       debug("after free_hpc_access\n");
+       ibmphp_unlock_operations();
+       debug("after unlock operations\n");
+       up(&sem_exit);
+       debug("after sem exit up\n");
+
+       debug("%s - Exit\n", __func__);
 }
 
 /*----------------------------------------------------------------------
@@ -1100,32 +1098,32 @@ void __exit ibmphp_hpc_stop_poll_thread (void)
 * Return   0, HPC_ERROR
 * Value:
 *---------------------------------------------------------------------*/
-static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
+static int hpc_wait_ctlr_notworking(int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
                                    u8 *pstatus)
 {
        int rc = 0;
        u8 done = 0;
 
-       debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
+       debug_polling("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
 
        while (!done) {
-               *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
+               *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
                if (*pstatus == HPC_ERROR) {
                        rc = HPC_ERROR;
                        done = 1;
                }
-               if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
+               if (CTLR_WORKING(*pstatus) == HPC_CTLR_WORKING_NO)
                        done = 1;
                if (!done) {
                        msleep(1000);
                        if (timeout < 1) {
                                done = 1;
-                               err ("HPCreadslot - Error ctlr timeout\n");
+                               err("HPCreadslot - Error ctlr timeout\n");
                                rc = HPC_ERROR;
                        } else
                                timeout--;
                }
        }
-       debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
+       debug_polling("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
        return rc;
 }
index 814cea2..dc1876f 100644 (file)
@@ -37,8 +37,8 @@
 static int configure_device(struct pci_func *);
 static int configure_bridge(struct pci_func **, u8);
 static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
-static int add_new_bus (struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
-static u8 find_sec_number (u8 primary_busno, u8 slotno);
+static int add_new_bus(struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
+static u8 find_sec_number(u8 primary_busno, u8 slotno);
 
 /*
  * NOTE..... If BIOS doesn't provide default routing, we assign:
@@ -47,7 +47,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno);
  * We also assign the same irq numbers for multi function devices.
  * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
  */
-static void assign_alt_irq (struct pci_func *cur_func, u8 class_code)
+static void assign_alt_irq(struct pci_func *cur_func, u8 class_code)
 {
        int j;
        for (j = 0; j < 4; j++) {
@@ -78,7 +78,7 @@ static void assign_alt_irq (struct pci_func *cur_func, u8 class_code)
  * if there is an error, will need to go through all previous functions and
  * unconfigure....or can add some code into unconfigure_card....
  */
-int ibmphp_configure_card (struct pci_func *func, u8 slotno)
+int ibmphp_configure_card(struct pci_func *func, u8 slotno)
 {
        u16 vendor_id;
        u32 class;
@@ -92,7 +92,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
        u8 flag;
        u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
 
-       debug ("inside configure_card, func->busno = %x\n", func->busno);
+       debug("inside configure_card, func->busno = %x\n", func->busno);
 
        device = func->device;
        cur_func = func;
@@ -109,15 +109,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
 
                cur_func->function = function;
 
-               debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->function = %x\n",
+               debug("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->function = %x\n",
                        cur_func->busno, cur_func->device, cur_func->function);
 
-               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
 
-               debug ("vendor_id is %x\n", vendor_id);
+               debug("vendor_id is %x\n", vendor_id);
                if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
                        /* found correct device!!! */
-                       debug ("found valid device, vendor_id = %x\n", vendor_id);
+                       debug("found valid device, vendor_id = %x\n", vendor_id);
 
                        ++valid_device;
 
@@ -126,29 +126,29 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                         *         |_=> 0 = single function device, 1 = multi-function device
                         */
 
-                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-                       pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+                       pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
 
                        class_code = class >> 24;
-                       debug ("hrd_type = %x, class = %x, class_code %x\n", hdr_type, class, class_code);
+                       debug("hrd_type = %x, class = %x, class_code %x\n", hdr_type, class, class_code);
                        class >>= 8;    /* to take revision out, class = class.subclass.prog i/f */
                        if (class == PCI_CLASS_NOT_DEFINED_VGA) {
-                               err ("The device %x is VGA compatible and as is not supported for hot plugging. "
+                               err("The device %x is VGA compatible and as is not supported for hot plugging. "
                                     "Please choose another device.\n", cur_func->device);
                                return -ENODEV;
                        } else if (class == PCI_CLASS_DISPLAY_VGA) {
-                               err ("The device %x is not supported for hot plugging. Please choose another device.\n",
+                               err("The device %x is not supported for hot plugging. Please choose another device.\n",
                                     cur_func->device);
                                return -ENODEV;
                        }
                        switch (hdr_type) {
                                case PCI_HEADER_TYPE_NORMAL:
-                                       debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
-                                       assign_alt_irq (cur_func, class_code);
+                                       debug("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
+                                       assign_alt_irq(cur_func, class_code);
                                        rc = configure_device(cur_func);
                                        if (rc < 0) {
                                                /* We need to do this in case some other BARs were properly inserted */
-                                               err ("was not able to configure devfunc %x on bus %x.\n",
+                                               err("was not able to configure devfunc %x on bus %x.\n",
                                                     cur_func->device, cur_func->busno);
                                                cleanup_count = 6;
                                                goto error;
@@ -157,18 +157,18 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                        function = 0x8;
                                        break;
                                case PCI_HEADER_TYPE_MULTIDEVICE:
-                                       assign_alt_irq (cur_func, class_code);
+                                       assign_alt_irq(cur_func, class_code);
                                        rc = configure_device(cur_func);
                                        if (rc < 0) {
                                                /* We need to do this in case some other BARs were properly inserted */
-                                               err ("was not able to configure devfunc %x on bus %x...bailing out\n",
+                                               err("was not able to configure devfunc %x on bus %x...bailing out\n",
                                                     cur_func->device, cur_func->busno);
                                                cleanup_count = 6;
                                                goto error;
                                        }
                                        newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                        if (!newfunc) {
-                                               err ("out of system memory\n");
+                                               err("out of system memory\n");
                                                return -ENOMEM;
                                        }
                                        newfunc->busno = cur_func->busno;
@@ -181,32 +181,32 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                case PCI_HEADER_TYPE_MULTIBRIDGE:
                                        class >>= 8;
                                        if (class != PCI_CLASS_BRIDGE_PCI) {
-                                               err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n",
+                                               err("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n",
                                                     cur_func->device);
                                                return -ENODEV;
                                        }
-                                       assign_alt_irq (cur_func, class_code);
-                                       rc = configure_bridge (&cur_func, slotno);
+                                       assign_alt_irq(cur_func, class_code);
+                                       rc = configure_bridge(&cur_func, slotno);
                                        if (rc == -ENODEV) {
-                                               err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
-                                               err ("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
+                                               err("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
+                                               err("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
                                                return rc;
                                        }
                                        if (rc) {
                                                /* We need to do this in case some other BARs were properly inserted */
-                                               err ("was not able to hot-add PPB properly.\n");
+                                               err("was not able to hot-add PPB properly.\n");
                                                func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
                                                cleanup_count = 2;
                                                goto error;
                                        }
 
-                                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+                                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
                                        flag = 0;
                                        for (i = 0; i < 32; i++) {
                                                if (func->devices[i]) {
                                                        newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                                        if (!newfunc) {
-                                                               err ("out of system memory\n");
+                                                               err("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
                                                        newfunc->busno = sec_number;
@@ -220,7 +220,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                                        } else
                                                                cur_func->next = newfunc;
 
-                                                       rc = ibmphp_configure_card (newfunc, slotno);
+                                                       rc = ibmphp_configure_card(newfunc, slotno);
                                                        /* This could only happen if kmalloc failed */
                                                        if (rc) {
                                                                /* We need to do this in case bridge itself got configured properly, but devices behind it failed */
@@ -234,53 +234,53 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
 
                                        newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                        if (!newfunc) {
-                                               err ("out of system memory\n");
+                                               err("out of system memory\n");
                                                return -ENOMEM;
                                        }
                                        newfunc->busno = cur_func->busno;
                                        newfunc->device = device;
                                        for (j = 0; j < 4; j++)
                                                newfunc->irq[j] = cur_func->irq[j];
-                                       for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+                                       for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next);
                                        prev_func->next = newfunc;
                                        cur_func = newfunc;
                                        break;
                                case PCI_HEADER_TYPE_BRIDGE:
                                        class >>= 8;
-                                       debug ("class now is %x\n", class);
+                                       debug("class now is %x\n", class);
                                        if (class != PCI_CLASS_BRIDGE_PCI) {
-                                               err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n",
+                                               err("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging.  Please insert another card.\n",
                                                     cur_func->device);
                                                return -ENODEV;
                                        }
 
-                                       assign_alt_irq (cur_func, class_code);
+                                       assign_alt_irq(cur_func, class_code);
 
-                                       debug ("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
-                                       rc = configure_bridge (&cur_func, slotno);
+                                       debug("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
+                                       rc = configure_bridge(&cur_func, slotno);
                                        if (rc == -ENODEV) {
-                                               err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
-                                               err ("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
+                                               err("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
+                                               err("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
                                                return rc;
                                        }
                                        if (rc) {
                                                /* We need to do this in case some other BARs were properly inserted */
                                                func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
-                                               err ("was not able to hot-add PPB properly.\n");
+                                               err("was not able to hot-add PPB properly.\n");
                                                cleanup_count = 2;
                                                goto error;
                                        }
-                                       debug ("cur_func->busno = %x, device = %x, function = %x\n",
+                                       debug("cur_func->busno = %x, device = %x, function = %x\n",
                                                cur_func->busno, device, function);
-                                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-                                       debug ("after configuring bridge..., sec_number = %x\n", sec_number);
+                                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+                                       debug("after configuring bridge..., sec_number = %x\n", sec_number);
                                        flag = 0;
                                        for (i = 0; i < 32; i++) {
                                                if (func->devices[i]) {
-                                                       debug ("inside for loop, device is %x\n", i);
+                                                       debug("inside for loop, device is %x\n", i);
                                                        newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                                        if (!newfunc) {
-                                                               err (" out of system memory\n");
+                                                               err(" out of system memory\n");
                                                                return -ENOMEM;
                                                        }
                                                        newfunc->busno = sec_number;
@@ -289,12 +289,12 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                                                newfunc->irq[j] = cur_func->irq[j];
 
                                                        if (flag) {
-                                                               for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+                                                               for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next);
                                                                prev_func->next = newfunc;
                                                        } else
                                                                cur_func->next = newfunc;
 
-                                                       rc = ibmphp_configure_card (newfunc, slotno);
+                                                       rc = ibmphp_configure_card(newfunc, slotno);
 
                                                        /* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
                                                        if (rc) {
@@ -310,7 +310,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                        function = 0x8;
                                        break;
                                default:
-                                       err ("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
+                                       err("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
                                        return -ENXIO;
                                        break;
                        }       /* end of switch */
@@ -318,7 +318,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
        }       /* end of for */
 
        if (!valid_device) {
-               err ("Cannot find any valid devices on the card.  Or unable to read from card.\n");
+               err("Cannot find any valid devices on the card.  Or unable to read from card.\n");
                return -ENODEV;
        }
 
@@ -327,13 +327,13 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
 error:
        for (i = 0; i < cleanup_count; i++) {
                if (cur_func->io[i]) {
-                       ibmphp_remove_resource (cur_func->io[i]);
+                       ibmphp_remove_resource(cur_func->io[i]);
                        cur_func->io[i] = NULL;
                } else if (cur_func->pfmem[i]) {
-                       ibmphp_remove_resource (cur_func->pfmem[i]);
+                       ibmphp_remove_resource(cur_func->pfmem[i]);
                        cur_func->pfmem[i] = NULL;
                } else if (cur_func->mem[i]) {
-                       ibmphp_remove_resource (cur_func->mem[i]);
+                       ibmphp_remove_resource(cur_func->mem[i]);
                        cur_func->mem[i] = NULL;
                }
        }
@@ -345,7 +345,7 @@ error:
  * Input: pointer to the pci_func
  * Output: configured PCI, 0, or error
  */
-static int configure_device (struct pci_func *func)
+static int configure_device(struct pci_func *func)
 {
        u32 bar[6];
        u32 address[] = {
@@ -366,7 +366,7 @@ static int configure_device (struct pci_func *func)
        struct resource_node *pfmem[6];
        unsigned int devfn;
 
-       debug ("%s - inside\n", __func__);
+       debug("%s - inside\n", __func__);
 
        devfn = PCI_DEVFN(func->device, func->function);
        ibmphp_pci_bus->number = func->busno;
@@ -386,27 +386,27 @@ static int configure_device (struct pci_func *func)
                        pcibios_write_config_dword(cur_func->busno, cur_func->device,
                        PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
                 */
-               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
 
                if (!bar[count])        /* This BAR is not implemented */
                        continue;
 
-               debug ("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
+               debug("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
 
                if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
                        /* This is IO */
-                       debug ("inside IO SPACE\n");
+                       debug("inside IO SPACE\n");
 
                        len[count] = bar[count] & 0xFFFFFFFC;
                        len[count] = ~len[count] + 1;
 
-                       debug ("len[count] in IO %x, count %d\n", len[count], count);
+                       debug("len[count] in IO %x, count %d\n", len[count], count);
 
                        io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 
                        if (!io[count]) {
-                               err ("out of system memory\n");
+                               err("out of system memory\n");
                                return -ENOMEM;
                        }
                        io[count]->type = IO;
@@ -414,36 +414,36 @@ static int configure_device (struct pci_func *func)
                        io[count]->devfunc = PCI_DEVFN(func->device, func->function);
                        io[count]->len = len[count];
                        if (ibmphp_check_resource(io[count], 0) == 0) {
-                               ibmphp_add_resource (io[count]);
+                               ibmphp_add_resource(io[count]);
                                func->io[count] = io[count];
                        } else {
-                               err ("cannot allocate requested io for bus %x device %x function %x len %x\n",
+                               err("cannot allocate requested io for bus %x device %x function %x len %x\n",
                                     func->busno, func->device, func->function, len[count]);
-                               kfree (io[count]);
+                               kfree(io[count]);
                                return -EIO;
                        }
-                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
+                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
 
                        /* _______________This is for debugging purposes only_____________________ */
-                       debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
-                       pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-                       debug ("after writing.... the start address is %x\n", bar[count]);
+                       debug("b4 writing, the IO address is %x\n", func->io[count]->start);
+                       pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
+                       debug("after writing.... the start address is %x\n", bar[count]);
                        /* _________________________________________________________________________*/
 
                } else {
                        /* This is Memory */
                        if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                                /* pfmem */
-                               debug ("PFMEM SPACE\n");
+                               debug("PFMEM SPACE\n");
 
                                len[count] = bar[count] & 0xFFFFFFF0;
                                len[count] = ~len[count] + 1;
 
-                               debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
+                               debug("len[count] in PFMEM %x, count %d\n", len[count], count);
 
                                pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!pfmem[count]) {
-                                       err ("out of system memory\n");
+                                       err("out of system memory\n");
                                        return -ENOMEM;
                                }
                                pfmem[count]->type = PFMEM;
@@ -452,64 +452,64 @@ static int configure_device (struct pci_func *func)
                                                        func->function);
                                pfmem[count]->len = len[count];
                                pfmem[count]->fromMem = 0;
-                               if (ibmphp_check_resource (pfmem[count], 0) == 0) {
-                                       ibmphp_add_resource (pfmem[count]);
+                               if (ibmphp_check_resource(pfmem[count], 0) == 0) {
+                                       ibmphp_add_resource(pfmem[count]);
                                        func->pfmem[count] = pfmem[count];
                                } else {
                                        mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
                                        if (!mem_tmp) {
-                                               err ("out of system memory\n");
-                                               kfree (pfmem[count]);
+                                               err("out of system memory\n");
+                                               kfree(pfmem[count]);
                                                return -ENOMEM;
                                        }
                                        mem_tmp->type = MEM;
                                        mem_tmp->busno = pfmem[count]->busno;
                                        mem_tmp->devfunc = pfmem[count]->devfunc;
                                        mem_tmp->len = pfmem[count]->len;
-                                       debug ("there's no pfmem... going into mem.\n");
-                                       if (ibmphp_check_resource (mem_tmp, 0) == 0) {
-                                               ibmphp_add_resource (mem_tmp);
+                                       debug("there's no pfmem... going into mem.\n");
+                                       if (ibmphp_check_resource(mem_tmp, 0) == 0) {
+                                               ibmphp_add_resource(mem_tmp);
                                                pfmem[count]->fromMem = 1;
                                                pfmem[count]->rangeno = mem_tmp->rangeno;
                                                pfmem[count]->start = mem_tmp->start;
                                                pfmem[count]->end = mem_tmp->end;
-                                               ibmphp_add_pfmem_from_mem (pfmem[count]);
+                                               ibmphp_add_pfmem_from_mem(pfmem[count]);
                                                func->pfmem[count] = pfmem[count];
                                        } else {
-                                               err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
+                                               err("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
                                                     func->busno, func->device, len[count]);
-                                               kfree (mem_tmp);
-                                               kfree (pfmem[count]);
+                                               kfree(mem_tmp);
+                                               kfree(pfmem[count]);
                                                return -EIO;
                                        }
                                }
 
-                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
+                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
 
                                /*_______________This is for debugging purposes only______________________________*/
-                               debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);
-                               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-                               debug ("after writing, start address is %x\n", bar[count]);
+                               debug("b4 writing, start address is %x\n", func->pfmem[count]->start);
+                               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
+                               debug("after writing, start address is %x\n", bar[count]);
                                /*_________________________________________________________________________________*/
 
                                if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {        /* takes up another dword */
-                                       debug ("inside the mem 64 case, count %d\n", count);
+                                       debug("inside the mem 64 case, count %d\n", count);
                                        count += 1;
                                        /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-                                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+                                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
                                }
                        } else {
                                /* regular memory */
-                               debug ("REGULAR MEM SPACE\n");
+                               debug("REGULAR MEM SPACE\n");
 
                                len[count] = bar[count] & 0xFFFFFFF0;
                                len[count] = ~len[count] + 1;
 
-                               debug ("len[count] in Mem %x, count %d\n", len[count], count);
+                               debug("len[count] in Mem %x, count %d\n", len[count], count);
 
                                mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!mem[count]) {
-                                       err ("out of system memory\n");
+                                       err("out of system memory\n");
                                        return -ENOMEM;
                                }
                                mem[count]->type = MEM;
@@ -517,43 +517,43 @@ static int configure_device (struct pci_func *func)
                                mem[count]->devfunc = PCI_DEVFN(func->device,
                                                        func->function);
                                mem[count]->len = len[count];
-                               if (ibmphp_check_resource (mem[count], 0) == 0) {
-                                       ibmphp_add_resource (mem[count]);
+                               if (ibmphp_check_resource(mem[count], 0) == 0) {
+                                       ibmphp_add_resource(mem[count]);
                                        func->mem[count] = mem[count];
                                } else {
-                                       err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
+                                       err("cannot allocate requested mem for bus %x, device %x, len %x\n",
                                             func->busno, func->device, len[count]);
-                                       kfree (mem[count]);
+                                       kfree(mem[count]);
                                        return -EIO;
                                }
-                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
+                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
                                /* _______________________This is for debugging purposes only _______________________*/
-                               debug ("b4 writing, start address is %x\n", func->mem[count]->start);
-                               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-                               debug ("after writing, the address is %x\n", bar[count]);
+                               debug("b4 writing, start address is %x\n", func->mem[count]->start);
+                               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
+                               debug("after writing, the address is %x\n", bar[count]);
                                /* __________________________________________________________________________________*/
 
                                if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
                                        /* takes up another dword */
-                                       debug ("inside mem 64 case, reg. mem, count %d\n", count);
+                                       debug("inside mem 64 case, reg. mem, count %d\n", count);
                                        count += 1;
                                        /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-                                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+                                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
                                }
                        }
                }               /* end of mem */
        }                       /* end of for */
 
        func->bus = 0;          /* To indicate that this is not a PPB */
-       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
+       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
        if ((irq > 0x00) && (irq < 0x05))
-               pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
+               pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
 
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
 
-       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
-       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
+       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
+       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
 
        return 0;
 }
@@ -563,7 +563,7 @@ static int configure_device (struct pci_func *func)
  * Parameters: pci_func
  * Returns:
  ******************************************************************************/
-static int configure_bridge (struct pci_func **func_passed, u8 slotno)
+static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 {
        int count;
        int i;
@@ -597,7 +597,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
        u8 irq;
        int retval;
 
-       debug ("%s - enter\n", __func__);
+       debug("%s - enter\n", __func__);
 
        devfn = PCI_DEVFN(func->function, func->device);
        ibmphp_pci_bus->number = func->busno;
@@ -606,43 +606,43 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
         * behind it
         */
 
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
 
        /* _____________________For debugging purposes only __________________________
-       pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
-       debug ("primary # written into the bridge is %x\n", pri_number);
+       pci_bus_config_byte(ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
+       debug("primary # written into the bridge is %x\n", pri_number);
         ___________________________________________________________________________*/
 
        /* in EBDA, only get allocated 1 additional bus # per slot */
-       sec_number = find_sec_number (func->busno, slotno);
+       sec_number = find_sec_number(func->busno, slotno);
        if (sec_number == 0xff) {
-               err ("cannot allocate secondary bus number for the bridged device\n");
+               err("cannot allocate secondary bus number for the bridged device\n");
                return -EINVAL;
        }
 
-       debug ("after find_sec_number, the number we got is %x\n", sec_number);
-       debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
+       debug("after find_sec_number, the number we got is %x\n", sec_number);
+       debug("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
 
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
 
        /* __________________For debugging purposes only __________________________________
-       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-       debug ("sec_number after write/read is %x\n", sec_number);
+       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+       debug("sec_number after write/read is %x\n", sec_number);
         ________________________________________________________________________________*/
 
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
 
        /* __________________For debugging purposes only ____________________________________
-       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
-       debug ("subordinate number after write/read is %x\n", sec_number);
+       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
+       debug("subordinate number after write/read is %x\n", sec_number);
         __________________________________________________________________________________*/
 
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
-       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
+       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
 
-       debug ("func->busno is %x\n", func->busno);
-       debug ("sec_number after writing is %x\n", sec_number);
+       debug("func->busno is %x\n", func->busno);
+       debug("sec_number after writing is %x\n", sec_number);
 
 
        /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -652,29 +652,29 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 
        /* First we need to allocate mem/io for the bridge itself in case it needs it */
        for (count = 0; address[count]; count++) {      /* for 2 BARs */
-               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
 
                if (!bar[count]) {
                        /* This BAR is not implemented */
-                       debug ("so we come here then, eh?, count = %d\n", count);
+                       debug("so we come here then, eh?, count = %d\n", count);
                        continue;
                }
                //  tmp_bar = bar[count];
 
-               debug ("Bar %d wants %x\n", count, bar[count]);
+               debug("Bar %d wants %x\n", count, bar[count]);
 
                if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
                        /* This is IO */
                        len[count] = bar[count] & 0xFFFFFFFC;
                        len[count] = ~len[count] + 1;
 
-                       debug ("len[count] in IO = %x\n", len[count]);
+                       debug("len[count] in IO = %x\n", len[count]);
 
                        bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 
                        if (!bus_io[count]) {
-                               err ("out of system memory\n");
+                               err("out of system memory\n");
                                retval = -ENOMEM;
                                goto error;
                        }
@@ -683,17 +683,17 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                        bus_io[count]->devfunc = PCI_DEVFN(func->device,
                                                        func->function);
                        bus_io[count]->len = len[count];
-                       if (ibmphp_check_resource (bus_io[count], 0) == 0) {
-                               ibmphp_add_resource (bus_io[count]);
+                       if (ibmphp_check_resource(bus_io[count], 0) == 0) {
+                               ibmphp_add_resource(bus_io[count]);
                                func->io[count] = bus_io[count];
                        } else {
-                               err ("cannot allocate requested io for bus %x, device %x, len %x\n",
+                               err("cannot allocate requested io for bus %x, device %x, len %x\n",
                                     func->busno, func->device, len[count]);
-                               kfree (bus_io[count]);
+                               kfree(bus_io[count]);
                                return -EIO;
                        }
 
-                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
+                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
 
                } else {
                        /* This is Memory */
@@ -702,11 +702,11 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                                len[count] = bar[count] & 0xFFFFFFF0;
                                len[count] = ~len[count] + 1;
 
-                               debug ("len[count] in PFMEM = %x\n", len[count]);
+                               debug("len[count] in PFMEM = %x\n", len[count]);
 
                                bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!bus_pfmem[count]) {
-                                       err ("out of system memory\n");
+                                       err("out of system memory\n");
                                        retval = -ENOMEM;
                                        goto error;
                                }
@@ -716,13 +716,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                                                        func->function);
                                bus_pfmem[count]->len = len[count];
                                bus_pfmem[count]->fromMem = 0;
-                               if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
-                                       ibmphp_add_resource (bus_pfmem[count]);
+                               if (ibmphp_check_resource(bus_pfmem[count], 0) == 0) {
+                                       ibmphp_add_resource(bus_pfmem[count]);
                                        func->pfmem[count] = bus_pfmem[count];
                                } else {
                                        mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
                                        if (!mem_tmp) {
-                                               err ("out of system memory\n");
+                                               err("out of system memory\n");
                                                retval = -ENOMEM;
                                                goto error;
                                        }
@@ -730,28 +730,28 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                                        mem_tmp->busno = bus_pfmem[count]->busno;
                                        mem_tmp->devfunc = bus_pfmem[count]->devfunc;
                                        mem_tmp->len = bus_pfmem[count]->len;
-                                       if (ibmphp_check_resource (mem_tmp, 0) == 0) {
-                                               ibmphp_add_resource (mem_tmp);
+                                       if (ibmphp_check_resource(mem_tmp, 0) == 0) {
+                                               ibmphp_add_resource(mem_tmp);
                                                bus_pfmem[count]->fromMem = 1;
                                                bus_pfmem[count]->rangeno = mem_tmp->rangeno;
-                                               ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
+                                               ibmphp_add_pfmem_from_mem(bus_pfmem[count]);
                                                func->pfmem[count] = bus_pfmem[count];
                                        } else {
-                                               err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
+                                               err("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
                                                     func->busno, func->device, len[count]);
-                                               kfree (mem_tmp);
-                                               kfree (bus_pfmem[count]);
+                                               kfree(mem_tmp);
+                                               kfree(bus_pfmem[count]);
                                                return -EIO;
                                        }
                                }
 
-                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
+                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
 
                                if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
                                        /* takes up another dword */
                                        count += 1;
                                        /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-                                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+                                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
 
                                }
                        } else {
@@ -759,11 +759,11 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                                len[count] = bar[count] & 0xFFFFFFF0;
                                len[count] = ~len[count] + 1;
 
-                               debug ("len[count] in Memory is %x\n", len[count]);
+                               debug("len[count] in Memory is %x\n", len[count]);
 
                                bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!bus_mem[count]) {
-                                       err ("out of system memory\n");
+                                       err("out of system memory\n");
                                        retval = -ENOMEM;
                                        goto error;
                                }
@@ -772,23 +772,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                                bus_mem[count]->devfunc = PCI_DEVFN(func->device,
                                                        func->function);
                                bus_mem[count]->len = len[count];
-                               if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
-                                       ibmphp_add_resource (bus_mem[count]);
+                               if (ibmphp_check_resource(bus_mem[count], 0) == 0) {
+                                       ibmphp_add_resource(bus_mem[count]);
                                        func->mem[count] = bus_mem[count];
                                } else {
-                                       err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
+                                       err("cannot allocate requested mem for bus %x, device %x, len %x\n",
                                             func->busno, func->device, len[count]);
-                                       kfree (bus_mem[count]);
+                                       kfree(bus_mem[count]);
                                        return -EIO;
                                }
 
-                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
+                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
 
                                if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
                                        /* takes up another dword */
                                        count += 1;
                                        /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-                                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+                                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0x00000000);
 
                                }
                        }
@@ -796,45 +796,45 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
        }                       /* end of for  */
 
        /* Now need to see how much space the devices behind the bridge needed */
-       amount_needed = scan_behind_bridge (func, sec_number);
+       amount_needed = scan_behind_bridge(func, sec_number);
        if (amount_needed == NULL)
                return -ENOMEM;
 
        ibmphp_pci_bus->number = func->busno;
-       debug ("after coming back from scan_behind_bridge\n");
-       debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
-       debug ("amount_needed->io = %x\n", amount_needed->io);
-       debug ("amount_needed->mem = %x\n", amount_needed->mem);
-       debug ("amount_needed->pfmem =  %x\n", amount_needed->pfmem);
+       debug("after coming back from scan_behind_bridge\n");
+       debug("amount_needed->not_correct = %x\n", amount_needed->not_correct);
+       debug("amount_needed->io = %x\n", amount_needed->io);
+       debug("amount_needed->mem = %x\n", amount_needed->mem);
+       debug("amount_needed->pfmem =  %x\n", amount_needed->pfmem);
 
        if (amount_needed->not_correct) {
-               debug ("amount_needed is not correct\n");
+               debug("amount_needed is not correct\n");
                for (count = 0; address[count]; count++) {
                        /* for 2 BARs */
                        if (bus_io[count]) {
-                               ibmphp_remove_resource (bus_io[count]);
+                               ibmphp_remove_resource(bus_io[count]);
                                func->io[count] = NULL;
                        } else if (bus_pfmem[count]) {
-                               ibmphp_remove_resource (bus_pfmem[count]);
+                               ibmphp_remove_resource(bus_pfmem[count]);
                                func->pfmem[count] = NULL;
                        } else if (bus_mem[count]) {
-                               ibmphp_remove_resource (bus_mem[count]);
+                               ibmphp_remove_resource(bus_mem[count]);
                                func->mem[count] = NULL;
                        }
                }
-               kfree (amount_needed);
+               kfree(amount_needed);
                return -ENODEV;
        }
 
        if (!amount_needed->io) {
-               debug ("it doesn't want IO?\n");
+               debug("it doesn't want IO?\n");
                flag_io = 1;
        } else {
-               debug ("it wants %x IO behind the bridge\n", amount_needed->io);
+               debug("it wants %x IO behind the bridge\n", amount_needed->io);
                io = kzalloc(sizeof(*io), GFP_KERNEL);
 
                if (!io) {
-                       err ("out of system memory\n");
+                       err("out of system memory\n");
                        retval = -ENOMEM;
                        goto error;
                }
@@ -842,21 +842,21 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                io->busno = func->busno;
                io->devfunc = PCI_DEVFN(func->device, func->function);
                io->len = amount_needed->io;
-               if (ibmphp_check_resource (io, 1) == 0) {
-                       debug ("were we able to add io\n");
-                       ibmphp_add_resource (io);
+               if (ibmphp_check_resource(io, 1) == 0) {
+                       debug("were we able to add io\n");
+                       ibmphp_add_resource(io);
                        flag_io = 1;
                }
        }
 
        if (!amount_needed->mem) {
-               debug ("it doesn't want n.e.memory?\n");
+               debug("it doesn't want n.e.memory?\n");
                flag_mem = 1;
        } else {
-               debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
+               debug("it wants %x memory behind the bridge\n", amount_needed->mem);
                mem = kzalloc(sizeof(*mem), GFP_KERNEL);
                if (!mem) {
-                       err ("out of system memory\n");
+                       err("out of system memory\n");
                        retval = -ENOMEM;
                        goto error;
                }
@@ -864,21 +864,21 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                mem->busno = func->busno;
                mem->devfunc = PCI_DEVFN(func->device, func->function);
                mem->len = amount_needed->mem;
-               if (ibmphp_check_resource (mem, 1) == 0) {
-                       ibmphp_add_resource (mem);
+               if (ibmphp_check_resource(mem, 1) == 0) {
+                       ibmphp_add_resource(mem);
                        flag_mem = 1;
-                       debug ("were we able to add mem\n");
+                       debug("were we able to add mem\n");
                }
        }
 
        if (!amount_needed->pfmem) {
-               debug ("it doesn't want n.e.pfmem mem?\n");
+               debug("it doesn't want n.e.pfmem mem?\n");
                flag_pfmem = 1;
        } else {
-               debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
+               debug("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
                pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL);
                if (!pfmem) {
-                       err ("out of system memory\n");
+                       err("out of system memory\n");
                        retval = -ENOMEM;
                        goto error;
                }
@@ -887,13 +887,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                pfmem->devfunc = PCI_DEVFN(func->device, func->function);
                pfmem->len = amount_needed->pfmem;
                pfmem->fromMem = 0;
-               if (ibmphp_check_resource (pfmem, 1) == 0) {
-                       ibmphp_add_resource (pfmem);
+               if (ibmphp_check_resource(pfmem, 1) == 0) {
+                       ibmphp_add_resource(pfmem);
                        flag_pfmem = 1;
                } else {
                        mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
                        if (!mem_tmp) {
-                               err ("out of system memory\n");
+                               err("out of system memory\n");
                                retval = -ENOMEM;
                                goto error;
                        }
@@ -901,18 +901,18 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                        mem_tmp->busno = pfmem->busno;
                        mem_tmp->devfunc = pfmem->devfunc;
                        mem_tmp->len = pfmem->len;
-                       if (ibmphp_check_resource (mem_tmp, 1) == 0) {
-                               ibmphp_add_resource (mem_tmp);
+                       if (ibmphp_check_resource(mem_tmp, 1) == 0) {
+                               ibmphp_add_resource(mem_tmp);
                                pfmem->fromMem = 1;
                                pfmem->rangeno = mem_tmp->rangeno;
-                               ibmphp_add_pfmem_from_mem (pfmem);
+                               ibmphp_add_pfmem_from_mem(pfmem);
                                flag_pfmem = 1;
                        }
                }
        }
 
-       debug ("b4 if (flag_io && flag_mem && flag_pfmem)\n");
-       debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
+       debug("b4 if (flag_io && flag_mem && flag_pfmem)\n");
+       debug("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
 
        if (flag_io && flag_mem && flag_pfmem) {
                /* If on bootup, there was a bridged card in this slot,
@@ -920,127 +920,127 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                 * back again, there's no way for us to remove the bus
                 * struct, so no need to kmalloc, can use existing node
                 */
-               bus = ibmphp_find_res_bus (sec_number);
+               bus = ibmphp_find_res_bus(sec_number);
                if (!bus) {
                        bus = kzalloc(sizeof(*bus), GFP_KERNEL);
                        if (!bus) {
-                               err ("out of system memory\n");
+                               err("out of system memory\n");
                                retval = -ENOMEM;
                                goto error;
                        }
                        bus->busno = sec_number;
-                       debug ("b4 adding new bus\n");
-                       rc = add_new_bus (bus, io, mem, pfmem, func->busno);
+                       debug("b4 adding new bus\n");
+                       rc = add_new_bus(bus, io, mem, pfmem, func->busno);
                } else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
-                       rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
+                       rc = add_new_bus(bus, io, mem, pfmem, 0xFF);
                else {
-                       err ("expected bus structure not empty?\n");
+                       err("expected bus structure not empty?\n");
                        retval = -EIO;
                        goto error;
                }
                if (rc) {
                        if (rc == -ENOMEM) {
-                               ibmphp_remove_bus (bus, func->busno);
-                               kfree (amount_needed);
+                               ibmphp_remove_bus(bus, func->busno);
+                               kfree(amount_needed);
                                return rc;
                        }
                        retval = rc;
                        goto error;
                }
-               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
-               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
+               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
+               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
 
                if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
-                       debug ("io 32\n");
+                       debug("io 32\n");
                        need_io_upper = 1;
                }
                if ((pfmem_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
-                       debug ("pfmem 64\n");
+                       debug("pfmem 64\n");
                        need_pfmem_upper = 1;
                }
 
                if (bus->noIORanges) {
-                       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
-                       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
+                       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
+                       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
 
                        /* _______________This is for debugging purposes only ____________________
-                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
-                       debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
-                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
-                       debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
+                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
+                       debug("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
+                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
+                       debug("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
                         ________________________________________________________________________*/
 
                        if (need_io_upper) {    /* since can't support n.e.ways */
-                               pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
-                               pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
+                               pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
+                               pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
                        }
                } else {
-                       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
-                       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
+                       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
+                       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
                }
 
                if (bus->noMemRanges) {
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
 
                        /* ____________________This is for debugging purposes only ________________________
-                       pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
-                       debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
-                       pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
-                       debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+                       pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
+                       debug("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+                       pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
+                       debug("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
                         __________________________________________________________________________________*/
 
                } else {
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
                }
                if (bus->noPFMemRanges) {
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
 
                        /* __________________________This is for debugging purposes only _______________________
-                       pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
-                       debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
-                       pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
-                       debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+                       pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
+                       debug("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+                       pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
+                       debug("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
                         ______________________________________________________________________________________*/
 
                        if (need_pfmem_upper) { /* since can't support n.e.ways */
-                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
-                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
+                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
+                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
                        }
                } else {
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
-                       pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
+                       pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
                }
 
-               debug ("b4 writing control information\n");
+               debug("b4 writing control information\n");
 
-               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
+               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
                if ((irq > 0x00) && (irq < 0x05))
-                       pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
+                       pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
                /*
-               pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
-               pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
-               pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
+               pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
+               pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
+               pci_bus_write_config_byte(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
                 */
 
-               pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
-               pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
+               pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
+               pci_bus_write_config_word(ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
                for (i = 0; i < 32; i++) {
                        if (amount_needed->devices[i]) {
-                               debug ("device where devices[i] is 1 = %x\n", i);
+                               debug("device where devices[i] is 1 = %x\n", i);
                                func->devices[i] = 1;
                        }
                }
                func->bus = 1;  /* For unconfiguring, to indicate it's PPB */
                func_passed = &func;
-               debug ("func->busno b4 returning is %x\n", func->busno);
-               debug ("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
-               kfree (amount_needed);
+               debug("func->busno b4 returning is %x\n", func->busno);
+               debug("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
+               kfree(amount_needed);
                return 0;
        } else {
-               err ("Configuring bridge was unsuccessful...\n");
+               err("Configuring bridge was unsuccessful...\n");
                mem_tmp = NULL;
                retval = -EIO;
                goto error;
@@ -1049,20 +1049,20 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 error:
        kfree(amount_needed);
        if (pfmem)
-               ibmphp_remove_resource (pfmem);
+               ibmphp_remove_resource(pfmem);
        if (io)
-               ibmphp_remove_resource (io);
+               ibmphp_remove_resource(io);
        if (mem)
-               ibmphp_remove_resource (mem);
+               ibmphp_remove_resource(mem);
        for (i = 0; i < 2; i++) {       /* for 2 BARs */
                if (bus_io[i]) {
-                       ibmphp_remove_resource (bus_io[i]);
+                       ibmphp_remove_resource(bus_io[i]);
                        func->io[i] = NULL;
                } else if (bus_pfmem[i]) {
-                       ibmphp_remove_resource (bus_pfmem[i]);
+                       ibmphp_remove_resource(bus_pfmem[i]);
                        func->pfmem[i] = NULL;
                } else if (bus_mem[i]) {
-                       ibmphp_remove_resource (bus_mem[i]);
+                       ibmphp_remove_resource(bus_mem[i]);
                        func->mem[i] = NULL;
                }
        }
@@ -1075,7 +1075,7 @@ error:
  * Input: bridge function
  * Output: amount of resources needed
  *****************************************************************************/
-static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)
+static struct res_needed *scan_behind_bridge(struct pci_func *func, u8 busno)
 {
        int count, len[6];
        u16 vendor_id;
@@ -1102,36 +1102,36 @@ static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)
 
        ibmphp_pci_bus->number = busno;
 
-       debug ("the bus_no behind the bridge is %x\n", busno);
-       debug ("scanning devices behind the bridge...\n");
+       debug("the bus_no behind the bridge is %x\n", busno);
+       debug("scanning devices behind the bridge...\n");
        for (device = 0; device < 32; device++) {
                amount->devices[device] = 0;
                for (function = 0; function < 8; function++) {
                        devfn = PCI_DEVFN(device, function);
 
-                       pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+                       pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
 
                        if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
                                /* found correct device!!! */
                                howmany++;
 
-                               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-                               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+                               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+                               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
 
-                               debug ("hdr_type behind the bridge is %x\n", hdr_type);
-                               if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
-                                       err ("embedded bridges not supported for hot-plugging.\n");
+                               debug("hdr_type behind the bridge is %x\n", hdr_type);
+                               if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
+                                       err("embedded bridges not supported for hot-plugging.\n");
                                        amount->not_correct = 1;
                                        return amount;
                                }
 
                                class >>= 8;    /* to take revision out, class = class.subclass.prog i/f */
                                if (class == PCI_CLASS_NOT_DEFINED_VGA) {
-                                       err ("The device %x is VGA compatible and as is not supported for hot plugging.  Please choose another device.\n", device);
+                                       err("The device %x is VGA compatible and as is not supported for hot plugging.  Please choose another device.\n", device);
                                        amount->not_correct = 1;
                                        return amount;
                                } else if (class == PCI_CLASS_DISPLAY_VGA) {
-                                       err ("The device %x is not supported for hot plugging.  Please choose another device.\n", device);
+                                       err("The device %x is not supported for hot plugging.  Please choose another device.\n", device);
                                        amount->not_correct = 1;
                                        return amount;
                                }
@@ -1141,23 +1141,23 @@ static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)
                                for (count = 0; address[count]; count++) {
                                        /* for 6 BARs */
                                        /*
-                                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
+                                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, address[count], &tmp);
                                        if (tmp & 0x01) // IO
-                                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
+                                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
                                        else // MEMORY
-                                               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+                                               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
                                        */
-                                       pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-                                       pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+                                       pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+                                       pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &bar[count]);
 
-                                       debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
+                                       debug("what is bar[count]? %x, count = %d\n", bar[count], count);
 
                                        if (!bar[count])        /* This BAR is not implemented */
                                                continue;
 
                                        //tmp_bar = bar[count];
 
-                                       debug ("count %d device %x function %x wants %x resources\n", count, device, function, bar[count]);
+                                       debug("count %d device %x function %x wants %x resources\n", count, device, function, bar[count]);
 
                                        if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
                                                /* This is IO */
@@ -1211,7 +1211,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)
  * Change: we also call these functions even if we configured the card ourselves (i.e., not
  * the bootup case), since it should work same way
  */
-static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
+static int unconfigure_boot_device(u8 busno, u8 device, u8 function)
 {
        u32 start_address;
        u32 address[] = {
@@ -1234,30 +1234,30 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
        u32 tmp_address;
        unsigned int devfn;
 
-       debug ("%s - enter\n", __func__);
+       debug("%s - enter\n", __func__);
 
-       bus = ibmphp_find_res_bus (busno);
+       bus = ibmphp_find_res_bus(busno);
        if (!bus) {
-               debug ("cannot find corresponding bus.\n");
+               debug("cannot find corresponding bus.\n");
                return -EINVAL;
        }
 
        devfn = PCI_DEVFN(device, function);
        ibmphp_pci_bus->number = busno;
        for (count = 0; address[count]; count++) {      /* for 6 BARs */
-               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
+               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &start_address);
 
                /* We can do this here, b/c by that time the device driver of the card has been stopped */
 
-               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
-               pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
+               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &size);
+               pci_bus_write_config_dword(ibmphp_pci_bus, devfn, address[count], start_address);
 
-               debug ("start_address is %x\n", start_address);
-               debug ("busno, device, function %x %x %x\n", busno, device, function);
+               debug("start_address is %x\n", start_address);
+               debug("busno, device, function %x %x %x\n", busno, device, function);
                if (!size) {
                        /* This BAR is not implemented */
-                       debug ("is this bar no implemented?, count = %d\n", count);
+                       debug("is this bar no implemented?, count = %d\n", count);
                        continue;
                }
                tmp_address = start_address;
@@ -1267,24 +1267,24 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
                        size = size & 0xFFFFFFFC;
                        size = ~size + 1;
                        end_address = start_address + size - 1;
-                       if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
-                               err ("cannot find corresponding IO resource to remove\n");
+                       if (ibmphp_find_resource(bus, start_address, &io, IO) < 0) {
+                               err("cannot find corresponding IO resource to remove\n");
                                return -EIO;
                        }
-                       debug ("io->start = %x\n", io->start);
+                       debug("io->start = %x\n", io->start);
                        temp_end = io->end;
                        start_address = io->end + 1;
-                       ibmphp_remove_resource (io);
+                       ibmphp_remove_resource(io);
                        /* This is needed b/c of the old I/O restrictions in the BIOS */
                        while (temp_end < end_address) {
-                               if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
-                                       err ("cannot find corresponding IO resource to remove\n");
+                               if (ibmphp_find_resource(bus, start_address, &io, IO) < 0) {
+                                       err("cannot find corresponding IO resource to remove\n");
                                        return -EIO;
                                }
-                               debug ("io->start = %x\n", io->start);
+                               debug("io->start = %x\n", io->start);
                                temp_end = io->end;
                                start_address = io->end + 1;
-                               ibmphp_remove_resource (io);
+                               ibmphp_remove_resource(io);
                        }
 
                        /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
@@ -1292,29 +1292,29 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
                        /* This is Memory */
                        if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                                /* pfmem */
-                               debug ("start address of pfmem is %x\n", start_address);
+                               debug("start address of pfmem is %x\n", start_address);
                                start_address &= PCI_BASE_ADDRESS_MEM_MASK;
 
-                               if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
-                                       err ("cannot find corresponding PFMEM resource to remove\n");
+                               if (ibmphp_find_resource(bus, start_address, &pfmem, PFMEM) < 0) {
+                                       err("cannot find corresponding PFMEM resource to remove\n");
                                        return -EIO;
                                }
                                if (pfmem) {
-                                       debug ("pfmem->start = %x\n", pfmem->start);
+                                       debug("pfmem->start = %x\n", pfmem->start);
 
                                        ibmphp_remove_resource(pfmem);
                                }
                        } else {
                                /* regular memory */
-                               debug ("start address of mem is %x\n", start_address);
+                               debug("start address of mem is %x\n", start_address);
                                start_address &= PCI_BASE_ADDRESS_MEM_MASK;
 
-                               if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
-                                       err ("cannot find corresponding MEM resource to remove\n");
+                               if (ibmphp_find_resource(bus, start_address, &mem, MEM) < 0) {
+                                       err("cannot find corresponding MEM resource to remove\n");
                                        return -EIO;
                                }
                                if (mem) {
-                                       debug ("mem->start = %x\n", mem->start);
+                                       debug("mem->start = %x\n", mem->start);
 
                                        ibmphp_remove_resource(mem);
                                }
@@ -1329,7 +1329,7 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
        return 0;
 }
 
-static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
+static int unconfigure_boot_bridge(u8 busno, u8 device, u8 function)
 {
        int count;
        int bus_no, pri_no, sub_no, sec_no = 0;
@@ -1349,40 +1349,40 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
        devfn = PCI_DEVFN(device, function);
        ibmphp_pci_bus->number = busno;
        bus_no = (int) busno;
-       debug ("busno is %x\n", busno);
-       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
-       debug ("%s - busno = %x, primary_number = %x\n", __func__, busno, pri_number);
+       debug("busno is %x\n", busno);
+       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
+       debug("%s - busno = %x, primary_number = %x\n", __func__, busno, pri_number);
 
-       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-       debug ("sec_number is %x\n", sec_number);
+       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+       debug("sec_number is %x\n", sec_number);
        sec_no = (int) sec_number;
        pri_no = (int) pri_number;
        if (pri_no != bus_no) {
-               err ("primary numbers in our structures and pci config space don't match.\n");
+               err("primary numbers in our structures and pci config space don't match.\n");
                return -EINVAL;
        }
 
-       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
+       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
        sub_no = (int) sub_number;
-       debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
+       debug("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
        if (sec_no != sub_number) {
-               err ("there're more buses behind this bridge.  Hot removal is not supported.  Please choose another card\n");
+               err("there're more buses behind this bridge.  Hot removal is not supported.  Please choose another card\n");
                return -ENODEV;
        }
 
-       bus = ibmphp_find_res_bus (sec_number);
+       bus = ibmphp_find_res_bus(sec_number);
        if (!bus) {
-               err ("cannot find Bus structure for the bridged device\n");
+               err("cannot find Bus structure for the bridged device\n");
                return -EINVAL;
        }
        debug("bus->busno is %x\n", bus->busno);
        debug("sec_number is %x\n", sec_number);
 
-       ibmphp_remove_bus (bus, busno);
+       ibmphp_remove_bus(bus, busno);
 
        for (count = 0; address[count]; count++) {
                /* for 2 BARs */
-               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
+               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, address[count], &start_address);
 
                if (!start_address) {
                        /* This BAR is not implemented */
@@ -1394,14 +1394,14 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
                if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
                        /* This is IO */
                        start_address &= PCI_BASE_ADDRESS_IO_MASK;
-                       if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
-                               err ("cannot find corresponding IO resource to remove\n");
+                       if (ibmphp_find_resource(bus, start_address, &io, IO) < 0) {
+                               err("cannot find corresponding IO resource to remove\n");
                                return -EIO;
                        }
                        if (io)
-                               debug ("io->start = %x\n", io->start);
+                               debug("io->start = %x\n", io->start);
 
-                       ibmphp_remove_resource (io);
+                       ibmphp_remove_resource(io);
 
                        /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
                } else {
@@ -1409,24 +1409,24 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
                        if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                                /* pfmem */
                                start_address &= PCI_BASE_ADDRESS_MEM_MASK;
-                               if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
-                                       err ("cannot find corresponding PFMEM resource to remove\n");
+                               if (ibmphp_find_resource(bus, start_address, &pfmem, PFMEM) < 0) {
+                                       err("cannot find corresponding PFMEM resource to remove\n");
                                        return -EINVAL;
                                }
                                if (pfmem) {
-                                       debug ("pfmem->start = %x\n", pfmem->start);
+                                       debug("pfmem->start = %x\n", pfmem->start);
 
                                        ibmphp_remove_resource(pfmem);
                                }
                        } else {
                                /* regular memory */
                                start_address &= PCI_BASE_ADDRESS_MEM_MASK;
-                               if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
-                                       err ("cannot find corresponding MEM resource to remove\n");
+                               if (ibmphp_find_resource(bus, start_address, &mem, MEM) < 0) {
+                                       err("cannot find corresponding MEM resource to remove\n");
                                        return -EINVAL;
                                }
                                if (mem) {
-                                       debug ("mem->start = %x\n", mem->start);
+                                       debug("mem->start = %x\n", mem->start);
 
                                        ibmphp_remove_resource(mem);
                                }
@@ -1437,11 +1437,11 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
                        }
                }       /* end of mem */
        }       /* end of for */
-       debug ("%s - exiting, returning success\n", __func__);
+       debug("%s - exiting, returning success\n", __func__);
        return 0;
 }
 
-static int unconfigure_boot_card (struct slot *slot_cur)
+static int unconfigure_boot_card(struct slot *slot_cur)
 {
        u16 vendor_id;
        u32 class;
@@ -1453,57 +1453,57 @@ static int unconfigure_boot_card (struct slot *slot_cur)
        unsigned int devfn;
        u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
 
-       debug ("%s - enter\n", __func__);
+       debug("%s - enter\n", __func__);
 
        device = slot_cur->device;
        busno = slot_cur->bus;
 
-       debug ("b4 for loop, device is %x\n", device);
+       debug("b4 for loop, device is %x\n", device);
        /* For every function on the card */
        for (function = 0x0; function < 0x08; function++) {
                devfn = PCI_DEVFN(device, function);
                ibmphp_pci_bus->number = busno;
 
-               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
 
                if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
                        /* found correct device!!! */
                        ++valid_device;
 
-                       debug ("%s - found correct device\n", __func__);
+                       debug("%s - found correct device\n", __func__);
 
                        /* header: x x x x x x x x
                         *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
                         *         |_=> 0 = single function device, 1 = multi-function device
                         */
 
-                       pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-                       pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+                       pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+                       pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
 
-                       debug ("hdr_type %x, class %x\n", hdr_type, class);
+                       debug("hdr_type %x, class %x\n", hdr_type, class);
                        class >>= 8;    /* to take revision out, class = class.subclass.prog i/f */
                        if (class == PCI_CLASS_NOT_DEFINED_VGA) {
-                               err ("The device %x function %x is VGA compatible and is not supported for hot removing.  Please choose another device.\n", device, function);
+                               err("The device %x function %x is VGA compatible and is not supported for hot removing.  Please choose another device.\n", device, function);
                                return -ENODEV;
                        } else if (class == PCI_CLASS_DISPLAY_VGA) {
-                               err ("The device %x function %x is not supported for hot removing.  Please choose another device.\n", device, function);
+                               err("The device %x function %x is not supported for hot removing.  Please choose another device.\n", device, function);
                                return -ENODEV;
                        }
 
                        switch (hdr_type) {
                                case PCI_HEADER_TYPE_NORMAL:
-                                       rc = unconfigure_boot_device (busno, device, function);
+                                       rc = unconfigure_boot_device(busno, device, function);
                                        if (rc) {
-                                               err ("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
+                                               err("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
                                                     device, function, busno);
                                                return rc;
                                        }
                                        function = 0x8;
                                        break;
                                case PCI_HEADER_TYPE_MULTIDEVICE:
-                                       rc = unconfigure_boot_device (busno, device, function);
+                                       rc = unconfigure_boot_device(busno, device, function);
                                        if (rc) {
-                                               err ("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
+                                               err("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
                                                     device, function, busno);
                                                return rc;
                                        }
@@ -1511,12 +1511,12 @@ static int unconfigure_boot_card (struct slot *slot_cur)
                                case PCI_HEADER_TYPE_BRIDGE:
                                        class >>= 8;
                                        if (class != PCI_CLASS_BRIDGE_PCI) {
-                                               err ("This device %x function %x is not PCI-to-PCI bridge, and is not supported for hot-removing.  Please try another card.\n", device, function);
+                                               err("This device %x function %x is not PCI-to-PCI bridge, and is not supported for hot-removing.  Please try another card.\n", device, function);
                                                return -ENODEV;
                                        }
-                                       rc = unconfigure_boot_bridge (busno, device, function);
+                                       rc = unconfigure_boot_bridge(busno, device, function);
                                        if (rc != 0) {
-                                               err ("was not able to hot-remove PPB properly.\n");
+                                               err("was not able to hot-remove PPB properly.\n");
                                                return rc;
                                        }
 
@@ -1525,17 +1525,17 @@ static int unconfigure_boot_card (struct slot *slot_cur)
                                case PCI_HEADER_TYPE_MULTIBRIDGE:
                                        class >>= 8;
                                        if (class != PCI_CLASS_BRIDGE_PCI) {
-                                               err ("This device %x function %x is not PCI-to-PCI bridge,  and is not supported for hot-removing.  Please try another card.\n", device, function);
+                                               err("This device %x function %x is not PCI-to-PCI bridge,  and is not supported for hot-removing.  Please try another card.\n", device, function);
                                                return -ENODEV;
                                        }
-                                       rc = unconfigure_boot_bridge (busno, device, function);
+                                       rc = unconfigure_boot_bridge(busno, device, function);
                                        if (rc != 0) {
-                                               err ("was not able to hot-remove PPB properly.\n");
+                                               err("was not able to hot-remove PPB properly.\n");
                                                return rc;
                                        }
                                        break;
                                default:
-                                       err ("MAJOR PROBLEM!!!! Cannot read device's header\n");
+                                       err("MAJOR PROBLEM!!!! Cannot read device's header\n");
                                        return -1;
                                        break;
                        }       /* end of switch */
@@ -1543,7 +1543,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)
        }       /* end of for */
 
        if (!valid_device) {
-               err ("Could not find device to unconfigure.  Or could not read the card.\n");
+               err("Could not find device to unconfigure.  Or could not read the card.\n");
                return -1;
        }
        return 0;
@@ -1558,7 +1558,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)
  *                     !!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
  * Returns: 0, -1, -ENODEV
  */
-int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
+int ibmphp_unconfigure_card(struct slot **slot_cur, int the_end)
 {
        int i;
        int count;
@@ -1567,11 +1567,11 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
        struct pci_func *cur_func = NULL;
        struct pci_func *temp_func;
 
-       debug ("%s - enter\n", __func__);
+       debug("%s - enter\n", __func__);
 
        if (!the_end) {
                /* Need to unconfigure the card */
-               rc = unconfigure_boot_card (sl);
+               rc = unconfigure_boot_card(sl);
                if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
                        /* In all other cases, will still need to get rid of func structure if it exists */
                        return rc;
@@ -1591,34 +1591,34 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
 
                        for (i = 0; i < count; i++) {
                                if (cur_func->io[i]) {
-                                       debug ("io[%d] exists\n", i);
+                                       debug("io[%d] exists\n", i);
                                        if (the_end > 0)
-                                               ibmphp_remove_resource (cur_func->io[i]);
+                                               ibmphp_remove_resource(cur_func->io[i]);
                                        cur_func->io[i] = NULL;
                                }
                                if (cur_func->mem[i]) {
-                                       debug ("mem[%d] exists\n", i);
+                                       debug("mem[%d] exists\n", i);
                                        if (the_end > 0)
-                                               ibmphp_remove_resource (cur_func->mem[i]);
+                                               ibmphp_remove_resource(cur_func->mem[i]);
                                        cur_func->mem[i] = NULL;
                                }
                                if (cur_func->pfmem[i]) {
-                                       debug ("pfmem[%d] exists\n", i);
+                                       debug("pfmem[%d] exists\n", i);
                                        if (the_end > 0)
-                                               ibmphp_remove_resource (cur_func->pfmem[i]);
+                                               ibmphp_remove_resource(cur_func->pfmem[i]);
                                        cur_func->pfmem[i] = NULL;
                                }
                        }
 
                        temp_func = cur_func->next;
-                       kfree (cur_func);
+                       kfree(cur_func);
                        cur_func = temp_func;
                }
        }
 
        sl->func = NULL;
        *slot_cur = sl;
-       debug ("%s - exit\n", __func__);
+       debug("%s - exit\n", __func__);
        return 0;
 }
 
@@ -1630,7 +1630,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
  * Output: bus added to the correct spot
  *         0, -1, error
  */
-static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
+static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
 {
        struct range_node *io_range = NULL;
        struct range_node *mem_range = NULL;
@@ -1639,18 +1639,18 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
 
        /* Trying to find the parent bus number */
        if (parent_busno != 0xFF) {
-               cur_bus = ibmphp_find_res_bus (parent_busno);
+               cur_bus = ibmphp_find_res_bus(parent_busno);
                if (!cur_bus) {
-                       err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
+                       err("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
                        return -ENODEV;
                }
 
-               list_add (&bus->bus_list, &cur_bus->bus_list);
+               list_add(&bus->bus_list, &cur_bus->bus_list);
        }
        if (io) {
                io_range = kzalloc(sizeof(*io_range), GFP_KERNEL);
                if (!io_range) {
-                       err ("out of system memory\n");
+                       err("out of system memory\n");
                        return -ENOMEM;
                }
                io_range->start = io->start;
@@ -1662,7 +1662,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
        if (mem) {
                mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL);
                if (!mem_range) {
-                       err ("out of system memory\n");
+                       err("out of system memory\n");
                        return -ENOMEM;
                }
                mem_range->start = mem->start;
@@ -1674,7 +1674,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
        if (pfmem) {
                pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL);
                if (!pfmem_range) {
-                       err ("out of system memory\n");
+                       err("out of system memory\n");
                        return -ENOMEM;
                }
                pfmem_range->start = pfmem->start;
@@ -1691,27 +1691,27 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
  * Parameters: bus_number of the primary bus
  * Returns: bus_number of the secondary bus or 0xff in case of failure
  */
-static u8 find_sec_number (u8 primary_busno, u8 slotno)
+static u8 find_sec_number(u8 primary_busno, u8 slotno)
 {
        int min, max;
        u8 busno;
        struct bus_info *bus;
        struct bus_node *bus_cur;
 
-       bus = ibmphp_find_same_bus_num (primary_busno);
+       bus = ibmphp_find_same_bus_num(primary_busno);
        if (!bus) {
-               err ("cannot get slot range of the bus from the BIOS\n");
+               err("cannot get slot range of the bus from the BIOS\n");
                return 0xff;
        }
        max = bus->slot_max;
        min = bus->slot_min;
        if ((slotno > max) || (slotno < min)) {
-               err ("got the wrong range\n");
+               err("got the wrong range\n");
                return 0xff;
        }
        busno = (u8) (slotno - (u8) min);
        busno += primary_busno + 0x01;
-       bus_cur = ibmphp_find_res_bus (busno);
+       bus_cur = ibmphp_find_res_bus(busno);
        /* either there is no such bus number, or there are no ranges, which
         * can only happen if we removed the bridged device in previous load
         * of the driver, and now only have the skeleton bus struct
index f279060..aee6e41 100644 (file)
 
 static int flags = 0;          /* for testing */
 
-static void update_resources (struct bus_node *bus_cur, int type, int rangeno);
-static int once_over (void);
-static int remove_ranges (struct bus_node *, struct bus_node *);
-static int update_bridge_ranges (struct bus_node **);
-static int add_bus_range (int type, struct range_node *, struct bus_node *);
-static void fix_resources (struct bus_node *);
-static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
+static void update_resources(struct bus_node *bus_cur, int type, int rangeno);
+static int once_over(void);
+static int remove_ranges(struct bus_node *, struct bus_node *);
+static int update_bridge_ranges(struct bus_node **);
+static int add_bus_range(int type, struct range_node *, struct bus_node *);
+static void fix_resources(struct bus_node *);
+static struct bus_node *find_bus_wprev(u8, struct bus_node **, u8);
 
 static LIST_HEAD(gbuses);
 
-static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc *curr, u8 busno, int flag)
+static struct bus_node * __init alloc_error_bus(struct ebda_pci_rsrc *curr, u8 busno, int flag)
 {
        struct bus_node *newbus;
 
        if (!(curr) && !(flag)) {
-               err ("NULL pointer passed\n");
+               err("NULL pointer passed\n");
                return NULL;
        }
 
        newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
        if (!newbus) {
-               err ("out of system memory\n");
+               err("out of system memory\n");
                return NULL;
        }
 
@@ -65,22 +65,22 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc *curr, u8
                newbus->busno = busno;
        else
                newbus->busno = curr->bus_num;
-       list_add_tail (&newbus->bus_list, &gbuses);
+       list_add_tail(&newbus->bus_list, &gbuses);
        return newbus;
 }
 
-static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc *curr)
+static struct resource_node * __init alloc_resources(struct ebda_pci_rsrc *curr)
 {
        struct resource_node *rs;
 
        if (!curr) {
-               err ("NULL passed to allocate\n");
+               err("NULL passed to allocate\n");
                return NULL;
        }
 
        rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
        if (!rs) {
-               err ("out of system memory\n");
+               err("out of system memory\n");
                return NULL;
        }
        rs->busno = curr->bus_num;
@@ -91,7 +91,7 @@ static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc *curr
        return rs;
 }
 
-static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
+static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
 {
        struct bus_node *newbus;
        struct range_node *newrange;
@@ -100,7 +100,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
        if (first_bus) {
                newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
                if (!newbus) {
-                       err ("out of system memory.\n");
+                       err("out of system memory.\n");
                        return -ENOMEM;
                }
                newbus->busno = curr->bus_num;
@@ -122,8 +122,8 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
        newrange = kzalloc(sizeof(struct range_node), GFP_KERNEL);
        if (!newrange) {
                if (first_bus)
-                       kfree (newbus);
-               err ("out of system memory\n");
+                       kfree(newbus);
+               err("out of system memory\n");
                return -ENOMEM;
        }
        newrange->start = curr->start_addr;
@@ -133,8 +133,8 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
                newrange->rangeno = 1;
        else {
                /* need to insert our range */
-               add_bus_range (flag, newrange, newbus);
-               debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
+               add_bus_range(flag, newrange, newbus);
+               debug("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
        }
 
        switch (flag) {
@@ -143,9 +143,9 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
                        if (first_bus)
                                newbus->noMemRanges = 1;
                        else {
-                               debug ("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                               debug("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                ++newbus->noMemRanges;
-                               fix_resources (newbus);
+                               fix_resources(newbus);
                        }
                        break;
                case IO:
@@ -153,9 +153,9 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
                        if (first_bus)
                                newbus->noIORanges = 1;
                        else {
-                               debug ("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                               debug("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                ++newbus->noIORanges;
-                               fix_resources (newbus);
+                               fix_resources(newbus);
                        }
                        break;
                case PFMEM:
@@ -163,9 +163,9 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
                        if (first_bus)
                                newbus->noPFMemRanges = 1;
                        else {
-                               debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                               debug("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                ++newbus->noPFMemRanges;
-                               fix_resources (newbus);
+                               fix_resources(newbus);
                        }
 
                        break;
@@ -183,7 +183,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
  * 2. If cannot allocate out of PFMem range, allocate from Mem ranges.  PFmemFromMem
  * are not sorted. (no need since use mem node). To not change the entire code, we
  * also add mem node whenever this case happens so as not to change
- * ibmphp_check_mem_resource etc (and since it really is taking Mem resource)
+ * ibmphp_check_mem_resource etc(and since it really is taking Mem resource)
  */
 
 /*****************************************************************************
@@ -196,25 +196,23 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
  * Input: ptr to the head of the resource list from EBDA
  * Output: 0, -1 or error codes
  ***************************************************************************/
-int __init ibmphp_rsrc_init (void)
+int __init ibmphp_rsrc_init(void)
 {
        struct ebda_pci_rsrc *curr;
        struct range_node *newrange = NULL;
        struct bus_node *newbus = NULL;
        struct bus_node *bus_cur;
        struct bus_node *bus_prev;
-       struct list_head *tmp;
        struct resource_node *new_io = NULL;
        struct resource_node *new_mem = NULL;
        struct resource_node *new_pfmem = NULL;
        int rc;
-       struct list_head *tmp_ebda;
 
-       list_for_each (tmp_ebda, &ibmphp_ebda_pci_rsrc_head) {
-               curr = list_entry (tmp_ebda, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+       list_for_each_entry(curr, &ibmphp_ebda_pci_rsrc_head,
+                           ebda_pci_rsrc_list) {
                if (!(curr->rsrc_type & PCIDEVMASK)) {
                        /* EBDA still lists non PCI devices, so ignore... */
-                       debug ("this is not a PCI DEVICE in rsrc_init, please take care\n");
+                       debug("this is not a PCI DEVICE in rsrc_init, please take care\n");
                        // continue;
                }
 
@@ -223,17 +221,17 @@ int __init ibmphp_rsrc_init (void)
                        /* memory */
                        if ((curr->rsrc_type & RESTYPE) == MMASK) {
                                /* no bus structure exists in place yet */
-                               if (list_empty (&gbuses)) {
+                               if (list_empty(&gbuses)) {
                                        rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1);
                                        if (rc)
                                                return rc;
-                                       list_add_tail (&newbus->bus_list, &gbuses);
-                                       debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                                       list_add_tail(&newbus->bus_list, &gbuses);
+                                       debug("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                } else {
-                                       bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+                                       bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
                                        /* found our bus */
                                        if (bus_cur) {
-                                               rc = alloc_bus_range (&bus_cur, &newrange, curr, MEM, 0);
+                                               rc = alloc_bus_range(&bus_cur, &newrange, curr, MEM, 0);
                                                if (rc)
                                                        return rc;
                                        } else {
@@ -242,24 +240,24 @@ int __init ibmphp_rsrc_init (void)
                                                if (rc)
                                                        return rc;
 
-                                               list_add_tail (&newbus->bus_list, &gbuses);
-                                               debug ("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                                               list_add_tail(&newbus->bus_list, &gbuses);
+                                               debug("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                        }
                                }
                        } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
                                /* prefetchable memory */
-                               if (list_empty (&gbuses)) {
+                               if (list_empty(&gbuses)) {
                                        /* no bus structure exists in place yet */
                                        rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1);
                                        if (rc)
                                                return rc;
-                                       list_add_tail (&newbus->bus_list, &gbuses);
-                                       debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                                       list_add_tail(&newbus->bus_list, &gbuses);
+                                       debug("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                } else {
-                                       bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+                                       bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
                                        if (bus_cur) {
                                                /* found our bus */
-                                               rc = alloc_bus_range (&bus_cur, &newrange, curr, PFMEM, 0);
+                                               rc = alloc_bus_range(&bus_cur, &newrange, curr, PFMEM, 0);
                                                if (rc)
                                                        return rc;
                                        } else {
@@ -267,23 +265,23 @@ int __init ibmphp_rsrc_init (void)
                                                rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1);
                                                if (rc)
                                                        return rc;
-                                               list_add_tail (&newbus->bus_list, &gbuses);
-                                               debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                                               list_add_tail(&newbus->bus_list, &gbuses);
+                                               debug("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                        }
                                }
                        } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
                                /* IO */
-                               if (list_empty (&gbuses)) {
+                               if (list_empty(&gbuses)) {
                                        /* no bus structure exists in place yet */
                                        rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1);
                                        if (rc)
                                                return rc;
-                                       list_add_tail (&newbus->bus_list, &gbuses);
-                                       debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                                       list_add_tail(&newbus->bus_list, &gbuses);
+                                       debug("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                } else {
-                                       bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+                                       bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
                                        if (bus_cur) {
-                                               rc = alloc_bus_range (&bus_cur, &newrange, curr, IO, 0);
+                                               rc = alloc_bus_range(&bus_cur, &newrange, curr, IO, 0);
                                                if (rc)
                                                        return rc;
                                        } else {
@@ -291,8 +289,8 @@ int __init ibmphp_rsrc_init (void)
                                                rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1);
                                                if (rc)
                                                        return rc;
-                                               list_add_tail (&newbus->bus_list, &gbuses);
-                                               debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+                                               list_add_tail(&newbus->bus_list, &gbuses);
+                                               debug("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
                                        }
                                }
 
@@ -304,7 +302,7 @@ int __init ibmphp_rsrc_init (void)
                        /* regular pci device resource */
                        if ((curr->rsrc_type & RESTYPE) == MMASK) {
                                /* Memory resource */
-                               new_mem = alloc_resources (curr);
+                               new_mem = alloc_resources(curr);
                                if (!new_mem)
                                        return -ENOMEM;
                                new_mem->type = MEM;
@@ -315,25 +313,25 @@ int __init ibmphp_rsrc_init (void)
                                 * assign a -1 and then update once the range
                                 * actually appears...
                                 */
-                               if (ibmphp_add_resource (new_mem) < 0) {
-                                       newbus = alloc_error_bus (curr, 0, 0);
+                               if (ibmphp_add_resource(new_mem) < 0) {
+                                       newbus = alloc_error_bus(curr, 0, 0);
                                        if (!newbus)
                                                return -ENOMEM;
                                        newbus->firstMem = new_mem;
                                        ++newbus->needMemUpdate;
                                        new_mem->rangeno = -1;
                                }
-                               debug ("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
+                               debug("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
 
                        } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
                                /* PFMemory resource */
-                               new_pfmem = alloc_resources (curr);
+                               new_pfmem = alloc_resources(curr);
                                if (!new_pfmem)
                                        return -ENOMEM;
                                new_pfmem->type = PFMEM;
                                new_pfmem->fromMem = 0;
-                               if (ibmphp_add_resource (new_pfmem) < 0) {
-                                       newbus = alloc_error_bus (curr, 0, 0);
+                               if (ibmphp_add_resource(new_pfmem) < 0) {
+                                       newbus = alloc_error_bus(curr, 0, 0);
                                        if (!newbus)
                                                return -ENOMEM;
                                        newbus->firstPFMem = new_pfmem;
@@ -341,10 +339,10 @@ int __init ibmphp_rsrc_init (void)
                                        new_pfmem->rangeno = -1;
                                }
 
-                               debug ("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
+                               debug("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
                        } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
                                /* IO resource */
-                               new_io = alloc_resources (curr);
+                               new_io = alloc_resources(curr);
                                if (!new_io)
                                        return -ENOMEM;
                                new_io->type = IO;
@@ -356,27 +354,26 @@ int __init ibmphp_rsrc_init (void)
                                 * Can assign a -1 and then update once the
                                 * range actually appears...
                                 */
-                               if (ibmphp_add_resource (new_io) < 0) {
-                                       newbus = alloc_error_bus (curr, 0, 0);
+                               if (ibmphp_add_resource(new_io) < 0) {
+                                       newbus = alloc_error_bus(curr, 0, 0);
                                        if (!newbus)
                                                return -ENOMEM;
                                        newbus->firstIO = new_io;
                                        ++newbus->needIOUpdate;
                                        new_io->rangeno = -1;
                                }
-                               debug ("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
+                               debug("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
                        }
                }
        }
 
-       list_for_each (tmp, &gbuses) {
-               bus_cur = list_entry (tmp, struct bus_node, bus_list);
+       list_for_each_entry(bus_cur, &gbuses, bus_list) {
                /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
-               rc = update_bridge_ranges (&bus_cur);
+               rc = update_bridge_ranges(&bus_cur);
                if (rc)
                        return rc;
        }
-       return once_over ();    /* This is to align ranges (so no -1) */
+       return once_over();     /* This is to align ranges (so no -1) */
 }
 
 /********************************************************************************
@@ -387,7 +384,7 @@ int __init ibmphp_rsrc_init (void)
  * Input: type of the resource, range to add, current bus
  * Output: 0 or -1, bus and range ptrs
  ********************************************************************************/
-static int add_bus_range (int type, struct range_node *range, struct bus_node *bus_cur)
+static int add_bus_range(int type, struct range_node *range, struct bus_node *bus_cur)
 {
        struct range_node *range_cur = NULL;
        struct range_node *range_prev;
@@ -452,7 +449,7 @@ static int add_bus_range (int type, struct range_node *range, struct bus_node *b
                range_cur = range_cur->next;
        }
 
-       update_resources (bus_cur, type, i_init + 1);
+       update_resources(bus_cur, type, i_init + 1);
        return 0;
 }
 
@@ -462,7 +459,7 @@ static int add_bus_range (int type, struct range_node *range, struct bus_node *b
  *
  * Input: bus, type of the resource, the rangeno starting from which to update
  ******************************************************************************/
-static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
+static void update_resources(struct bus_node *bus_cur, int type, int rangeno)
 {
        struct resource_node *res = NULL;
        u8 eol = 0;     /* end of list indicator */
@@ -506,9 +503,9 @@ static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
        }
 }
 
-static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
+static void fix_me(struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
 {
-       char * str = "";
+       char *str = "";
        switch (res->type) {
                case IO:
                        str = "io";
@@ -526,7 +523,7 @@ static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct
                        while (range) {
                                if ((res->start >= range->start) && (res->end <= range->end)) {
                                        res->rangeno = range->rangeno;
-                                       debug ("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
+                                       debug("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
                                        switch (res->type) {
                                                case IO:
                                                        --bus_cur->needIOUpdate;
@@ -561,27 +558,27 @@ static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct
  * Input: current bus
  * Output: none, list of resources for that bus are fixed if can be
  *******************************************************************************/
-static void fix_resources (struct bus_node *bus_cur)
+static void fix_resources(struct bus_node *bus_cur)
 {
        struct range_node *range;
        struct resource_node *res;
 
-       debug ("%s - bus_cur->busno = %d\n", __func__, bus_cur->busno);
+       debug("%s - bus_cur->busno = %d\n", __func__, bus_cur->busno);
 
        if (bus_cur->needIOUpdate) {
                res = bus_cur->firstIO;
                range = bus_cur->rangeIO;
-               fix_me (res, bus_cur, range);
+               fix_me(res, bus_cur, range);
        }
        if (bus_cur->needMemUpdate) {
                res = bus_cur->firstMem;
                range = bus_cur->rangeMem;
-               fix_me (res, bus_cur, range);
+               fix_me(res, bus_cur, range);
        }
        if (bus_cur->needPFMemUpdate) {
                res = bus_cur->firstPFMem;
                range = bus_cur->rangePFMem;
-               fix_me (res, bus_cur, range);
+               fix_me(res, bus_cur, range);
        }
 }
 
@@ -594,7 +591,7 @@ static void fix_resources (struct bus_node *bus_cur)
  * Output: ptrs assigned (to the node)
  * 0 or -1
  *******************************************************************************/
-int ibmphp_add_resource (struct resource_node *res)
+int ibmphp_add_resource(struct resource_node *res)
 {
        struct resource_node *res_cur;
        struct resource_node *res_prev;
@@ -602,18 +599,18 @@ int ibmphp_add_resource (struct resource_node *res)
        struct range_node *range_cur = NULL;
        struct resource_node *res_start = NULL;
 
-       debug ("%s - enter\n", __func__);
+       debug("%s - enter\n", __func__);
 
        if (!res) {
-               err ("NULL passed to add\n");
+               err("NULL passed to add\n");
                return -ENODEV;
        }
 
-       bus_cur = find_bus_wprev (res->busno, NULL, 0);
+       bus_cur = find_bus_wprev(res->busno, NULL, 0);
 
        if (!bus_cur) {
                /* didn't find a bus, something's wrong!!! */
-               debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
+               debug("no bus in the system, either pci_dev's wrong or allocation failed\n");
                return -ENODEV;
        }
 
@@ -632,7 +629,7 @@ int ibmphp_add_resource (struct resource_node *res)
                        res_start = bus_cur->firstPFMem;
                        break;
                default:
-                       err ("cannot read the type of the resource to add... problem\n");
+                       err("cannot read the type of the resource to add... problem\n");
                        return -EINVAL;
        }
        while (range_cur) {
@@ -663,7 +660,7 @@ int ibmphp_add_resource (struct resource_node *res)
                res->rangeno = -1;
        }
 
-       debug ("The range is %d\n", res->rangeno);
+       debug("The range is %d\n", res->rangeno);
        if (!res_start) {
                /* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
                switch (res->type) {
@@ -683,7 +680,7 @@ int ibmphp_add_resource (struct resource_node *res)
                res_cur = res_start;
                res_prev = NULL;
 
-               debug ("res_cur->rangeno is %d\n", res_cur->rangeno);
+               debug("res_cur->rangeno is %d\n", res_cur->rangeno);
 
                while (res_cur) {
                        if (res_cur->rangeno >= res->rangeno)
@@ -697,7 +694,7 @@ int ibmphp_add_resource (struct resource_node *res)
 
                if (!res_cur) {
                        /* at the end of the resource list */
-                       debug ("i should be here, [%x - %x]\n", res->start, res->end);
+                       debug("i should be here, [%x - %x]\n", res->start, res->end);
                        res_prev->nextRange = res;
                        res->next = NULL;
                        res->nextRange = NULL;
@@ -765,7 +762,7 @@ int ibmphp_add_resource (struct resource_node *res)
                }
        }
 
-       debug ("%s - exit\n", __func__);
+       debug("%s - exit\n", __func__);
        return 0;
 }
 
@@ -776,23 +773,23 @@ int ibmphp_add_resource (struct resource_node *res)
  * Output: modified resource list
  *        0 or error code
  ****************************************************************************/
-int ibmphp_remove_resource (struct resource_node *res)
+int ibmphp_remove_resource(struct resource_node *res)
 {
        struct bus_node *bus_cur;
        struct resource_node *res_cur = NULL;
        struct resource_node *res_prev;
        struct resource_node *mem_cur;
-       char * type = "";
+       char *type = "";
 
        if (!res)  {
-               err ("resource to remove is NULL\n");
+               err("resource to remove is NULL\n");
                return -ENODEV;
        }
 
-       bus_cur = find_bus_wprev (res->busno, NULL, 0);
+       bus_cur = find_bus_wprev(res->busno, NULL, 0);
 
        if (!bus_cur) {
-               err ("cannot find corresponding bus of the io resource to remove  bailing out...\n");
+               err("cannot find corresponding bus of the io resource to remove  bailing out...\n");
                return -ENODEV;
        }
 
@@ -810,7 +807,7 @@ int ibmphp_remove_resource (struct resource_node *res)
                        type = "pfmem";
                        break;
                default:
-                       err ("unknown type for resource to remove\n");
+                       err("unknown type for resource to remove\n");
                        return -EINVAL;
        }
        res_prev = NULL;
@@ -848,16 +845,16 @@ int ibmphp_remove_resource (struct resource_node *res)
                                                        mem_cur = mem_cur->nextRange;
                                        }
                                        if (!mem_cur) {
-                                               err ("cannot find corresponding mem node for pfmem...\n");
+                                               err("cannot find corresponding mem node for pfmem...\n");
                                                return -EINVAL;
                                        }
 
-                                       ibmphp_remove_resource (mem_cur);
+                                       ibmphp_remove_resource(mem_cur);
                                        if (!res_prev)
                                                bus_cur->firstPFMemFromMem = res_cur->next;
                                        else
                                                res_prev->next = res_cur->next;
-                                       kfree (res_cur);
+                                       kfree(res_cur);
                                        return 0;
                                }
                                res_prev = res_cur;
@@ -867,11 +864,11 @@ int ibmphp_remove_resource (struct resource_node *res)
                                        res_cur = res_cur->nextRange;
                        }
                        if (!res_cur) {
-                               err ("cannot find pfmem to delete...\n");
+                               err("cannot find pfmem to delete...\n");
                                return -EINVAL;
                        }
                } else {
-                       err ("the %s resource is not in the list to be deleted...\n", type);
+                       err("the %s resource is not in the list to be deleted...\n", type);
                        return -EINVAL;
                }
        }
@@ -914,7 +911,7 @@ int ibmphp_remove_resource (struct resource_node *res)
                                        break;
                        }
                }
-               kfree (res_cur);
+               kfree(res_cur);
                return 0;
        } else {
                if (res_cur->next) {
@@ -929,14 +926,14 @@ int ibmphp_remove_resource (struct resource_node *res)
                        res_prev->next = NULL;
                        res_prev->nextRange = NULL;
                }
-               kfree (res_cur);
+               kfree(res_cur);
                return 0;
        }
 
        return 0;
 }
 
-static struct range_node *find_range (struct bus_node *bus_cur, struct resource_node *res)
+static struct range_node *find_range(struct bus_node *bus_cur, struct resource_node *res)
 {
        struct range_node *range = NULL;
 
@@ -951,7 +948,7 @@ static struct range_node *find_range (struct bus_node *bus_cur, struct resource_
                        range = bus_cur->rangePFMem;
                        break;
                default:
-                       err ("cannot read resource type in find_range\n");
+                       err("cannot read resource type in find_range\n");
        }
 
        while (range) {
@@ -971,7 +968,7 @@ static struct range_node *find_range (struct bus_node *bus_cur, struct resource_
  * Output: the correct start and end address are inputted into the resource node,
  *        0 or -EINVAL
  *****************************************************************************/
-int ibmphp_check_resource (struct resource_node *res, u8 bridge)
+int ibmphp_check_resource(struct resource_node *res, u8 bridge)
 {
        struct bus_node *bus_cur;
        struct range_node *range = NULL;
@@ -995,16 +992,16 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
        } else
                tmp_divide = res->len;
 
-       bus_cur = find_bus_wprev (res->busno, NULL, 0);
+       bus_cur = find_bus_wprev(res->busno, NULL, 0);
 
        if (!bus_cur) {
                /* didn't find a bus, something's wrong!!! */
-               debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
+               debug("no bus in the system, either pci_dev's wrong or allocation failed\n");
                return -EINVAL;
        }
 
-       debug ("%s - enter\n", __func__);
-       debug ("bus_cur->busno is %d\n", bus_cur->busno);
+       debug("%s - enter\n", __func__);
+       debug("bus_cur->busno is %d\n", bus_cur->busno);
 
        /* This is a quick fix to not mess up with the code very much.  i.e.,
         * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
@@ -1024,17 +1021,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                        noranges = bus_cur->noPFMemRanges;
                        break;
                default:
-                       err ("wrong type of resource to check\n");
+                       err("wrong type of resource to check\n");
                        return -EINVAL;
        }
        res_prev = NULL;
 
        while (res_cur) {
-               range = find_range (bus_cur, res_cur);
-               debug ("%s - rangeno = %d\n", __func__, res_cur->rangeno);
+               range = find_range(bus_cur, res_cur);
+               debug("%s - rangeno = %d\n", __func__, res_cur->rangeno);
 
                if (!range) {
-                       err ("no range for the device exists... bailing out...\n");
+                       err("no range for the device exists... bailing out...\n");
                        return -EINVAL;
                }
 
@@ -1044,7 +1041,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                        len_tmp = res_cur->start - 1 - range->start;
 
                        if ((res_cur->start != range->start) && (len_tmp >= res->len)) {
-                               debug ("len_tmp = %x\n", len_tmp);
+                               debug("len_tmp = %x\n", len_tmp);
 
                                if ((len_tmp < len_cur) || (len_cur == 0)) {
 
@@ -1072,7 +1069,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                                        }
 
                                        if (flag && len_cur == res->len) {
-                                               debug ("but we are not here, right?\n");
+                                               debug("but we are not here, right?\n");
                                                res->start = start_cur;
                                                res->len += 1; /* To restore the balance */
                                                res->end = res->start + res->len - 1;
@@ -1086,7 +1083,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                        len_tmp = range->end - (res_cur->end + 1);
 
                        if ((range->end != res_cur->end) && (len_tmp >= res->len)) {
-                               debug ("len_tmp = %x\n", len_tmp);
+                               debug("len_tmp = %x\n", len_tmp);
                                if ((len_tmp < len_cur) || (len_cur == 0)) {
 
                                        if (((res_cur->end + 1) % tmp_divide) == 0) {
@@ -1262,7 +1259,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
 
                if ((!range) && (len_cur == 0)) {
                        /* have gone through the list of devices and ranges and haven't found n.e.thing */
-                       err ("no appropriate range.. bailing out...\n");
+                       err("no appropriate range.. bailing out...\n");
                        return -EINVAL;
                } else if (len_cur) {
                        res->start = start_cur;
@@ -1273,7 +1270,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
        }
 
        if (!res_cur) {
-               debug ("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
+               debug("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
                if (res_prev->rangeno < noranges) {
                        /* if there're more ranges out there to check */
                        switch (res->type) {
@@ -1328,7 +1325,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
 
                        if ((!range) && (len_cur == 0)) {
                                /* have gone through the list of devices and ranges and haven't found n.e.thing */
-                               err ("no appropriate range.. bailing out...\n");
+                               err("no appropriate range.. bailing out...\n");
                                return -EINVAL;
                        } else if (len_cur) {
                                res->start = start_cur;
@@ -1345,7 +1342,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                                return 0;
                        } else {
                                /* have gone through the list of devices and haven't found n.e.thing */
-                               err ("no appropriate range.. bailing out...\n");
+                               err("no appropriate range.. bailing out...\n");
                                return -EINVAL;
                        }
                }
@@ -1359,23 +1356,23 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
  * Input: Bus
  * Output: 0, -ENODEV
  ********************************************************************************/
-int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
+int ibmphp_remove_bus(struct bus_node *bus, u8 parent_busno)
 {
        struct resource_node *res_cur;
        struct resource_node *res_tmp;
        struct bus_node *prev_bus;
        int rc;
 
-       prev_bus = find_bus_wprev (parent_busno, NULL, 0);
+       prev_bus = find_bus_wprev(parent_busno, NULL, 0);
 
        if (!prev_bus) {
-               debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
+               debug("something terribly wrong. Cannot find parent bus to the one to remove\n");
                return -ENODEV;
        }
 
-       debug ("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
+       debug("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
 
-       rc = remove_ranges (bus, prev_bus);
+       rc = remove_ranges(bus, prev_bus);
        if (rc)
                return rc;
 
@@ -1387,7 +1384,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
                                res_cur = res_cur->next;
                        else
                                res_cur = res_cur->nextRange;
-                       kfree (res_tmp);
+                       kfree(res_tmp);
                        res_tmp = NULL;
                }
                bus->firstIO = NULL;
@@ -1400,7 +1397,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
                                res_cur = res_cur->next;
                        else
                                res_cur = res_cur->nextRange;
-                       kfree (res_tmp);
+                       kfree(res_tmp);
                        res_tmp = NULL;
                }
                bus->firstMem = NULL;
@@ -1413,7 +1410,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
                                res_cur = res_cur->next;
                        else
                                res_cur = res_cur->nextRange;
-                       kfree (res_tmp);
+                       kfree(res_tmp);
                        res_tmp = NULL;
                }
                bus->firstPFMem = NULL;
@@ -1425,14 +1422,14 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
                        res_tmp = res_cur;
                        res_cur = res_cur->next;
 
-                       kfree (res_tmp);
+                       kfree(res_tmp);
                        res_tmp = NULL;
                }
                bus->firstPFMemFromMem = NULL;
        }
 
-       list_del (&bus->bus_list);
-       kfree (bus);
+       list_del(&bus->bus_list);
+       kfree(bus);
        return 0;
 }
 
@@ -1442,7 +1439,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
  * Input: current bus, previous bus
  * Output: 0, -EINVAL
  ******************************************************************************/
-static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
+static int remove_ranges(struct bus_node *bus_cur, struct bus_node *bus_prev)
 {
        struct range_node *range_cur;
        struct range_node *range_tmp;
@@ -1452,13 +1449,13 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
        if (bus_cur->noIORanges) {
                range_cur = bus_cur->rangeIO;
                for (i = 0; i < bus_cur->noIORanges; i++) {
-                       if (ibmphp_find_resource (bus_prev, range_cur->start, &res, IO) < 0)
+                       if (ibmphp_find_resource(bus_prev, range_cur->start, &res, IO) < 0)
                                return -EINVAL;
-                       ibmphp_remove_resource (res);
+                       ibmphp_remove_resource(res);
 
                        range_tmp = range_cur;
                        range_cur = range_cur->next;
-                       kfree (range_tmp);
+                       kfree(range_tmp);
                        range_tmp = NULL;
                }
                bus_cur->rangeIO = NULL;
@@ -1466,13 +1463,13 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
        if (bus_cur->noMemRanges) {
                range_cur = bus_cur->rangeMem;
                for (i = 0; i < bus_cur->noMemRanges; i++) {
-                       if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0)
+                       if (ibmphp_find_resource(bus_prev, range_cur->start, &res, MEM) < 0)
                                return -EINVAL;
 
-                       ibmphp_remove_resource (res);
+                       ibmphp_remove_resource(res);
                        range_tmp = range_cur;
                        range_cur = range_cur->next;
-                       kfree (range_tmp);
+                       kfree(range_tmp);
                        range_tmp = NULL;
                }
                bus_cur->rangeMem = NULL;
@@ -1480,13 +1477,13 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
        if (bus_cur->noPFMemRanges) {
                range_cur = bus_cur->rangePFMem;
                for (i = 0; i < bus_cur->noPFMemRanges; i++) {
-                       if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0)
+                       if (ibmphp_find_resource(bus_prev, range_cur->start, &res, PFMEM) < 0)
                                return -EINVAL;
 
-                       ibmphp_remove_resource (res);
+                       ibmphp_remove_resource(res);
                        range_tmp = range_cur;
                        range_cur = range_cur->next;
-                       kfree (range_tmp);
+                       kfree(range_tmp);
                        range_tmp = NULL;
                }
                bus_cur->rangePFMem = NULL;
@@ -1498,13 +1495,13 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
  * find the resource node in the bus
  * Input: Resource needed, start address of the resource, type of resource
  */
-int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
+int ibmphp_find_resource(struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
 {
        struct resource_node *res_cur = NULL;
-       char * type = "";
+       char *type = "";
 
        if (!bus) {
-               err ("The bus passed in NULL to find resource\n");
+               err("The bus passed in NULL to find resource\n");
                return -ENODEV;
        }
 
@@ -1522,7 +1519,7 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour
                        type = "pfmem";
                        break;
                default:
-                       err ("wrong type of flag\n");
+                       err("wrong type of flag\n");
                        return -EINVAL;
        }
 
@@ -1548,17 +1545,17 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour
                                res_cur = res_cur->next;
                        }
                        if (!res_cur) {
-                               debug ("SOS...cannot find %s resource in the bus.\n", type);
+                               debug("SOS...cannot find %s resource in the bus.\n", type);
                                return -EINVAL;
                        }
                } else {
-                       debug ("SOS... cannot find %s resource in the bus.\n", type);
+                       debug("SOS... cannot find %s resource in the bus.\n", type);
                        return -EINVAL;
                }
        }
 
        if (*res)
-               debug ("*res->start = %x\n", (*res)->start);
+               debug("*res->start = %x\n", (*res)->start);
 
        return 0;
 }
@@ -1569,21 +1566,18 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour
  * Parameters: none
  * Returns: none
  ***********************************************************************/
-void ibmphp_free_resources (void)
+void ibmphp_free_resources(void)
 {
-       struct bus_node *bus_cur = NULL;
+       struct bus_node *bus_cur = NULL, *next;
        struct bus_node *bus_tmp;
        struct range_node *range_cur;
        struct range_node *range_tmp;
        struct resource_node *res_cur;
        struct resource_node *res_tmp;
-       struct list_head *tmp;
-       struct list_head *next;
        int i = 0;
        flags = 1;
 
-       list_for_each_safe (tmp, next, &gbuses) {
-               bus_cur = list_entry (tmp, struct bus_node, bus_list);
+       list_for_each_entry_safe(bus_cur, next, &gbuses, bus_list) {
                if (bus_cur->noIORanges) {
                        range_cur = bus_cur->rangeIO;
                        for (i = 0; i < bus_cur->noIORanges; i++) {
@@ -1591,7 +1585,7 @@ void ibmphp_free_resources (void)
                                        break;
                                range_tmp = range_cur;
                                range_cur = range_cur->next;
-                               kfree (range_tmp);
+                               kfree(range_tmp);
                                range_tmp = NULL;
                        }
                }
@@ -1602,7 +1596,7 @@ void ibmphp_free_resources (void)
                                        break;
                                range_tmp = range_cur;
                                range_cur = range_cur->next;
-                               kfree (range_tmp);
+                               kfree(range_tmp);
                                range_tmp = NULL;
                        }
                }
@@ -1613,7 +1607,7 @@ void ibmphp_free_resources (void)
                                        break;
                                range_tmp = range_cur;
                                range_cur = range_cur->next;
-                               kfree (range_tmp);
+                               kfree(range_tmp);
                                range_tmp = NULL;
                        }
                }
@@ -1626,7 +1620,7 @@ void ibmphp_free_resources (void)
                                        res_cur = res_cur->next;
                                else
                                        res_cur = res_cur->nextRange;
-                               kfree (res_tmp);
+                               kfree(res_tmp);
                                res_tmp = NULL;
                        }
                        bus_cur->firstIO = NULL;
@@ -1639,7 +1633,7 @@ void ibmphp_free_resources (void)
                                        res_cur = res_cur->next;
                                else
                                        res_cur = res_cur->nextRange;
-                               kfree (res_tmp);
+                               kfree(res_tmp);
                                res_tmp = NULL;
                        }
                        bus_cur->firstMem = NULL;
@@ -1652,7 +1646,7 @@ void ibmphp_free_resources (void)
                                        res_cur = res_cur->next;
                                else
                                        res_cur = res_cur->nextRange;
-                               kfree (res_tmp);
+                               kfree(res_tmp);
                                res_tmp = NULL;
                        }
                        bus_cur->firstPFMem = NULL;
@@ -1664,15 +1658,15 @@ void ibmphp_free_resources (void)
                                res_tmp = res_cur;
                                res_cur = res_cur->next;
 
-                               kfree (res_tmp);
+                               kfree(res_tmp);
                                res_tmp = NULL;
                        }
                        bus_cur->firstPFMemFromMem = NULL;
                }
 
                bus_tmp = bus_cur;
-               list_del (&bus_cur->bus_list);
-               kfree (bus_tmp);
+               list_del(&bus_cur->bus_list);
+               kfree(bus_tmp);
                bus_tmp = NULL;
        }
 }
@@ -1685,16 +1679,14 @@ void ibmphp_free_resources (void)
  * a new Mem node
  * This routine is called right after initialization
  *******************************************************************************/
-static int __init once_over (void)
+static int __init once_over(void)
 {
        struct resource_node *pfmem_cur;
        struct resource_node *pfmem_prev;
        struct resource_node *mem;
        struct bus_node *bus_cur;
-       struct list_head *tmp;
 
-       list_for_each (tmp, &gbuses) {
-               bus_cur = list_entry (tmp, struct bus_node, bus_list);
+       list_for_each_entry(bus_cur, &gbuses, bus_list) {
                if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
                        for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
                                pfmem_cur->fromMem = 1;
@@ -1716,7 +1708,7 @@ static int __init once_over (void)
 
                                mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!mem) {
-                                       err ("out of system memory\n");
+                                       err("out of system memory\n");
                                        return -ENOMEM;
                                }
                                mem->type = MEM;
@@ -1725,8 +1717,8 @@ static int __init once_over (void)
                                mem->start = pfmem_cur->start;
                                mem->end = pfmem_cur->end;
                                mem->len = pfmem_cur->len;
-                               if (ibmphp_add_resource (mem) < 0)
-                                       err ("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
+                               if (ibmphp_add_resource(mem) < 0)
+                                       err("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
                                pfmem_cur->rangeno = mem->rangeno;
                        }       /* end for pfmem */
                }       /* end if */
@@ -1734,12 +1726,12 @@ static int __init once_over (void)
        return 0;
 }
 
-int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
+int ibmphp_add_pfmem_from_mem(struct resource_node *pfmem)
 {
-       struct bus_node *bus_cur = find_bus_wprev (pfmem->busno, NULL, 0);
+       struct bus_node *bus_cur = find_bus_wprev(pfmem->busno, NULL, 0);
 
        if (!bus_cur) {
-               err ("cannot find bus of pfmem to add...\n");
+               err("cannot find bus of pfmem to add...\n");
                return -ENODEV;
        }
 
@@ -1759,22 +1751,18 @@ int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
  * Parameters: bus_number
  * Returns: Bus pointer or NULL
  */
-struct bus_node *ibmphp_find_res_bus (u8 bus_number)
+struct bus_node *ibmphp_find_res_bus(u8 bus_number)
 {
-       return find_bus_wprev (bus_number, NULL, 0);
+       return find_bus_wprev(bus_number, NULL, 0);
 }
 
-static struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag)
+static struct bus_node *find_bus_wprev(u8 bus_number, struct bus_node **prev, u8 flag)
 {
        struct bus_node *bus_cur;
-       struct list_head *tmp;
-       struct list_head *tmp_prev;
 
-       list_for_each (tmp, &gbuses) {
-               tmp_prev = tmp->prev;
-               bus_cur = list_entry (tmp, struct bus_node, bus_list);
+       list_for_each_entry(bus_cur, &gbuses, bus_list) {
                if (flag)
-                       *prev = list_entry (tmp_prev, struct bus_node, bus_list);
+                       *prev = list_prev_entry(bus_cur, bus_list);
                if (bus_cur->busno == bus_number)
                        return bus_cur;
        }
@@ -1782,23 +1770,21 @@ static struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u
        return NULL;
 }
 
-void ibmphp_print_test (void)
+void ibmphp_print_test(void)
 {
        int i = 0;
        struct bus_node *bus_cur = NULL;
        struct range_node *range;
        struct resource_node *res;
-       struct list_head *tmp;
 
-       debug_pci ("*****************START**********************\n");
+       debug_pci("*****************START**********************\n");
 
        if ((!list_empty(&gbuses)) && flags) {
-               err ("The GBUSES is not NULL?!?!?!?!?\n");
+               err("The GBUSES is not NULL?!?!?!?!?\n");
                return;
        }
 
-       list_for_each (tmp, &gbuses) {
-               bus_cur = list_entry (tmp, struct bus_node, bus_list);
+       list_for_each_entry(bus_cur, &gbuses, bus_list) {
                debug_pci ("This is bus # %d.  There are\n", bus_cur->busno);
                debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
                debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
@@ -1807,42 +1793,42 @@ void ibmphp_print_test (void)
                if (bus_cur->rangeIO) {
                        range = bus_cur->rangeIO;
                        for (i = 0; i < bus_cur->noIORanges; i++) {
-                               debug_pci ("rangeno is %d\n", range->rangeno);
-                               debug_pci ("[%x - %x]\n", range->start, range->end);
+                               debug_pci("rangeno is %d\n", range->rangeno);
+                               debug_pci("[%x - %x]\n", range->start, range->end);
                                range = range->next;
                        }
                }
 
-               debug_pci ("The Mem Ranges are as follows:\n");
+               debug_pci("The Mem Ranges are as follows:\n");
                if (bus_cur->rangeMem) {
                        range = bus_cur->rangeMem;
                        for (i = 0; i < bus_cur->noMemRanges; i++) {
-                               debug_pci ("rangeno is %d\n", range->rangeno);
-                               debug_pci ("[%x - %x]\n", range->start, range->end);
+                               debug_pci("rangeno is %d\n", range->rangeno);
+                               debug_pci("[%x - %x]\n", range->start, range->end);
                                range = range->next;
                        }
                }
 
-               debug_pci ("The PFMem Ranges are as follows:\n");
+               debug_pci("The PFMem Ranges are as follows:\n");
 
                if (bus_cur->rangePFMem) {
                        range = bus_cur->rangePFMem;
                        for (i = 0; i < bus_cur->noPFMemRanges; i++) {
-                               debug_pci ("rangeno is %d\n", range->rangeno);
-                               debug_pci ("[%x - %x]\n", range->start, range->end);
+                               debug_pci("rangeno is %d\n", range->rangeno);
+                               debug_pci("[%x - %x]\n", range->start, range->end);
                                range = range->next;
                        }
                }
 
-               debug_pci ("The resources on this bus are as follows\n");
+               debug_pci("The resources on this bus are as follows\n");
 
-               debug_pci ("IO...\n");
+               debug_pci("IO...\n");
                if (bus_cur->firstIO) {
                        res = bus_cur->firstIO;
                        while (res) {
-                               debug_pci ("The range # is %d\n", res->rangeno);
-                               debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-                               debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+                               debug_pci("The range # is %d\n", res->rangeno);
+                               debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+                               debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
                                if (res->next)
                                        res = res->next;
                                else if (res->nextRange)
@@ -1851,13 +1837,13 @@ void ibmphp_print_test (void)
                                        break;
                        }
                }
-               debug_pci ("Mem...\n");
+               debug_pci("Mem...\n");
                if (bus_cur->firstMem) {
                        res = bus_cur->firstMem;
                        while (res) {
-                               debug_pci ("The range # is %d\n", res->rangeno);
-                               debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-                               debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+                               debug_pci("The range # is %d\n", res->rangeno);
+                               debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+                               debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
                                if (res->next)
                                        res = res->next;
                                else if (res->nextRange)
@@ -1866,13 +1852,13 @@ void ibmphp_print_test (void)
                                        break;
                        }
                }
-               debug_pci ("PFMem...\n");
+               debug_pci("PFMem...\n");
                if (bus_cur->firstPFMem) {
                        res = bus_cur->firstPFMem;
                        while (res) {
-                               debug_pci ("The range # is %d\n", res->rangeno);
-                               debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-                               debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+                               debug_pci("The range # is %d\n", res->rangeno);
+                               debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+                               debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
                                if (res->next)
                                        res = res->next;
                                else if (res->nextRange)
@@ -1882,23 +1868,23 @@ void ibmphp_print_test (void)
                        }
                }
 
-               debug_pci ("PFMemFromMem...\n");
+               debug_pci("PFMemFromMem...\n");
                if (bus_cur->firstPFMemFromMem) {
                        res = bus_cur->firstPFMemFromMem;
                        while (res) {
-                               debug_pci ("The range # is %d\n", res->rangeno);
-                               debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-                               debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+                               debug_pci("The range # is %d\n", res->rangeno);
+                               debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+                               debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
                                res = res->next;
                        }
                }
        }
-       debug_pci ("***********************END***********************\n");
+       debug_pci("***********************END***********************\n");
 }
 
-static int range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
+static int range_exists_already(struct range_node *range, struct bus_node *bus_cur, u8 type)
 {
-       struct range_node * range_cur = NULL;
+       struct range_node *range_cur = NULL;
        switch (type) {
                case IO:
                        range_cur = bus_cur->rangeIO;
@@ -1910,7 +1896,7 @@ static int range_exists_already (struct range_node * range, struct bus_node * bu
                        range_cur = bus_cur->rangePFMem;
                        break;
                default:
-                       err ("wrong type passed to find out if range already exists\n");
+                       err("wrong type passed to find out if range already exists\n");
                        return -ENODEV;
        }
 
@@ -1937,7 +1923,7 @@ static int range_exists_already (struct range_node * range, struct bus_node * bu
  *      behind them All these are TO DO.
  *      Also need to add more error checkings... (from fnc returns etc)
  */
-static int __init update_bridge_ranges (struct bus_node **bus)
+static int __init update_bridge_ranges(struct bus_node **bus)
 {
        u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
        u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
@@ -1955,17 +1941,17 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                return -ENODEV;
        ibmphp_pci_bus->number = bus_cur->busno;
 
-       debug ("inside %s\n", __func__);
-       debug ("bus_cur->busno = %x\n", bus_cur->busno);
+       debug("inside %s\n", __func__);
+       debug("bus_cur->busno = %x\n", bus_cur->busno);
 
        for (device = 0; device < 32; device++) {
                for (function = 0x00; function < 0x08; function++) {
                        devfn = PCI_DEVFN(device, function);
-                       pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+                       pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
 
                        if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
                                /* found correct device!!! */
-                               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+                               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
 
                                switch (hdr_type) {
                                        case PCI_HEADER_TYPE_NORMAL:
@@ -1984,18 +1970,18 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                   temp++;
                                                   }
                                                 */
-                                               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
-                                               bus_sec = find_bus_wprev (sec_busno, NULL, 0);
+                                               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
+                                               bus_sec = find_bus_wprev(sec_busno, NULL, 0);
                                                /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
                                                if (!bus_sec) {
-                                                       bus_sec = alloc_error_bus (NULL, sec_busno, 1);
+                                                       bus_sec = alloc_error_bus(NULL, sec_busno, 1);
                                                        /* the rest will be populated during NVRAM call */
                                                        return 0;
                                                }
-                                               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
-                                               pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
-                                               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
-                                               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
+                                               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
+                                               pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
+                                               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
+                                               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
                                                start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
                                                start_address |= (upper_io_start << 16);
                                                end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
@@ -2004,18 +1990,18 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                if ((start_address) && (start_address <= end_address)) {
                                                        range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
                                                        if (!range) {
-                                                               err ("out of system memory\n");
+                                                               err("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
                                                        range->start = start_address;
                                                        range->end = end_address + 0xfff;
 
                                                        if (bus_sec->noIORanges > 0) {
-                                                               if (!range_exists_already (range, bus_sec, IO)) {
-                                                                       add_bus_range (IO, range, bus_sec);
+                                                               if (!range_exists_already(range, bus_sec, IO)) {
+                                                                       add_bus_range(IO, range, bus_sec);
                                                                        ++bus_sec->noIORanges;
                                                                } else {
-                                                                       kfree (range);
+                                                                       kfree(range);
                                                                        range = NULL;
                                                                }
                                                        } else {
@@ -2024,13 +2010,13 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                                bus_sec->rangeIO = range;
                                                                ++bus_sec->noIORanges;
                                                        }
-                                                       fix_resources (bus_sec);
+                                                       fix_resources(bus_sec);
 
-                                                       if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
+                                                       if (ibmphp_find_resource(bus_cur, start_address, &io, IO)) {
                                                                io = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                                                if (!io) {
-                                                                       kfree (range);
-                                                                       err ("out of system memory\n");
+                                                                       kfree(range);
+                                                                       err("out of system memory\n");
                                                                        return -ENOMEM;
                                                                }
                                                                io->type = IO;
@@ -2039,12 +2025,12 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                                io->start = start_address;
                                                                io->end = end_address + 0xfff;
                                                                io->len = io->end - io->start + 1;
-                                                               ibmphp_add_resource (io);
+                                                               ibmphp_add_resource(io);
                                                        }
                                                }
 
-                                               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
-                                               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
+                                               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
+                                               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
 
                                                start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
                                                end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
@@ -2053,18 +2039,18 @@ static int __init update_bridge_ranges (struct bus_node **bus)
 
                                                        range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
                                                        if (!range) {
-                                                               err ("out of system memory\n");
+                                                               err("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
                                                        range->start = start_address;
                                                        range->end = end_address + 0xfffff;
 
                                                        if (bus_sec->noMemRanges > 0) {
-                                                               if (!range_exists_already (range, bus_sec, MEM)) {
-                                                                       add_bus_range (MEM, range, bus_sec);
+                                                               if (!range_exists_already(range, bus_sec, MEM)) {
+                                                                       add_bus_range(MEM, range, bus_sec);
                                                                        ++bus_sec->noMemRanges;
                                                                } else {
-                                                                       kfree (range);
+                                                                       kfree(range);
                                                                        range = NULL;
                                                                }
                                                        } else {
@@ -2074,13 +2060,13 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                                ++bus_sec->noMemRanges;
                                                        }
 
-                                                       fix_resources (bus_sec);
+                                                       fix_resources(bus_sec);
 
-                                                       if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
+                                                       if (ibmphp_find_resource(bus_cur, start_address, &mem, MEM)) {
                                                                mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                                                if (!mem) {
-                                                                       kfree (range);
-                                                                       err ("out of system memory\n");
+                                                                       kfree(range);
+                                                                       err("out of system memory\n");
                                                                        return -ENOMEM;
                                                                }
                                                                mem->type = MEM;
@@ -2089,13 +2075,13 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                                mem->start = start_address;
                                                                mem->end = end_address + 0xfffff;
                                                                mem->len = mem->end - mem->start + 1;
-                                                               ibmphp_add_resource (mem);
+                                                               ibmphp_add_resource(mem);
                                                        }
                                                }
-                                               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
-                                               pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
-                                               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
-                                               pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
+                                               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
+                                               pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
+                                               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
+                                               pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
                                                start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
                                                end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
 #if BITS_PER_LONG == 64
@@ -2107,18 +2093,18 @@ static int __init update_bridge_ranges (struct bus_node **bus)
 
                                                        range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
                                                        if (!range) {
-                                                               err ("out of system memory\n");
+                                                               err("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
                                                        range->start = start_address;
                                                        range->end = end_address + 0xfffff;
 
                                                        if (bus_sec->noPFMemRanges > 0) {
-                                                               if (!range_exists_already (range, bus_sec, PFMEM)) {
-                                                                       add_bus_range (PFMEM, range, bus_sec);
+                                                               if (!range_exists_already(range, bus_sec, PFMEM)) {
+                                                                       add_bus_range(PFMEM, range, bus_sec);
                                                                        ++bus_sec->noPFMemRanges;
                                                                } else {
-                                                                       kfree (range);
+                                                                       kfree(range);
                                                                        range = NULL;
                                                                }
                                                        } else {
@@ -2128,12 +2114,12 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                                ++bus_sec->noPFMemRanges;
                                                        }
 
-                                                       fix_resources (bus_sec);
-                                                       if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
+                                                       fix_resources(bus_sec);
+                                                       if (ibmphp_find_resource(bus_cur, start_address, &pfmem, PFMEM)) {
                                                                pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                                                if (!pfmem) {
-                                                                       kfree (range);
-                                                                       err ("out of system memory\n");
+                                                                       kfree(range);
+                                                                       err("out of system memory\n");
                                                                        return -ENOMEM;
                                                                }
                                                                pfmem->type = PFMEM;
@@ -2144,7 +2130,7 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                                pfmem->len = pfmem->end - pfmem->start + 1;
                                                                pfmem->fromMem = 0;
 
-                                                               ibmphp_add_resource (pfmem);
+                                                               ibmphp_add_resource(pfmem);
                                                        }
                                                }
                                                break;
index d1fab97..9acd199 100644 (file)
 
 #define MY_NAME        "pci_hotplug"
 
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __func__ , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __func__, ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 
 /* local variables */
@@ -226,7 +226,7 @@ static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf,
        u32 test;
        int retval = 0;
 
-       ltest = simple_strtoul (buf, NULL, 10);
+       ltest = simple_strtoul(buf, NULL, 10);
        test = (u32)(ltest & 0xffffffff);
        dbg("test = %d\n", test);
 
@@ -396,10 +396,8 @@ static void fs_remove_slot(struct pci_slot *pci_slot)
 static struct hotplug_slot *get_slot_from_name(const char *name)
 {
        struct hotplug_slot *slot;
-       struct list_head *tmp;
 
-       list_for_each(tmp, &pci_hotplug_slot_list) {
-               slot = list_entry(tmp, struct hotplug_slot, slot_list);
+       list_for_each_entry(slot, &pci_hotplug_slot_list, slot_list) {
                if (strcmp(hotplug_slot_name(slot), name) == 0)
                        return slot;
        }
index 62d6fe6..e764918 100644 (file)
@@ -47,14 +47,14 @@ extern bool pciehp_debug;
 #define dbg(format, arg...)                                            \
 do {                                                                   \
        if (pciehp_debug)                                               \
-               printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg);     \
+               printk(KERN_DEBUG "%s: " format, MY_NAME, ## arg);      \
 } while (0)
 #define err(format, arg...)                                            \
-       printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+       printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
 #define info(format, arg...)                                           \
-       printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+       printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
 #define warn(format, arg...)                                           \
-       printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+       printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 #define ctrl_dbg(ctrl, format, arg...)                                 \
        do {                                                            \
index 612b21a..ac531e6 100644 (file)
@@ -62,14 +62,14 @@ MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");
 
 #define PCIE_MODULE_NAME "pciehp"
 
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int enable_slot         (struct hotplug_slot *slot);
-static int disable_slot                (struct hotplug_slot *slot);
-static int get_power_status    (struct hotplug_slot *slot, u8 *value);
-static int get_attention_status        (struct hotplug_slot *slot, u8 *value);
-static int get_latch_status    (struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status  (struct hotplug_slot *slot, u8 *value);
-static int reset_slot          (struct hotplug_slot *slot, int probe);
+static int set_attention_status(struct hotplug_slot *slot, u8 value);
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int get_power_status(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
+static int reset_slot(struct hotplug_slot *slot, int probe);
 
 /**
  * release_slot - free up the memory used by a slot
index 4c8f4cd..880978b 100644 (file)
@@ -511,7 +511,9 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
        case STATIC_STATE:
                p_slot->state = POWEROFF_STATE;
                mutex_unlock(&p_slot->lock);
+               mutex_lock(&p_slot->hotplug_lock);
                retval = pciehp_disable_slot(p_slot);
+               mutex_unlock(&p_slot->hotplug_lock);
                mutex_lock(&p_slot->lock);
                p_slot->state = STATIC_STATE;
                break;
index d062c00..172ed89 100644 (file)
@@ -52,11 +52,11 @@ static LIST_HEAD(slot_list);
        do {                                                    \
                if (debug)                                      \
                        printk(KERN_DEBUG "%s: " format "\n",   \
-                               MY_NAME , ## arg);              \
+                               MY_NAME, ## arg);               \
        } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME, ## arg)
 
 /* local variables */
 static bool debug;
@@ -72,14 +72,14 @@ MODULE_LICENSE("GPL");
 module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
 
-static int enable_slot         (struct hotplug_slot *slot);
-static int disable_slot                (struct hotplug_slot *slot);
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int hardware_test       (struct hotplug_slot *slot, u32 value);
-static int get_power_status    (struct hotplug_slot *slot, u8 *value);
-static int get_attention_status        (struct hotplug_slot *slot, u8 *value);
-static int get_latch_status    (struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status  (struct hotplug_slot *slot, u8 *value);
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int set_attention_status(struct hotplug_slot *slot, u8 value);
+static int hardware_test(struct hotplug_slot *slot, u32 value);
+static int get_power_status(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
 
 static struct hotplug_slot_ops skel_hotplug_slot_ops = {
        .enable_slot =          enable_slot,
@@ -321,17 +321,14 @@ error:
 
 static void __exit cleanup_slots(void)
 {
-       struct list_head *tmp;
-       struct list_head *next;
-       struct slot *slot;
+       struct slot *slot, *next;
 
        /*
         * Unregister all of our slots with the pci_hotplug subsystem.
         * Memory will be freed in release_slot() callback after slot's
         * lifespan is finished.
         */
-       list_for_each_safe(tmp, next, &slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
+       list_for_each_entry_safe(slot, next, &slot_list, slot_list) {
                list_del(&slot->slot_list);
                pci_hp_deregister(slot->hotplug_slot);
        }
index e12bafd..b46b57d 100644 (file)
@@ -114,11 +114,10 @@ static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
  */
 static struct slot *find_php_slot(struct device_node *dn)
 {
-       struct list_head *tmp, *n;
-       struct slot *slot;
+       struct slot *slot, *next;
 
-       list_for_each_safe(tmp, n, &rpaphp_slot_head) {
-               slot = list_entry(tmp, struct slot, rpaphp_slot_list);
+       list_for_each_entry_safe(slot, next, &rpaphp_slot_head,
+                                rpaphp_slot_list) {
                if (slot->dn == dn)
                        return slot;
        }
index b2593e8..7db024e 100644 (file)
@@ -51,11 +51,11 @@ extern bool rpaphp_debug;
        do {                                                    \
                if (rpaphp_debug)                               \
                        printk(KERN_DEBUG "%s: " format,        \
-                               MY_NAME , ## arg);              \
+                               MY_NAME, ## arg);               \
        } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 /* slot states */
 
index f2945fa..611f605 100644 (file)
@@ -94,7 +94,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
        int retval, level;
        struct slot *slot = (struct slot *)hotplug_slot->private;
 
-       retval = rtas_get_power_level (slot->power_domain, &level);
+       retval = rtas_get_power_level(slot->power_domain, &level);
        if (!retval)
                *value = level;
        return retval;
@@ -356,8 +356,7 @@ EXPORT_SYMBOL_GPL(rpaphp_add_slot);
 
 static void __exit cleanup_slots(void)
 {
-       struct list_head *tmp, *n;
-       struct slot *slot;
+       struct slot *slot, *next;
 
        /*
         * Unregister all of our slots with the pci_hotplug subsystem,
@@ -365,8 +364,8 @@ static void __exit cleanup_slots(void)
         * memory will be freed in release_slot callback.
         */
 
-       list_for_each_safe(tmp, n, &rpaphp_slot_head) {
-               slot = list_entry(tmp, struct slot, rpaphp_slot_list);
+       list_for_each_entry_safe(slot, next, &rpaphp_slot_head,
+                                rpaphp_slot_list) {
                list_del(&slot->rpaphp_slot_list);
                pci_hp_deregister(slot->hotplug_slot);
        }
index 9243f3e..7836d69 100644 (file)
@@ -126,7 +126,7 @@ int rpaphp_enable_slot(struct slot *slot)
                if (rpaphp_debug) {
                        struct pci_dev *dev;
                        dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name);
-                       list_for_each_entry (dev, &bus->devices, bus_list)
+                       list_for_each_entry(dev, &bus->devices, bus_list)
                                dbg("\t%s\n", pci_name(dev));
                }
        }
index a6082cc..6937c72 100644 (file)
@@ -48,7 +48,7 @@ void dealloc_slot_struct(struct slot *slot)
 }
 
 struct slot *alloc_slot_struct(struct device_node *dn,
-                       int drc_index, char *drc_name, int power_domain)
+               int drc_index, char *drc_name, int power_domain)
 {
        struct slot *slot;
 
index d77e46b..eb5efae 100644 (file)
@@ -201,11 +201,10 @@ error:
 
 void zpci_exit_slot(struct zpci_dev *zdev)
 {
-       struct list_head *tmp, *n;
-       struct slot *slot;
+       struct slot *slot, *next;
 
-       list_for_each_safe(tmp, n, &s390_hotplug_slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
+       list_for_each_entry_safe(slot, next, &s390_hotplug_slot_list,
+                                slot_list) {
                if (slot->zdev != zdev)
                        continue;
                list_del(&slot->slot_list);
index c32fb78..339bce0 100644 (file)
@@ -99,7 +99,7 @@ static ssize_t path_show(struct pci_slot *pci_slot, char *buf)
        if (!slot)
                return retval;
 
-       retval = sprintf (buf, "%s\n", slot->physical_path);
+       retval = sprintf(buf, "%s\n", slot->physical_path);
        return retval;
 }
 
@@ -313,7 +313,7 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
        }
 
        if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
-               dev_dbg(&slot->pci_bus->self->dev,"remove failed rc = %d\n", rc);
+               dev_dbg(&slot->pci_bus->self->dev, "remove failed rc = %d\n", rc);
        }
 
        return rc;
@@ -488,7 +488,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
 
        /* free the ACPI resources for the slot */
        if (SN_ACPI_BASE_SUPPORT() &&
-            PCI_CONTROLLER(slot->pci_bus)->companion) {
+               PCI_CONTROLLER(slot->pci_bus)->companion) {
                unsigned long long adr;
                struct acpi_device *device;
                acpi_handle phandle;
index 5897d51..4da8fc6 100644 (file)
@@ -50,14 +50,14 @@ extern bool shpchp_debug;
 #define dbg(format, arg...)                                            \
 do {                                                                   \
        if (shpchp_debug)                                               \
-               printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg);     \
+               printk(KERN_DEBUG "%s: " format, MY_NAME, ## arg);      \
 } while (0)
 #define err(format, arg...)                                            \
-       printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+       printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
 #define info(format, arg...)                                           \
-       printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+       printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
 #define warn(format, arg...)                                           \
-       printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+       printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
 
 #define ctrl_dbg(ctrl, format, arg...)                                 \
        do {                                                            \
@@ -84,7 +84,7 @@ struct slot {
        u8 presence_save;
        u8 pwr_save;
        struct controller *ctrl;
-       struct hpc_ops *hpc_ops;
+       const struct hpc_ops *hpc_ops;
        struct hotplug_slot *hotplug_slot;
        struct list_head        slot_list;
        struct delayed_work work;       /* work for button event */
@@ -106,7 +106,7 @@ struct controller {
        int slot_num_inc;               /* 1 or -1 */
        struct pci_dev *pci_dev;
        struct list_head slot_list;
-       struct hpc_ops *hpc_ops;
+       const struct hpc_ops *hpc_ops;
        wait_queue_head_t queue;        /* sleep & wake process */
        u8 slot_device_offset;
        u32 pcix_misc2_reg;     /* for amd pogo errata */
@@ -295,7 +295,7 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
                pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, rse_set);
        }
        /* restore MiscII register */
-       pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp );
+       pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp);
 
        if (p_slot->ctrl->pcix_misc2_reg & SERRFATALENABLE_MASK)
                pcix_misc2_temp |= SERRFATALENABLE_MASK;
index 294ef4b..3454dc7 100644 (file)
@@ -57,13 +57,13 @@ MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
 
 #define SHPC_MODULE_NAME "shpchp"
 
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int enable_slot         (struct hotplug_slot *slot);
-static int disable_slot                (struct hotplug_slot *slot);
-static int get_power_status    (struct hotplug_slot *slot, u8 *value);
-static int get_attention_status        (struct hotplug_slot *slot, u8 *value);
-static int get_latch_status    (struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status  (struct hotplug_slot *slot, u8 *value);
+static int set_attention_status(struct hotplug_slot *slot, u8 value);
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int get_power_status(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 *value);
 
 static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
        .set_attention_status = set_attention_status,
@@ -178,12 +178,9 @@ error:
 
 void cleanup_slots(struct controller *ctrl)
 {
-       struct list_head *tmp;
-       struct list_head *next;
-       struct slot *slot;
+       struct slot *slot, *next;
 
-       list_for_each_safe(tmp, next, &ctrl->slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
+       list_for_each_entry_safe(slot, next, &ctrl->slot_list, slot_list) {
                list_del(&slot->slot_list);
                cancel_delayed_work(&slot->work);
                destroy_workqueue(slot->wq);
@@ -194,7 +191,7 @@ void cleanup_slots(struct controller *ctrl)
 /*
  * set_attention_status - Turns the Amber LED for a slot on, off or blink
  */
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
 {
        struct slot *slot = get_slot(hotplug_slot);
 
@@ -207,7 +204,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
        return 0;
 }
 
-static int enable_slot (struct hotplug_slot *hotplug_slot)
+static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = get_slot(hotplug_slot);
 
@@ -217,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot)
        return shpchp_sysfs_enable_slot(slot);
 }
 
-static int disable_slot (struct hotplug_slot *hotplug_slot)
+static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = get_slot(hotplug_slot);
 
@@ -227,7 +224,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot)
        return shpchp_sysfs_disable_slot(slot);
 }
 
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
@@ -242,7 +239,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
        return 0;
 }
 
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
@@ -257,7 +254,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
        return 0;
 }
 
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
@@ -272,7 +269,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
        return 0;
 }
 
-static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
index 7d223e9..de0ea47 100644 (file)
@@ -542,7 +542,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
        u8 slot_cmd = 0;
 
        switch (value) {
-               case 0 :
+               case 0:
                        slot_cmd = SET_ATTN_OFF;        /* OFF */
                        break;
                case 1:
@@ -910,7 +910,7 @@ static int shpc_get_max_bus_speed(struct controller *ctrl)
        return retval;
 }
 
-static struct hpc_ops shpchp_hpc_ops = {
+static const struct hpc_ops shpchp_hpc_ops = {
        .power_on_slot                  = hpc_power_on_slot,
        .slot_enable                    = hpc_slot_enable,
        .slot_disable                   = hpc_slot_disable,
index 52875b3..7efb56a 100644 (file)
@@ -35,7 +35,7 @@
 
 /* A few routines that create sysfs entries for the hot plug controller */
 
-static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_ctrl(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct pci_dev *pdev;
        char *out = buf;
@@ -43,7 +43,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
        struct resource *res;
        struct pci_bus *bus;
 
-       pdev = container_of (dev, struct pci_dev, dev);
+       pdev = to_pci_dev(dev);
        bus = pdev->subordinate;
 
        out += sprintf(buf, "Free resources: memory\n");
@@ -83,11 +83,11 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
 
        return out - buf;
 }
-static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
+static DEVICE_ATTR(ctrl, S_IRUGO, show_ctrl, NULL);
 
-int shpchp_create_ctrl_files (struct controller *ctrl)
+int shpchp_create_ctrl_files(struct controller *ctrl)
 {
-       return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
+       return device_create_file(&ctrl->pci_dev->dev, &dev_attr_ctrl);
 }
 
 void shpchp_remove_ctrl_files(struct controller *ctrl)
index 7a0df3f..a080f44 100644 (file)
@@ -1026,10 +1026,6 @@ int pci_msi_enabled(void)
 }
 EXPORT_SYMBOL(pci_msi_enabled);
 
-void pci_msi_init_pci_dev(struct pci_dev *dev)
-{
-}
-
 /**
  * pci_enable_msi_range - configure device's MSI capability structure
  * @dev: device to configure
index 024b5c1..0ae74d9 100644 (file)
@@ -77,7 +77,7 @@ static umode_t smbios_instance_string_exist(struct kobject *kobj,
        struct device *dev;
        struct pci_dev *pdev;
 
-       dev = container_of(kobj, struct device, kobj);
+       dev = kobj_to_dev(kobj);
        pdev = to_pci_dev(dev);
 
        return find_smbios_instance_string(pdev, NULL, SMBIOS_ATTR_NONE) ?
@@ -221,7 +221,7 @@ static umode_t acpi_index_string_exist(struct kobject *kobj,
 {
        struct device *dev;
 
-       dev = container_of(kobj, struct device, kobj);
+       dev = kobj_to_dev(kobj);
 
        if (device_has_dsm(dev))
                return S_IRUGO;
index eead54c..95d9e7b 100644 (file)
@@ -630,8 +630,7 @@ static ssize_t pci_read_config(struct file *filp, struct kobject *kobj,
                               struct bin_attribute *bin_attr, char *buf,
                               loff_t off, size_t count)
 {
-       struct pci_dev *dev = to_pci_dev(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
        unsigned int size = 64;
        loff_t init_off = off;
        u8 *data = (u8 *) buf;
@@ -707,8 +706,7 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
                                struct bin_attribute *bin_attr, char *buf,
                                loff_t off, size_t count)
 {
-       struct pci_dev *dev = to_pci_dev(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
        unsigned int size = count;
        loff_t init_off = off;
        u8 *data = (u8 *) buf;
@@ -769,8 +767,7 @@ static ssize_t read_vpd_attr(struct file *filp, struct kobject *kobj,
                             struct bin_attribute *bin_attr, char *buf,
                             loff_t off, size_t count)
 {
-       struct pci_dev *dev =
-               to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
 
        if (off > bin_attr->size)
                count = 0;
@@ -784,8 +781,7 @@ static ssize_t write_vpd_attr(struct file *filp, struct kobject *kobj,
                              struct bin_attribute *bin_attr, char *buf,
                              loff_t off, size_t count)
 {
-       struct pci_dev *dev =
-               to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
 
        if (off > bin_attr->size)
                count = 0;
@@ -812,8 +808,7 @@ static ssize_t pci_read_legacy_io(struct file *filp, struct kobject *kobj,
                                  struct bin_attribute *bin_attr, char *buf,
                                  loff_t off, size_t count)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        /* Only support 1, 2 or 4 byte accesses */
        if (count != 1 && count != 2 && count != 4)
@@ -838,8 +833,7 @@ static ssize_t pci_write_legacy_io(struct file *filp, struct kobject *kobj,
                                   struct bin_attribute *bin_attr, char *buf,
                                   loff_t off, size_t count)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        /* Only support 1, 2 or 4 byte accesses */
        if (count != 1 && count != 2 && count != 4)
@@ -863,8 +857,7 @@ static int pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj,
                               struct bin_attribute *attr,
                               struct vm_area_struct *vma)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
 }
@@ -884,8 +877,7 @@ static int pci_mmap_legacy_io(struct file *filp, struct kobject *kobj,
                              struct bin_attribute *attr,
                              struct vm_area_struct *vma)
 {
-       struct pci_bus *bus = to_pci_bus(container_of(kobj, struct device,
-                                                     kobj));
+       struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
 
        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
 }
@@ -1000,8 +992,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
 static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
                             struct vm_area_struct *vma, int write_combine)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj,
-                                                      struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
        struct resource *res = attr->private;
        enum pci_mmap_state mmap_type;
        resource_size_t start, end;
@@ -1054,8 +1045,7 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
                               struct bin_attribute *attr, char *buf,
                               loff_t off, size_t count, bool write)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj,
-                                                      struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
        struct resource *res = attr->private;
        unsigned long port = off;
        int i;
@@ -1225,7 +1215,7 @@ static ssize_t pci_write_rom(struct file *filp, struct kobject *kobj,
                             struct bin_attribute *bin_attr, char *buf,
                             loff_t off, size_t count)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
 
        if ((off ==  0) && (*buf == '0') && (count == 2))
                pdev->rom_attr_enabled = 0;
@@ -1251,7 +1241,7 @@ static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj,
                            struct bin_attribute *bin_attr, char *buf,
                            loff_t off, size_t count)
 {
-       struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
        void __iomem *rom;
        size_t size;
 
@@ -1372,10 +1362,10 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
        if (!sysfs_initialized)
                return -EACCES;
 
-       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       else
+       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
                retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+       else
+               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
        if (retval)
                goto err;
 
@@ -1427,10 +1417,10 @@ err_rom_file:
 err_resource_files:
        pci_remove_resource_files(pdev);
 err_config_file:
-       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       else
+       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+       else
+               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
 err:
        return retval;
 }
@@ -1464,10 +1454,10 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 
        pci_remove_capabilities_sysfs(pdev);
 
-       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       else
+       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+       else
+               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
 
        pci_remove_resource_files(pdev);
 
@@ -1511,7 +1501,7 @@ static struct attribute *pci_dev_dev_attrs[] = {
 static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
                                         struct attribute *a, int n)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
 
        if (a == &vga_attr.attr)
@@ -1530,7 +1520,7 @@ static struct attribute *pci_dev_hp_attrs[] = {
 static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
                                            struct attribute *a, int n)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
 
        if (pdev->is_virtfn)
@@ -1554,7 +1544,7 @@ static struct attribute *sriov_dev_attrs[] = {
 static umode_t sriov_attrs_are_visible(struct kobject *kobj,
                                       struct attribute *a, int n)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
 
        if (!dev_is_pf(dev))
                return 0;
index d1a7105..602eb42 100644 (file)
@@ -1417,7 +1417,7 @@ struct pci_devres {
 
 static void pcim_release(struct device *gendev, void *res)
 {
-       struct pci_dev *dev = container_of(gendev, struct pci_dev, dev);
+       struct pci_dev *dev = to_pci_dev(gendev);
        struct pci_devres *this = res;
        int i;
 
@@ -1534,7 +1534,7 @@ void __weak pcibios_release_device(struct pci_dev *dev) {}
  * is the default implementation. Architecture implementations can
  * override this.
  */
-void __weak pcibios_disable_device (struct pci_dev *dev) {}
+void __weak pcibios_disable_device(struct pci_dev *dev) {}
 
 /**
  * pcibios_penalize_isa_irq - penalize an ISA IRQ
index f6f151a..9a1660f 100644 (file)
@@ -144,10 +144,8 @@ extern unsigned int pci_pm_d3_delay;
 
 #ifdef CONFIG_PCI_MSI
 void pci_no_msi(void);
-void pci_msi_init_pci_dev(struct pci_dev *dev);
 #else
 static inline void pci_no_msi(void) { }
-static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
 #endif
 
 static inline void pci_msi_set_enable(struct pci_dev *dev, int enable)
index 182224a..20db790 100644 (file)
@@ -41,12 +41,12 @@ struct aer_error_inj {
        u32 header_log1;
        u32 header_log2;
        u32 header_log3;
-       u16 domain;
+       u32 domain;
 };
 
 struct aer_error {
        struct list_head list;
-       u16 domain;
+       u32 domain;
        unsigned int bus;
        unsigned int devfn;
        int pos_cap_err;
@@ -74,7 +74,7 @@ static LIST_HEAD(pci_bus_ops_list);
 /* Protect einjected and pci_bus_ops_list */
 static DEFINE_SPINLOCK(inject_lock);
 
-static void aer_error_init(struct aer_error *err, u16 domain,
+static void aer_error_init(struct aer_error *err, u32 domain,
                           unsigned int bus, unsigned int devfn,
                           int pos_cap_err)
 {
@@ -86,7 +86,7 @@ static void aer_error_init(struct aer_error *err, u16 domain,
 }
 
 /* inject_lock must be held before calling */
-static struct aer_error *__find_aer_error(u16 domain, unsigned int bus,
+static struct aer_error *__find_aer_error(u32 domain, unsigned int bus,
                                          unsigned int devfn)
 {
        struct aer_error *err;
@@ -106,7 +106,7 @@ static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev)
        int domain = pci_domain_nr(dev->bus);
        if (domain < 0)
                return NULL;
-       return __find_aer_error((u16)domain, dev->bus->number, dev->devfn);
+       return __find_aer_error(domain, dev->bus->number, dev->devfn);
 }
 
 /* inject_lock must be held before calling */
@@ -196,7 +196,7 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where,
        domain = pci_domain_nr(bus);
        if (domain < 0)
                goto out;
-       err = __find_aer_error((u16)domain, bus->number, devfn);
+       err = __find_aer_error(domain, bus->number, devfn);
        if (!err)
                goto out;
 
@@ -228,7 +228,7 @@ static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where,
        domain = pci_domain_nr(bus);
        if (domain < 0)
                goto out;
-       err = __find_aer_error((u16)domain, bus->number, devfn);
+       err = __find_aer_error(domain, bus->number, devfn);
        if (!err)
                goto out;
 
@@ -329,7 +329,7 @@ static int aer_inject(struct aer_error_inj *einj)
        u32 sever, cor_mask, uncor_mask, cor_mask_orig = 0, uncor_mask_orig = 0;
        int ret = 0;
 
-       dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
+       dev = pci_get_domain_bus_and_slot(einj->domain, einj->bus, devfn);
        if (!dev)
                return -ENODEV;
        rpdev = pcie_find_root_port(dev);
index fba785e..7123925 100644 (file)
@@ -246,7 +246,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
                !dev->driver->err_handler ||
                !dev->driver->err_handler->error_detected) {
                if (result_data->state == pci_channel_io_frozen &&
-                       !(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) {
+                       dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
                        /*
                         * In case of fatal recovery, if one of down-
                         * stream device has no driver. We might be
@@ -269,7 +269,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
                 * without recovery.
                 */
 
-               if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
+               if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
                        vote = PCI_ERS_RESULT_NO_AER_DRIVER;
                else
                        vote = PCI_ERS_RESULT_NONE;
@@ -369,7 +369,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
        else
                result_data.result = PCI_ERS_RESULT_RECOVERED;
 
-       if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
+       if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
                /*
                 * If the error is reported by a bridge, we think this error
                 * is related to the downstream link of the bridge, so we
@@ -440,7 +440,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
        pci_ers_result_t status;
        struct pcie_port_service_driver *driver;
 
-       if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
+       if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
                /* Reset this port for all subordinates */
                udev = dev;
        } else {
@@ -660,7 +660,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
                        &info->mask);
                if (!(info->status & ~info->mask))
                        return 0;
-       } else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE ||
+       } else if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
                info->severity == AER_NONFATAL) {
 
                /* Link is still healthy for IO reads */
index 317e355..2dfe7fd 100644 (file)
@@ -834,21 +834,15 @@ static ssize_t link_state_store(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct pcie_link_state *link, *root = pdev->link_state->root;
-       u32 val, state = 0;
-
-       if (kstrtouint(buf, 10, &val))
-               return -EINVAL;
+       u32 state;
 
        if (aspm_disabled)
                return -EPERM;
-       if (n < 1 || val > 3)
-               return -EINVAL;
 
-       /* Convert requested state to ASPM state */
-       if (val & PCIE_LINK_STATE_L0S)
-               state |= ASPM_STATE_L0S;
-       if (val & PCIE_LINK_STATE_L1)
-               state |= ASPM_STATE_L1;
+       if (kstrtouint(buf, 10, &state))
+               return -EINVAL;
+       if ((state & ~ASPM_STATE_ALL) != 0)
+               return -EINVAL;
 
        down_read(&pci_bus_sem);
        mutex_lock(&aspm_lock);
index 553a029..6d7ab9b 100644 (file)
@@ -1109,14 +1109,11 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev)
        int pos = PCI_CFG_SPACE_SIZE;
 
        if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
-               goto fail;
+               return PCI_CFG_SPACE_SIZE;
        if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev))
-               goto fail;
+               return PCI_CFG_SPACE_SIZE;
 
        return PCI_CFG_SPACE_EXP_SIZE;
-
- fail:
-       return PCI_CFG_SPACE_SIZE;
 }
 
 int pci_cfg_space_size(struct pci_dev *dev)
@@ -1129,25 +1126,23 @@ int pci_cfg_space_size(struct pci_dev *dev)
        if (class == PCI_CLASS_BRIDGE_HOST)
                return pci_cfg_space_size_ext(dev);
 
-       if (!pci_is_pcie(dev)) {
-               pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
-               if (!pos)
-                       goto fail;
+       if (pci_is_pcie(dev))
+               return pci_cfg_space_size_ext(dev);
 
-               pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
-               if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
-                       goto fail;
-       }
+       pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+       if (!pos)
+               return PCI_CFG_SPACE_SIZE;
 
-       return pci_cfg_space_size_ext(dev);
+       pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
+       if (status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ))
+               return pci_cfg_space_size_ext(dev);
 
- fail:
        return PCI_CFG_SPACE_SIZE;
 }
 
 #define LEGACY_IO_RESOURCE     (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
-void pci_msi_setup_pci_dev(struct pci_dev *dev)
+static void pci_msi_setup_pci_dev(struct pci_dev *dev)
 {
        /*
         * Disable the MSI hardware to avoid screaming interrupts
@@ -1214,8 +1209,6 @@ int pci_setup_device(struct pci_dev *dev)
        /* "Unknown power state" */
        dev->current_state = PCI_UNKNOWN;
 
-       pci_msi_setup_pci_dev(dev);
-
        /* Early fixups, before probing the BARs */
        pci_fixup_device(pci_fixup_early, dev);
        /* device class may be changed after fixup */
@@ -1605,8 +1598,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
        /* Enhanced Allocation */
        pci_ea_init(dev);
 
-       /* MSI/MSI-X list */
-       pci_msi_init_pci_dev(dev);
+       /* Setup MSI caps & disable MSI/MSI-X interrupts */
+       pci_msi_setup_pci_dev(dev);
 
        /* Buffers for saving PCIe and PCI-X capabilities */
        pci_allocate_cap_save_buffers(dev);
index c2dd52e..0575a1e 100644 (file)
@@ -287,6 +287,18 @@ static void quirk_citrine(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,    PCI_DEVICE_ID_IBM_CITRINE,      quirk_citrine);
 
+/*
+ * This chip can cause bus lockups if config addresses above 0x600
+ * are read or written.
+ */
+static void quirk_nfp6000(struct pci_dev *dev)
+{
+       dev->cfg_size = 0x600;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME,      PCI_DEVICE_ID_NETRONOME_NFP4000,        quirk_nfp6000);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME,      PCI_DEVICE_ID_NETRONOME_NFP6000,        quirk_nfp6000);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME,      PCI_DEVICE_ID_NETRONOME_NFP6000_VF,     quirk_nfp6000);
+
 /*  On IBM Crocodile ipr SAS adapters, expand BAR to system page size */
 static void quirk_extend_bar_to_page(struct pci_dev *dev)
 {
@@ -3622,6 +3634,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642,
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
                         PCI_DEVICE_ID_JMICRON_JMB388_ESD,
                         quirk_dma_func1_alias);
+/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c117 */
+DECLARE_PCI_FIXUP_HEADER(0x1c28, /* Lite-On */
+                        0x0122, /* Plextor M6E (Marvell 88SS9183)*/
+                        quirk_dma_func1_alias);
 
 /*
  * Some devices DMA with the wrong devfn, not just the wrong function.
index eb0ad53..9eaca39 100644 (file)
@@ -77,25 +77,24 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
        do {
                void __iomem *pds;
                /* Standard PCI ROMs start out with these bytes 55 AA */
-               if (readb(image) != 0x55) {
-                       dev_err(&pdev->dev, "Invalid ROM contents\n");
+               if (readw(image) != 0xAA55) {
+                       dev_err(&pdev->dev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
+                               readw(image));
                        break;
                }
-               if (readb(image + 1) != 0xAA)
-                       break;
-               /* get the PCI data structure and check its signature */
+               /* get the PCI data structure and check its "PCIR" signature */
                pds = image + readw(image + 24);
-               if (readb(pds) != 'P')
-                       break;
-               if (readb(pds + 1) != 'C')
-                       break;
-               if (readb(pds + 2) != 'I')
-                       break;
-               if (readb(pds + 3) != 'R')
+               if (readl(pds) != 0x52494350) {
+                       dev_err(&pdev->dev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
+                               readl(pds));
                        break;
+               }
                last_image = readb(pds + 21) & 0x80;
                length = readw(pds + 16);
                image += length * 512;
+               /* Avoid iterating through memory outside the resource window */
+               if (image > rom + size)
+                       break;
        } while (length && !last_image);
 
        /* never return a size larger than the PCI resource window */
index 1723ac1..7796d0a 100644 (file)
@@ -442,7 +442,7 @@ static void __assign_resources_sorted(struct list_head *head,
                                        break;
                                }
                        }
-               }
+               }
 
        }
 
index d28db0e..d78ee15 100644 (file)
@@ -899,6 +899,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"),
                },
        },
+       {
+               .ident = "Lenovo Yoga 700",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 700"),
+               },
+       },
        {
                .ident = "Lenovo Yoga 900",
                .matches = {
index 5b31d15..f5134ac 100644 (file)
        } \
 }
 
+#ifdef CONFIG_PM_SLEEP
 static u8 suspend_prep_ok;
 static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
 static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
+#endif
 
 struct telemetry_susp_stats {
        u32 shlw_swake_ctr;
index 1f0eda2..a268a7a 100644 (file)
@@ -3489,7 +3489,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
        /* Do not issue duplicate brightness change events to
         * userspace. tpacpi_detect_brightness_capabilities() must have
         * been called before this point  */
-       if (acpi_video_handles_brightness_key_presses()) {
+       if (acpi_video_get_backlight_type() != acpi_backlight_vendor) {
                pr_info("This ThinkPad has standard ACPI backlight "
                        "brightness control, supported by the ACPI "
                        "video driver\n");
index 2f4641a..8cf0dae 100644 (file)
@@ -148,6 +148,7 @@ config PWM_EP93XX
 
 config PWM_FSL_FTM
        tristate "Freescale FlexTimer Module (FTM) PWM support"
+       depends on HAS_IOMEM
        depends on OF
        select REGMAP_MMIO
        help
@@ -222,18 +223,12 @@ config PWM_LPC32XX
          will be called pwm-lpc32xx.
 
 config PWM_LPSS
-       tristate "Intel LPSS PWM support"
-       depends on X86
-       help
-         Generic PWM framework driver for Intel Low Power Subsystem PWM
-         controller.
-
-         To compile this driver as a module, choose M here: the module
-         will be called pwm-lpss.
+       tristate
 
 config PWM_LPSS_PCI
        tristate "Intel LPSS PWM PCI driver"
-       depends on PWM_LPSS && PCI
+       depends on X86 && PCI
+       select PWM_LPSS
        help
          The PCI driver for Intel Low Power Subsystem PWM controller.
 
@@ -242,7 +237,8 @@ config PWM_LPSS_PCI
 
 config PWM_LPSS_PLATFORM
        tristate "Intel LPSS PWM platform driver"
-       depends on PWM_LPSS && ACPI
+       depends on X86 && ACPI
+       select PWM_LPSS
        help
          The platform driver for Intel Low Power Subsystem PWM controller.
 
@@ -270,6 +266,15 @@ config PWM_MXS
          To compile this driver as a module, choose M here: the module
          will be called pwm-mxs.
 
+config PWM_OMAP_DMTIMER
+       tristate "OMAP Dual-Mode Timer PWM support"
+       depends on OF && ARCH_OMAP && OMAP_DM_TIMER
+       help
+         Generic PWM framework driver for OMAP Dual-Mode Timer PWM output
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-omap-dmtimer
+
 config PWM_PCA9685
        tristate "NXP PCA9685 PWM driver"
        depends on I2C
index 69b8275..dd35bc1 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)    += pwm-lpss-pci.o
 obj-$(CONFIG_PWM_LPSS_PLATFORM)        += pwm-lpss-platform.o
 obj-$(CONFIG_PWM_MTK_DISP)     += pwm-mtk-disp.o
 obj-$(CONFIG_PWM_MXS)          += pwm-mxs.o
+obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
 obj-$(CONFIG_PWM_PCA9685)      += pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)         += pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)          += pwm-pxa.o
index d24ca5f..7831bc6 100644 (file)
@@ -889,7 +889,7 @@ EXPORT_SYMBOL_GPL(devm_pwm_put);
   */
 bool pwm_can_sleep(struct pwm_device *pwm)
 {
-       return pwm->chip->can_sleep;
+       return true;
 }
 EXPORT_SYMBOL_GPL(pwm_can_sleep);
 
index b4c7f95..c5dbf16 100644 (file)
@@ -29,7 +29,6 @@
 struct bcm2835_pwm {
        struct pwm_chip chip;
        struct device *dev;
-       unsigned long scaler;
        void __iomem *base;
        struct clk *clk;
 };
@@ -66,6 +65,15 @@ static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                              int duty_ns, int period_ns)
 {
        struct bcm2835_pwm *pc = to_bcm2835_pwm(chip);
+       unsigned long rate = clk_get_rate(pc->clk);
+       unsigned long scaler;
+
+       if (!rate) {
+               dev_err(pc->dev, "failed to get clock rate\n");
+               return -EINVAL;
+       }
+
+       scaler = NSEC_PER_SEC / rate;
 
        if (period_ns <= MIN_PERIOD) {
                dev_err(pc->dev, "period %d not supported, minimum %d\n",
@@ -73,8 +81,8 @@ static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                return -EINVAL;
        }
 
-       writel(duty_ns / pc->scaler, pc->base + DUTY(pwm->hwpwm));
-       writel(period_ns / pc->scaler, pc->base + PERIOD(pwm->hwpwm));
+       writel(duty_ns / scaler, pc->base + DUTY(pwm->hwpwm));
+       writel(period_ns / scaler, pc->base + PERIOD(pwm->hwpwm));
 
        return 0;
 }
@@ -156,8 +164,6 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       pc->scaler = NSEC_PER_SEC / clk_get_rate(pc->clk);
-
        pc->chip.dev = &pdev->dev;
        pc->chip.ops = &bcm2835_pwm_ops;
        pc->chip.npwm = 2;
@@ -200,6 +206,6 @@ static struct platform_driver bcm2835_pwm_driver = {
 };
 module_platform_driver(bcm2835_pwm_driver);
 
-MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be");
+MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be>");
 MODULE_DESCRIPTION("Broadcom BCM2835 PWM driver");
 MODULE_LICENSE("GPL v2");
index f9dfc8b..7225ac6 100644 (file)
@@ -80,7 +80,6 @@ struct fsl_pwm_chip {
 
        struct mutex lock;
 
-       unsigned int use_count;
        unsigned int cnt_select;
        unsigned int clk_ps;
 
@@ -300,9 +299,6 @@ static int fsl_counter_clock_enable(struct fsl_pwm_chip *fpc)
 {
        int ret;
 
-       if (fpc->use_count++ != 0)
-               return 0;
-
        /* select counter clock source */
        regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK,
                           FTM_SC_CLK(fpc->cnt_select));
@@ -334,25 +330,6 @@ static int fsl_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        return ret;
 }
 
-static void fsl_counter_clock_disable(struct fsl_pwm_chip *fpc)
-{
-       /*
-        * already disabled, do nothing
-        */
-       if (fpc->use_count == 0)
-               return;
-
-       /* there are still users, so can't disable yet */
-       if (--fpc->use_count > 0)
-               return;
-
-       /* no users left, disable PWM counter clock */
-       regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK, 0);
-
-       clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
-       clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
-}
-
 static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
@@ -362,7 +339,8 @@ static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
                           BIT(pwm->hwpwm));
 
-       fsl_counter_clock_disable(fpc);
+       clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
+       clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
 
        regmap_read(fpc->regmap, FTM_OUTMASK, &val);
        if ((val & 0xFF) == 0xFF)
@@ -492,17 +470,24 @@ static int fsl_pwm_remove(struct platform_device *pdev)
 static int fsl_pwm_suspend(struct device *dev)
 {
        struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
-       u32 val;
+       int i;
 
        regcache_cache_only(fpc->regmap, true);
        regcache_mark_dirty(fpc->regmap);
 
-       /* read from cache */
-       regmap_read(fpc->regmap, FTM_OUTMASK, &val);
-       if ((val & 0xFF) != 0xFF) {
+       for (i = 0; i < fpc->chip.npwm; i++) {
+               struct pwm_device *pwm = &fpc->chip.pwms[i];
+
+               if (!test_bit(PWMF_REQUESTED, &pwm->flags))
+                       continue;
+
+               clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+
+               if (!pwm_is_enabled(pwm))
+                       continue;
+
                clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
                clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
-               clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
        }
 
        return 0;
@@ -511,12 +496,19 @@ static int fsl_pwm_suspend(struct device *dev)
 static int fsl_pwm_resume(struct device *dev)
 {
        struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
-       u32 val;
+       int i;
+
+       for (i = 0; i < fpc->chip.npwm; i++) {
+               struct pwm_device *pwm = &fpc->chip.pwms[i];
+
+               if (!test_bit(PWMF_REQUESTED, &pwm->flags))
+                       continue;
 
-       /* read from cache */
-       regmap_read(fpc->regmap, FTM_OUTMASK, &val);
-       if ((val & 0xFF) != 0xFF) {
                clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+
+               if (!pwm_is_enabled(pwm))
+                       continue;
+
                clk_prepare_enable(fpc->clk[fpc->cnt_select]);
                clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
        }
index 9fde60c..4d470c1 100644 (file)
@@ -24,9 +24,7 @@ struct lpc32xx_pwm_chip {
        void __iomem *base;
 };
 
-#define PWM_ENABLE     (1 << 31)
-#define PWM_RELOADV(x) (((x) & 0xFF) << 8)
-#define PWM_DUTY(x)    ((x) & 0xFF)
+#define PWM_ENABLE     BIT(31)
 
 #define to_lpc32xx_pwm_chip(_chip) \
        container_of(_chip, struct lpc32xx_pwm_chip, chip)
@@ -38,40 +36,27 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        unsigned long long c;
        int period_cycles, duty_cycles;
        u32 val;
-
-       c = clk_get_rate(lpc32xx->clk) / 256;
-       c = c * period_ns;
-       do_div(c, NSEC_PER_SEC);
-
-       /* Handle high and low extremes */
-       if (c == 0)
-               c = 1;
-       if (c > 255)
-               c = 0; /* 0 set division by 256 */
-       period_cycles = c;
-
-       /* The duty-cycle value is as follows:
-        *
-        *  DUTY-CYCLE     HIGH LEVEL
-        *      1            99.9%
-        *      25           90.0%
-        *      128          50.0%
-        *      220          10.0%
-        *      255           0.1%
-        *      0             0.0%
-        *
-        * In other words, the register value is duty-cycle % 256 with
-        * duty-cycle in the range 1-256.
-        */
-       c = 256 * duty_ns;
-       do_div(c, period_ns);
-       if (c > 255)
-               c = 255;
-       duty_cycles = 256 - c;
+       c = clk_get_rate(lpc32xx->clk);
+
+       /* The highest acceptable divisor is 256, which is represented by 0 */
+       period_cycles = div64_u64(c * period_ns,
+                              (unsigned long long)NSEC_PER_SEC * 256);
+       if (!period_cycles || period_cycles > 256)
+               return -ERANGE;
+       if (period_cycles == 256)
+               period_cycles = 0;
+
+       /* Compute 256 x #duty/period value and care for corner cases */
+       duty_cycles = div64_u64((unsigned long long)(period_ns - duty_ns) * 256,
+                               period_ns);
+       if (!duty_cycles)
+               duty_cycles = 1;
+       if (duty_cycles > 255)
+               duty_cycles = 255;
 
        val = readl(lpc32xx->base + (pwm->hwpwm << 2));
        val &= ~0xFFFF;
-       val |= PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles);
+       val |= (period_cycles << 8) | duty_cycles;
        writel(val, lpc32xx->base + (pwm->hwpwm << 2));
 
        return 0;
@@ -83,7 +68,7 @@ static int lpc32xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        u32 val;
        int ret;
 
-       ret = clk_enable(lpc32xx->clk);
+       ret = clk_prepare_enable(lpc32xx->clk);
        if (ret)
                return ret;
 
@@ -103,7 +88,7 @@ static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        val &= ~PWM_ENABLE;
        writel(val, lpc32xx->base + (pwm->hwpwm << 2));
 
-       clk_disable(lpc32xx->clk);
+       clk_disable_unprepare(lpc32xx->clk);
 }
 
 static const struct pwm_ops lpc32xx_pwm_ops = {
@@ -134,7 +119,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
 
        lpc32xx->chip.dev = &pdev->dev;
        lpc32xx->chip.ops = &lpc32xx_pwm_ops;
-       lpc32xx->chip.npwm = 2;
+       lpc32xx->chip.npwm = 1;
        lpc32xx->chip.base = -1;
 
        ret = pwmchip_add(&lpc32xx->chip);
index 2504410..295b963 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/time.h>
 
 #include "pwm-lpss.h"
 
 #define PWM_ENABLE                     BIT(31)
 #define PWM_SW_UPDATE                  BIT(30)
 #define PWM_BASE_UNIT_SHIFT            8
-#define PWM_BASE_UNIT_MASK             0x00ffff00
 #define PWM_ON_TIME_DIV_MASK           0x000000ff
 #define PWM_DIVISION_CORRECTION                0x2
-#define PWM_LIMIT                      (0x8000 + PWM_DIVISION_CORRECTION)
-#define NSECS_PER_SEC                  1000000000UL
 
 /* Size of each PWM register space if multiple */
 #define PWM_SIZE                       0x400
 struct pwm_lpss_chip {
        struct pwm_chip chip;
        void __iomem *regs;
-       unsigned long clk_rate;
+       const struct pwm_lpss_boardinfo *info;
 };
 
 /* BayTrail */
 const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
        .clk_rate = 25000000,
        .npwm = 1,
+       .base_unit_bits = 16,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
 
@@ -50,6 +50,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
 const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
        .clk_rate = 19200000,
        .npwm = 1,
+       .base_unit_bits = 16,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
 
@@ -57,6 +58,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
 const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
        .clk_rate = 19200000,
        .npwm = 4,
+       .base_unit_bits = 22,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info);
 
@@ -79,28 +81,37 @@ static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
        writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
 }
 
+static void pwm_lpss_update(struct pwm_device *pwm)
+{
+       pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
+       /* Give it some time to propagate */
+       usleep_range(10, 50);
+}
+
 static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
                           int duty_ns, int period_ns)
 {
        struct pwm_lpss_chip *lpwm = to_lpwm(chip);
        u8 on_time_div;
-       unsigned long c;
-       unsigned long long base_unit, freq = NSECS_PER_SEC;
+       unsigned long c, base_unit_range;
+       unsigned long long base_unit, freq = NSEC_PER_SEC;
        u32 ctrl;
 
        do_div(freq, period_ns);
 
-       /* The equation is: base_unit = ((freq / c) * 65536) + correction */
-       base_unit = freq * 65536;
+       /*
+        * The equation is:
+        * base_unit = ((freq / c) * base_unit_range) + correction
+        */
+       base_unit_range = BIT(lpwm->info->base_unit_bits);
+       base_unit = freq * base_unit_range;
 
-       c = lpwm->clk_rate;
+       c = lpwm->info->clk_rate;
        if (!c)
                return -EINVAL;
 
        do_div(base_unit, c);
        base_unit += PWM_DIVISION_CORRECTION;
-       if (base_unit > PWM_LIMIT)
-               return -EINVAL;
 
        if (duty_ns <= 0)
                duty_ns = 1;
@@ -109,13 +120,20 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
        pm_runtime_get_sync(chip->dev);
 
        ctrl = pwm_lpss_read(pwm);
-       ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
-       ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
+       ctrl &= ~PWM_ON_TIME_DIV_MASK;
+       ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT);
+       base_unit &= (base_unit_range - 1);
+       ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
        ctrl |= on_time_div;
-       /* request PWM to update on next cycle */
-       ctrl |= PWM_SW_UPDATE;
        pwm_lpss_write(pwm, ctrl);
 
+       /*
+        * If the PWM is already enabled we need to notify the hardware
+        * about the change by setting PWM_SW_UPDATE.
+        */
+       if (pwm_is_enabled(pwm))
+               pwm_lpss_update(pwm);
+
        pm_runtime_put(chip->dev);
 
        return 0;
@@ -124,6 +142,12 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
 static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        pm_runtime_get_sync(chip->dev);
+
+       /*
+        * Hardware must first see PWM_SW_UPDATE before the PWM can be
+        * enabled.
+        */
+       pwm_lpss_update(pwm);
        pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
        return 0;
 }
@@ -135,7 +159,6 @@ static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 }
 
 static const struct pwm_ops pwm_lpss_ops = {
-       .free = pwm_lpss_disable,
        .config = pwm_lpss_config,
        .enable = pwm_lpss_enable,
        .disable = pwm_lpss_disable,
@@ -156,7 +179,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
        if (IS_ERR(lpwm->regs))
                return ERR_CAST(lpwm->regs);
 
-       lpwm->clk_rate = info->clk_rate;
+       lpwm->info = info;
        lpwm->chip.dev = dev;
        lpwm->chip.ops = &pwm_lpss_ops;
        lpwm->chip.base = -1;
index e8cf337..04766e0 100644 (file)
@@ -21,6 +21,7 @@ struct pwm_lpss_chip;
 struct pwm_lpss_boardinfo {
        unsigned long clk_rate;
        unsigned int npwm;
+       unsigned long base_unit_bits;
 };
 
 extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
new file mode 100644 (file)
index 0000000..826634e
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2015 Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2014 Joachim Eastwood <manabian@gmail.com>
+ * Copyright (c) 2012 NeilBrown <neilb@suse.de>
+ * Heavily based on earlier code which is:
+ * Copyright (c) 2010 Grant Erickson <marathon96@gmail.com>
+ *
+ * Also based on pwm-samsung.c
+ *
+ * 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.
+ *
+ * Description:
+ *   This file is the core OMAP support for the generic, Linux
+ *   PWM driver / controller, using the OMAP's dual-mode timers.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/pwm_omap_dmtimer.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+
+#define DM_TIMER_LOAD_MIN 0xfffffffe
+
+struct pwm_omap_dmtimer_chip {
+       struct pwm_chip chip;
+       struct mutex mutex;
+       pwm_omap_dmtimer *dm_timer;
+       struct pwm_omap_dmtimer_pdata *pdata;
+       struct platform_device *dm_timer_pdev;
+};
+
+static inline struct pwm_omap_dmtimer_chip *
+to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
+{
+       return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
+}
+
+static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns)
+{
+       u64 c = (u64)clk_rate * ns;
+
+       do_div(c, NSEC_PER_SEC);
+
+       return DM_TIMER_LOAD_MIN - c;
+}
+
+static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
+{
+       /*
+        * According to OMAP 4 TRM section 22.2.4.10 the counter should be
+        * started at 0xFFFFFFFE when overflow and match is used to ensure
+        * that the PWM line is toggled on the first event.
+        *
+        * Note that omap_dm_timer_enable/disable is for register access and
+        * not the timer counter itself.
+        */
+       omap->pdata->enable(omap->dm_timer);
+       omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN);
+       omap->pdata->disable(omap->dm_timer);
+
+       omap->pdata->start(omap->dm_timer);
+}
+
+static int pwm_omap_dmtimer_enable(struct pwm_chip *chip,
+                                  struct pwm_device *pwm)
+{
+       struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+       mutex_lock(&omap->mutex);
+       pwm_omap_dmtimer_start(omap);
+       mutex_unlock(&omap->mutex);
+
+       return 0;
+}
+
+static void pwm_omap_dmtimer_disable(struct pwm_chip *chip,
+                                    struct pwm_device *pwm)
+{
+       struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+       mutex_lock(&omap->mutex);
+       omap->pdata->stop(omap->dm_timer);
+       mutex_unlock(&omap->mutex);
+}
+
+static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
+                                  struct pwm_device *pwm,
+                                  int duty_ns, int period_ns)
+{
+       struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+       int load_value, match_value;
+       struct clk *fclk;
+       unsigned long clk_rate;
+       bool timer_active;
+
+       dev_dbg(chip->dev, "duty cycle: %d, period %d\n", duty_ns, period_ns);
+
+       mutex_lock(&omap->mutex);
+       if (duty_ns == pwm_get_duty_cycle(pwm) &&
+           period_ns == pwm_get_period(pwm)) {
+               /* No change - don't cause any transients. */
+               mutex_unlock(&omap->mutex);
+               return 0;
+       }
+
+       fclk = omap->pdata->get_fclk(omap->dm_timer);
+       if (!fclk) {
+               dev_err(chip->dev, "invalid pmtimer fclk\n");
+               mutex_unlock(&omap->mutex);
+               return -EINVAL;
+       }
+
+       clk_rate = clk_get_rate(fclk);
+       if (!clk_rate) {
+               dev_err(chip->dev, "invalid pmtimer fclk rate\n");
+               mutex_unlock(&omap->mutex);
+               return -EINVAL;
+       }
+
+       dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
+
+       /*
+        * Calculate the appropriate load and match values based on the
+        * specified period and duty cycle. The load value determines the
+        * cycle time and the match value determines the duty cycle.
+        */
+       load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns);
+       match_value = pwm_omap_dmtimer_calc_value(clk_rate,
+                                                 period_ns - duty_ns);
+
+       /*
+        * We MUST stop the associated dual-mode timer before attempting to
+        * write its registers, but calls to omap_dm_timer_start/stop must
+        * be balanced so check if timer is active before calling timer_stop.
+        */
+       timer_active = pm_runtime_active(&omap->dm_timer_pdev->dev);
+       if (timer_active)
+               omap->pdata->stop(omap->dm_timer);
+
+       omap->pdata->set_load(omap->dm_timer, true, load_value);
+       omap->pdata->set_match(omap->dm_timer, true, match_value);
+
+       dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
+               load_value, load_value, match_value, match_value);
+
+       omap->pdata->set_pwm(omap->dm_timer,
+                             pwm->polarity == PWM_POLARITY_INVERSED,
+                             true,
+                             PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+
+       /* If config was called while timer was running it must be reenabled. */
+       if (timer_active)
+               pwm_omap_dmtimer_start(omap);
+
+       mutex_unlock(&omap->mutex);
+
+       return 0;
+}
+
+static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
+                                        struct pwm_device *pwm,
+                                        enum pwm_polarity polarity)
+{
+       struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
+
+       /*
+        * PWM core will not call set_polarity while PWM is enabled so it's
+        * safe to reconfigure the timer here without stopping it first.
+        */
+       mutex_lock(&omap->mutex);
+       omap->pdata->set_pwm(omap->dm_timer,
+                             polarity == PWM_POLARITY_INVERSED,
+                             true,
+                             PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+       mutex_unlock(&omap->mutex);
+
+       return 0;
+}
+
+static const struct pwm_ops pwm_omap_dmtimer_ops = {
+       .enable = pwm_omap_dmtimer_enable,
+       .disable = pwm_omap_dmtimer_disable,
+       .config = pwm_omap_dmtimer_config,
+       .set_polarity = pwm_omap_dmtimer_set_polarity,
+       .owner = THIS_MODULE,
+};
+
+static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct device_node *timer;
+       struct pwm_omap_dmtimer_chip *omap;
+       struct pwm_omap_dmtimer_pdata *pdata;
+       pwm_omap_dmtimer *dm_timer;
+       u32 prescaler;
+       int status;
+
+       pdata = dev_get_platdata(&pdev->dev);
+       if (!pdata) {
+               dev_err(&pdev->dev, "Missing dmtimer platform data\n");
+               return -EINVAL;
+       }
+
+       if (!pdata->request_by_node ||
+           !pdata->free ||
+           !pdata->enable ||
+           !pdata->disable ||
+           !pdata->get_fclk ||
+           !pdata->start ||
+           !pdata->stop ||
+           !pdata->set_load ||
+           !pdata->set_match ||
+           !pdata->set_pwm ||
+           !pdata->set_prescaler ||
+           !pdata->write_counter) {
+               dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
+               return -EINVAL;
+       }
+
+       timer = of_parse_phandle(np, "ti,timers", 0);
+       if (!timer)
+               return -ENODEV;
+
+       if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
+               dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
+               return -ENODEV;
+       }
+
+       dm_timer = pdata->request_by_node(timer);
+       if (!dm_timer)
+               return -EPROBE_DEFER;
+
+       omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
+       if (!omap) {
+               pdata->free(dm_timer);
+               return -ENOMEM;
+       }
+
+       omap->pdata = pdata;
+       omap->dm_timer = dm_timer;
+
+       omap->dm_timer_pdev = of_find_device_by_node(timer);
+       if (!omap->dm_timer_pdev) {
+               dev_err(&pdev->dev, "Unable to find timer pdev\n");
+               omap->pdata->free(dm_timer);
+               return -EINVAL;
+       }
+
+       /*
+        * Ensure that the timer is stopped before we allow PWM core to call
+        * pwm_enable.
+        */
+       if (pm_runtime_active(&omap->dm_timer_pdev->dev))
+               omap->pdata->stop(omap->dm_timer);
+
+       /* setup dmtimer prescaler */
+       if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler",
+                               &prescaler))
+               omap->pdata->set_prescaler(omap->dm_timer, prescaler);
+
+       omap->chip.dev = &pdev->dev;
+       omap->chip.ops = &pwm_omap_dmtimer_ops;
+       omap->chip.base = -1;
+       omap->chip.npwm = 1;
+       omap->chip.of_xlate = of_pwm_xlate_with_flags;
+       omap->chip.of_pwm_n_cells = 3;
+
+       mutex_init(&omap->mutex);
+
+       status = pwmchip_add(&omap->chip);
+       if (status < 0) {
+               dev_err(&pdev->dev, "failed to register PWM\n");
+               omap->pdata->free(omap->dm_timer);
+               return status;
+       }
+
+       platform_set_drvdata(pdev, omap);
+
+       return 0;
+}
+
+static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
+{
+       struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
+
+       if (pm_runtime_active(&omap->dm_timer_pdev->dev))
+               omap->pdata->stop(omap->dm_timer);
+
+       omap->pdata->free(omap->dm_timer);
+
+       mutex_destroy(&omap->mutex);
+
+       return pwmchip_remove(&omap->chip);
+}
+
+static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
+       {.compatible = "ti,omap-dmtimer-pwm"},
+       {}
+};
+MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match);
+
+static struct platform_driver pwm_omap_dmtimer_driver = {
+       .driver = {
+               .name = "omap-dmtimer-pwm",
+               .of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match),
+       },
+       .probe = pwm_omap_dmtimer_probe,
+       .remove = pwm_omap_dmtimer_remove,
+};
+module_platform_driver(pwm_omap_dmtimer_driver);
+
+MODULE_AUTHOR("Grant Erickson <marathon96@gmail.com>");
+MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers");
index 6e99a63..7b8ac06 100644 (file)
@@ -81,7 +81,7 @@ static int rcar_pwm_get_clock_division(struct rcar_pwm_chip *rp, int period_ns)
                max = (unsigned long long)NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE *
                        (1 << div);
                do_div(max, clk_rate);
-               if (period_ns < max)
+               if (period_ns <= max)
                        break;
        }
 
index cdb005c..eda4156 100644 (file)
@@ -125,8 +125,7 @@ rio_read_config(struct file *filp, struct kobject *kobj,
                struct bin_attribute *bin_attr,
                char *buf, loff_t off, size_t count)
 {
-       struct rio_dev *dev =
-           to_rio_dev(container_of(kobj, struct device, kobj));
+       struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
        unsigned int size = 0x100;
        loff_t init_off = off;
        u8 *data = (u8 *) buf;
@@ -197,8 +196,7 @@ rio_write_config(struct file *filp, struct kobject *kobj,
                 struct bin_attribute *bin_attr,
                 char *buf, loff_t off, size_t count)
 {
-       struct rio_dev *dev =
-           to_rio_dev(container_of(kobj, struct device, kobj));
+       struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
        unsigned int size = count;
        loff_t init_off = off;
        u8 *data = (u8 *) buf;
index 0615f50..df37212 100644 (file)
@@ -13,3 +13,4 @@ menuconfig RESET_CONTROLLER
          If unsure, say no.
 
 source "drivers/reset/sti/Kconfig"
+source "drivers/reset/hisilicon/Kconfig"
index 85d5904..4d7178e 100644 (file)
@@ -1,8 +1,9 @@
-obj-$(CONFIG_RESET_CONTROLLER) += core.o
+obj-y += core.o
 obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o
 obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_ARCH_STI) += sti/
+obj-$(CONFIG_ARCH_HISI) += hisilicon/
 obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o
 obj-$(CONFIG_ATH79) += reset-ath79.o
index 7955e00..8737663 100644 (file)
@@ -30,7 +30,6 @@ static LIST_HEAD(reset_controller_list);
  */
 struct reset_control {
        struct reset_controller_dev *rcdev;
-       struct device *dev;
        unsigned int id;
 };
 
@@ -95,7 +94,7 @@ int reset_control_reset(struct reset_control *rstc)
        if (rstc->rcdev->ops->reset)
                return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
 
-       return -ENOSYS;
+       return -ENOTSUPP;
 }
 EXPORT_SYMBOL_GPL(reset_control_reset);
 
@@ -108,7 +107,7 @@ int reset_control_assert(struct reset_control *rstc)
        if (rstc->rcdev->ops->assert)
                return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id);
 
-       return -ENOSYS;
+       return -ENOTSUPP;
 }
 EXPORT_SYMBOL_GPL(reset_control_assert);
 
@@ -121,7 +120,7 @@ int reset_control_deassert(struct reset_control *rstc)
        if (rstc->rcdev->ops->deassert)
                return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id);
 
-       return -ENOSYS;
+       return -ENOTSUPP;
 }
 EXPORT_SYMBOL_GPL(reset_control_deassert);
 
@@ -136,32 +135,29 @@ int reset_control_status(struct reset_control *rstc)
        if (rstc->rcdev->ops->status)
                return rstc->rcdev->ops->status(rstc->rcdev, rstc->id);
 
-       return -ENOSYS;
+       return -ENOTSUPP;
 }
 EXPORT_SYMBOL_GPL(reset_control_status);
 
 /**
- * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * of_reset_control_get_by_index - Lookup and obtain a reference to a reset
+ * controller by index.
  * @node: device to be reset by the controller
- * @id: reset line name
+ * @index: index of the reset controller
  *
- * Returns a struct reset_control or IS_ERR() condition containing errno.
- *
- * Use of id names is optional.
+ * This is to be used to perform a list of resets for a device or power domain
+ * in whatever order. Returns a struct reset_control or IS_ERR() condition
+ * containing errno.
  */
-struct reset_control *of_reset_control_get(struct device_node *node,
-                                          const char *id)
+struct reset_control *of_reset_control_get_by_index(struct device_node *node,
+                                          int index)
 {
        struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER);
        struct reset_controller_dev *r, *rcdev;
        struct of_phandle_args args;
-       int index = 0;
        int rstc_id;
        int ret;
 
-       if (id)
-               index = of_property_match_string(node,
-                                                "reset-names", id);
        ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
                                         index, &args);
        if (ret)
@@ -202,6 +198,30 @@ struct reset_control *of_reset_control_get(struct device_node *node,
 
        return rstc;
 }
+EXPORT_SYMBOL_GPL(of_reset_control_get_by_index);
+
+/**
+ * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * @node: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Returns a struct reset_control or IS_ERR() condition containing errno.
+ *
+ * Use of id names is optional.
+ */
+struct reset_control *of_reset_control_get(struct device_node *node,
+                                          const char *id)
+{
+       int index = 0;
+
+       if (id) {
+               index = of_property_match_string(node,
+                                                "reset-names", id);
+               if (index < 0)
+                       return ERR_PTR(-ENOENT);
+       }
+       return of_reset_control_get_by_index(node, index);
+}
 EXPORT_SYMBOL_GPL(of_reset_control_get);
 
 /**
@@ -215,16 +235,10 @@ EXPORT_SYMBOL_GPL(of_reset_control_get);
  */
 struct reset_control *reset_control_get(struct device *dev, const char *id)
 {
-       struct reset_control *rstc;
-
        if (!dev)
                return ERR_PTR(-EINVAL);
 
-       rstc = of_reset_control_get(dev->of_node, id);
-       if (!IS_ERR(rstc))
-               rstc->dev = dev;
-
-       return rstc;
+       return of_reset_control_get(dev->of_node, id);
 }
 EXPORT_SYMBOL_GPL(reset_control_get);
 
diff --git a/drivers/reset/hisilicon/Kconfig b/drivers/reset/hisilicon/Kconfig
new file mode 100644 (file)
index 0000000..26bf95a
--- /dev/null
@@ -0,0 +1,5 @@
+config COMMON_RESET_HI6220
+       tristate "Hi6220 Reset Driver"
+       depends on (ARCH_HISI && RESET_CONTROLLER)
+       help
+         Build the Hisilicon Hi6220 reset driver.
diff --git a/drivers/reset/hisilicon/Makefile b/drivers/reset/hisilicon/Makefile
new file mode 100644 (file)
index 0000000..c932f86
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o
diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c
new file mode 100644 (file)
index 0000000..7787a9b
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Hisilicon Hi6220 reset controller driver
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ *
+ * Author: Feng Chen <puck.chen@hisilicon.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/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/of.h>
+#include <linux/reset-controller.h>
+#include <linux/reset.h>
+#include <linux/platform_device.h>
+
+#define ASSERT_OFFSET            0x300
+#define DEASSERT_OFFSET          0x304
+#define MAX_INDEX                0x509
+
+#define to_reset_data(x) container_of(x, struct hi6220_reset_data, rc_dev)
+
+struct hi6220_reset_data {
+       void __iomem                    *assert_base;
+       void __iomem                    *deassert_base;
+       struct reset_controller_dev     rc_dev;
+};
+
+static int hi6220_reset_assert(struct reset_controller_dev *rc_dev,
+                              unsigned long idx)
+{
+       struct hi6220_reset_data *data = to_reset_data(rc_dev);
+
+       int bank = idx >> 8;
+       int offset = idx & 0xff;
+
+       writel(BIT(offset), data->assert_base + (bank * 0x10));
+
+       return 0;
+}
+
+static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev,
+                                unsigned long idx)
+{
+       struct hi6220_reset_data *data = to_reset_data(rc_dev);
+
+       int bank = idx >> 8;
+       int offset = idx & 0xff;
+
+       writel(BIT(offset), data->deassert_base + (bank * 0x10));
+
+       return 0;
+}
+
+static struct reset_control_ops hi6220_reset_ops = {
+       .assert = hi6220_reset_assert,
+       .deassert = hi6220_reset_deassert,
+};
+
+static int hi6220_reset_probe(struct platform_device *pdev)
+{
+       struct hi6220_reset_data *data;
+       struct resource *res;
+       void __iomem *src_base;
+
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       src_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(src_base))
+               return PTR_ERR(src_base);
+
+       data->assert_base = src_base + ASSERT_OFFSET;
+       data->deassert_base = src_base + DEASSERT_OFFSET;
+       data->rc_dev.nr_resets = MAX_INDEX;
+       data->rc_dev.ops = &hi6220_reset_ops;
+       data->rc_dev.of_node = pdev->dev.of_node;
+
+       reset_controller_register(&data->rc_dev);
+
+       return 0;
+}
+
+static const struct of_device_id hi6220_reset_match[] = {
+       { .compatible = "hisilicon,hi6220-sysctrl" },
+       { },
+};
+
+static struct platform_driver hi6220_reset_driver = {
+       .probe = hi6220_reset_probe,
+       .driver = {
+               .name = "reset-hi6220",
+               .of_match_table = hi6220_reset_match,
+       },
+};
+
+static int __init hi6220_reset_init(void)
+{
+       return platform_driver_register(&hi6220_reset_driver);
+}
+
+postcore_initcall(hi6220_reset_init);
index 9aaf646..692fc89 100644 (file)
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
+#include <linux/reboot.h>
 
 struct ath79_reset {
        struct reset_controller_dev rcdev;
+       struct notifier_block restart_nb;
        void __iomem *base;
        spinlock_t lock;
 };
 
+#define FULL_CHIP_RESET 24
+
 static int ath79_reset_update(struct reset_controller_dev *rcdev,
                        unsigned long id, bool assert)
 {
@@ -72,10 +76,22 @@ static struct reset_control_ops ath79_reset_ops = {
        .status = ath79_reset_status,
 };
 
+static int ath79_reset_restart_handler(struct notifier_block *nb,
+                               unsigned long action, void *data)
+{
+       struct ath79_reset *ath79_reset =
+               container_of(nb, struct ath79_reset, restart_nb);
+
+       ath79_reset_assert(&ath79_reset->rcdev, FULL_CHIP_RESET);
+
+       return NOTIFY_DONE;
+}
+
 static int ath79_reset_probe(struct platform_device *pdev)
 {
        struct ath79_reset *ath79_reset;
        struct resource *res;
+       int err;
 
        ath79_reset = devm_kzalloc(&pdev->dev,
                                sizeof(*ath79_reset), GFP_KERNEL);
@@ -96,13 +112,25 @@ static int ath79_reset_probe(struct platform_device *pdev)
        ath79_reset->rcdev.of_reset_n_cells = 1;
        ath79_reset->rcdev.nr_resets = 32;
 
-       return reset_controller_register(&ath79_reset->rcdev);
+       err = reset_controller_register(&ath79_reset->rcdev);
+       if (err)
+               return err;
+
+       ath79_reset->restart_nb.notifier_call = ath79_reset_restart_handler;
+       ath79_reset->restart_nb.priority = 128;
+
+       err = register_restart_handler(&ath79_reset->restart_nb);
+       if (err)
+               dev_warn(&pdev->dev, "Failed to register restart handler\n");
+
+       return 0;
 }
 
 static int ath79_reset_remove(struct platform_device *pdev)
 {
        struct ath79_reset *ath79_reset = platform_get_drvdata(pdev);
 
+       unregister_restart_handler(&ath79_reset->restart_nb);
        reset_controller_unregister(&ath79_reset->rcdev);
 
        return 0;
index 3c922d3..970b1ad 100644 (file)
@@ -87,9 +87,7 @@ static int berlin2_reset_probe(struct platform_device *pdev)
        priv->rcdev.of_reset_n_cells = 2;
        priv->rcdev.of_xlate = berlin_reset_xlate;
 
-       reset_controller_register(&priv->rcdev);
-
-       return 0;
+       return reset_controller_register(&priv->rcdev);
 }
 
 static const struct of_device_id berlin_reset_dt_match[] = {
index 1a6c5d6..b7d773d 100644 (file)
@@ -133,9 +133,8 @@ static int socfpga_reset_probe(struct platform_device *pdev)
        data->rcdev.nr_resets = NR_BANKS * BITS_PER_LONG;
        data->rcdev.ops = &socfpga_reset_ops;
        data->rcdev.of_node = pdev->dev.of_node;
-       reset_controller_register(&data->rcdev);
 
-       return 0;
+       return reset_controller_register(&data->rcdev);
 }
 
 static int socfpga_reset_remove(struct platform_device *pdev)
index 3d95c87..8d41a18 100644 (file)
@@ -108,9 +108,8 @@ static int sunxi_reset_init(struct device_node *np)
        data->rcdev.nr_resets = size * 32;
        data->rcdev.ops = &sunxi_reset_ops;
        data->rcdev.of_node = np;
-       reset_controller_register(&data->rcdev);
 
-       return 0;
+       return reset_controller_register(&data->rcdev);
 
 err_alloc:
        kfree(data);
@@ -122,7 +121,7 @@ err_alloc:
  * our system, before we can even think of using a regular device
  * driver for it.
  */
-static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = {
+static const struct of_device_id sunxi_early_reset_dt_ids[] __initconst = {
        { .compatible = "allwinner,sun6i-a31-ahb1-reset", },
        { /* sentinel */ },
 };
index 89318a5..c6b3cd8 100644 (file)
@@ -121,9 +121,8 @@ static int zynq_reset_probe(struct platform_device *pdev)
        priv->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_LONG;
        priv->rcdev.ops = &zynq_reset_ops;
        priv->rcdev.of_node = pdev->dev.of_node;
-       reset_controller_register(&priv->rcdev);
 
-       return 0;
+       return reset_controller_register(&priv->rcdev);
 }
 
 static int zynq_reset_remove(struct platform_device *pdev)
index 827eb3d..6fb22af 100644 (file)
@@ -52,6 +52,7 @@ static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
 };
 
 /* Reset Generator control 0/1 */
+#define SYSCFG_5128    0x200
 #define SYSCFG_5131    0x20c
 #define SYSCFG_5132    0x210
 
@@ -96,6 +97,10 @@ static const struct syscfg_reset_channel_data stih407_softresets[] = {
        [STIH407_ERAM_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 1),
        [STIH407_LPM_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 2),
        [STIH407_KEYSCAN_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 8),
+       [STIH407_ST231_AUD_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 26),
+       [STIH407_ST231_DMU_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 27),
+       [STIH407_ST231_GP0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 28),
+       [STIH407_ST231_GP1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5128, 2),
 };
 
 /* PicoPHY reset/control */
index a145cc0..1600cc7 100644 (file)
@@ -103,17 +103,42 @@ static int syscfg_reset_deassert(struct reset_controller_dev *rcdev,
 static int syscfg_reset_dev(struct reset_controller_dev *rcdev,
                            unsigned long idx)
 {
-       int err = syscfg_reset_assert(rcdev, idx);
+       int err;
+
+       err = syscfg_reset_assert(rcdev, idx);
        if (err)
                return err;
 
        return syscfg_reset_deassert(rcdev, idx);
 }
 
+static int syscfg_reset_status(struct reset_controller_dev *rcdev,
+                              unsigned long idx)
+{
+       struct syscfg_reset_controller *rst = to_syscfg_reset_controller(rcdev);
+       const struct syscfg_reset_channel *ch;
+       u32 ret_val = 0;
+       int err;
+
+       if (idx >= rcdev->nr_resets)
+               return -EINVAL;
+
+       ch = &rst->channels[idx];
+       if (ch->ack)
+               err = regmap_field_read(ch->ack, &ret_val);
+       else
+               err = regmap_field_read(ch->reset, &ret_val);
+       if (err)
+               return err;
+
+       return rst->active_low ? !ret_val : !!ret_val;
+}
+
 static struct reset_control_ops syscfg_reset_ops = {
        .reset    = syscfg_reset_dev,
        .assert   = syscfg_reset_assert,
        .deassert = syscfg_reset_deassert,
+       .status   = syscfg_reset_status,
 };
 
 static int syscfg_reset_controller_register(struct device *dev,
index 2940bd7..25aba16 100644 (file)
@@ -1045,6 +1045,9 @@ static int tw_chrdev_open(struct inode *inode, struct file *file)
 static const struct file_operations tw_fops = {
        .owner          = THIS_MODULE,
        .unlocked_ioctl = tw_chrdev_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = tw_chrdev_ioctl,
+#endif
        .open           = tw_chrdev_open,
        .release        = NULL,
        .llseek         = noop_llseek,
index c1fe0d2..e2f31c9 100644 (file)
@@ -1106,6 +1106,7 @@ config SCSI_IPR
        tristate "IBM Power Linux RAID adapter support"
        depends on PCI && SCSI && ATA
        select FW_LOADER
+       select IRQ_POLL
        ---help---
          This driver supports the IBM Power Linux family RAID adapters.
          This includes IBM pSeries 5712, 5703, 5709, and 570A, as well
@@ -1620,23 +1621,6 @@ config ATARI_SCSI
          ST-DMA, replacing ACSI).  It does NOT support other schemes, like
          in the Hades (without DMA).
 
-config ATARI_SCSI_TOSHIBA_DELAY
-       bool "Long delays for Toshiba CD-ROMs"
-       depends on ATARI_SCSI
-       help
-         This option increases the delay after a SCSI arbitration to
-         accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
-         use a Toshiba CD-ROM drive; otherwise, the option is not needed and
-         would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
-       bool "Reset SCSI-devices at boottime"
-       depends on ATARI_SCSI
-       help
-         Reset the devices on your Atari whenever it boots.  This makes the
-         boot process fractionally longer but may assist recovery from errors
-         that leave the devices with SCSI operations partway completed.
-
 config MAC_SCSI
        tristate "Macintosh NCR5380 SCSI"
        depends on MAC && SCSI=y
index a777e5c..d728672 100644 (file)
@@ -1,17 +1,17 @@
-/* 
+/*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *      to implement 5380 SCSI drivers under Linux with a non-trantor
- *      architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *      Note that these routines also work with NR53c400 family chips.
+ * Note that these routines also work with NR53c400 family chips.
  *
  * Copyright 1993, Drew Eckhardt
- *      Visionary Computing 
- *      (Unix and Linux consulting and custom programming)
- *      drew@colorado.edu
- *      +1 (303) 666-5836
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * drew@colorado.edu
+ * +1 (303) 666-5836
  *
- * For more information, please consult 
+ * For more information, please consult
  *
  * NCR 5380 Family
  * SCSI Protocol Controller
  */
 
 /*
- * Revision 1.10 1998/9/2      Alan Cox
- *                             (alan@lxorguk.ukuu.org.uk)
- * Fixed up the timer lockups reported so far. Things still suck. Looking 
- * forward to 2.3 and per device request queues. Then it'll be possible to
- * SMP thread this beast and improve life no end.
- * Revision 1.9  1997/7/27     Ronald van Cuijlenborg
- *                             (ronald.van.cuijlenborg@tip.nl or nutty@dds.nl)
- * (hopefully) fixed and enhanced USLEEP
- * added support for DTC3181E card (for Mustek scanner)
- *
-
- * Revision 1.8                        Ingmar Baumgart
- *                             (ingmar@gonzo.schwaben.de)
- * added support for NCR53C400a card
- *
-
- * Revision 1.7  1996/3/2       Ray Van Tassle (rayvt@comm.mot.com)
- * added proc_info
- * added support needed for DTC 3180/3280
- * fixed a couple of bugs
- *
-
- * Revision 1.5  1994/01/19  09:14:57  drew
- * Fixed udelay() hack that was being used on DATAOUT phases
- * instead of a proper wait for the final handshake.
- *
- * Revision 1.4  1994/01/19  06:44:25  drew
- * *** empty log message ***
- *
- * Revision 1.3  1994/01/19  05:24:40  drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.2  1994/01/15  06:14:11  drew
- * REAL DMA support, bug fixes.
- *
- * Revision 1.1  1994/01/15  06:00:54  drew
- * Initial revision
- *
+ * With contributions from Ray Van Tassle, Ingmar Baumgart,
+ * Ronald van Cuijlenborg, Alan Cox and others.
  */
 
 /*
- * Further development / testing that should be done : 
+ * Further development / testing that should be done :
  * 1.  Cleanup the NCR5380_transfer_dma function and DMA operation complete
- *     code so that everything does the same thing that's done at the 
- *     end of a pseudo-DMA read operation.
+ * code so that everything does the same thing that's done at the
+ * end of a pseudo-DMA read operation.
  *
  * 2.  Fix REAL_DMA (interrupt driven, polled works fine) -
- *     basically, transfer size needs to be reduced by one 
- *     and the last byte read as is done with PSEUDO_DMA.
- * 
- * 4.  Test SCSI-II tagged queueing (I have no devices which support 
- *      tagged queueing)
- *
- * 5.  Test linked command handling code after Eric is ready with 
- *      the high level code.
+ * basically, transfer size needs to be reduced by one
+ * and the last byte read as is done with PSEUDO_DMA.
+ *
+ * 4.  Test SCSI-II tagged queueing (I have no devices which support
+ * tagged queueing)
  */
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_transport_spi.h>
-
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
-#define REMOVE(w,x,y,z) {printk("LINE:%d   Removing: %p->%p  %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
 
 #ifndef notyet
-#undef LINKED
 #undef REAL_DMA
 #endif
 
-#ifdef REAL_DMA_POLL
-#undef READ_OVERRUNS
-#define READ_OVERRUNS
-#endif
-
 #ifdef BOARD_REQUIRES_NO_DELAY
 #define io_recovery_delay(x)
 #else
 /*
  * Design
  *
- * This is a generic 5380 driver.  To use it on a different platform, 
+ * This is a generic 5380 driver.  To use it on a different platform,
  * one simply writes appropriate system specific macros (ie, data
- * transfer - some PC's will use the I/O bus, 68K's must use 
+ * transfer - some PC's will use the I/O bus, 68K's must use
  * memory mapped) and drops this file in their 'C' wrapper.
  *
- * (Note from hch:  unfortunately it was not enough for the different
- * m68k folks and instead of improving this driver they copied it
- * and hacked it up for their needs.  As a consequence they lost
- * most updates to this driver.  Maybe someone will fix all these
- * drivers to use a common core one day..)
- *
- * As far as command queueing, two queues are maintained for 
+ * As far as command queueing, two queues are maintained for
  * each 5380 in the system - commands that haven't been issued yet,
- * and commands that are currently executing.  This means that an 
- * unlimited number of commands may be queued, letting 
- * more commands propagate from the higher driver levels giving higher 
- * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported, 
- * allowing multiple commands to propagate all the way to a SCSI-II device 
+ * and commands that are currently executing.  This means that an
+ * unlimited number of commands may be queued, letting
+ * more commands propagate from the higher driver levels giving higher
+ * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported,
+ * allowing multiple commands to propagate all the way to a SCSI-II device
  * while a command is already executing.
  *
  *
- * Issues specific to the NCR5380 : 
- *
- * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead 
- * piece of hardware that requires you to sit in a loop polling for 
- * the REQ signal as long as you are connected.  Some devices are 
- * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect 
- * while doing long seek operations.
- * 
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like 
+ * Issues specific to the NCR5380 :
  *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- * 
- * Some tweaking of N and M needs to be done.  An algorithm based 
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these 
+ * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead
+ * piece of hardware that requires you to sit in a loop polling for
+ * the REQ signal as long as you are connected.  Some devices are
+ * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
+ * while doing long seek operations. [...] These
  * broken devices are the exception rather than the rule and I'd rather
  * spend my time optimizing for the normal case.
  *
  * which is started from a workqueue for each NCR5380 host in the
  * system.  It attempts to establish I_T_L or I_T_L_Q nexuses by
  * removing the commands from the issue queue and calling
- * NCR5380_select() if a nexus is not established. 
+ * NCR5380_select() if a nexus is not established.
  *
  * Once a nexus is established, the NCR5380_information_transfer()
  * phase goes through the various phases as instructed by the target.
  * if the target goes into MSG IN and sends a DISCONNECT message,
  * the command structure is placed into the per instance disconnected
- * queue, and NCR5380_main tries to find more work.  If the target is 
+ * queue, and NCR5380_main tries to find more work.  If the target is
  * idle for too long, the system will try to sleep.
  *
  * If a command has disconnected, eventually an interrupt will trigger,
  * calling NCR5380_intr()  which will in turn call NCR5380_reselect
  * to reestablish a nexus.  This will run main if necessary.
  *
- * On command termination, the done function will be called as 
+ * On command termination, the done function will be called as
  * appropriate.
  *
- * SCSI pointers are maintained in the SCp field of SCSI command 
+ * SCSI pointers are maintained in the SCp field of SCSI command
  * structures, being initialized after the command is connected
  * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
  * Note that in violation of the standard, an implicit SAVE POINTERS operation
 /*
  * Using this file :
  * This file a skeleton Linux SCSI driver for the NCR 5380 series
- * of chips.  To use it, you write an architecture specific functions 
+ * of chips.  To use it, you write an architecture specific functions
  * and macros and include this file in your driver.
  *
- * These macros control options : 
- * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be 
- *      defined.
- * 
+ * These macros control options :
+ * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be
+ * defined.
+ *
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- *      for commands that return with a CHECK CONDITION status. 
+ * for commands that return with a CHECK CONDITION status.
  *
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- *      transceivers. 
+ * transceivers.
  *
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
- *      override-configure an IRQ.
- *
- * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
- *      bytes at a time.  Since interrupts are disabled by default during
- *      these transfers, we might need this to give reasonable interrupt
- *      service time if the transfer size gets too large.
- *
- * LINKED - if defined, linked commands are supported.
+ * override-configure an IRQ.
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
  *
  * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't
- *      rely on phase mismatch and EOP interrupts to determine end 
- *      of phase.
- *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
- *          only really want to use this if you're having a problem with
- *          dropped characters during high speed communications, and even
- *          then, you're going to be better off twiddling with transfersize
- *          in the high level code.
- *
- * Defaults for these will be provided although the user may want to adjust 
- * these to allocate CPU resources to the SCSI driver or "real" code.
- * 
- * USLEEP_SLEEP - amount of time, in jiffies, to sleep
- *
- * USLEEP_POLL - amount of time, in jiffies, to poll
+ * rely on phase mismatch and EOP interrupts to determine end
+ * of phase.
  *
  * These macros MUST be defined :
- * NCR5380_local_declare() - declare any local variables needed for your
- *      transfer routines.
  *
- * NCR5380_setup(instance) - initialize any local variables needed from a given
- *      instance of the host adapter for NCR5380_{read,write,pread,pwrite}
- * 
  * NCR5380_read(register)  - read from the specified register
  *
- * NCR5380_write(register, value) - write to the specific register 
+ * NCR5380_write(register, value) - write to the specific register
  *
- * NCR5380_implementation_fields  - additional fields needed for this 
- *      specific implementation of the NCR5380
+ * NCR5380_implementation_fields  - additional fields needed for this
+ * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions : 
+ * REAL functions :
  * NCR5380_REAL_DMA should be defined if real DMA is to be used.
- * Note that the DMA setup functions should return the number of bytes 
- *      that they were able to program the controller for.
+ * Note that the DMA setup functions should return the number of bytes
+ * that they were able to program the controller for.
  *
- * Also note that generic i386/PC versions of these macros are 
- *      available as NCR5380_i386_dma_write_setup,
- *      NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
+ * Also note that generic i386/PC versions of these macros are
+ * available as NCR5380_i386_dma_write_setup,
+ * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
  *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_pread(instance, dst, count);
  *
  * The generic driver is initialized by calling NCR5380_init(instance),
- * after setting the appropriate host specific fields and ID.  If the 
+ * after setting the appropriate host specific fields and ID.  If the
  * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
  * possible) function may be used.
  */
 
-static int do_abort(struct Scsi_Host *host);
-static void do_reset(struct Scsi_Host *host);
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
 
-/*
- *     initialize_SCp          -       init the scsi pointer field
- *     @cmd: command block to set up
+/**
+ * initialize_SCp - init the scsi pointer field
+ * @cmd: command block to set up
  *
- *     Set up the internal fields in the SCSI command.
+ * Set up the internal fields in the SCSI command.
  */
 
 static inline void initialize_SCp(struct scsi_cmnd *cmd)
 {
-       /* 
-        * Initialize the Scsi Pointer field so that all of the commands in the 
+       /*
+        * Initialize the Scsi Pointer field so that all of the commands in the
         * various queues are valid.
         */
 
@@ -295,120 +198,123 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
                cmd->SCp.ptr = NULL;
                cmd->SCp.this_residual = 0;
        }
+
+       cmd->SCp.Status = 0;
+       cmd->SCp.Message = 0;
 }
 
 /**
- *     NCR5380_poll_politely   -       wait for NCR5380 status bits
- *     @instance: controller to poll
- *     @reg: 5380 register to poll
- *     @bit: Bitmask to check
- *     @val: Value required to exit
- *
- *     Polls the NCR5380 in a reasonably efficient manner waiting for
- *     an event to occur, after a short quick poll we begin giving the
- *     CPU back in non IRQ contexts
- *
- *     Returns the value of the register or a negative error code.
+ * NCR5380_poll_politely2 - wait for two chip register values
+ * @instance: controller to poll
+ * @reg1: 5380 register to poll
+ * @bit1: Bitmask to check
+ * @val1: Expected value
+ * @reg2: Second 5380 register to poll
+ * @bit2: Second bitmask to check
+ * @val2: Second expected value
+ * @wait: Time-out in jiffies
+ *
+ * Polls the chip in a reasonably efficient manner waiting for an
+ * event to occur. After a short quick poll we begin to yield the CPU
+ * (if possible). In irq contexts the time-out is arbitrarily limited.
+ * Callers may hold locks as long as they are held in irq mode.
+ *
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
  */
-static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
+
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+                                  int reg1, int bit1, int val1,
+                                  int reg2, int bit2, int val2, int wait)
 {
-       NCR5380_local_declare();
-       int n = 500;            /* At about 8uS a cycle for the cpu access */
-       unsigned long end = jiffies + t;
-       int r;
-       
-       NCR5380_setup(instance);
-
-       while( n-- > 0)
-       {
-               r = NCR5380_read(reg);
-               if((r & bit) == val)
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       unsigned long deadline = jiffies + wait;
+       unsigned long n;
+
+       /* Busy-wait for up to 10 ms */
+       n = min(10000U, jiffies_to_usecs(wait));
+       n *= hostdata->accesses_per_ms;
+       n /= 2000;
+       do {
+               if ((NCR5380_read(reg1) & bit1) == val1)
+                       return 0;
+               if ((NCR5380_read(reg2) & bit2) == val2)
                        return 0;
                cpu_relax();
-       }
-       
-       /* t time yet ? */
-       while(time_before(jiffies, end))
-       {
-               r = NCR5380_read(reg);
-               if((r & bit) == val)
+       } while (n--);
+
+       if (irqs_disabled() || in_interrupt())
+               return -ETIMEDOUT;
+
+       /* Repeatedly sleep for 1 ms until deadline */
+       while (time_is_after_jiffies(deadline)) {
+               schedule_timeout_uninterruptible(1);
+               if ((NCR5380_read(reg1) & bit1) == val1)
+                       return 0;
+               if ((NCR5380_read(reg2) & bit2) == val2)
                        return 0;
-               if(!in_interrupt())
-                       cond_resched();
-               else
-                       cpu_relax();
        }
+
        return -ETIMEDOUT;
 }
 
-static struct {
-       unsigned char value;
-       const char *name;
-} phases[] __maybe_unused = {
-       {PHASE_DATAOUT, "DATAOUT"}, 
-       {PHASE_DATAIN, "DATAIN"}, 
-       {PHASE_CMDOUT, "CMDOUT"}, 
-       {PHASE_STATIN, "STATIN"}, 
-       {PHASE_MSGOUT, "MSGOUT"}, 
-       {PHASE_MSGIN, "MSGIN"}, 
-       {PHASE_UNKNOWN, "UNKNOWN"}
-};
+static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                        int reg, int bit, int val, int wait)
+{
+       return NCR5380_poll_politely2(instance, reg, bit, val,
+                                               reg, bit, val, wait);
+}
 
 #if NDEBUG
 static struct {
        unsigned char mask;
        const char *name;
-} signals[] = { 
-       {SR_DBP, "PARITY"}, 
-       {SR_RST, "RST"}, 
-       {SR_BSY, "BSY"}, 
-       {SR_REQ, "REQ"}, 
-       {SR_MSG, "MSG"}, 
-       {SR_CD, "CD"}, 
-       {SR_IO, "IO"}, 
-       {SR_SEL, "SEL"}, 
+} signals[] = {
+       {SR_DBP, "PARITY"},
+       {SR_RST, "RST"},
+       {SR_BSY, "BSY"},
+       {SR_REQ, "REQ"},
+       {SR_MSG, "MSG"},
+       {SR_CD, "CD"},
+       {SR_IO, "IO"},
+       {SR_SEL, "SEL"},
        {0, NULL}
-}, 
+},
 basrs[] = {
-       {BASR_ATN, "ATN"}, 
-       {BASR_ACK, "ACK"}, 
+       {BASR_ATN, "ATN"},
+       {BASR_ACK, "ACK"},
        {0, NULL}
-}, 
-icrs[] = { 
-       {ICR_ASSERT_RST, "ASSERT RST"}, 
-       {ICR_ASSERT_ACK, "ASSERT ACK"}, 
-       {ICR_ASSERT_BSY, "ASSERT BSY"}, 
-       {ICR_ASSERT_SEL, "ASSERT SEL"}, 
-       {ICR_ASSERT_ATN, "ASSERT ATN"}, 
-       {ICR_ASSERT_DATA, "ASSERT DATA"}, 
+},
+icrs[] = {
+       {ICR_ASSERT_RST, "ASSERT RST"},
+       {ICR_ASSERT_ACK, "ASSERT ACK"},
+       {ICR_ASSERT_BSY, "ASSERT BSY"},
+       {ICR_ASSERT_SEL, "ASSERT SEL"},
+       {ICR_ASSERT_ATN, "ASSERT ATN"},
+       {ICR_ASSERT_DATA, "ASSERT DATA"},
        {0, NULL}
-}, 
-mrs[] = { 
-       {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, 
-       {MR_TARGET, "MODE TARGET"}, 
-       {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, 
-       {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"}, 
-       {MR_MONITOR_BSY, "MODE MONITOR BSY"}, 
-       {MR_DMA_MODE, "MODE DMA"}, 
-       {MR_ARBITRATE, "MODE ARBITRATION"}, 
+},
+mrs[] = {
+       {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
+       {MR_TARGET, "MODE TARGET"},
+       {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
+       {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
+       {MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
+       {MR_MONITOR_BSY, "MODE MONITOR BSY"},
+       {MR_DMA_MODE, "MODE DMA"},
+       {MR_ARBITRATE, "MODE ARBITRATION"},
        {0, NULL}
 };
 
 /**
- *     NCR5380_print   -       print scsi bus signals
- *     @instance:      adapter state to dump
- *
- *     Print the SCSI bus signals for debugging purposes
+ * NCR5380_print - print scsi bus signals
+ * @instance: adapter state to dump
  *
- *     Locks: caller holds hostdata lock (not essential)
+ * Print the SCSI bus signals for debugging purposes
  */
 
 static void NCR5380_print(struct Scsi_Host *instance)
 {
-       NCR5380_local_declare();
        unsigned char status, data, basr, mr, icr, i;
-       NCR5380_setup(instance);
 
        data = NCR5380_read(CURRENT_SCSI_DATA_REG);
        status = NCR5380_read(STATUS_REG);
@@ -435,117 +341,56 @@ static void NCR5380_print(struct Scsi_Host *instance)
        printk("\n");
 }
 
+static struct {
+       unsigned char value;
+       const char *name;
+} phases[] = {
+       {PHASE_DATAOUT, "DATAOUT"},
+       {PHASE_DATAIN, "DATAIN"},
+       {PHASE_CMDOUT, "CMDOUT"},
+       {PHASE_STATIN, "STATIN"},
+       {PHASE_MSGOUT, "MSGOUT"},
+       {PHASE_MSGIN, "MSGIN"},
+       {PHASE_UNKNOWN, "UNKNOWN"}
+};
 
-/* 
- *     NCR5380_print_phase     -       show SCSI phase
- *     @instance: adapter to dump
- *
- *     Print the current SCSI phase for debugging purposes
+/**
+ * NCR5380_print_phase - show SCSI phase
+ * @instance: adapter to dump
  *
- *     Locks: none
+ * Print the current SCSI phase for debugging purposes
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
 {
-       NCR5380_local_declare();
        unsigned char status;
        int i;
-       NCR5380_setup(instance);
 
        status = NCR5380_read(STATUS_REG);
        if (!(status & SR_REQ))
-               printk("scsi%d : REQ not asserted, phase unknown.\n", instance->host_no);
+               shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n");
        else {
-               for (i = 0; (phases[i].value != PHASE_UNKNOWN) && (phases[i].value != (status & PHASE_MASK)); ++i);
-               printk("scsi%d : phase %s\n", instance->host_no, phases[i].name);
+               for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
+                    (phases[i].value != (status & PHASE_MASK)); ++i)
+                       ;
+               shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
        }
 }
 #endif
 
-/*
- * These need tweaking, and would probably work best as per-device 
- * flags initialized differently for disk, tape, cd, etc devices.
- * People with broken devices are free to experiment as to what gives
- * the best results for them.
- *
- * USLEEP_SLEEP should be a minimum seek time.
- *
- * USLEEP_POLL should be a maximum rotational latency.
- */
-#ifndef USLEEP_SLEEP
-/* 20 ms (reasonable hard disk speed) */
-#define USLEEP_SLEEP msecs_to_jiffies(20)
-#endif
-/* 300 RPM (floppy speed) */
-#ifndef USLEEP_POLL
-#define USLEEP_POLL msecs_to_jiffies(200)
-#endif
-#ifndef USLEEP_WAITLONG
-/* RvC: (reasonable time to wait on select error) */
-#define USLEEP_WAITLONG USLEEP_SLEEP
-#endif
-
-/* 
- * Function : int should_disconnect (unsigned char cmd)
- *
- * Purpose : decide whether a command would normally disconnect or 
- *      not, since if it won't disconnect we should go to sleep.
- *
- * Input : cmd - opcode of SCSI command
- *
- * Returns : DISCONNECT_LONG if we should disconnect for a really long 
- *      time (ie always, sleep, look for REQ active, sleep), 
- *      DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
- *      time-to-data delay, DISCONNECT_NONE if this command would return
- *      immediately.
- *
- *      Future sleep algorithms based on time to data can exploit 
- *      something like this so they can differentiate between "normal" 
- *      (ie, read, write, seek) and unusual commands (ie, * format).
- *
- * Note : We don't deal with commands that handle an immediate disconnect,
- *        
- */
 
-static int should_disconnect(unsigned char cmd)
-{
-       switch (cmd) {
-       case READ_6:
-       case WRITE_6:
-       case SEEK_6:
-       case READ_10:
-       case WRITE_10:
-       case SEEK_10:
-               return DISCONNECT_TIME_TO_DATA;
-       case FORMAT_UNIT:
-       case SEARCH_HIGH:
-       case SEARCH_LOW:
-       case SEARCH_EQUAL:
-               return DISCONNECT_LONG;
-       default:
-               return DISCONNECT_NONE;
-       }
-}
-
-static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
-{
-       hostdata->time_expires = jiffies + timeout;
-       schedule_delayed_work(&hostdata->coroutine, timeout);
-}
-
-
-static int probe_irq __initdata = 0;
+static int probe_irq __initdata;
 
 /**
- *     probe_intr      -       helper for IRQ autoprobe
- *     @irq: interrupt number
- *     @dev_id: unused
- *     @regs: unused
+ * probe_intr  -       helper for IRQ autoprobe
+ * @irq: interrupt number
+ * @dev_id: unused
+ * @regs: unused
  *
- *     Set a flag to indicate the IRQ in question was received. This is
- *     used by the IRQ probe code.
+ * Set a flag to indicate the IRQ in question was received. This is
+ * used by the IRQ probe code.
  */
+
 static irqreturn_t __init probe_intr(int irq, void *dev_id)
 {
        probe_irq = irq;
@@ -553,24 +398,20 @@ static irqreturn_t __init probe_intr(int irq, void *dev_id)
 }
 
 /**
- *     NCR5380_probe_irq       -       find the IRQ of an NCR5380
- *     @instance: NCR5380 controller
- *     @possible: bitmask of ISA IRQ lines
- *
- *     Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
- *     and then looking to see what interrupt actually turned up.
+ * NCR5380_probe_irq   -       find the IRQ of an NCR5380
+ * @instance: NCR5380 controller
+ * @possible: bitmask of ISA IRQ lines
  *
- *     Locks: none, irqs must be enabled on entry
+ * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
+ * and then looking to see what interrupt actually turned up.
  */
 
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
                                                int possible)
 {
-       NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned long timeout;
        int trying_irqs, i, mask;
-       NCR5380_setup(instance);
 
        for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1)
                if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0))
@@ -581,7 +422,7 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 
        /*
         * A interrupt is triggered whenever BSY = false, SEL = true
-        * and a bit set in the SELECT_ENABLE_REG is asserted on the 
+        * and a bit set in the SELECT_ENABLE_REG is asserted on the
         * SCSI bus.
         *
         * Note that the bus is only driven when the phase control signals
@@ -596,7 +437,7 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 
        while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
                schedule_timeout_uninterruptible(1);
-       
+
        NCR5380_write(SELECT_ENABLE_REG, 0);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
@@ -608,12 +449,10 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 }
 
 /**
- *     NCR58380_info - report driver and host information
- *     @instance: relevant scsi host instance
- *
- *     For use as the host template info() handler.
+ * NCR58380_info - report driver and host information
+ * @instance: relevant scsi host instance
  *
- *     Locks: none
+ * For use as the host template info() handler.
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -633,20 +472,14 @@ static void prepare_info(struct Scsi_Host *instance)
                 "can_queue %d, cmd_per_lun %d, "
                 "sg_tablesize %d, this_id %d, "
                 "flags { %s%s%s}, "
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-                "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
-#endif
                 "options { %s} ",
                 instance->hostt->name, instance->io_port, instance->n_io_port,
                 instance->base, instance->irq,
                 instance->can_queue, instance->cmd_per_lun,
                 instance->sg_tablesize, instance->this_id,
-                hostdata->flags & FLAG_NCR53C400     ? "NCR53C400 "     : "",
-                hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
+                hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
                 hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-                USLEEP_POLL, USLEEP_WAITLONG,
-#endif
+                hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #ifdef AUTOPROBE_IRQ
                 "AUTOPROBE_IRQ "
 #endif
@@ -664,47 +497,11 @@ static void prepare_info(struct Scsi_Host *instance)
 #endif
 #ifdef PSEUDO_DMA
                 "PSEUDO_DMA "
-#endif
-#ifdef UNSAFE
-                "UNSAFE "
-#endif
-#ifdef NCR53C400
-                "NCR53C400 "
 #endif
                 "");
 }
 
-/**
- *     NCR5380_print_status    -       dump controller info
- *     @instance: controller to dump
- *
- *     Print commands in the various queues, called from NCR5380_abort 
- *     and NCR5380_debug to aid debugging.
- *
- *     Locks: called functions disable irqs
- */
-
-static void NCR5380_print_status(struct Scsi_Host *instance)
-{
-       NCR5380_dprint(NDEBUG_ANY, instance);
-       NCR5380_dprint_phase(NDEBUG_ANY, instance);
-}
-
 #ifdef PSEUDO_DMA
-/******************************************/
-/*
- * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED]
- *
- * *buffer: I/O buffer
- * **start: if inout == FALSE pointer into buffer where user read should start
- * offset: current offset
- * length: length of buffer
- * hostno: Scsi_Host host_no
- * inout: TRUE - user is writing; FALSE - user is reading
- *
- * Return the number of bytes read from or written
- */
-
 static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
        char *buffer, int length)
 {
@@ -714,104 +511,41 @@ static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
        hostdata->spin_max_w = 0;
        return 0;
 }
-#endif
-
-static
-void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m);
-static
-void lprint_command(unsigned char *cmd, struct seq_file *m);
-static
-void lprint_opcode(int opcode, struct seq_file *m);
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-       struct Scsi_Host *instance)
+                                            struct Scsi_Host *instance)
 {
-       struct NCR5380_hostdata *hostdata;
-       struct scsi_cmnd *ptr;
-
-       hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-#ifdef PSEUDO_DMA
        seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
                hostdata->spin_max_w, hostdata->spin_max_r);
-#endif
-       spin_lock_irq(instance->host_lock);
-       if (!hostdata->connected)
-               seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no);
-       else
-               lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-       seq_printf(m, "scsi%d: issue_queue\n", instance->host_no);
-       for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
-               lprint_Scsi_Cmnd(ptr, m);
-
-       seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
-       for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
-               lprint_Scsi_Cmnd(ptr, m);
-       spin_unlock_irq(instance->host_lock);
        return 0;
 }
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-       seq_printf(m, "scsi%d : destination target %d, lun %llu\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
-       seq_puts(m, "        command = ");
-       lprint_command(cmd->cmnd, m);
-}
-
-static void lprint_command(unsigned char *command, struct seq_file *m)
-{
-       int i, s;
-       lprint_opcode(command[0], m);
-       for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-               seq_printf(m, "%02x ", command[i]);
-       seq_putc(m, '\n');
-}
-
-static void lprint_opcode(int opcode, struct seq_file *m)
-{
-       seq_printf(m, "%2d (0x%02x)", opcode, opcode);
-}
-
+#endif
 
 /**
- *     NCR5380_init    -       initialise an NCR5380
- *     @instance: adapter to configure
- *     @flags: control flags
+ * NCR5380_init - initialise an NCR5380
+ * @instance: adapter to configure
+ * @flags: control flags
  *
- *     Initializes *instance and corresponding 5380 chip,
- *      with flags OR'd into the initial flags value.
+ * Initializes *instance and corresponding 5380 chip,
+ * with flags OR'd into the initial flags value.
  *
- *     Notes : I assume that the host, hostno, and id bits have been
- *      set correctly.  I don't care about the irq and other fields. 
+ * Notes : I assume that the host, hostno, and id bits have been
+ * set correctly. I don't care about the irq and other fields.
  *
- *     Returns 0 for success
- *
- *     Locks: interrupts must be enabled when we are called 
+ * Returns 0 for success
  */
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
-       NCR5380_local_declare();
-       int i, pass;
-       unsigned long timeout;
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-
-       if(in_interrupt())
-               printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-       /* 
-        * On NCR53C400 boards, NCR5380 registers are mapped 8 past 
-        * the base address.
-        */
-
-#ifdef NCR53C400
-       if (flags & FLAG_NCR53C400)
-               instance->NCR5380_instance_name += NCR53C400_address_adjust;
-#endif
-
-       NCR5380_setup(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       int i;
+       unsigned long deadline;
 
-       hostdata->aborted = 0;
+       hostdata->host = instance;
        hostdata->id_mask = 1 << instance->this_id;
+       hostdata->id_higher_mask = 0;
        for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
                if (i > hostdata->id_mask)
                        hostdata->id_higher_mask |= i;
@@ -820,21 +554,21 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
 #ifdef REAL_DMA
        hostdata->dmalen = 0;
 #endif
-       hostdata->targets_present = 0;
+       spin_lock_init(&hostdata->lock);
        hostdata->connected = NULL;
-       hostdata->issue_queue = NULL;
-       hostdata->disconnected_queue = NULL;
-       
-       INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
-       
-       /* The CHECK code seems to break the 53C400. Will check it later maybe */
-       if (flags & FLAG_NCR53C400)
-               hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
-       else
-               hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
+       hostdata->sensing = NULL;
+       INIT_LIST_HEAD(&hostdata->autosense);
+       INIT_LIST_HEAD(&hostdata->unissued);
+       INIT_LIST_HEAD(&hostdata->disconnected);
 
-       hostdata->host = instance;
-       hostdata->time_expires = 0;
+       hostdata->flags = flags;
+
+       INIT_WORK(&hostdata->main_task, NCR5380_main);
+       hostdata->work_q = alloc_workqueue("ncr5380_%d",
+                               WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1, instance->host_no);
+       if (!hostdata->work_q)
+               return -ENOMEM;
 
        prepare_info(instance);
 
@@ -843,43 +577,69 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
        NCR5380_write(TARGET_COMMAND_REG, 0);
        NCR5380_write(SELECT_ENABLE_REG, 0);
 
-#ifdef NCR53C400
-       if (hostdata->flags & FLAG_NCR53C400) {
-               NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-       }
-#endif
+       /* Calibrate register polling loop */
+       i = 0;
+       deadline = jiffies + 1;
+       do {
+               cpu_relax();
+       } while (time_is_after_jiffies(deadline));
+       deadline += msecs_to_jiffies(256);
+       do {
+               NCR5380_read(STATUS_REG);
+               ++i;
+               cpu_relax();
+       } while (time_is_after_jiffies(deadline));
+       hostdata->accesses_per_ms = i / 256;
 
-       /* 
-        * Detect and correct bus wedge problems.
-        *
-        * If the system crashed, it may have crashed in a state 
-        * where a SCSI command was still executing, and the 
-        * SCSI bus is not in a BUS FREE STATE.
-        *
-        * If this is the case, we'll try to abort the currently
-        * established nexus which we know nothing about, and that
-        * failing, do a hard reset of the SCSI bus 
-        */
+       return 0;
+}
+
+/**
+ * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
+ * @instance: adapter to check
+ *
+ * If the system crashed, it may have crashed with a connected target and
+ * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
+ * currently established nexus, which we know nothing about. Failing that
+ * do a bus reset.
+ *
+ * Note that a bus reset will cause the chip to assert IRQ.
+ *
+ * Returns 0 if successful, otherwise -ENXIO.
+ */
+
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       int pass;
 
        for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
                switch (pass) {
                case 1:
                case 3:
                case 5:
-                       printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
-                       timeout = jiffies + 5 * HZ;
-                       NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
+                       shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n");
+                       NCR5380_poll_politely(instance,
+                                             STATUS_REG, SR_BSY, 0, 5 * HZ);
                        break;
                case 2:
-                       printk(KERN_WARNING "scsi%d: bus busy, attempting abort\n", instance->host_no);
+                       shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
                        do_abort(instance);
                        break;
                case 4:
-                       printk(KERN_WARNING "scsi%d: bus busy, attempting reset\n", instance->host_no);
+                       shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
                        do_reset(instance);
+                       /* Wait after a reset; the SCSI standard calls for
+                        * 250ms, we wait 500ms to be on the safe side.
+                        * But some Toshiba CD-ROMs need ten times that.
+                        */
+                       if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+                               msleep(2500);
+                       else
+                               msleep(500);
                        break;
                case 6:
-                       printk(KERN_ERR "scsi%d: bus locked solid or invalid override\n", instance->host_no);
+                       shost_printk(KERN_ERR, instance, "bus locked solid\n");
                        return -ENXIO;
                }
        }
@@ -887,450 +647,513 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
 }
 
 /**
- *     NCR5380_exit    -       remove an NCR5380
- *     @instance: adapter to remove
+ * NCR5380_exit - remove an NCR5380
+ * @instance: adapter to remove
+ *
+ * Assumes that no more work can be queued (e.g. by NCR5380_intr).
  */
 
 static void NCR5380_exit(struct Scsi_Host *instance)
 {
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-       cancel_delayed_work_sync(&hostdata->coroutine);
+       cancel_work_sync(&hostdata->main_task);
+       destroy_workqueue(hostdata->work_q);
 }
 
 /**
- *     NCR5380_queue_command           -       queue a command
- *     @cmd: SCSI command
- *     @done: completion handler
- *
- *      cmd is added to the per instance issue_queue, with minor 
- *      twiddling done to the host specific fields of cmd.  If the 
- *      main coroutine is not running, it is restarted.
+ * complete_cmd - finish processing a command and return it to the SCSI ML
+ * @instance: the host instance
+ * @cmd: command to complete
+ */
+
+static void complete_cmd(struct Scsi_Host *instance,
+                         struct scsi_cmnd *cmd)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+       dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
+
+       if (hostdata->sensing == cmd) {
+               /* Autosense processing ends here */
+               if ((cmd->result & 0xff) != SAM_STAT_GOOD) {
+                       scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+                       set_host_byte(cmd, DID_ERROR);
+               } else
+                       scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+               hostdata->sensing = NULL;
+       }
+
+       hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+
+       cmd->scsi_done(cmd);
+}
+
+/**
+ * NCR5380_queue_command - queue a command
+ * @instance: the relevant SCSI adapter
+ * @cmd: SCSI command
  *
- *     Locks: host lock taken by caller
+ * cmd is added to the per-instance issue queue, with minor
+ * twiddling done to the host specific fields of cmd.  If the
+ * main coroutine is not running, it is restarted.
  */
 
-static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *))
+static int NCR5380_queue_command(struct Scsi_Host *instance,
+                                 struct scsi_cmnd *cmd)
 {
-       struct Scsi_Host *instance = cmd->device->host;
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-       struct scsi_cmnd *tmp;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+       unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
        switch (cmd->cmnd[0]) {
        case WRITE_6:
        case WRITE_10:
-               printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
+               shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
                cmd->result = (DID_ERROR << 16);
-               done(cmd);
+               cmd->scsi_done(cmd);
                return 0;
        }
-#endif                         /* (NDEBUG & NDEBUG_NO_WRITE) */
+#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
-       /* 
-        * We use the host_scribble field as a pointer to the next command  
-        * in a queue 
-        */
-
-       cmd->host_scribble = NULL;
-       cmd->scsi_done = done;
        cmd->result = 0;
 
-       /* 
-        * Insert the cmd into the issue queue. Note that REQUEST SENSE 
+       spin_lock_irqsave(&hostdata->lock, flags);
+
+       /*
+        * Insert the cmd into the issue queue. Note that REQUEST SENSE
         * commands are added to the head of the queue since any command will
-        * clear the contingent allegiance condition that exists and the 
+        * clear the contingent allegiance condition that exists and the
         * sense data is only guaranteed to be valid while the condition exists.
         */
 
-       if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-               LIST(cmd, hostdata->issue_queue);
-               cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
-               hostdata->issue_queue = cmd;
-       } else {
-               for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-               LIST(cmd, tmp);
-               tmp->host_scribble = (unsigned char *) cmd;
-       }
-       dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+       if (cmd->cmnd[0] == REQUEST_SENSE)
+               list_add(&ncmd->list, &hostdata->unissued);
+       else
+               list_add_tail(&ncmd->list, &hostdata->unissued);
+
+       spin_unlock_irqrestore(&hostdata->lock, flags);
+
+       dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n",
+                cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-       /* Run the coroutine if it isn't already running. */
        /* Kick off command processing */
-       schedule_delayed_work(&hostdata->coroutine, 0);
+       queue_work(hostdata->work_q, &hostdata->main_task);
        return 0;
 }
 
-static DEF_SCSI_QCMD(NCR5380_queue_command)
+/**
+ * dequeue_next_cmd - dequeue a command for processing
+ * @instance: the scsi host instance
+ *
+ * Priority is given to commands on the autosense queue. These commands
+ * need autosense because of a CHECK CONDITION result.
+ *
+ * Returns a command pointer if a command is found for a target that is
+ * not already busy. Otherwise returns NULL.
+ */
+
+static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       struct NCR5380_cmd *ncmd;
+       struct scsi_cmnd *cmd;
+
+       if (list_empty(&hostdata->autosense)) {
+               list_for_each_entry(ncmd, &hostdata->unissued, list) {
+                       cmd = NCR5380_to_scmd(ncmd);
+                       dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
+                                cmd, scmd_id(cmd), hostdata->busy[scmd_id(cmd)], cmd->device->lun);
+
+                       if (!(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))) {
+                               list_del(&ncmd->list);
+                               dsprintk(NDEBUG_QUEUES, instance,
+                                        "dequeue: removed %p from issue queue\n", cmd);
+                               return cmd;
+                       }
+               }
+       } else {
+               /* Autosense processing begins here */
+               ncmd = list_first_entry(&hostdata->autosense,
+                                       struct NCR5380_cmd, list);
+               list_del(&ncmd->list);
+               cmd = NCR5380_to_scmd(ncmd);
+               dsprintk(NDEBUG_QUEUES, instance,
+                        "dequeue: removed %p from autosense queue\n", cmd);
+               scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
+               hostdata->sensing = cmd;
+               return cmd;
+       }
+       return NULL;
+}
+
+static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
+       if (hostdata->sensing) {
+               scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+               list_add(&ncmd->list, &hostdata->autosense);
+               hostdata->sensing = NULL;
+       } else
+               list_add(&ncmd->list, &hostdata->unissued);
+}
 
 /**
- *     NCR5380_main    -       NCR state machines
- *
- *     NCR5380_main is a coroutine that runs as long as more work can 
- *      be done on the NCR5380 host adapters in a system.  Both 
- *      NCR5380_queue_command() and NCR5380_intr() will try to start it 
- *      in case it is not running.
- * 
- *     Locks: called as its own thread with no locks held. Takes the
- *     host lock and called routines may take the isa dma lock.
+ * NCR5380_main - NCR state machines
+ *
+ * NCR5380_main is a coroutine that runs as long as more work can
+ * be done on the NCR5380 host adapters in a system.  Both
+ * NCR5380_queue_command() and NCR5380_intr() will try to start it
+ * in case it is not running.
  */
 
 static void NCR5380_main(struct work_struct *work)
 {
        struct NCR5380_hostdata *hostdata =
-               container_of(work, struct NCR5380_hostdata, coroutine.work);
+               container_of(work, struct NCR5380_hostdata, main_task);
        struct Scsi_Host *instance = hostdata->host;
-       struct scsi_cmnd *tmp, *prev;
+       struct scsi_cmnd *cmd;
        int done;
-       
-       spin_lock_irq(instance->host_lock);
+
        do {
-               /* Lock held here */
                done = 1;
-               if (!hostdata->connected && !hostdata->selecting) {
-                       dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
-                       /*
-                        * Search through the issue_queue for a command destined
-                        * for a target that's not busy.
-                        */
-                       for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-                       {
-                               if (prev != tmp)
-                                   dprintk(NDEBUG_LISTS, "MAIN tmp=%p   target=%d   busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
-                               /*  When we find one, remove it from the issue queue. */
-                               if (!(hostdata->busy[tmp->device->id] &
-                                     (1 << (u8)(tmp->device->lun & 0xff)))) {
-                                       if (prev) {
-                                               REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
-                                               prev->host_scribble = tmp->host_scribble;
-                                       } else {
-                                               REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
-                                               hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
-                                       }
-                                       tmp->host_scribble = NULL;
 
-                                       /* 
-                                        * Attempt to establish an I_T_L nexus here. 
-                                        * On success, instance->hostdata->connected is set.
-                                        * On failure, we must add the command back to the
-                                        *   issue queue so we can keep trying. 
-                                        */
-                                       dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
-       
-                                       /*
-                                        * A successful selection is defined as one that 
-                                        * leaves us with the command connected and 
-                                        * in hostdata->connected, OR has terminated the
-                                        * command.
-                                        *
-                                        * With successful commands, we fall through
-                                        * and see if we can do an information transfer,
-                                        * with failures we will restart.
-                                        */
-                                       hostdata->selecting = NULL;
-                                       /* RvC: have to preset this to indicate a new command is being performed */
+               spin_lock_irq(&hostdata->lock);
+               while (!hostdata->connected &&
+                      (cmd = dequeue_next_cmd(instance))) {
 
-                                       /*
-                                        * REQUEST SENSE commands are issued without tagged
-                                        * queueing, even on SCSI-II devices because the
-                                        * contingent allegiance condition exists for the
-                                        * entire unit.
-                                        */
+                       dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
 
-                                       if (!NCR5380_select(instance, tmp)) {
-                                               break;
-                                       } else {
-                                               LIST(tmp, hostdata->issue_queue);
-                                               tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
-                                               hostdata->issue_queue = tmp;
-                                               done = 0;
-                                               dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
-                                       }
-                                       /* lock held here still */
-                               }       /* if target/lun is not busy */
-                       }       /* for */
-                       /* exited locked */
-               }       /* if (!hostdata->connected) */
-               if (hostdata->selecting) {
-                       tmp = (struct scsi_cmnd *) hostdata->selecting;
-                       /* Selection will drop and retake the lock */
-                       if (!NCR5380_select(instance, tmp)) {
-                               /* Ok ?? */
+                       /*
+                        * Attempt to establish an I_T_L nexus here.
+                        * On success, instance->hostdata->connected is set.
+                        * On failure, we must add the command back to the
+                        * issue queue so we can keep trying.
+                        */
+                       /*
+                        * REQUEST SENSE commands are issued without tagged
+                        * queueing, even on SCSI-II devices because the
+                        * contingent allegiance condition exists for the
+                        * entire unit.
+                        */
+
+                       cmd = NCR5380_select(instance, cmd);
+                       if (!cmd) {
+                               dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
                        } else {
-                               /* RvC: device failed, so we wait a long time
-                                  this is needed for Mustek scanners, that
-                                  do not respond to commands immediately
-                                  after a scan */
-                               printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->device->id);
-                               LIST(tmp, hostdata->issue_queue);
-                               tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
-                               hostdata->issue_queue = tmp;
-                               NCR5380_set_timer(hostdata, USLEEP_WAITLONG);
+                               dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
+                                        "main: select failed, returning %p to queue\n", cmd);
+                               requeue_cmd(instance, cmd);
                        }
-               }       /* if hostdata->selecting */
+               }
                if (hostdata->connected
 #ifdef REAL_DMA
                    && !hostdata->dmalen
 #endif
-                   && (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies))
                    ) {
-                       dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
+                       dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
                        NCR5380_information_transfer(instance);
-                       dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
                        done = 0;
-               } else
-                       break;
+               }
+               spin_unlock_irq(&hostdata->lock);
+               if (!done)
+                       cond_resched();
        } while (!done);
-       
-       spin_unlock_irq(instance->host_lock);
 }
 
 #ifndef DONT_USE_INTR
 
 /**
- *     NCR5380_intr    -       generic NCR5380 irq handler
- *     @irq: interrupt number
- *     @dev_id: device info
- *
- *     Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
- *      from the disconnected queue, and restarting NCR5380_main() 
- *      as required.
- *
- *     Locks: takes the needed instance locks
+ * NCR5380_intr - generic NCR5380 irq handler
+ * @irq: interrupt number
+ * @dev_id: device info
+ *
+ * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
+ * from the disconnected queue, and restarting NCR5380_main()
+ * as required.
+ *
+ * The chip can assert IRQ in any of six different conditions. The IRQ flag
+ * is then cleared by reading the Reset Parity/Interrupt Register (RPIR).
+ * Three of these six conditions are latched in the Bus and Status Register:
+ * - End of DMA (cleared by ending DMA Mode)
+ * - Parity error (cleared by reading RPIR)
+ * - Loss of BSY (cleared by reading RPIR)
+ * Two conditions have flag bits that are not latched:
+ * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode)
+ * - Bus reset (non-maskable)
+ * The remaining condition has no flag bit at all:
+ * - Selection/reselection
+ *
+ * Hence, establishing the cause(s) of any interrupt is partly guesswork.
+ * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor
+ * claimed that "the design of the [DP8490] interrupt logic ensures
+ * interrupts will not be lost (they can be on the DP5380)."
+ * The L5380/53C80 datasheet from LOGIC Devices has more details.
+ *
+ * Checking for bus reset by reading RST is futile because of interrupt
+ * latency, but a bus reset will reset chip logic. Checking for parity error
+ * is unnecessary because that interrupt is never enabled. A Loss of BSY
+ * condition will clear DMA Mode. We can tell when this occurs because the
+ * the Busy Monitor interrupt is enabled together with DMA Mode.
  */
 
-static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
+static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
-       NCR5380_local_declare();
        struct Scsi_Host *instance = dev_id;
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-       int done;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       int handled = 0;
        unsigned char basr;
        unsigned long flags;
 
-       dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n",
-               instance->irq);
+       spin_lock_irqsave(&hostdata->lock, flags);
+
+       basr = NCR5380_read(BUS_AND_STATUS_REG);
+       if (basr & BASR_IRQ) {
+               unsigned char mr = NCR5380_read(MODE_REG);
+               unsigned char sr = NCR5380_read(STATUS_REG);
+
+               dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+                        irq, basr, sr, mr);
 
-       do {
-               done = 1;
-               spin_lock_irqsave(instance->host_lock, flags);
-               /* Look for pending interrupts */
-               NCR5380_setup(instance);
-               basr = NCR5380_read(BUS_AND_STATUS_REG);
-               /* XXX dispatch to appropriate routine if found and done=0 */
-               if (basr & BASR_IRQ) {
-                       NCR5380_dprint(NDEBUG_INTR, instance);
-                       if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
-                               done = 0;
-                               dprintk(NDEBUG_INTR, "scsi%d : SEL interrupt\n", instance->host_no);
-                               NCR5380_reselect(instance);
-                               (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-                       } else if (basr & BASR_PARITY_ERROR) {
-                               dprintk(NDEBUG_INTR, "scsi%d : PARITY interrupt\n", instance->host_no);
-                               (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-                       } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-                               dprintk(NDEBUG_INTR, "scsi%d : RESET interrupt\n", instance->host_no);
-                               (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-                       } else {
 #if defined(REAL_DMA)
-                               /*
-                                * We should only get PHASE MISMATCH and EOP interrupts
-                                * if we have DMA enabled, so do a sanity check based on
-                                * the current setting of the MODE register.
-                                */
+               if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
+                       /* Probably End of DMA, Phase Mismatch or Loss of BSY.
+                        * We ack IRQ after clearing Mode Register. Workarounds
+                        * for End of DMA errata need to happen in DMA Mode.
+                        */
 
-                               if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) {
-                                       int transferred;
+                       dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
 
-                                       if (!hostdata->connected)
-                                               panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
+                       int transferred;
 
-                                       transferred = (hostdata->dmalen - NCR5380_dma_residual(instance));
-                                       hostdata->connected->SCp.this_residual -= transferred;
-                                       hostdata->connected->SCp.ptr += transferred;
-                                       hostdata->dmalen = 0;
+                       if (!hostdata->connected)
+                               panic("scsi%d : DMA interrupt with no connected cmd\n",
+                                     instance->hostno);
 
-                                       (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-                                                       
-                                       /* FIXME: we need to poll briefly then defer a workqueue task ! */
-                                       NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ);
+                       transferred = hostdata->dmalen - NCR5380_dma_residual(instance);
+                       hostdata->connected->SCp.this_residual -= transferred;
+                       hostdata->connected->SCp.ptr += transferred;
+                       hostdata->dmalen = 0;
 
-                                       NCR5380_write(MODE_REG, MR_BASE);
-                                       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                               }
-#else
-                               dprintk(NDEBUG_INTR, "scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-                               (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-#endif
+                       /* FIXME: we need to poll briefly then defer a workqueue task ! */
+                       NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2 * HZ);
+
+                       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+                       NCR5380_write(MODE_REG, MR_BASE);
+                       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+               } else
+#endif /* REAL_DMA */
+               if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
+                   (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
+                       /* Probably reselected */
+                       NCR5380_write(SELECT_ENABLE_REG, 0);
+                       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+                       dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
+
+                       if (!hostdata->connected) {
+                               NCR5380_reselect(instance);
+                               queue_work(hostdata->work_q, &hostdata->main_task);
                        }
-               }       /* if BASR_IRQ */
-               spin_unlock_irqrestore(instance->host_lock, flags);
-               if(!done)
-                       schedule_delayed_work(&hostdata->coroutine, 0);
-       } while (!done);
-       return IRQ_HANDLED;
+                       if (!hostdata->connected)
+                               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+               } else {
+                       /* Probably Bus Reset */
+                       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+                       dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
+               }
+               handled = 1;
+       } else {
+               shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
+       }
+
+       spin_unlock_irqrestore(&hostdata->lock, flags);
+
+       return IRQ_RETVAL(handled);
 }
 
-#endif 
+#endif
 
-/* 
+/*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
- *                               struct scsi_cmnd *cmd)
+ * struct scsi_cmnd *cmd)
  *
  * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
- *      including ARBITRATION, SELECTION, and initial message out for 
- *      IDENTIFY and queue messages. 
- *
- * Inputs : instance - instantiation of the 5380 driver on which this 
- *      target lives, cmd - SCSI command to execute.
- * 
- * Returns : -1 if selection could not execute for some reason,
- *      0 if selection succeeded or failed because the target 
- *      did not respond.
- *
- * Side effects : 
- *      If bus busy, arbitration failed, etc, NCR5380_select() will exit 
- *              with registers as they should have been on entry - ie
- *              SELECT_ENABLE will be set appropriately, the NCR5380
- *              will cease to drive any SCSI bus signals.
- *
- *      If successful : I_T_L or I_T_L_Q nexus will be established, 
- *              instance->connected will be set to cmd.  
- *              SELECT interrupt will be disabled.
- *
- *      If failed (no target) : cmd->scsi_done() will be called, and the 
- *              cmd->result host byte set to DID_BAD_TARGET.
- *
- *     Locks: caller holds hostdata lock in IRQ mode
+ * including ARBITRATION, SELECTION, and initial message out for
+ * IDENTIFY and queue messages.
+ *
+ * Inputs : instance - instantiation of the 5380 driver on which this
+ * target lives, cmd - SCSI command to execute.
+ *
+ * Returns cmd if selection failed but should be retried,
+ * NULL if selection failed and should not be retried, or
+ * NULL if selection succeeded (hostdata->connected == cmd).
+ *
+ * Side effects :
+ * If bus busy, arbitration failed, etc, NCR5380_select() will exit
+ * with registers as they should have been on entry - ie
+ * SELECT_ENABLE will be set appropriately, the NCR5380
+ * will cease to drive any SCSI bus signals.
+ *
+ * If successful : I_T_L or I_T_L_Q nexus will be established,
+ * instance->connected will be set to cmd.
+ * SELECT interrupt will be disabled.
+ *
+ * If failed (no target) : cmd->scsi_done() will be called, and the
+ * cmd->result host byte set to DID_BAD_TARGET.
  */
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
+                                        struct scsi_cmnd *cmd)
 {
-       NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char tmp[3], phase;
        unsigned char *data;
        int len;
-       unsigned long timeout;
-       unsigned char value;
        int err;
-       NCR5380_setup(instance);
-
-       if (hostdata->selecting)
-               goto part2;
-
-       hostdata->restart_select = 0;
 
        NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-       dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
+       dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+                instance->this_id);
+
+       /*
+        * Arbitration and selection phases are slow and involve dropping the
+        * lock, so we have to watch out for EH. An exception handler may
+        * change 'selecting' to NULL. This function will then return NULL
+        * so that the caller will forget about 'cmd'. (During information
+        * transfer phases, EH may change 'connected' to NULL.)
+        */
+       hostdata->selecting = cmd;
 
-       /* 
-        * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
+       /*
+        * Set the phase bits to 0, otherwise the NCR5380 won't drive the
         * data bus during SELECTION.
         */
 
        NCR5380_write(TARGET_COMMAND_REG, 0);
 
-       /* 
+       /*
         * Start arbitration.
         */
 
        NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
        NCR5380_write(MODE_REG, MR_ARBITRATE);
 
+       /* The chip now waits for BUS FREE phase. Then after the 800 ns
+        * Bus Free Delay, arbitration will begin.
+        */
 
-       /* We can be relaxed here, interrupts are on, we are
-          in workqueue context, the birds are singing in the trees */
-       spin_unlock_irq(instance->host_lock);
-       err = NCR5380_poll_politely(instance, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, ICR_ARBITRATION_PROGRESS, 5*HZ);
-       spin_lock_irq(instance->host_lock);
+       spin_unlock_irq(&hostdata->lock);
+       err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+                       INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+                                              ICR_ARBITRATION_PROGRESS, HZ);
+       spin_lock_irq(&hostdata->lock);
+       if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+               /* Reselection interrupt */
+               goto out;
+       }
        if (err < 0) {
-               printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
                NCR5380_write(MODE_REG, MR_BASE);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               goto failed;
+               shost_printk(KERN_ERR, instance,
+                            "select: arbitration timeout\n");
+               goto out;
        }
+       spin_unlock_irq(&hostdata->lock);
 
-       dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
-
-       /* 
-        * The arbitration delay is 2.2us, but this is a minimum and there is 
-        * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-        * the integral nature of udelay().
-        *
-        */
-
+       /* The SCSI-2 arbitration delay is 2.4 us */
        udelay(3);
 
        /* Check for lost arbitration */
-       if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
-               NCR5380_write(MODE_REG, MR_BASE);
-               dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
-               goto failed;
-       }
-       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
-
-       if (!(hostdata->flags & FLAG_DTC3181E) &&
-           /* RvC: DTC3181E has some trouble with this
-            *      so we simply removed it. Seems to work with
-            *      only Mustek scanner attached
-            */
+       if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
+           (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
            (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
                NCR5380_write(MODE_REG, MR_BASE);
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
-               goto failed;
+               dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
+               spin_lock_irq(&hostdata->lock);
+               goto out;
        }
-       /* 
-        * Again, bus clear + bus settle time is 1.2us, however, this is 
+
+       /* After/during arbitration, BSY should be asserted.
+        * IBM DPES-31080 Version S31Q works now
+        * Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman)
+        */
+       NCR5380_write(INITIATOR_COMMAND_REG,
+                     ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
+
+       /*
+        * Again, bus clear + bus settle time is 1.2us, however, this is
         * a minimum so we'll udelay ceil(1.2)
         */
 
-       udelay(2);
+       if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+               udelay(15);
+       else
+               udelay(2);
+
+       spin_lock_irq(&hostdata->lock);
+
+       /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+       if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
+               goto out;
 
-       dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
+       if (!hostdata->selecting) {
+               NCR5380_write(MODE_REG, MR_BASE);
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+               goto out;
+       }
 
-       /* 
-        * Now that we have won arbitration, start Selection process, asserting 
+       dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
+
+       /*
+        * Now that we have won arbitration, start Selection process, asserting
         * the host and target ID's on the SCSI bus.
         */
 
-       NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd))));
+       NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
-       /* 
+       /*
         * Raise ATN while SEL is true before BSY goes false from arbitration,
         * since this is the only way to guarantee that we'll get a MESSAGE OUT
         * phase immediately after selection.
         */
 
-       NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+                     ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
        NCR5380_write(MODE_REG, MR_BASE);
 
-       /* 
+       /*
         * Reselect interrupts must be turned off prior to the dropping of BSY,
         * otherwise we will trigger an interrupt.
         */
        NCR5380_write(SELECT_ENABLE_REG, 0);
 
+       spin_unlock_irq(&hostdata->lock);
+
        /*
-        * The initiator shall then wait at least two deskew delays and release 
+        * The initiator shall then wait at least two deskew delays and release
         * the BSY signal.
         */
-       udelay(1);              /* wingel -- wait two bus deskew delay >2*45ns */
+       udelay(1);        /* wingel -- wait two bus deskew delay >2*45ns */
 
        /* Reset BSY */
-       NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
+                     ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 
-       /* 
+       /*
         * Something weird happens when we cease to drive BSY - looks
-        * like the board/chip is letting us do another read before the 
+        * like the board/chip is letting us do another read before the
         * appropriate propagation delay has expired, and we're confusing
         * a BSY signal from ourselves as the target's response to SELECTION.
         *
         * A small delay (the 'C++' frontend breaks the pipeline with an
         * unnecessary jump, making it work on my 386-33/Trantor T128, the
-        * tighter 'C' code breaks and requires this) solves the problem - 
-        * the 1 us delay is arbitrary, and only used because this delay will 
-        * be the same on other platforms and since it works here, it should 
+        * tighter 'C' code breaks and requires this) solves the problem -
+        * the 1 us delay is arbitrary, and only used because this delay will
+        * be the same on other platforms and since it works here, it should
         * work there.
         *
         * wingel suggests that this could be due to failing to wait
@@ -1339,50 +1162,43 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
        udelay(1);
 
-       dprintk(NDEBUG_SELECTION, "scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd));
+       dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
-       /* 
-        * The SCSI specification calls for a 250 ms timeout for the actual 
+       /*
+        * The SCSI specification calls for a 250 ms timeout for the actual
         * selection.
         */
 
-       timeout = jiffies + msecs_to_jiffies(250);
+       err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+                                   msecs_to_jiffies(250));
 
-       /* 
-        * XXX very interesting - we're seeing a bounce where the BSY we 
-        * asserted is being reflected / still asserted (propagation delay?)
-        * and it's detecting as true.  Sigh.
-        */
-
-       hostdata->select_time = 0;      /* we count the clock ticks at which we polled */
-       hostdata->selecting = cmd;
-
-part2:
-       /* RvC: here we enter after a sleeping period, or immediately after
-          execution of part 1
-          we poll only once ech clock tick */
-       value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO);
-
-       if (!value && (hostdata->select_time < HZ/4)) {
-               /* RvC: we still must wait for a device response */
-               hostdata->select_time++;        /* after 25 ticks the device has failed */
-               NCR5380_set_timer(hostdata, 1);
-               return 0;       /* RvC: we return here with hostdata->selecting set,
-                                  to go to sleep */
-       }
-
-       hostdata->selecting = NULL;/* clear this pointer, because we passed the
-                                          waiting period */
        if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
+               spin_lock_irq(&hostdata->lock);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_reselect(instance);
-               printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
+               if (!hostdata->connected)
+                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+               shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
+               goto out;
+       }
+
+       if (err < 0) {
+               spin_lock_irq(&hostdata->lock);
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               return -1;
+               /* Can't touch cmd if it has been reclaimed by the scsi ML */
+               if (hostdata->selecting) {
+                       cmd->result = DID_BAD_TARGET << 16;
+                       complete_cmd(instance, cmd);
+                       dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n");
+                       cmd = NULL;
+               }
+               goto out;
        }
-       /* 
-        * No less than two deskew delays after the initiator detects the 
-        * BSY signal is true, it shall release the SEL signal and may 
+
+       /*
+        * No less than two deskew delays after the initiator detects the
+        * BSY signal is true, it shall release the SEL signal and may
         * change the DATA BUS.                                     -wingel
         */
 
@@ -1390,53 +1206,38 @@ part2:
 
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
-       if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               if (hostdata->targets_present & (1 << scmd_id(cmd))) {
-                       printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
-                       if (hostdata->restart_select)
-                               printk(KERN_DEBUG "\trestart select\n");
-                       NCR5380_dprint(NDEBUG_SELECTION, instance);
-                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                       return -1;
-               }
-               cmd->result = DID_BAD_TARGET << 16;
-               cmd->scsi_done(cmd);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               return 0;
-       }
-       hostdata->targets_present |= (1 << scmd_id(cmd));
-
        /*
-        * Since we followed the SCSI spec, and raised ATN while SEL 
+        * Since we followed the SCSI spec, and raised ATN while SEL
         * was true but before BSY was false during selection, the information
         * transfer phase should be a MESSAGE OUT phase so that we can send the
         * IDENTIFY message.
-        * 
+        *
         * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
         * message (2 bytes) with a tag ID that we increment with every command
         * until it wraps back to 0.
         *
         * XXX - it turns out that there are some broken SCSI-II devices,
-        *       which claim to support tagged queuing but fail when more than
-        *       some number of commands are issued at once.
+        * which claim to support tagged queuing but fail when more than
+        * some number of commands are issued at once.
         */
 
        /* Wait for start of REQ/ACK handshake */
 
-       spin_unlock_irq(instance->host_lock);
        err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-       spin_lock_irq(instance->host_lock);
-       
-       if(err) {
-               printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
+       spin_lock_irq(&hostdata->lock);
+       if (err < 0) {
+               shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               goto failed;
+               goto out;
+       }
+       if (!hostdata->selecting) {
+               do_abort(instance);
+               goto out;
        }
 
-       dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
+       dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
+                scmd_id(cmd));
        tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
 
        len = 1;
@@ -1446,104 +1247,82 @@ part2:
        data = tmp;
        phase = PHASE_MSGOUT;
        NCR5380_transfer_pio(instance, &phase, &len, &data);
-       dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
+       dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
        /* XXX need to handle errors here */
+
        hostdata->connected = cmd;
-       hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
+       hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 
        initialize_SCp(cmd);
 
-       return 0;
-
-       /* Selection failed */
-failed:
-       return -1;
+       cmd = NULL;
 
+out:
+       if (!hostdata->selecting)
+               return NULL;
+       hostdata->selecting = NULL;
+       return cmd;
 }
 
-/* 
- * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, 
- *      unsigned char *phase, int *count, unsigned char **data)
+/*
+ * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
+ * unsigned char *phase, int *count, unsigned char **data)
  *
  * Purpose : transfers data in given phase using polled I/O
  *
- * Inputs : instance - instance of driver, *phase - pointer to 
- *      what phase is expected, *count - pointer to number of 
- *      bytes to transfer, **data - pointer to data pointer.
- * 
+ * Inputs : instance - instance of driver, *phase - pointer to
+ * what phase is expected, *count - pointer to number of
+ * bytes to transfer, **data - pointer to data pointer.
+ *
  * Returns : -1 when different phase is entered without transferring
- *      maximum number of bytes, 0 if all bytes or transferred or exit
- *      is in same phase.
+ * maximum number of bytes, 0 if all bytes are transferred or exit
+ * is in same phase.
  *
- *      Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  *
  * XXX Note : handling for bus free may be useful.
  */
 
 /*
- * Note : this code is not as quick as it could be, however it 
+ * Note : this code is not as quick as it could be, however it
  * IS 100% reliable, and for the actual data transfer where speed
  * counts, we will always do a pseudo DMA or DMA transfer.
  */
 
-static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
-       NCR5380_local_declare();
+static int NCR5380_transfer_pio(struct Scsi_Host *instance,
+                               unsigned char *phase, int *count,
+                               unsigned char **data)
+{
        unsigned char p = *phase, tmp;
        int c = *count;
        unsigned char *d = *data;
-       /*
-        *      RvC: some administrative data to process polling time
-        */
-       int break_allowed = 0;
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-       NCR5380_setup(instance);
-
-       if (!(p & SR_IO))
-               dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
-       else
-               dprintk(NDEBUG_PIO, "scsi%d : pio read %d bytes\n", instance->host_no, c);
 
-       /* 
-        * The NCR5380 chip will only drive the SCSI bus when the 
+       /*
+        * The NCR5380 chip will only drive the SCSI bus when the
         * phase specified in the appropriate bits of the TARGET COMMAND
         * REGISTER match the STATUS REGISTER
         */
 
-        NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-       /* RvC: don't know if this is necessary, but other SCSI I/O is short
-        *      so breaks are not necessary there
-        */
-       if ((p == PHASE_DATAIN) || (p == PHASE_DATAOUT)) {
-               break_allowed = 1;
-       }
-       do {
-               /* 
-                * Wait for assertion of REQ, after which the phase bits will be 
-                * valid 
-                */
+       NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
-               /* RvC: we simply poll once, after that we stop temporarily
-                *      and let the device buffer fill up
-                *      if breaking is not allowed, we keep polling as long as needed
+       do {
+               /*
+                * Wait for assertion of REQ, after which the phase bits will be
+                * valid
                 */
 
-               /* FIXME */
-               while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) && !break_allowed);
-               if (!(tmp & SR_REQ)) {
-                       /* timeout condition */
-                       NCR5380_set_timer(hostdata, USLEEP_SLEEP);
+               if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
                        break;
-               }
 
-               dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
+               dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
 
                /* Check for phase mismatch */
-               if ((tmp & PHASE_MASK) != p) {
-                       dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
-                       NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
+               if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
+                       dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
+                       NCR5380_dprint_phase(NDEBUG_PIO, instance);
                        break;
                }
+
                /* Do actual transfer from SCSI bus to / from memory */
                if (!(p & SR_IO))
                        NCR5380_write(OUTPUT_DATA_REG, *d);
@@ -1552,7 +1331,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
 
                ++d;
 
-               /* 
+               /*
                 * The SCSI standard suggests that in MSGOUT phase, the initiator
                 * should drop ATN on the last byte of the message phase
                 * after REQ has been asserted for the handshake but before
@@ -1563,29 +1342,34 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
                        if (!((p & SR_MSG) && c > 1)) {
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
                                NCR5380_dprint(NDEBUG_PIO, instance);
-                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ACK);
+                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+                                             ICR_ASSERT_DATA | ICR_ASSERT_ACK);
                        } else {
-                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+                                             ICR_ASSERT_DATA | ICR_ASSERT_ATN);
                                NCR5380_dprint(NDEBUG_PIO, instance);
-                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+                                             ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
                        }
                } else {
                        NCR5380_dprint(NDEBUG_PIO, instance);
                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
                }
 
-               /* FIXME - if this fails bus reset ?? */
-               NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
-               dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
+               if (NCR5380_poll_politely(instance,
+                                         STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+                       break;
+
+               dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
 
 /*
- * We have several special cases to consider during REQ/ACK handshaking : 
- * 1.  We were in MSGOUT phase, and we are on the last byte of the 
- *      message.  ATN must be dropped as ACK is dropped.
+ * We have several special cases to consider during REQ/ACK handshaking :
+ * 1.  We were in MSGOUT phase, and we are on the last byte of the
+ * message.  ATN must be dropped as ACK is dropped.
  *
- * 2.  We are in a MSGIN phase, and we are on the last byte of the  
- *      message.  We must exit with ACK asserted, so that the calling
- *      code may raise ATN before dropping ACK to reject the message.
+ * 2.  We are in a MSGIN phase, and we are on the last byte of the
+ * message.  We must exit with ACK asserted, so that the calling
+ * code may raise ATN before dropping ACK to reject the message.
  *
  * 3.  ACK and ATN are clear and the target may proceed as normal.
  */
@@ -1597,12 +1381,16 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
                }
        } while (--c);
 
-       dprintk(NDEBUG_PIO, "scsi%d : residual %d\n", instance->host_no, c);
+       dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
 
        *count = c;
        *data = d;
        tmp = NCR5380_read(STATUS_REG);
-       if (tmp & SR_REQ)
+       /* The phase read from the bus is valid if either REQ is (already)
+        * asserted or if ACK hasn't been released yet. The latter applies if
+        * we're in MSG IN, DATA IN or STATUS and all bytes have been received.
+        */
+       if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
                *phase = tmp & PHASE_MASK;
        else
                *phase = PHASE_UNKNOWN;
@@ -1614,79 +1402,80 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
 }
 
 /**
- *     do_reset        -       issue a reset command
- *     @host: adapter to reset
+ * do_reset - issue a reset command
+ * @instance: adapter to reset
  *
- *     Issue a reset sequence to the NCR5380 and try and get the bus
- *     back into sane shape.
+ * Issue a reset sequence to the NCR5380 and try and get the bus
+ * back into sane shape.
  *
- *     Locks: caller holds queue lock
+ * This clears the reset interrupt flag because there may be no handler for
+ * it. When the driver is initialized, the NCR5380_intr() handler has not yet
+ * been installed. And when in EH we may have released the ST DMA interrupt.
  */
-static void do_reset(struct Scsi_Host *host) {
-       NCR5380_local_declare();
-       NCR5380_setup(host);
 
-       NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
+static void do_reset(struct Scsi_Host *instance)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       NCR5380_write(TARGET_COMMAND_REG,
+                     PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-       udelay(25);
+       udelay(50);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+       local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
- * 
- * Purpose : abort the currently established nexus.  Should only be 
- *      called from a routine which can drop into a 
- * 
- * Returns : 0 on success, -1 on failure.
- *
- * Locks: queue lock held by caller
- *     FIXME: sort this out and get new_eh running
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
+ *
+ * Returns 0 on success, -1 on failure.
  */
 
-static int do_abort(struct Scsi_Host *host) {
-       NCR5380_local_declare();
+static int do_abort(struct Scsi_Host *instance)
+{
        unsigned char *msgptr, phase, tmp;
        int len;
        int rc;
-       NCR5380_setup(host);
-
 
        /* Request message out phase */
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
-       /* 
-        * Wait for the target to indicate a valid phase by asserting 
-        * REQ.  Once this happens, we'll have either a MSGOUT phase 
-        * and can immediately send the ABORT message, or we'll have some 
+       /*
+        * Wait for the target to indicate a valid phase by asserting
+        * REQ.  Once this happens, we'll have either a MSGOUT phase
+        * and can immediately send the ABORT message, or we'll have some
         * other phase and will have to source/sink data.
-        * 
+        *
         * We really don't care what value was on the bus or what value
         * the target sees, so we just handshake.
         */
 
-       rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
-       
-       if(rc < 0)
-               return -1;
+       rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
+       if (rc < 0)
+               goto timeout;
+
+       tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
-       tmp = (unsigned char)rc;
-       
        NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-       if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-               rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, 0, 3*HZ);
+       if (tmp != PHASE_MSGOUT) {
+               NCR5380_write(INITIATOR_COMMAND_REG,
+                             ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+               rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
+               if (rc < 0)
+                       goto timeout;
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-               if(rc == -1)
-                       return -1;
        }
+
        tmp = ABORT;
        msgptr = &tmp;
        len = 1;
        phase = PHASE_MSGOUT;
-       NCR5380_transfer_pio(host, &phase, &len, &msgptr);
+       NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
 
        /*
         * If we got here, and the command completed successfully,
@@ -1694,32 +1483,37 @@ static int do_abort(struct Scsi_Host *host) {
         */
 
        return len ? -1 : 0;
+
+timeout:
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+       return -1;
 }
 
 #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
-/* 
- * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, 
- *      unsigned char *phase, int *count, unsigned char **data)
+/*
+ * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
+ * unsigned char *phase, int *count, unsigned char **data)
  *
  * Purpose : transfers data in given phase using either real
- *      or pseudo DMA.
+ * or pseudo DMA.
  *
- * Inputs : instance - instance of driver, *phase - pointer to 
- *      what phase is expected, *count - pointer to number of 
- *      bytes to transfer, **data - pointer to data pointer.
- * 
- * Returns : -1 when different phase is entered without transferring
- *      maximum number of bytes, 0 if all bytes or transferred or exit
- *      is in same phase.
+ * Inputs : instance - instance of driver, *phase - pointer to
+ * what phase is expected, *count - pointer to number of
+ * bytes to transfer, **data - pointer to data pointer.
  *
- *      Also, *phase, *count, *data are modified in place.
+ * Returns : -1 when different phase is entered without transferring
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *     Locks: io_request lock held by caller
+ * Also, *phase, *count, *data are modified in place.
  */
 
 
-static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
-       NCR5380_local_declare();
+static int NCR5380_transfer_dma(struct Scsi_Host *instance,
+                               unsigned char *phase, int *count,
+                               unsigned char **data)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        register int c = *count;
        register unsigned char p = *phase;
        register unsigned char *d = *data;
@@ -1730,54 +1524,47 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
        unsigned char saved_data = 0, overrun = 0, residue;
 #endif
 
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-
-       NCR5380_setup(instance);
-
        if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
                *phase = tmp;
                return -1;
        }
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-#ifdef READ_OVERRUNS
        if (p & SR_IO) {
-               c -= 2;
+               if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
+                       c -= 2;
        }
-#endif
-       dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
        hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
+
+       dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+                (p & SR_IO) ? "receive" : "send", c, *data);
 #endif
 
        NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 #ifdef REAL_DMA
-       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
+                               MR_ENABLE_EOP_INTR);
 #elif defined(REAL_DMA_POLL)
-       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
+       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
 #else
        /*
         * Note : on my sample board, watch-dog timeouts occurred when interrupts
-        * were not disabled for the duration of a single DMA transfer, from 
+        * were not disabled for the duration of a single DMA transfer, from
         * before the setting of DMA mode to after transfer of the last byte.
         */
 
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-       spin_unlock_irq(instance->host_lock);
-#endif
-       /* KLL May need eop and parity in 53c400 */
-       if (hostdata->flags & FLAG_NCR53C400)
-               NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
-                               MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR |
-                               MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+       if (hostdata->flags & FLAG_NO_DMA_FIXUP)
+               NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
+                                       MR_ENABLE_EOP_INTR);
        else
-               NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
+               NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
 #endif                         /* def REAL_DMA */
 
        dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
-       /* 
-        *      On the PAS16 at least I/O recovery delays are not needed here.
-        *      Everyone else seems to want them.
+       /*
+        * On the PAS16 at least I/O recovery delays are not needed here.
+        * Everyone else seems to want them.
         */
 
        if (p & SR_IO) {
@@ -1797,49 +1584,49 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
        } while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | BASR_END_DMA_TRANSFER)));
 
 /*
-   At this point, either we've completed DMA, or we have a phase mismatch,
-   or we've unexpectedly lost BUSY (which is a real error).
-
-   For write DMAs, we want to wait until the last byte has been
-   transferred out over the bus before we turn off DMA mode.  Alas, there
-   seems to be no terribly good way of doing this on a 5380 under all
-   conditions.  For non-scatter-gather operations, we can wait until REQ
-   and ACK both go false, or until a phase mismatch occurs.  Gather-writes
-   are nastier, since the device will be expecting more data than we
-   are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
-   could test LAST BIT SENT to assure transfer (I imagine this is precisely
-   why this signal was added to the newer chips) but on the older 538[01]
-   this signal does not exist.  The workaround for this lack is a watchdog;
-   we bail out of the wait-loop after a modest amount of wait-time if
-   the usual exit conditions are not met.  Not a terribly clean or
-   correct solution :-%
-
-   Reads are equally tricky due to a nasty characteristic of the NCR5380.
-   If the chip is in DMA mode for an READ, it will respond to a target's
-   REQ by latching the SCSI data into the INPUT DATA register and asserting
-   ACK, even if it has _already_ been notified by the DMA controller that
-   the current DMA transfer has completed!  If the NCR5380 is then taken
-   out of DMA mode, this already-acknowledged byte is lost.
-
-   This is not a problem for "one DMA transfer per command" reads, because
-   the situation will never arise... either all of the data is DMA'ed
-   properly, or the target switches to MESSAGE IN phase to signal a
-   disconnection (either operation bringing the DMA to a clean halt).
-   However, in order to handle scatter-reads, we must work around the
-   problem.  The chosen fix is to DMA N-2 bytes, then check for the
-   condition before taking the NCR5380 out of DMA mode.  One or two extra
-   bytes are transferred via PIO as necessary to fill out the original
-   request.
+ * At this point, either we've completed DMA, or we have a phase mismatch,
+ * or we've unexpectedly lost BUSY (which is a real error).
+ *
+ * For DMA sends, we want to wait until the last byte has been
+ * transferred out over the bus before we turn off DMA mode.  Alas, there
+ * seems to be no terribly good way of doing this on a 5380 under all
+ * conditions.  For non-scatter-gather operations, we can wait until REQ
+ * and ACK both go false, or until a phase mismatch occurs.  Gather-sends
+ * are nastier, since the device will be expecting more data than we
+ * are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
+ * could test Last Byte Sent to assure transfer (I imagine this is precisely
+ * why this signal was added to the newer chips) but on the older 538[01]
+ * this signal does not exist.  The workaround for this lack is a watchdog;
+ * we bail out of the wait-loop after a modest amount of wait-time if
+ * the usual exit conditions are not met.  Not a terribly clean or
+ * correct solution :-%
+ *
+ * DMA receive is equally tricky due to a nasty characteristic of the NCR5380.
+ * If the chip is in DMA receive mode, it will respond to a target's
+ * REQ by latching the SCSI data into the INPUT DATA register and asserting
+ * ACK, even if it has _already_ been notified by the DMA controller that
+ * the current DMA transfer has completed!  If the NCR5380 is then taken
+ * out of DMA mode, this already-acknowledged byte is lost. This is
+ * not a problem for "one DMA transfer per READ command", because
+ * the situation will never arise... either all of the data is DMA'ed
+ * properly, or the target switches to MESSAGE IN phase to signal a
+ * disconnection (either operation bringing the DMA to a clean halt).
+ * However, in order to handle scatter-receive, we must work around the
+ * problem.  The chosen fix is to DMA N-2 bytes, then check for the
+ * condition before taking the NCR5380 out of DMA mode.  One or two extra
+ * bytes are transferred via PIO as necessary to fill out the original
+ * request.
  */
 
        if (p & SR_IO) {
-#ifdef READ_OVERRUNS
-               udelay(10);
-               if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) == (BASR_PHASE_MATCH | BASR_ACK))) {
-                       saved_data = NCR5380_read(INPUT_DATA_REGISTER);
-                       overrun = 1;
+               if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS)) {
+                       udelay(10);
+                       if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
+                           (BASR_PHASE_MATCH | BASR_ACK)) {
+                               saved_data = NCR5380_read(INPUT_DATA_REGISTER);
+                               overrun = 1;
+                       }
                }
-#endif
        } else {
                int limit = 100;
                while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) {
@@ -1850,7 +1637,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
                }
        }
 
-       dprintk(NDEBUG_DMA, "scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG));
+       dsprintk(NDEBUG_DMA, "polled DMA transfer complete, basr 0x%02x, sr 0x%02x\n",
+                tmp, NCR5380_read(STATUS_REG));
 
        NCR5380_write(MODE_REG, MR_BASE);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1861,8 +1649,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
        *data += c;
        *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
-#ifdef READ_OVERRUNS
-       if (*phase == p && (p & SR_IO) && residue == 0) {
+       if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS) &&
+           *phase == p && (p & SR_IO) && residue == 0) {
                if (overrun) {
                        dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
                        **data = saved_data;
@@ -1877,7 +1665,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
                NCR5380_transfer_pio(instance, phase, &cnt, data);
                *count -= toPIO - cnt;
        }
-#endif
 
        dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count));
        return 0;
@@ -1886,95 +1673,64 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
        return 0;
 #else                          /* defined(REAL_DMA_POLL) */
        if (p & SR_IO) {
-#ifdef DMA_WORKS_RIGHT
-               foo = NCR5380_pread(instance, d, c);
-#else
-               int diff = 1;
-               if (hostdata->flags & FLAG_NCR53C400) {
-                       diff = 0;
-               }
-               if (!(foo = NCR5380_pread(instance, d, c - diff))) {
+               foo = NCR5380_pread(instance, d,
+                       hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1);
+               if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
                        /*
-                        * We can't disable DMA mode after successfully transferring 
+                        * We can't disable DMA mode after successfully transferring
                         * what we plan to be the last byte, since that would open up
-                        * a race condition where if the target asserted REQ before 
+                        * a race condition where if the target asserted REQ before
                         * we got the DMA mode reset, the NCR5380 would have latched
                         * an additional byte into the INPUT DATA register and we'd
                         * have dropped it.
-                        * 
-                        * The workaround was to transfer one fewer bytes than we 
-                        * intended to with the pseudo-DMA read function, wait for 
+                        *
+                        * The workaround was to transfer one fewer bytes than we
+                        * intended to with the pseudo-DMA read function, wait for
                         * the chip to latch the last byte, read it, and then disable
                         * pseudo-DMA mode.
-                        * 
+                        *
                         * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
                         * REQ is deasserted when ACK is asserted, and not reasserted
                         * until ACK goes false.  Since the NCR5380 won't lower ACK
                         * until DACK is asserted, which won't happen unless we twiddle
-                        * the DMA port or we take the NCR5380 out of DMA mode, we 
-                        * can guarantee that we won't handshake another extra 
+                        * the DMA port or we take the NCR5380 out of DMA mode, we
+                        * can guarantee that we won't handshake another extra
                         * byte.
                         */
 
-                       if (!(hostdata->flags & FLAG_NCR53C400)) {
-                               while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
-                               /* Wait for clean handshake */
-                               while (NCR5380_read(STATUS_REG) & SR_REQ);
-                               d[c - 1] = NCR5380_read(INPUT_DATA_REG);
+                       if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+                                                 BASR_DRQ, BASR_DRQ, HZ) < 0) {
+                               foo = -1;
+                               shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n");
                        }
+                       if (NCR5380_poll_politely(instance, STATUS_REG,
+                                                 SR_REQ, 0, HZ) < 0) {
+                               foo = -1;
+                               shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
+                       }
+                       d[c - 1] = NCR5380_read(INPUT_DATA_REG);
                }
-#endif
        } else {
-#ifdef DMA_WORKS_RIGHT
                foo = NCR5380_pwrite(instance, d, c);
-#else
-               int timeout;
-               dprintk(NDEBUG_C400_PWRITE, "About to pwrite %d bytes\n", c);
-               if (!(foo = NCR5380_pwrite(instance, d, c))) {
+               if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
                        /*
-                        * Wait for the last byte to be sent.  If REQ is being asserted for 
-                        * the byte we're interested, we'll ACK it and it will go false.  
+                        * Wait for the last byte to be sent.  If REQ is being asserted for
+                        * the byte we're interested, we'll ACK it and it will go false.
                         */
-                       if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
-                               timeout = 20000;
-                               while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH));
-
-                               if (!timeout)
-                                       dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : timed out on last byte\n", instance->host_no);
-
-                               if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
-                                       hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
-                                       if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
-                                               hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
-                                               dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : last byte sent works\n", instance->host_no);
-                                       }
-                               }
-                       } else {
-                               dprintk(NDEBUG_C400_PWRITE, "Waiting for LASTBYTE\n");
-                               while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
-                               dprintk(NDEBUG_C400_PWRITE, "Got LASTBYTE\n");
+                       if (NCR5380_poll_politely2(instance,
+                            BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
+                            BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) {
+                               foo = -1;
+                               shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
                        }
                }
-#endif
        }
        NCR5380_write(MODE_REG, MR_BASE);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-       if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
-               dprintk(NDEBUG_C400_PWRITE, "53C400w: Checking for IRQ\n");
-               if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
-                       dprintk(NDEBUG_C400_PWRITE, "53C400w:    got it, reading reset interrupt reg\n");
-                       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-               } else {
-                       printk("53C400w:    IRQ NOT THERE!\n");
-               }
-       }
+       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        *data = d + c;
        *count = 0;
        *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-       spin_lock_irq(instance->host_lock);
-#endif                         /* defined(REAL_DMA_POLL) */
        return foo;
 #endif                         /* def REAL_DMA */
 }
@@ -1983,25 +1739,23 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
  *
- * Purpose : run through the various SCSI phases and do as the target 
- *      directs us to.  Operates on the currently connected command, 
- *      instance->connected.
+ * Purpose : run through the various SCSI phases and do as the target
+ * directs us to.  Operates on the currently connected command,
+ * instance->connected.
  *
  * Inputs : instance, instance for which we are doing commands
  *
- * Side effects : SCSI things happen, the disconnected queue will be 
- *      modified if a command disconnects, *instance->connected will
- *      change.
+ * Side effects : SCSI things happen, the disconnected queue will be
+ * modified if a command disconnects, *instance->connected will
+ * change.
  *
- * XXX Note : we need to watch for bus free or a reset condition here 
- *      to recover from an unexpected bus free condition.
- *
- * Locks: io_request_lock held by caller in IRQ mode
+ * XXX Note : we need to watch for bus free or a reset condition here
+ * to recover from an unexpected bus free condition.
  */
 
-static void NCR5380_information_transfer(struct Scsi_Host *instance) {
-       NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata;
+static void NCR5380_information_transfer(struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char msgout = NOP;
        int sink = 0;
        int len;
@@ -2010,13 +1764,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 #endif
        unsigned char *data;
        unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-       struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
-       /* RvC: we need to set the end of the polling time */
-       unsigned long poll_time = jiffies + USLEEP_POLL;
+       struct scsi_cmnd *cmd;
 
-       NCR5380_setup(instance);
+       while ((cmd = hostdata->connected)) {
+               struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
-       while (1) {
                tmp = NCR5380_read(STATUS_REG);
                /* We only have a valid SCSI phase when REQ is asserted */
                if (tmp & SR_REQ) {
@@ -2028,24 +1780,28 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                        if (sink && (phase != PHASE_MSGOUT)) {
                                NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-                               while (NCR5380_read(STATUS_REG) & SR_REQ);
-                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
+                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
+                                             ICR_ASSERT_ACK);
+                               while (NCR5380_read(STATUS_REG) & SR_REQ)
+                                       ;
+                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+                                             ICR_ASSERT_ATN);
                                sink = 0;
                                continue;
                        }
+
                        switch (phase) {
-                       case PHASE_DATAIN:
                        case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-                               printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);
+                               shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
                                sink = 1;
                                do_abort(instance);
                                cmd->result = DID_ERROR << 16;
-                               cmd->scsi_done(cmd);
+                               complete_cmd(instance, cmd);
                                return;
 #endif
-                               /* 
+                       case PHASE_DATAIN:
+                               /*
                                 * If there is no room left in the current buffer in the
                                 * scatter-gather list, move onto the next one.
                                 */
@@ -2055,10 +1811,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                        --cmd->SCp.buffers_residual;
                                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
                                        cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-                                       dprintk(NDEBUG_INFORMATION, "scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual);
+                                       dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
+                                                cmd->SCp.this_residual,
+                                                cmd->SCp.buffers_residual);
                                }
+
                                /*
-                                * The preferred transfer method is going to be 
+                                * The preferred transfer method is going to be
                                 * PSEUDO-DMA for systems that are strictly PIO,
                                 * since we can let the hardware do the handshaking.
                                 *
@@ -2068,50 +1827,39 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                 */
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
-                               /* KLL
-                                * PSEUDO_DMA is defined here. If this is the g_NCR5380
-                                * driver then it will always be defined, so the
-                                * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base
-                                * NCR5380 case.  I think this is a fairly clean solution.
-                                * We supplement these 2 if's with the flag.
-                                */
-#ifdef NCR5380_dma_xfer_len
-                               if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
-#else
-                               transfersize = cmd->transfersize;
-
-#ifdef LIMIT_TRANSFERSIZE      /* If we have problems with interrupt service */
-                               if (transfersize > 512)
-                                       transfersize = 512;
-#endif                         /* LIMIT_TRANSFERSIZE */
-
-                               if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) {
-                                       /* Limit transfers to 32K, for xx400 & xx406
-                                        * pseudoDMA that transfers in 128 bytes blocks. */
-                                       if (transfersize > 32 * 1024)
-                                               transfersize = 32 * 1024;
-#endif
+                               transfersize = 0;
+                               if (!cmd->device->borken &&
+                                   !(hostdata->flags & FLAG_NO_PSEUDO_DMA))
+                                       transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
+
+                               if (transfersize) {
                                        len = transfersize;
-                                       if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
+                                       if (NCR5380_transfer_dma(instance, &phase,
+                                           &len, (unsigned char **)&cmd->SCp.ptr)) {
                                                /*
-                                                * If the watchdog timer fires, all future accesses to this
-                                                * device will use the polled-IO.
+                                                * If the watchdog timer fires, all future
+                                                * accesses to this device will use the
+                                                * polled-IO.
                                                 */
                                                scmd_printk(KERN_INFO, cmd,
-                                                           "switching to slow handshake\n");
+                                                       "switching to slow handshake\n");
                                                cmd->device->borken = 1;
-                                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
                                                sink = 1;
                                                do_abort(instance);
                                                cmd->result = DID_ERROR << 16;
-                                               cmd->scsi_done(cmd);
+                                               complete_cmd(instance, cmd);
                                                /* XXX - need to source or sink data here, as appropriate */
                                        } else
                                                cmd->SCp.this_residual -= transfersize - len;
                                } else
 #endif                         /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
-                                       NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
-                                                            &cmd->SCp.ptr);
+                               {
+                                       spin_unlock_irq(&hostdata->lock);
+                                       NCR5380_transfer_pio(instance, &phase,
+                                                            (int *)&cmd->SCp.this_residual,
+                                                            (unsigned char **)&cmd->SCp.ptr);
+                                       spin_lock_irq(&hostdata->lock);
+                               }
                                break;
                        case PHASE_MSGIN:
                                len = 1;
@@ -2120,101 +1868,42 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                cmd->SCp.Message = tmp;
 
                                switch (tmp) {
-                                       /*
-                                        * Linking lets us reduce the time required to get the 
-                                        * next command out to the device, hopefully this will
-                                        * mean we don't waste another revolution due to the delays
-                                        * required by ARBITRATION and another SELECTION.
-                                        *
-                                        * In the current implementation proposal, low level drivers
-                                        * merely have to start the next command, pointed to by 
-                                        * next_link, done() is called as with unlinked commands.
-                                        */
-#ifdef LINKED
-                               case LINKED_CMD_COMPLETE:
-                               case LINKED_FLG_CMD_COMPLETE:
-                                       /* Accept message by clearing ACK */
-                                       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun);
-                                       /* 
-                                        * Sanity check : A linked command should only terminate with
-                                        * one of these messages if there are more linked commands
-                                        * available.
-                                        */
-                                       if (!cmd->next_link) {
-                                           printk("scsi%d : target %d lun %llu linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);
-                                               sink = 1;
-                                               do_abort(instance);
-                                               return;
-                                       }
-                                       initialize_SCp(cmd->next_link);
-                                       /* The next command is still part of this process */
-                                       cmd->next_link->tag = cmd->tag;
-                                       cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-                                       dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
-                                       cmd->scsi_done(cmd);
-                                       cmd = hostdata->connected;
-                                       break;
-#endif                         /* def LINKED */
                                case ABORT:
                                case COMMAND_COMPLETE:
                                        /* Accept message by clearing ACK */
                                        sink = 1;
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       hostdata->connected = NULL;
-                                       dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %llu completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
-                                       hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
-
-                                       /* 
-                                        * I'm not sure what the correct thing to do here is : 
-                                        * 
-                                        * If the command that just executed is NOT a request 
-                                        * sense, the obvious thing to do is to set the result
-                                        * code to the values of the stored parameters.
-                                        * 
-                                        * If it was a REQUEST SENSE command, we need some way 
-                                        * to differentiate between the failure code of the original
-                                        * and the failure code of the REQUEST sense - the obvious
-                                        * case is success, where we fall through and leave the result
-                                        * code unchanged.
-                                        * 
-                                        * The non-obvious place is where the REQUEST SENSE failed 
-                                        */
-
-                                       if (cmd->cmnd[0] != REQUEST_SENSE)
-                                               cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-                                       else if (status_byte(cmd->SCp.Status) != GOOD)
-                                               cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-                                       if ((cmd->cmnd[0] == REQUEST_SENSE) &&
-                                               hostdata->ses.cmd_len) {
-                                               scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-                                               hostdata->ses.cmd_len = 0 ;
-                                       }
+                                       dsprintk(NDEBUG_QUEUES, instance,
+                                                "COMMAND COMPLETE %p target %d lun %llu\n",
+                                                cmd, scmd_id(cmd), cmd->device->lun);
 
-                                       if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
-                                               scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
-
-                                               dprintk(NDEBUG_AUTOSENSE, "scsi%d : performing request sense\n", instance->host_no);
+                                       hostdata->connected = NULL;
 
-                                               LIST(cmd, hostdata->issue_queue);
-                                               cmd->host_scribble = (unsigned char *)
-                                                   hostdata->issue_queue;
-                                               hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-                                               dprintk(NDEBUG_QUEUES, "scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no);
-                                       } else {
-                                               cmd->scsi_done(cmd);
+                                       cmd->result &= ~0xffff;
+                                       cmd->result |= cmd->SCp.Status;
+                                       cmd->result |= cmd->SCp.Message << 8;
+
+                                       if (cmd->cmnd[0] == REQUEST_SENSE)
+                                               complete_cmd(instance, cmd);
+                                       else {
+                                               if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION ||
+                                                   cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) {
+                                                       dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n",
+                                                                cmd);
+                                                       list_add_tail(&ncmd->list,
+                                                                     &hostdata->autosense);
+                                               } else
+                                                       complete_cmd(instance, cmd);
                                        }
 
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                                       /* 
-                                        * Restore phase bits to 0 so an interrupted selection, 
+                                       /*
+                                        * Restore phase bits to 0 so an interrupted selection,
                                         * arbitration can resume.
                                         */
                                        NCR5380_write(TARGET_COMMAND_REG, 0);
 
-                                       while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-                                               barrier();
+                                       /* Enable reselect interrupts */
+                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        return;
                                case MESSAGE_REJECT:
                                        /* Accept message by clearing ACK */
@@ -2229,38 +1918,33 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                        default:
                                                break;
                                        }
-                               case DISCONNECT:{
-                                               /* Accept message by clearing ACK */
-                                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                               cmd->device->disconnect = 1;
-                                               LIST(cmd, hostdata->disconnected_queue);
-                                               cmd->host_scribble = (unsigned char *)
-                                                   hostdata->disconnected_queue;
-                                               hostdata->connected = NULL;
-                                               hostdata->disconnected_queue = cmd;
-                                               dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %llu was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
-                                               /* 
-                                                * Restore phase bits to 0 so an interrupted selection, 
-                                                * arbitration can resume.
-                                                */
-                                               NCR5380_write(TARGET_COMMAND_REG, 0);
-
-                                               /* Enable reselect interrupts */
-                                               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                                               /* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/
-                                               /* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */
-                                               while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-                                                       barrier();
-                                               return;
-                                       }
-                                       /* 
+                                       break;
+                               case DISCONNECT:
+                                       /* Accept message by clearing ACK */
+                                       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+                                       hostdata->connected = NULL;
+                                       list_add(&ncmd->list, &hostdata->disconnected);
+                                       dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
+                                                instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
+                                                cmd, scmd_id(cmd), cmd->device->lun);
+
+                                       /*
+                                        * Restore phase bits to 0 so an interrupted selection,
+                                        * arbitration can resume.
+                                        */
+                                       NCR5380_write(TARGET_COMMAND_REG, 0);
+
+                                       /* Enable reselect interrupts */
+                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+                                       return;
+                                       /*
                                         * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
-                                        * operation, in violation of the SCSI spec so we can safely 
+                                        * operation, in violation of the SCSI spec so we can safely
                                         * ignore SAVE/RESTORE pointers calls.
                                         *
-                                        * Unfortunately, some disks violate the SCSI spec and 
+                                        * Unfortunately, some disks violate the SCSI spec and
                                         * don't issue the required SAVE_POINTERS message before
-                                        * disconnecting, and we have to break spec to remain 
+                                        * disconnecting, and we have to break spec to remain
                                         * compatible.
                                         */
                                case SAVE_POINTERS:
@@ -2269,31 +1953,28 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                                        break;
                                case EXTENDED_MESSAGE:
-/* 
- * Extended messages are sent in the following format :
- * Byte         
- * 0            EXTENDED_MESSAGE == 1
- * 1            length (includes one byte for code, doesn't 
- *              include first two bytes)
- * 2            code
- * 3..length+1  arguments
- *
- * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since spi_print_msg() wants the whole thing.  
- */
+                                       /*
+                                        * Start the message buffer with the EXTENDED_MESSAGE
+                                        * byte, since spi_print_msg() wants the whole thing.
+                                        */
                                        extended_msg[0] = EXTENDED_MESSAGE;
                                        /* Accept first byte by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
+
+                                       spin_unlock_irq(&hostdata->lock);
+
+                                       dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
 
                                        len = 2;
                                        data = extended_msg + 1;
                                        phase = PHASE_MSGIN;
                                        NCR5380_transfer_pio(instance, &phase, &len, &data);
+                                       dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
+                                                (int)extended_msg[1],
+                                                (int)extended_msg[2]);
 
-                                       dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
-
-                                       if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {
+                                       if (!len && extended_msg[1] > 0 &&
+                                           extended_msg[1] <= sizeof(extended_msg) - 2) {
                                                /* Accept third byte by clearing ACK */
                                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                                                len = extended_msg[1] - 1;
@@ -2301,7 +1982,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                                phase = PHASE_MSGIN;
 
                                                NCR5380_transfer_pio(instance, &phase, &len, &data);
-                                               dprintk(NDEBUG_EXTENDED, "scsi%d : message received, residual %d\n", instance->host_no, len);
+                                               dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+                                                        len);
 
                                                switch (extended_msg[2]) {
                                                case EXTENDED_SDTR:
@@ -2311,34 +1993,42 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                                        tmp = 0;
                                                }
                                        } else if (len) {
-                                               printk("scsi%d: error receiving extended message\n", instance->host_no);
+                                               shost_printk(KERN_ERR, instance, "error receiving extended message\n");
                                                tmp = 0;
                                        } else {
-                                               printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
+                                               shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
+                                                            extended_msg[2], extended_msg[1]);
                                                tmp = 0;
                                        }
+
+                                       spin_lock_irq(&hostdata->lock);
+                                       if (!hostdata->connected)
+                                               return;
+
                                        /* Fall through to reject message */
 
-                                       /* 
-                                        * If we get something weird that we aren't expecting, 
+                                       /*
+                                        * If we get something weird that we aren't expecting,
                                         * reject it.
                                         */
                                default:
                                        if (!tmp) {
-                                               printk("scsi%d: rejecting message ", instance->host_no);
+                                               shost_printk(KERN_ERR, instance, "rejecting message ");
                                                spi_print_msg(extended_msg);
                                                printk("\n");
                                        } else if (tmp != EXTENDED_MESSAGE)
                                                scmd_printk(KERN_INFO, cmd,
-                                                       "rejecting unknown message %02x\n",tmp);
+                                                           "rejecting unknown message %02x\n",
+                                                           tmp);
                                        else
                                                scmd_printk(KERN_INFO, cmd,
-                                                       "rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]);
+                                                           "rejecting unknown extended message code %02x, length %d\n",
+                                                           extended_msg[1], extended_msg[0]);
 
                                        msgout = MESSAGE_REJECT;
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
                                        break;
-                               }       /* switch (tmp) */
+                               } /* switch (tmp) */
                                break;
                        case PHASE_MSGOUT:
                                len = 1;
@@ -2346,10 +2036,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                hostdata->last_message = msgout;
                                NCR5380_transfer_pio(instance, &phase, &len, &data);
                                if (msgout == ABORT) {
-                                       hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
                                        hostdata->connected = NULL;
                                        cmd->result = DID_ERROR << 16;
-                                       cmd->scsi_done(cmd);
+                                       complete_cmd(instance, cmd);
                                        NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        return;
                                }
@@ -2358,17 +2047,12 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                        case PHASE_CMDOUT:
                                len = cmd->cmd_len;
                                data = cmd->cmnd;
-                               /* 
-                                * XXX for performance reasons, on machines with a 
-                                * PSEUDO-DMA architecture we should probably 
-                                * use the dma transfer function.  
+                               /*
+                                * XXX for performance reasons, on machines with a
+                                * PSEUDO-DMA architecture we should probably
+                                * use the dma transfer function.
                                 */
                                NCR5380_transfer_pio(instance, &phase, &len, &data);
-                               if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
-                                       NCR5380_set_timer(hostdata, USLEEP_SLEEP);
-                                       dprintk(NDEBUG_USLEEP, "scsi%d : issued command, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
-                                       return;
-                               }
                                break;
                        case PHASE_STATIN:
                                len = 1;
@@ -2377,46 +2061,37 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                cmd->SCp.Status = tmp;
                                break;
                        default:
-                               printk("scsi%d : unknown phase\n", instance->host_no);
+                               shost_printk(KERN_ERR, instance, "unknown phase\n");
                                NCR5380_dprint(NDEBUG_ANY, instance);
-                       }       /* switch(phase) */
-               }               /* if (tmp * SR_REQ) */
-               else {
-                       /* RvC: go to sleep if polling time expired
-                        */
-                       if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
-                               NCR5380_set_timer(hostdata, USLEEP_SLEEP);
-                               dprintk(NDEBUG_USLEEP, "scsi%d : poll timed out, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
-                               return;
-                       }
+                       } /* switch(phase) */
+               } else {
+                       spin_unlock_irq(&hostdata->lock);
+                       NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+                       spin_lock_irq(&hostdata->lock);
                }
-       }                       /* while (1) */
+       }
 }
 
 /*
  * Function : void NCR5380_reselect (struct Scsi_Host *instance)
  *
- * Purpose : does reselection, initializing the instance->connected 
- *      field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
- *      nexus has been reestablished,
- *      
- * Inputs : instance - this instance of the NCR5380.
+ * Purpose : does reselection, initializing the instance->connected
+ * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
+ * nexus has been reestablished,
  *
- * Locks: io_request_lock held by caller if IRQ driven
+ * Inputs : instance - this instance of the NCR5380.
  */
 
-static void NCR5380_reselect(struct Scsi_Host *instance) {
-       NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-        instance->hostdata;
+static void NCR5380_reselect(struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char target_mask;
        unsigned char lun, phase;
        int len;
        unsigned char msg[3];
        unsigned char *data;
-       struct scsi_cmnd *tmp = NULL, *prev;
-       int abort = 0;
-       NCR5380_setup(instance);
+       struct NCR5380_cmd *ncmd;
+       struct scsi_cmnd *tmp;
 
        /*
         * Disable arbitration, etc. since the host adapter obviously
@@ -2424,12 +2099,12 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
         */
 
        NCR5380_write(MODE_REG, MR_BASE);
-       hostdata->restart_select = 1;
 
        target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-       dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
 
-       /* 
+       dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
+
+       /*
         * At this point, we have detected that our SCSI ID is on the bus,
         * SEL is true and BSY was false for at least one bus settle delay
         * (400 ns).
@@ -2439,103 +2114,110 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
         */
 
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-       /* FIXME: timeout too long, must fail to workqueue */   
-       if(NCR5380_poll_politely(instance, STATUS_REG, SR_SEL, 0, 2*HZ)<0)
-               abort = 1;
-               
+       if (NCR5380_poll_politely(instance,
+                                 STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+               return;
+       }
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
        /*
         * Wait for target to go into MSGIN.
-        * FIXME: timeout needed and fail to work queeu
         */
 
-       if(NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 2*HZ))
-               abort = 1;
+       if (NCR5380_poll_politely(instance,
+                                 STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+               do_abort(instance);
+               return;
+       }
 
        len = 1;
        data = msg;
        phase = PHASE_MSGIN;
        NCR5380_transfer_pio(instance, &phase, &len, &data);
 
+       if (len) {
+               do_abort(instance);
+               return;
+       }
+
        if (!(msg[0] & 0x80)) {
-               printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
+               shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
                spi_print_msg(msg);
-               abort = 1;
-       } else {
-               /* Accept message by clearing ACK */
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               lun = (msg[0] & 0x07);
+               printk("\n");
+               do_abort(instance);
+               return;
+       }
+       lun = msg[0] & 0x07;
 
-               /* 
-                * We need to add code for SCSI-II to track which devices have
-                * I_T_L_Q nexuses established, and which have simple I_T_L
-                * nexuses so we can chose to do additional data transfer.
-                */
+       /*
+        * We need to add code for SCSI-II to track which devices have
+        * I_T_L_Q nexuses established, and which have simple I_T_L
+        * nexuses so we can chose to do additional data transfer.
+        */
 
-               /* 
-                * Find the command corresponding to the I_T_L or I_T_L_Q  nexus we 
-                * just reestablished, and remove it from the disconnected queue.
-                */
+       /*
+        * Find the command corresponding to the I_T_L or I_T_L_Q  nexus we
+        * just reestablished, and remove it from the disconnected queue.
+        */
 
+       tmp = NULL;
+       list_for_each_entry(ncmd, &hostdata->disconnected, list) {
+               struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
 
-               for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-                       if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
-                           ) {
-                               if (prev) {
-                                       REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
-                                       prev->host_scribble = tmp->host_scribble;
-                               } else {
-                                       REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
-                                       hostdata->disconnected_queue = (struct scsi_cmnd *) tmp->host_scribble;
-                               }
-                               tmp->host_scribble = NULL;
-                               break;
-                       }
-               if (!tmp) {
-                       printk(KERN_ERR "scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun);
-                       /* 
-                        * Since we have an established nexus that we can't do anything with,
-                        * we must abort it.  
-                        */
-                       abort = 1;
+               if (target_mask == (1 << scmd_id(cmd)) &&
+                   lun == (u8)cmd->device->lun) {
+                       list_del(&ncmd->list);
+                       tmp = cmd;
+                       break;
                }
        }
 
-       if (abort) {
-               do_abort(instance);
+       if (tmp) {
+               dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+                        "reselect: removed %p from disconnected queue\n", tmp);
        } else {
-               hostdata->connected = tmp;
-               dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+               shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
+                            target_mask, lun);
+               /*
+                * Since we have an established nexus that we can't do anything
+                * with, we must abort it.
+                */
+               do_abort(instance);
+               return;
        }
+
+       /* Accept message by clearing ACK */
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+
+       hostdata->connected = tmp;
+       dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+                scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
 /*
  * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
  *
  * Purpose : called by interrupt handler when DMA finishes or a phase
- *      mismatch occurs (which would finish the DMA transfer).  
+ * mismatch occurs (which would finish the DMA transfer).
  *
  * Inputs : instance - this instance of the NCR5380.
  *
  * Returns : pointer to the scsi_cmnd structure for which the I_T_L
- *      nexus has been reestablished, on failure NULL is returned.
+ * nexus has been reestablished, on failure NULL is returned.
  */
 
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
-       NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int transferred;
-       NCR5380_setup(instance);
 
        /*
         * XXX this might not be right.
         *
         * Wait for final byte to transfer, ie wait for ACK to go false.
         *
-        * We should use the Last Byte Sent bit, unfortunately this is 
+        * We should use the Last Byte Sent bit, unfortunately this is
         * not available on the 5380/5381 (only the various CMOS chips)
         *
         * FIXME: timeout, and need to handle long timeout/irq case
@@ -2543,7 +2225,6 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
 
        NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ);
 
-       NCR5380_write(MODE_REG, MR_BASE);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
        /*
@@ -2560,190 +2241,251 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
 }
 #endif                         /* def REAL_DMA */
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
- *
- * Purpose : abort a command
- *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- *      host byte of the result field to, if zero DID_ABORTED is
- *      used.
- *
- * Returns : SUCCESS - success, FAILED on failure.
- *
- *     XXX - there is no way to abort the command that is currently
- *     connected, you have to wait for it to complete.  If this is
- *     a problem, we could implement longjmp() / setjmp(), setjmp()
- *     called where the loop started in NCR5380_main().
- *
- * Locks: host lock taken by caller
+/**
+ * list_find_cmd - test for presence of a command in a linked list
+ * @haystack: list of commands
+ * @needle: command to search for
  */
 
-static int NCR5380_abort(struct scsi_cmnd *cmd)
+static bool list_find_cmd(struct list_head *haystack,
+                          struct scsi_cmnd *needle)
 {
-       NCR5380_local_declare();
-       struct Scsi_Host *instance = cmd->device->host;
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-       struct scsi_cmnd *tmp, **prev;
+       struct NCR5380_cmd *ncmd;
 
-       scmd_printk(KERN_WARNING, cmd, "aborting command\n");
+       list_for_each_entry(ncmd, haystack, list)
+               if (NCR5380_to_scmd(ncmd) == needle)
+                       return true;
+       return false;
+}
 
-       NCR5380_print_status(instance);
+/**
+ * list_remove_cmd - remove a command from linked list
+ * @haystack: list of commands
+ * @needle: command to remove
+ */
 
-       NCR5380_setup(instance);
+static bool list_del_cmd(struct list_head *haystack,
+                         struct scsi_cmnd *needle)
+{
+       if (list_find_cmd(haystack, needle)) {
+               struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle);
 
-       dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
-       dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
+               list_del(&ncmd->list);
+               return true;
+       }
+       return false;
+}
 
-#if 0
-/*
- * Case 1 : If the command is the currently executing command, 
- * we'll set the aborted flag and return control so that 
- * information transfer routine can exit cleanly.
+/**
+ * NCR5380_abort - scsi host eh_abort_handler() method
+ * @cmd: the command to be aborted
+ *
+ * Try to abort a given command by removing it from queues and/or sending
+ * the target an abort message. This may not succeed in causing a target
+ * to abort the command. Nonetheless, the low-level driver must forget about
+ * the command because the mid-layer reclaims it and it may be re-issued.
+ *
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
+ *
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
+ *
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * If cmd was not found at all then presumably it has already been completed,
+ * in which case return SUCCESS to try to avoid further EH measures.
+ * If the command has not completed yet, we must not fail to find it.
  */
 
-       if (hostdata->connected == cmd) {
-               dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no);
-               hostdata->aborted = 1;
-/*
- * We should perform BSY checking, and make sure we haven't slipped
- * into BUS FREE.
- */
+static int NCR5380_abort(struct scsi_cmnd *cmd)
+{
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       unsigned long flags;
+       int result = SUCCESS;
 
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
-/* 
- * Since we can't change phases until we've completed the current 
- * handshake, we have to source or sink a byte of data if the current
- * phase is not MSGOUT.
- */
+       spin_lock_irqsave(&hostdata->lock, flags);
 
-/* 
- * Return control to the executing NCR drive so we can clear the
- * aborted flag and get back into our main loop.
- */
+#if (NDEBUG & NDEBUG_ANY)
+       scmd_printk(KERN_INFO, cmd, __func__);
+#endif
+       NCR5380_dprint(NDEBUG_ANY, instance);
+       NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-               return SUCCESS;
+       if (list_del_cmd(&hostdata->unissued, cmd)) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: removed %p from issue queue\n", cmd);
+               cmd->result = DID_ABORT << 16;
+               cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
        }
-#endif
 
-/* 
- * Case 2 : If the command hasn't been issued yet, we simply remove it 
- *          from the issue queue.
- */
-       dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
-       for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
-               if (cmd == tmp) {
-                       REMOVE(5, *prev, tmp, tmp->host_scribble);
-                       (*prev) = (struct scsi_cmnd *) tmp->host_scribble;
-                       tmp->host_scribble = NULL;
-                       tmp->result = DID_ABORT << 16;
-                       dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
-                       tmp->scsi_done(tmp);
-                       return SUCCESS;
+       if (hostdata->selecting == cmd) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: cmd %p == selecting\n", cmd);
+               hostdata->selecting = NULL;
+               cmd->result = DID_ABORT << 16;
+               complete_cmd(instance, cmd);
+               goto out;
+       }
+
+       if (list_del_cmd(&hostdata->disconnected, cmd)) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: removed %p from disconnected list\n", cmd);
+               cmd->result = DID_ERROR << 16;
+               if (!hostdata->connected)
+                       NCR5380_select(instance, cmd);
+               if (hostdata->connected != cmd) {
+                       complete_cmd(instance, cmd);
+                       result = FAILED;
+                       goto out;
+               }
+       }
+
+       if (hostdata->connected == cmd) {
+               dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+               hostdata->connected = NULL;
+               if (do_abort(instance)) {
+                       set_host_byte(cmd, DID_ERROR);
+                       complete_cmd(instance, cmd);
+                       result = FAILED;
+                       goto out;
                }
-#if (NDEBUG  & NDEBUG_ABORT)
-       /* KLL */
-               else if (prev == tmp)
-                       printk(KERN_ERR "scsi%d : LOOP\n", instance->host_no);
+               set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+               hostdata->dma_len = 0;
 #endif
+               if (cmd->cmnd[0] == REQUEST_SENSE)
+                       complete_cmd(instance, cmd);
+               else {
+                       struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
-/* 
- * Case 3 : If any commands are connected, we're going to fail the abort
- *          and let the high level SCSI driver retry at a later time or 
- *          issue a reset.
- *
- *          Timeouts, and therefore aborted commands, will be highly unlikely
- *          and handling them cleanly in this situation would make the common
- *          case of noresets less efficient, and would pollute our code.  So,
- *          we fail.
- */
+                       /* Perform autosense for this command */
+                       list_add(&ncmd->list, &hostdata->autosense);
+               }
+       }
 
-       if (hostdata->connected) {
-               dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
-               return FAILED;
+       if (list_find_cmd(&hostdata->autosense, cmd)) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: found %p on sense queue\n", cmd);
+               spin_unlock_irqrestore(&hostdata->lock, flags);
+               queue_work(hostdata->work_q, &hostdata->main_task);
+               msleep(1000);
+               spin_lock_irqsave(&hostdata->lock, flags);
+               if (list_del_cmd(&hostdata->autosense, cmd)) {
+                       dsprintk(NDEBUG_ABORT, instance,
+                                "abort: removed %p from sense queue\n", cmd);
+                       set_host_byte(cmd, DID_ABORT);
+                       complete_cmd(instance, cmd);
+                       goto out;
+               }
        }
-/*
- * Case 4: If the command is currently disconnected from the bus, and 
- *      there are no connected commands, we reconnect the I_T_L or 
- *      I_T_L_Q nexus associated with it, go into message out, and send 
- *      an abort message.
- *
- * This case is especially ugly. In order to reestablish the nexus, we
- * need to call NCR5380_select().  The easiest way to implement this 
- * function was to abort if the bus was busy, and let the interrupt
- * handler triggered on the SEL for reselect take care of lost arbitrations
- * where necessary, meaning interrupts need to be enabled.
- *
- * When interrupts are enabled, the queues may change - so we 
- * can't remove it from the disconnected queue before selecting it
- * because that could cause a failure in hashing the nexus if that 
- * device reselected.
- * 
- * Since the queues may change, we can't use the pointers from when we
- * first locate it.
- *
- * So, we must first locate the command, and if NCR5380_select()
- * succeeds, then issue the abort, relocate the command and remove
- * it from the disconnected queue.
- */
 
-       for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = (struct scsi_cmnd *) tmp->host_scribble)
-               if (cmd == tmp) {
-                       dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
+       if (hostdata->connected == cmd) {
+               dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+               hostdata->connected = NULL;
+               if (do_abort(instance)) {
+                       set_host_byte(cmd, DID_ERROR);
+                       complete_cmd(instance, cmd);
+                       result = FAILED;
+                       goto out;
+               }
+               set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+               hostdata->dma_len = 0;
+#endif
+               complete_cmd(instance, cmd);
+       }
 
-                       if (NCR5380_select(instance, cmd))
-                               return FAILED;
-                       dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
+out:
+       if (result == FAILED)
+               dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd);
+       else
+               dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
 
-                       do_abort(instance);
+       queue_work(hostdata->work_q, &hostdata->main_task);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
-                       for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
-                               if (cmd == tmp) {
-                                       REMOVE(5, *prev, tmp, tmp->host_scribble);
-                                       *prev = (struct scsi_cmnd *) tmp->host_scribble;
-                                       tmp->host_scribble = NULL;
-                                       tmp->result = DID_ABORT << 16;
-                                       tmp->scsi_done(tmp);
-                                       return SUCCESS;
-                               }
-               }
-/*
- * Case 5 : If we reached this point, the command was not found in any of 
- *          the queues.
- *
- * We probably reached this point because of an unlikely race condition
- * between the command completing successfully and the abortion code,
- * so we won't panic, but we will notify the user in case something really
- * broke.
- */
-       printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
-                       "         before abortion\n", instance->host_no);
-       return FAILED;
+       return result;
 }
 
 
-/* 
- * Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd)
- * 
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
- * Locks: host lock taken by caller
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
        struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       int i;
+       unsigned long flags;
+       struct NCR5380_cmd *ncmd;
 
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
-       NCR5380_print_status(instance);
+       spin_lock_irqsave(&hostdata->lock, flags);
+
+#if (NDEBUG & NDEBUG_ANY)
+       scmd_printk(KERN_INFO, cmd, __func__);
+#endif
+       NCR5380_dprint(NDEBUG_ANY, instance);
+       NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-       spin_lock_irq(instance->host_lock);
        do_reset(instance);
-       spin_unlock_irq(instance->host_lock);
+
+       /* reset NCR registers */
+       NCR5380_write(MODE_REG, MR_BASE);
+       NCR5380_write(TARGET_COMMAND_REG, 0);
+       NCR5380_write(SELECT_ENABLE_REG, 0);
+
+       /* After the reset, there are no more connected or disconnected commands
+        * and no busy units; so clear the low-level status here to avoid
+        * conflicts when the mid-level code tries to wake up the affected
+        * commands!
+        */
+
+       hostdata->selecting = NULL;
+
+       list_for_each_entry(ncmd, &hostdata->disconnected, list) {
+               struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+               set_host_byte(cmd, DID_RESET);
+               cmd->scsi_done(cmd);
+       }
+
+       list_for_each_entry(ncmd, &hostdata->autosense, list) {
+               struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+               set_host_byte(cmd, DID_RESET);
+               cmd->scsi_done(cmd);
+       }
+
+       if (hostdata->connected) {
+               set_host_byte(hostdata->connected, DID_RESET);
+               complete_cmd(instance, hostdata->connected);
+               hostdata->connected = NULL;
+       }
+
+       if (hostdata->sensing) {
+               set_host_byte(hostdata->connected, DID_RESET);
+               complete_cmd(instance, hostdata->sensing);
+               hostdata->sensing = NULL;
+       }
+
+       for (i = 0; i < 8; ++i)
+               hostdata->busy[i] = 0;
+#ifdef REAL_DMA
+       hostdata->dma_len = 0;
+#endif
+
+       queue_work(hostdata->work_q, &hostdata->main_task);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
        return SUCCESS;
 }
index 162112d..a792886 100644 (file)
 #ifndef NCR5380_H
 #define NCR5380_H
 
+#include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/workqueue.h>
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
+#include <scsi/scsi_transport_spi.h>
 
 #define NDEBUG_ARBITRATION     0x1
 #define NDEBUG_AUTOSENSE       0x2
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7      /* wo */
 
-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8    /* rw */
-
+/* NCR 53C400(A) Control Status Register bits: */
 #define CSR_RESET              0x80    /* wo  Resets 53c400 */
 #define CSR_53C80_REG          0x80    /* ro  5380 registers busy */
 #define CSR_TRANS_DIR          0x40    /* rw  Data transfer direction */
 #define CSR_BASE CSR_53C80_INTR
 #endif
 
-/* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7   /* rw */
-
-/* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6   /* wo */
-
-/* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4   /* rw */
-
-
 /* Note : PHASE_* macros are based on the values of the STATUS register */
 #define PHASE_MASK     (SR_MSG | SR_CD | SR_IO)
 
 
 #define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
 
-/*
- * The internal should_disconnect() function returns these based on the 
- * expected length of a disconnect if a device supports disconnect/
- * reconnect.
- */
-
-#define DISCONNECT_NONE                0
-#define DISCONNECT_TIME_TO_DATA        1
-#define DISCONNECT_LONG                2
-
 /* 
  * "Special" value for the (unsigned char) command tag, to indicate
  * I_T_L nexus instead of I_T_L_Q.
 #define NO_IRQ         0
 #endif
 
-#define FLAG_HAS_LAST_BYTE_SENT                1       /* NCR53c81 or better */
-#define FLAG_CHECK_LAST_BYTE_SENT      2       /* Only test once */
-#define FLAG_NCR53C400                 4       /* NCR53c400 */
+#define FLAG_NO_DMA_FIXUP              1       /* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA             8       /* Inhibit DMA */
-#define FLAG_DTC3181E                  16      /* DTC3181E */
 #define FLAG_LATE_DMA_SETUP            32      /* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING            64      /* as X3T9.2 spelled it */
-
-#ifndef ASM
+#define FLAG_TOSHIBA_DELAY             128     /* Allow for borken CD-ROMs */
 
 #ifdef SUPPORT_TAGS
 struct tag_alloc {
@@ -258,33 +238,24 @@ struct NCR5380_hostdata {
        NCR5380_implementation_fields;          /* implementation specific */
        struct Scsi_Host *host;                 /* Host backpointer */
        unsigned char id_mask, id_higher_mask;  /* 1 << id, all bits greater */
-       unsigned char targets_present;          /* targets we have connected
-                                                  to, so we can call a select
-                                                  failure a retryable condition */
-       volatile unsigned char busy[8];         /* index = target, bit = lun */
+       unsigned char busy[8];                  /* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-       volatile int dma_len;                   /* requested length of DMA */
+       int dma_len;                            /* requested length of DMA */
 #endif
-       volatile unsigned char last_message;    /* last message OUT */
-       volatile struct scsi_cmnd *connected;   /* currently connected command */
-       volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */
-       volatile struct scsi_cmnd *disconnected_queue;  /* waiting for reconnect */
-       volatile int restart_select;            /* we have disconnected,
-                                                  used to restart 
-                                                  NCR5380_select() */
-       volatile unsigned aborted:1;            /* flag, says aborted */
+       unsigned char last_message;             /* last message OUT */
+       struct scsi_cmnd *connected;            /* currently connected cmnd */
+       struct scsi_cmnd *selecting;            /* cmnd to be connected */
+       struct list_head unissued;              /* waiting to be issued */
+       struct list_head autosense;             /* priority issue queue */
+       struct list_head disconnected;          /* waiting for reconnect */
+       spinlock_t lock;                        /* protects this struct */
        int flags;
-       unsigned long time_expires;             /* in jiffies, set prior to sleeping */
-       int select_time;                        /* timer in select for target response */
-       volatile struct scsi_cmnd *selecting;
-       struct delayed_work coroutine;          /* our co-routine */
        struct scsi_eh_save ses;
+       struct scsi_cmnd *sensing;
        char info[256];
        int read_overruns;                /* number of bytes to cut from a
                                           * transfer to handle chip overruns */
-       int retain_dma_intr;
        struct work_struct main_task;
-       volatile int main_running;
 #ifdef SUPPORT_TAGS
        struct tag_alloc TagAlloc[8][8];        /* 8 targets and 8 LUNs */
 #endif
@@ -292,10 +263,23 @@ struct NCR5380_hostdata {
        unsigned spin_max_r;
        unsigned spin_max_w;
 #endif
+       struct workqueue_struct *work_q;
+       unsigned long accesses_per_ms;  /* chip register accesses per ms */
 };
 
 #ifdef __KERNEL__
 
+struct NCR5380_cmd {
+       struct list_head list;
+};
+
+#define NCR5380_CMD_SIZE               (sizeof(struct NCR5380_cmd))
+
+static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr)
+{
+       return ((struct scsi_cmnd *)ncmd_ptr) - 1;
+}
+
 #ifndef NDEBUG
 #define NDEBUG (0)
 #endif
@@ -304,6 +288,11 @@ struct NCR5380_hostdata {
        do { if ((NDEBUG) & (flg)) \
                printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0)
 
+#define dsprintk(flg, host, fmt, ...) \
+       do { if ((NDEBUG) & (flg)) \
+               shost_printk(KERN_DEBUG, host, fmt, ## __VA_ARGS__); \
+       } while (0)
+
 #if NDEBUG
 #define NCR5380_dprint(flg, arg) \
        do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0)
@@ -320,6 +309,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
 static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
 #endif
 static int NCR5380_init(struct Scsi_Host *instance, int flags);
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
 static void NCR5380_exit(struct Scsi_Host *instance);
 static void NCR5380_information_transfer(struct Scsi_Host *instance);
 #ifndef DONT_USE_INTR
@@ -328,7 +318,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id);
 static void NCR5380_main(struct work_struct *work);
 static const char *NCR5380_info(struct Scsi_Host *instance);
 static void NCR5380_reselect(struct Scsi_Host *instance);
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd);
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
 #if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 #endif
@@ -443,5 +433,4 @@ static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
 #endif                         /* defined(i386) || defined(__alpha__) */
 #endif                         /* defined(REAL_DMA)  */
 #endif                         /* __KERNEL__ */
-#endif                         /* ndef ASM */
 #endif                         /* NCR5380_H */
index d28d6c0..221f18c 100644 (file)
@@ -4,9 +4,7 @@
  * Copyright 1995-2002, Russell King
  */
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/ioport.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 
 
 #include <scsi/scsi_host.h>
 
-#include <scsi/scsicam.h>
-
 #define PSEUDO_DMA
 
 #define priv(host)                     ((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_local_declare()                struct Scsi_Host *_instance
-#define NCR5380_setup(instance)                _instance = instance
-#define NCR5380_read(reg)              cumanascsi_read(_instance, reg)
-#define NCR5380_write(reg, value)      cumanascsi_write(_instance, reg, value)
+#define NCR5380_read(reg)              cumanascsi_read(instance, reg)
+#define NCR5380_write(reg, value)      cumanascsi_write(instance, reg, value)
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase)     (cmd->transfersize)
+
 #define NCR5380_intr                   cumanascsi_intr
 #define NCR5380_queue_command          cumanascsi_queue_command
 #define NCR5380_info                   cumanascsi_info
@@ -211,6 +208,8 @@ static struct scsi_host_template cumanascsi_template = {
        .cmd_per_lun            = 2,
        .use_clustering         = DISABLE_CLUSTERING,
        .proc_name              = "CumanaSCSI-1",
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 
 static int cumanascsi1_probe(struct expansion_card *ec,
@@ -240,23 +239,21 @@ static int cumanascsi1_probe(struct expansion_card *ec,
 
        host->irq = ec->irq;
 
-       NCR5380_init(host, 0);
+       ret = NCR5380_init(host, 0);
+       if (ret)
+               goto out_unmap;
+
+       NCR5380_maybe_reset_bus(host);
 
         priv(host)->ctrl = 0;
         writeb(0, priv(host)->base + CTRL);
 
-       host->n_io_port = 255;
-       if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
-               ret = -EBUSY;
-               goto out_unmap;
-       }
-
        ret = request_irq(host->irq, cumanascsi_intr, 0,
                          "CumanaSCSI-1", host);
        if (ret) {
                printk("scsi%d: IRQ%d not free: %d\n",
                    host->host_no, host->irq, ret);
-               goto out_unmap;
+               goto out_exit;
        }
 
        ret = scsi_add_host(host, &ec->dev);
@@ -268,6 +265,8 @@ static int cumanascsi1_probe(struct expansion_card *ec,
 
  out_free_irq:
        free_irq(host->irq, host);
+ out_exit:
+       NCR5380_exit(host);
  out_unmap:
        iounmap(priv(host)->base);
        iounmap(priv(host)->dma);
index 7c6fa14..1fab1d1 100644 (file)
@@ -5,9 +5,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/ioport.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 
 #define DONT_USE_INTR
 
 #define priv(host)                     ((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_local_declare()                void __iomem *_base
-#define NCR5380_setup(host)            _base = priv(host)->base
 
-#define NCR5380_read(reg)              readb(_base + ((reg) << 2))
-#define NCR5380_write(reg, value)      writeb(value, _base + ((reg) << 2))
+#define NCR5380_read(reg) \
+       readb(priv(instance)->base + ((reg) << 2))
+#define NCR5380_write(reg, value) \
+       writeb(value, priv(instance)->base + ((reg) << 2))
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase)     (cmd->transfersize)
+
 #define NCR5380_queue_command          oakscsi_queue_command
 #define NCR5380_info                   oakscsi_info
-#define NCR5380_show_info              oakscsi_show_info
 
 #define NCR5380_implementation_fields  \
        void __iomem *base
@@ -103,7 +103,6 @@ printk("reading %p len %d\n", addr, len);
 
 static struct scsi_host_template oakscsi_template = {
        .module                 = THIS_MODULE,
-       .show_info              = oakscsi_show_info,
        .name                   = "Oak 16-bit SCSI",
        .info                   = oakscsi_info,
        .queuecommand           = oakscsi_queue_command,
@@ -115,6 +114,8 @@ static struct scsi_host_template oakscsi_template = {
        .cmd_per_lun            = 2,
        .use_clustering         = DISABLE_CLUSTERING,
        .proc_name              = "oakscsi",
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 
 static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
@@ -142,15 +143,21 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
        host->irq = NO_IRQ;
        host->n_io_port = 255;
 
-       NCR5380_init(host, 0);
+       ret = NCR5380_init(host, 0);
+       if (ret)
+               goto out_unmap;
+
+       NCR5380_maybe_reset_bus(host);
 
        ret = scsi_add_host(host, &ec->dev);
        if (ret)
-               goto out_unmap;
+               goto out_exit;
 
        scsi_scan_host(host);
        goto out;
 
+ out_exit:
+       NCR5380_exit(host);
  out_unmap:
        iounmap(priv(host)->base);
  unreg:
index db87ece..e654786 100644 (file)
@@ -1,15 +1,15 @@
 /*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *     to implement 5380 SCSI drivers under Linux with a non-trantor
- *     architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *     Note that these routines also work with NR53c400 family chips.
+ * Note that these routines also work with NR53c400 family chips.
  *
  * Copyright 1993, Drew Eckhardt
- *     Visionary Computing
- *     (Unix and Linux consulting and custom programming)
- *     drew@colorado.edu
- *     +1 (303) 666-5836
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * drew@colorado.edu
+ * +1 (303) 666-5836
  *
  * For more information, please consult
  *
  * 1+ (800) 334-5454
  */
 
-/*
- * ++roman: To port the 5380 driver to the Atari, I had to do some changes in
- * this file, too:
- *
- *  - Some of the debug statements were incorrect (undefined variables and the
- *    like). I fixed that.
- *
- *  - In information_transfer(), I think a #ifdef was wrong. Looking at the
- *    possible DMA transfer size should also happen for REAL_DMA. I added this
- *    in the #if statement.
- *
- *  - When using real DMA, information_transfer() should return in a DATAOUT
- *    phase after starting the DMA. It has nothing more to do.
- *
- *  - The interrupt service routine should run main after end of DMA, too (not
- *    only after RESELECTION interrupts). Additionally, it should _not_ test
- *    for more interrupts after running main, since a DMA process may have
- *    been started and interrupts are turned on now. The new int could happen
- *    inside the execution of NCR5380_intr(), leading to recursive
- *    calls.
- *
- *  - I've added a function merge_contiguous_buffers() that tries to
- *    merge scatter-gather buffers that are located at contiguous
- *    physical addresses and can be processed with the same DMA setup.
- *    Since most scatter-gather operations work on a page (4K) of
- *    4 buffers (1K), in more than 90% of all cases three interrupts and
- *    DMA setup actions are saved.
- *
- * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA
- *    and USLEEP, because these were messing up readability and will never be
- *    needed for Atari SCSI.
- *
- * - I've revised the NCR5380_main() calling scheme (relax the 'main_running'
- *   stuff), and 'main' is executed in a bottom half if awoken by an
- *   interrupt.
- *
- * - The code was quite cluttered up by "#if (NDEBUG & NDEBUG_*) printk..."
- *   constructs. In my eyes, this made the source rather unreadable, so I
- *   finally replaced that by the *_PRINTK() macros.
- *
- */
-
-/*
- * Further development / testing that should be done :
- * 1.  Test linked command handling code after Eric is ready with
- *     the high level code.
- */
+/* Ported to Atari by Roman Hodek and others. */
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_transport_spi.h>
-
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x, y)                                             \
-       do {                                                    \
-               printk("LINE:%d   Adding %p to %p\n",           \
-                      __LINE__, (void*)(x), (void*)(y));       \
-               if ((x) == (y))                                 \
-                       udelay(5);                              \
-       } while (0)
-#define REMOVE(w, x, y, z)                                     \
-       do {                                                    \
-               printk("LINE:%d   Removing: %p->%p  %p->%p \n", \
-                      __LINE__, (void*)(w), (void*)(x),        \
-                      (void*)(y), (void*)(z));                 \
-               if ((x) == (y))                                 \
-                       udelay(5);                              \
-       } while (0)
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
-#ifndef notyet
-#undef LINKED
-#endif
-
 /*
  * Design
  *
  * piece of hardware that requires you to sit in a loop polling for
  * the REQ signal as long as you are connected.  Some devices are
  * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
- * while doing long seek operations.
- *
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- *
- * Some tweaking of N and M needs to be done.  An algorithm based
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these
+ * while doing long seek operations. [...] These
  * broken devices are the exception rather than the rule and I'd rather
  * spend my time optimizing for the normal case.
  *
  *
  * These macros control options :
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- *     for commands that return with a CHECK CONDITION status.
+ * for commands that return with a CHECK CONDITION status.
  *
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- *     transceivers.
- *
- * LINKED - if defined, linked commands are supported.
+ * transceivers.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
  *
  * NCR5380_write(register, value) - write to the specific register
  *
  * NCR5380_implementation_fields  - additional fields needed for this
- *      specific implementation of the NCR5380
+ * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
  * REAL functions :
  * NCR5380_REAL_DMA should be defined if real DMA is to be used.
  * Note that the DMA setup functions should return the number of bytes
- *     that they were able to program the controller for.
+ * that they were able to program the controller for.
  *
  * Also note that generic i386/PC versions of these macros are
- *     available as NCR5380_i386_dma_write_setup,
- *     NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
+ * available as NCR5380_i386_dma_write_setup,
+ * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
  *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * possible) function may be used.
  */
 
-/* Macros ease life... :-) */
-#define        SETUP_HOSTDATA(in)                              \
-    struct NCR5380_hostdata *hostdata =                        \
-       (struct NCR5380_hostdata *)(in)->hostdata
-#define        HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
-
-#define        NEXT(cmd)               ((struct scsi_cmnd *)(cmd)->host_scribble)
-#define        SET_NEXT(cmd,next)      ((cmd)->host_scribble = (void *)(next))
-#define        NEXTADDR(cmd)           ((struct scsi_cmnd **)&(cmd)->host_scribble)
-
-#define        HOSTNO          instance->host_no
-#define        H_NO(cmd)       (cmd)->device->host->host_no
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
 
 #ifdef SUPPORT_TAGS
 
  * cannot know it in advance :-( We just see a QUEUE_FULL status being
  * returned. So, in this case, the driver internal queue size assumption is
  * reduced to the number of active tags if QUEUE_FULL is returned by the
- * target. The command is returned to the mid-level, but with status changed
- * to BUSY, since --as I've seen-- the mid-level can't handle QUEUE_FULL
- * correctly.
+ * target.
  *
  * We're also not allowed running tagged commands as long as an untagged
  * command is active. And REQUEST SENSE commands after a contingent allegiance
@@ -304,7 +206,8 @@ static void __init init_tags(struct NCR5380_hostdata *hostdata)
 static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 {
        u8 lun = cmd->device->lun;
-       SETUP_HOSTDATA(cmd->device->host);
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        if (hostdata->busy[cmd->device->id] & (1 << lun))
                return 1;
@@ -314,8 +217,8 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
                return 0;
        if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
            hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
-                          H_NO(cmd), cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n",
+                        scmd_id(cmd), lun);
                return 1;
        }
        return 0;
@@ -330,7 +233,8 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 {
        u8 lun = cmd->device->lun;
-       SETUP_HOSTDATA(cmd->device->host);
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        /* If we or the target don't support tagged queuing, allocate the LUN for
         * an untagged command.
@@ -340,18 +244,16 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
            !cmd->device->tagged_supported) {
                cmd->tag = TAG_NONE;
                hostdata->busy[cmd->device->id] |= (1 << lun);
-               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
-                          "command\n", H_NO(cmd), cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "target %d lun %d now allocated by untagged command\n",
+                        scmd_id(cmd), lun);
        } else {
                struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
 
                cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
                set_bit(cmd->tag, ta->allocated);
                ta->nr_allocated++;
-               dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
-                          "(now %d tags in use)\n",
-                          H_NO(cmd), cmd->tag, cmd->device->id,
-                          lun, ta->nr_allocated);
+               dsprintk(NDEBUG_TAGS, instance, "using tag %d for target %d lun %d (%d tags allocated)\n",
+                        cmd->tag, scmd_id(cmd), lun, ta->nr_allocated);
        }
 }
 
@@ -363,21 +265,22 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 static void cmd_free_tag(struct scsi_cmnd *cmd)
 {
        u8 lun = cmd->device->lun;
-       SETUP_HOSTDATA(cmd->device->host);
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        if (cmd->tag == TAG_NONE) {
                hostdata->busy[cmd->device->id] &= ~(1 << lun);
-               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
-                          H_NO(cmd), cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n",
+                        scmd_id(cmd), lun);
        } else if (cmd->tag >= MAX_TAGS) {
-               printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
-                      H_NO(cmd), cmd->tag);
+               shost_printk(KERN_NOTICE, instance,
+                            "trying to free bad tag %d!\n", cmd->tag);
        } else {
                struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
                clear_bit(cmd->tag, ta->allocated);
                ta->nr_allocated--;
-               dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
-                          H_NO(cmd), cmd->tag, cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n",
+                        cmd->tag, scmd_id(cmd), lun);
        }
 }
 
@@ -401,17 +304,15 @@ static void free_all_tags(struct NCR5380_hostdata *hostdata)
 
 #endif /* SUPPORT_TAGS */
 
-
-/*
- * Function: void merge_contiguous_buffers( struct scsi_cmnd *cmd )
- *
- * Purpose: Try to merge several scatter-gather requests into one DMA
- *    transfer. This is possible if the scatter buffers lie on
- *    physical contiguous addresses.
- *
- * Parameters: struct scsi_cmnd *cmd
- *    The command to work on. The first scatter buffer's data are
- *    assumed to be already transferred into ptr/this_residual.
+/**
+ * merge_contiguous_buffers - coalesce scatter-gather list entries
+ * @cmd: command requesting IO
+ *
+ * Try to merge several scatter-gather buffers into one DMA transfer.
+ * This is possible if the scatter buffers lie on physically
+ * contiguous addresses. The first scatter-gather buffer's data are
+ * assumed to be already transferred into cmd->SCp.this_residual.
+ * Every buffer merged avoids an interrupt and a DMA setup operation.
  */
 
 static void merge_contiguous_buffers(struct scsi_cmnd *cmd)
@@ -463,9 +364,7 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
                cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
                cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
-               /* ++roman: Try to merge some scatter-buffers if they are at
-                * contiguous physical addresses.
-                */
+
                merge_contiguous_buffers(cmd);
        } else {
                cmd->SCp.buffer = NULL;
@@ -473,31 +372,110 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
                cmd->SCp.ptr = NULL;
                cmd->SCp.this_residual = 0;
        }
+
+       cmd->SCp.Status = 0;
+       cmd->SCp.Message = 0;
+}
+
+/**
+ * NCR5380_poll_politely2 - wait for two chip register values
+ * @instance: controller to poll
+ * @reg1: 5380 register to poll
+ * @bit1: Bitmask to check
+ * @val1: Expected value
+ * @reg2: Second 5380 register to poll
+ * @bit2: Second bitmask to check
+ * @val2: Second expected value
+ * @wait: Time-out in jiffies
+ *
+ * Polls the chip in a reasonably efficient manner waiting for an
+ * event to occur. After a short quick poll we begin to yield the CPU
+ * (if possible). In irq contexts the time-out is arbitrarily limited.
+ * Callers may hold locks as long as they are held in irq mode.
+ *
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
+ */
+
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+                                  int reg1, int bit1, int val1,
+                                  int reg2, int bit2, int val2, int wait)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       unsigned long deadline = jiffies + wait;
+       unsigned long n;
+
+       /* Busy-wait for up to 10 ms */
+       n = min(10000U, jiffies_to_usecs(wait));
+       n *= hostdata->accesses_per_ms;
+       n /= 2000;
+       do {
+               if ((NCR5380_read(reg1) & bit1) == val1)
+                       return 0;
+               if ((NCR5380_read(reg2) & bit2) == val2)
+                       return 0;
+               cpu_relax();
+       } while (n--);
+
+       if (irqs_disabled() || in_interrupt())
+               return -ETIMEDOUT;
+
+       /* Repeatedly sleep for 1 ms until deadline */
+       while (time_is_after_jiffies(deadline)) {
+               schedule_timeout_uninterruptible(1);
+               if ((NCR5380_read(reg1) & bit1) == val1)
+                       return 0;
+               if ((NCR5380_read(reg2) & bit2) == val2)
+                       return 0;
+       }
+
+       return -ETIMEDOUT;
 }
 
-#include <linux/delay.h>
+static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                        int reg, int bit, int val, int wait)
+{
+       return NCR5380_poll_politely2(instance, reg, bit, val,
+                                               reg, bit, val, wait);
+}
 
 #if NDEBUG
 static struct {
        unsigned char mask;
        const char *name;
 } signals[] = {
-       { SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" },
-       { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD,  "CD" }, { SR_IO, "IO" },
-       { SR_SEL, "SEL" }, {0, NULL}
-}, basrs[] = {
-       {BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL}
-}, icrs[] = {
-       {ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"},
-       {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"},
-       {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"},
+       {SR_DBP, "PARITY"},
+       {SR_RST, "RST"},
+       {SR_BSY, "BSY"},
+       {SR_REQ, "REQ"},
+       {SR_MSG, "MSG"},
+       {SR_CD, "CD"},
+       {SR_IO, "IO"},
+       {SR_SEL, "SEL"},
        {0, NULL}
-}, mrs[] = {
-       {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"},
-       {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR,
-       "MODE PARITY INTR"}, {MR_ENABLE_EOP_INTR,"MODE EOP INTR"},
+},
+basrs[] = {
+       {BASR_ATN, "ATN"},
+       {BASR_ACK, "ACK"},
+       {0, NULL}
+},
+icrs[] = {
+       {ICR_ASSERT_RST, "ASSERT RST"},
+       {ICR_ASSERT_ACK, "ASSERT ACK"},
+       {ICR_ASSERT_BSY, "ASSERT BSY"},
+       {ICR_ASSERT_SEL, "ASSERT SEL"},
+       {ICR_ASSERT_ATN, "ASSERT ATN"},
+       {ICR_ASSERT_DATA, "ASSERT DATA"},
+       {0, NULL}
+},
+mrs[] = {
+       {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
+       {MR_TARGET, "MODE TARGET"},
+       {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
+       {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
+       {MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
        {MR_MONITOR_BSY, "MODE MONITOR BSY"},
-       {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"},
+       {MR_DMA_MODE, "MODE DMA"},
+       {MR_ARBITRATE, "MODE ARBITRATION"},
        {0, NULL}
 };
 
@@ -511,15 +489,13 @@ static struct {
 static void NCR5380_print(struct Scsi_Host *instance)
 {
        unsigned char status, data, basr, mr, icr, i;
-       unsigned long flags;
 
-       local_irq_save(flags);
        data = NCR5380_read(CURRENT_SCSI_DATA_REG);
        status = NCR5380_read(STATUS_REG);
        mr = NCR5380_read(MODE_REG);
        icr = NCR5380_read(INITIATOR_COMMAND_REG);
        basr = NCR5380_read(BUS_AND_STATUS_REG);
-       local_irq_restore(flags);
+
        printk("STATUS_REG: %02x ", status);
        for (i = 0; signals[i].mask; ++i)
                if (status & signals[i].mask)
@@ -543,8 +519,12 @@ static struct {
        unsigned char value;
        const char *name;
 } phases[] = {
-       {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"},
-       {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"},
+       {PHASE_DATAOUT, "DATAOUT"},
+       {PHASE_DATAIN, "DATAIN"},
+       {PHASE_CMDOUT, "CMDOUT"},
+       {PHASE_STATIN, "STATIN"},
+       {PHASE_MSGOUT, "MSGOUT"},
+       {PHASE_MSGIN, "MSGIN"},
        {PHASE_UNKNOWN, "UNKNOWN"}
 };
 
@@ -553,8 +533,6 @@ static struct {
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
- *
- * Locks: none
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -564,54 +542,21 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
 
        status = NCR5380_read(STATUS_REG);
        if (!(status & SR_REQ))
-               printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
+               shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n");
        else {
                for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
                     (phases[i].value != (status & PHASE_MASK)); ++i)
                        ;
-               printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
+               shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
        }
 }
-
 #endif
 
-/*
- * ++roman: New scheme of calling NCR5380_main()
- *
- * If we're not in an interrupt, we can call our main directly, it cannot be
- * already running. Else, we queue it on a task queue, if not 'main_running'
- * tells us that a lower level is already executing it. This way,
- * 'main_running' needs not be protected in a special way.
- *
- * queue_main() is a utility function for putting our main onto the task
- * queue, if main_running is false. It should be called only from a
- * interrupt or bottom half.
- */
-
-#include <linux/gfp.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-
-static inline void queue_main(struct NCR5380_hostdata *hostdata)
-{
-       if (!hostdata->main_running) {
-               /* If in interrupt and NCR5380_main() not already running,
-                  queue it on the 'immediate' task queue, to be processed
-                  immediately after the current interrupt processing has
-                  finished. */
-               schedule_work(&hostdata->main_task);
-       }
-       /* else: nothing to do: the running NCR5380_main() will pick up
-          any newly queued command. */
-}
-
 /**
  * NCR58380_info - report driver and host information
  * @instance: relevant scsi host instance
  *
  * For use as the host template info() handler.
- *
- * Locks: none
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -630,13 +575,14 @@ static void prepare_info(struct Scsi_Host *instance)
                 "base 0x%lx, irq %d, "
                 "can_queue %d, cmd_per_lun %d, "
                 "sg_tablesize %d, this_id %d, "
-                "flags { %s}, "
+                "flags { %s%s}, "
                 "options { %s} ",
                 instance->hostt->name, instance->io_port, instance->n_io_port,
                 instance->base, instance->irq,
                 instance->can_queue, instance->cmd_per_lun,
                 instance->sg_tablesize, instance->this_id,
                 hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
+                hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
 #ifdef DIFFERENTIAL
                 "DIFFERENTIAL "
 #endif
@@ -652,102 +598,6 @@ static void prepare_info(struct Scsi_Host *instance)
                 "");
 }
 
-/**
- * NCR5380_print_status - dump controller info
- * @instance: controller to dump
- *
- * Print commands in the various queues, called from NCR5380_abort
- * to aid debugging.
- */
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd)
-{
-       int i, s;
-       unsigned char *command;
-       printk("scsi%d: destination target %d, lun %llu\n",
-               H_NO(cmd), cmd->device->id, cmd->device->lun);
-       printk(KERN_CONT "        command = ");
-       command = cmd->cmnd;
-       printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
-       for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-               printk(KERN_CONT " %02x", command[i]);
-       printk("\n");
-}
-
-static void NCR5380_print_status(struct Scsi_Host *instance)
-{
-       struct NCR5380_hostdata *hostdata;
-       struct scsi_cmnd *ptr;
-       unsigned long flags;
-
-       NCR5380_dprint(NDEBUG_ANY, instance);
-       NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-       hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-       local_irq_save(flags);
-       printk("NCR5380: coroutine is%s running.\n",
-               hostdata->main_running ? "" : "n't");
-       if (!hostdata->connected)
-               printk("scsi%d: no currently connected command\n", HOSTNO);
-       else
-               lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected);
-       printk("scsi%d: issue_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-               lprint_Scsi_Cmnd(ptr);
-
-       printk("scsi%d: disconnected_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-            ptr = NEXT(ptr))
-               lprint_Scsi_Cmnd(ptr);
-
-       local_irq_restore(flags);
-       printk("\n");
-}
-
-static void show_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-       int i, s;
-       unsigned char *command;
-       seq_printf(m, "scsi%d: destination target %d, lun %llu\n",
-               H_NO(cmd), cmd->device->id, cmd->device->lun);
-       seq_puts(m, "        command = ");
-       command = cmd->cmnd;
-       seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
-       for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-               seq_printf(m, " %02x", command[i]);
-       seq_putc(m, '\n');
-}
-
-static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-                                            struct Scsi_Host *instance)
-{
-       struct NCR5380_hostdata *hostdata;
-       struct scsi_cmnd *ptr;
-       unsigned long flags;
-
-       hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-       local_irq_save(flags);
-       seq_printf(m, "NCR5380: coroutine is%s running.\n",
-               hostdata->main_running ? "" : "n't");
-       if (!hostdata->connected)
-               seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
-       else
-               show_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-       seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-               show_Scsi_Cmnd(ptr, m);
-
-       seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-            ptr = NEXT(ptr))
-               show_Scsi_Cmnd(ptr, m);
-
-       local_irq_restore(flags);
-       return 0;
-}
-
 /**
  * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
@@ -764,11 +614,11 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m,
 
 static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int i;
-       SETUP_HOSTDATA(instance);
+       unsigned long deadline;
 
        hostdata->host = instance;
-       hostdata->aborted = 0;
        hostdata->id_mask = 1 << instance->this_id;
        hostdata->id_higher_mask = 0;
        for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
@@ -782,13 +632,21 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
 #if defined (REAL_DMA)
        hostdata->dma_len = 0;
 #endif
-       hostdata->targets_present = 0;
+       spin_lock_init(&hostdata->lock);
        hostdata->connected = NULL;
-       hostdata->issue_queue = NULL;
-       hostdata->disconnected_queue = NULL;
+       hostdata->sensing = NULL;
+       INIT_LIST_HEAD(&hostdata->autosense);
+       INIT_LIST_HEAD(&hostdata->unissued);
+       INIT_LIST_HEAD(&hostdata->disconnected);
+
        hostdata->flags = flags;
 
        INIT_WORK(&hostdata->main_task, NCR5380_main);
+       hostdata->work_q = alloc_workqueue("ncr5380_%d",
+                               WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1, instance->host_no);
+       if (!hostdata->work_q)
+               return -ENOMEM;
 
        prepare_info(instance);
 
@@ -797,6 +655,72 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
        NCR5380_write(TARGET_COMMAND_REG, 0);
        NCR5380_write(SELECT_ENABLE_REG, 0);
 
+       /* Calibrate register polling loop */
+       i = 0;
+       deadline = jiffies + 1;
+       do {
+               cpu_relax();
+       } while (time_is_after_jiffies(deadline));
+       deadline += msecs_to_jiffies(256);
+       do {
+               NCR5380_read(STATUS_REG);
+               ++i;
+               cpu_relax();
+       } while (time_is_after_jiffies(deadline));
+       hostdata->accesses_per_ms = i / 256;
+
+       return 0;
+}
+
+/**
+ * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
+ * @instance: adapter to check
+ *
+ * If the system crashed, it may have crashed with a connected target and
+ * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
+ * currently established nexus, which we know nothing about. Failing that
+ * do a bus reset.
+ *
+ * Note that a bus reset will cause the chip to assert IRQ.
+ *
+ * Returns 0 if successful, otherwise -ENXIO.
+ */
+
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       int pass;
+
+       for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
+               switch (pass) {
+               case 1:
+               case 3:
+               case 5:
+                       shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n");
+                       NCR5380_poll_politely(instance,
+                                             STATUS_REG, SR_BSY, 0, 5 * HZ);
+                       break;
+               case 2:
+                       shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
+                       do_abort(instance);
+                       break;
+               case 4:
+                       shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
+                       do_reset(instance);
+                       /* Wait after a reset; the SCSI standard calls for
+                        * 250ms, we wait 500ms to be on the safe side.
+                        * But some Toshiba CD-ROMs need ten times that.
+                        */
+                       if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+                               msleep(2500);
+                       else
+                               msleep(500);
+                       break;
+               case 6:
+                       shost_printk(KERN_ERR, instance, "bus locked solid\n");
+                       return -ENXIO;
+               }
+       }
        return 0;
 }
 
@@ -812,6 +736,38 @@ static void NCR5380_exit(struct Scsi_Host *instance)
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        cancel_work_sync(&hostdata->main_task);
+       destroy_workqueue(hostdata->work_q);
+}
+
+/**
+ * complete_cmd - finish processing a command and return it to the SCSI ML
+ * @instance: the host instance
+ * @cmd: command to complete
+ */
+
+static void complete_cmd(struct Scsi_Host *instance,
+                         struct scsi_cmnd *cmd)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+       dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
+
+       if (hostdata->sensing == cmd) {
+               /* Autosense processing ends here */
+               if ((cmd->result & 0xff) != SAM_STAT_GOOD) {
+                       scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+                       set_host_byte(cmd, DID_ERROR);
+               } else
+                       scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+               hostdata->sensing = NULL;
+       }
+
+#ifdef SUPPORT_TAGS
+       cmd_free_tag(cmd);
+#else
+       hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+#endif
+       cmd->scsi_done(cmd);
 }
 
 /**
@@ -819,7 +775,7 @@ static void NCR5380_exit(struct Scsi_Host *instance)
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
  *
- * cmd is added to the per instance issue_queue, with minor
+ * cmd is added to the per-instance issue queue, with minor
  * twiddling done to the host specific fields of cmd.  If the
  * main coroutine is not running, it is restarted.
  */
@@ -828,44 +784,23 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
                                  struct scsi_cmnd *cmd)
 {
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
-       struct scsi_cmnd *tmp;
+       struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
        unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
        switch (cmd->cmnd[0]) {
        case WRITE_6:
        case WRITE_10:
-               printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
-                      H_NO(cmd));
+               shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
                cmd->result = (DID_ERROR << 16);
                cmd->scsi_done(cmd);
                return 0;
        }
 #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
-       /*
-        * We use the host_scribble field as a pointer to the next command
-        * in a queue
-        */
-
-       SET_NEXT(cmd, NULL);
        cmd->result = 0;
 
        /*
-        * Insert the cmd into the issue queue. Note that REQUEST SENSE
-        * commands are added to the head of the queue since any command will
-        * clear the contingent allegiance condition that exists and the
-        * sense data is only guaranteed to be valid while the condition exists.
-        */
-
-       /* ++guenther: now that the issue queue is being set up, we can lock ST-DMA.
-        * Otherwise a running NCR5380_main may steal the lock.
-        * Lock before actually inserting due to fairness reasons explained in
-        * atari_scsi.c. If we insert first, then it's impossible for this driver
-        * to release the lock.
-        * Stop timer for this command while waiting for the lock, or timeouts
-        * may happen (and they really do), and it's no good if the command doesn't
-        * appear in any of the queues.
         * ++roman: Just disabling the NCR interrupt isn't sufficient here,
         * because also a timer int can trigger an abort or reset, which would
         * alter queues and touch the lock.
@@ -873,7 +808,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
        if (!NCR5380_acquire_dma_irq(instance))
                return SCSI_MLQUEUE_HOST_BUSY;
 
-       local_irq_save(flags);
+       spin_lock_irqsave(&hostdata->lock, flags);
 
        /*
         * Insert the cmd into the issue queue. Note that REQUEST SENSE
@@ -882,33 +817,18 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
         * sense data is only guaranteed to be valid while the condition exists.
         */
 
-       if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-               LIST(cmd, hostdata->issue_queue);
-               SET_NEXT(cmd, hostdata->issue_queue);
-               hostdata->issue_queue = cmd;
-       } else {
-               for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
-                    NEXT(tmp); tmp = NEXT(tmp))
-                       ;
-               LIST(cmd, tmp);
-               SET_NEXT(tmp, cmd);
-       }
-       local_irq_restore(flags);
+       if (cmd->cmnd[0] == REQUEST_SENSE)
+               list_add(&ncmd->list, &hostdata->unissued);
+       else
+               list_add_tail(&ncmd->list, &hostdata->unissued);
 
-       dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
-                 (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
-       /* If queue_command() is called from an interrupt (real one or bottom
-        * half), we let queue_main() do the job of taking care about main. If it
-        * is already running, this is a no-op, else main will be queued.
-        *
-        * If we're not in an interrupt, we can call NCR5380_main()
-        * unconditionally, because it cannot be already running.
-        */
-       if (in_interrupt() || irqs_disabled())
-               queue_main(hostdata);
-       else
-               NCR5380_main(&hostdata->main_task);
+       dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n",
+                cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+
+       /* Kick off command processing */
+       queue_work(hostdata->work_q, &hostdata->main_task);
        return 0;
 }
 
@@ -917,13 +837,78 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        /* Caller does the locking needed to set & test these data atomically */
-       if (!hostdata->disconnected_queue &&
-           !hostdata->issue_queue &&
+       if (list_empty(&hostdata->disconnected) &&
+           list_empty(&hostdata->unissued) &&
+           list_empty(&hostdata->autosense) &&
            !hostdata->connected &&
-           !hostdata->retain_dma_intr)
+           !hostdata->selecting)
                NCR5380_release_dma_irq(instance);
 }
 
+/**
+ * dequeue_next_cmd - dequeue a command for processing
+ * @instance: the scsi host instance
+ *
+ * Priority is given to commands on the autosense queue. These commands
+ * need autosense because of a CHECK CONDITION result.
+ *
+ * Returns a command pointer if a command is found for a target that is
+ * not already busy. Otherwise returns NULL.
+ */
+
+static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       struct NCR5380_cmd *ncmd;
+       struct scsi_cmnd *cmd;
+
+       if (list_empty(&hostdata->autosense)) {
+               list_for_each_entry(ncmd, &hostdata->unissued, list) {
+                       cmd = NCR5380_to_scmd(ncmd);
+                       dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
+                                cmd, scmd_id(cmd), hostdata->busy[scmd_id(cmd)], cmd->device->lun);
+
+                       if (
+#ifdef SUPPORT_TAGS
+                           !is_lun_busy(cmd, 1)
+#else
+                           !(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))
+#endif
+                       ) {
+                               list_del(&ncmd->list);
+                               dsprintk(NDEBUG_QUEUES, instance,
+                                        "dequeue: removed %p from issue queue\n", cmd);
+                               return cmd;
+                       }
+               }
+       } else {
+               /* Autosense processing begins here */
+               ncmd = list_first_entry(&hostdata->autosense,
+                                       struct NCR5380_cmd, list);
+               list_del(&ncmd->list);
+               cmd = NCR5380_to_scmd(ncmd);
+               dsprintk(NDEBUG_QUEUES, instance,
+                        "dequeue: removed %p from autosense queue\n", cmd);
+               scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
+               hostdata->sensing = cmd;
+               return cmd;
+       }
+       return NULL;
+}
+
+static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
+       if (hostdata->sensing) {
+               scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+               list_add(&ncmd->list, &hostdata->autosense);
+               hostdata->sensing = NULL;
+       } else
+               list_add(&ncmd->list, &hostdata->unissued);
+}
+
 /**
  * NCR5380_main - NCR state machines
  *
@@ -931,8 +916,6 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
  * be done on the NCR5380 host adapters in a system.  Both
  * NCR5380_queue_command() and NCR5380_intr() will try to start it
  * in case it is not running.
- *
- * Locks: called as its own thread with no locks held.
  */
 
 static void NCR5380_main(struct work_struct *work)
@@ -940,154 +923,69 @@ static void NCR5380_main(struct work_struct *work)
        struct NCR5380_hostdata *hostdata =
                container_of(work, struct NCR5380_hostdata, main_task);
        struct Scsi_Host *instance = hostdata->host;
-       struct scsi_cmnd *tmp, *prev;
+       struct scsi_cmnd *cmd;
        int done;
-       unsigned long flags;
 
        /*
-        * We run (with interrupts disabled) until we're sure that none of
-        * the host adapters have anything that can be done, at which point
-        * we set main_running to 0 and exit.
-        *
-        * Interrupts are enabled before doing various other internal
-        * instructions, after we've decided that we need to run through
-        * the loop again.
-        *
-        * this should prevent any race conditions.
-        *
         * ++roman: Just disabling the NCR interrupt isn't sufficient here,
         * because also a timer int can trigger an abort or reset, which can
         * alter queues and touch the Falcon lock.
         */
 
-       /* Tell int handlers main() is now already executing.  Note that
-          no races are possible here. If an int comes in before
-          'main_running' is set here, and queues/executes main via the
-          task queue, it doesn't do any harm, just this instance of main
-          won't find any work left to do. */
-       if (hostdata->main_running)
-               return;
-       hostdata->main_running = 1;
-
-       local_save_flags(flags);
        do {
-               local_irq_disable();    /* Freeze request queues */
                done = 1;
 
-               if (!hostdata->connected) {
-                       dprintk(NDEBUG_MAIN, "scsi%d: not connected\n", HOSTNO);
-                       /*
-                        * Search through the issue_queue for a command destined
-                        * for a target that's not busy.
-                        */
-#if (NDEBUG & NDEBUG_LISTS)
-                       for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL;
-                            tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
-                               ;
-                       /*printk("%p  ", tmp);*/
-                       if ((tmp == prev) && tmp)
-                               printk(" LOOP\n");
-                       /* else printk("\n"); */
-#endif
-                       for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
-                            prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
-                               u8 lun = tmp->device->lun;
-
-                               dprintk(NDEBUG_LISTS,
-                                       "MAIN tmp=%p target=%d busy=%d lun=%d\n",
-                                       tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
-                                       lun);
-                               /*  When we find one, remove it from the issue queue. */
-                               /* ++guenther: possible race with Falcon locking */
-                               if (
-#ifdef SUPPORT_TAGS
-                                   !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
-#else
-                                   !(hostdata->busy[tmp->device->id] & (1 << lun))
-#endif
-                                   ) {
-                                       /* ++guenther: just to be sure, this must be atomic */
-                                       local_irq_disable();
-                                       if (prev) {
-                                               REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
-                                               SET_NEXT(prev, NEXT(tmp));
-                                       } else {
-                                               REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
-                                               hostdata->issue_queue = NEXT(tmp);
-                                       }
-                                       SET_NEXT(tmp, NULL);
-                                       hostdata->retain_dma_intr++;
+               spin_lock_irq(&hostdata->lock);
+               while (!hostdata->connected &&
+                      (cmd = dequeue_next_cmd(instance))) {
 
-                                       /* reenable interrupts after finding one */
-                                       local_irq_restore(flags);
+                       dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
 
-                                       /*
-                                        * Attempt to establish an I_T_L nexus here.
-                                        * On success, instance->hostdata->connected is set.
-                                        * On failure, we must add the command back to the
-                                        *   issue queue so we can keep trying.
-                                        */
-                                       dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
-                                                   "lun %d removed from issue_queue\n",
-                                                   HOSTNO, tmp->device->id, lun);
-                                       /*
-                                        * REQUEST SENSE commands are issued without tagged
-                                        * queueing, even on SCSI-II devices because the
-                                        * contingent allegiance condition exists for the
-                                        * entire unit.
-                                        */
-                                       /* ++roman: ...and the standard also requires that
-                                        * REQUEST SENSE command are untagged.
-                                        */
+                       /*
+                        * Attempt to establish an I_T_L nexus here.
+                        * On success, instance->hostdata->connected is set.
+                        * On failure, we must add the command back to the
+                        * issue queue so we can keep trying.
+                        */
+                       /*
+                        * REQUEST SENSE commands are issued without tagged
+                        * queueing, even on SCSI-II devices because the
+                        * contingent allegiance condition exists for the
+                        * entire unit.
+                        */
+                       /* ++roman: ...and the standard also requires that
+                        * REQUEST SENSE command are untagged.
+                        */
 
 #ifdef SUPPORT_TAGS
-                                       cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE);
+                       cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
 #endif
-                                       if (!NCR5380_select(instance, tmp)) {
-                                               local_irq_disable();
-                                               hostdata->retain_dma_intr--;
-                                               /* release if target did not response! */
-                                               maybe_release_dma_irq(instance);
-                                               local_irq_restore(flags);
-                                               break;
-                                       } else {
-                                               local_irq_disable();
-                                               LIST(tmp, hostdata->issue_queue);
-                                               SET_NEXT(tmp, hostdata->issue_queue);
-                                               hostdata->issue_queue = tmp;
+                       cmd = NCR5380_select(instance, cmd);
+                       if (!cmd) {
+                               dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
+                               maybe_release_dma_irq(instance);
+                       } else {
+                               dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
+                                        "main: select failed, returning %p to queue\n", cmd);
+                               requeue_cmd(instance, cmd);
 #ifdef SUPPORT_TAGS
-                                               cmd_free_tag(tmp);
+                               cmd_free_tag(cmd);
 #endif
-                                               hostdata->retain_dma_intr--;
-                                               local_irq_restore(flags);
-                                               dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
-                                                           "returned to issue_queue\n", HOSTNO);
-                                               if (hostdata->connected)
-                                                       break;
-                                       }
-                               } /* if target/lun/target queue is not busy */
-                       } /* for issue_queue */
-               } /* if (!hostdata->connected) */
-
+                       }
+               }
                if (hostdata->connected
 #ifdef REAL_DMA
                    && !hostdata->dma_len
 #endif
                    ) {
-                       local_irq_restore(flags);
-                       dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
-                                   HOSTNO);
+                       dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
                        NCR5380_information_transfer(instance);
-                       dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", HOSTNO);
                        done = 0;
                }
+               spin_unlock_irq(&hostdata->lock);
+               if (!done)
+                       cond_resched();
        } while (!done);
-
-       /* Better allow ints _after_ 'main_running' has been cleared, else
-          an interrupt could believe we'll pick up the work it left for
-          us, but we won't see it anymore here... */
-       hostdata->main_running = 0;
-       local_irq_restore(flags);
 }
 
 
@@ -1096,27 +994,20 @@ static void NCR5380_main(struct work_struct *work)
  * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
  *
  * Purpose : Called by interrupt handler when DMA finishes or a phase
- *     mismatch occurs (which would finish the DMA transfer).
+ * mismatch occurs (which would finish the DMA transfer).
  *
  * Inputs : instance - this instance of the NCR5380.
- *
  */
 
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int transferred;
        unsigned char **data;
-       volatile int *count;
+       int *count;
        int saved_data = 0, overrun = 0;
        unsigned char p;
 
-       if (!hostdata->connected) {
-               printk(KERN_WARNING "scsi%d: received end of DMA interrupt with "
-                      "no connected cmd\n", HOSTNO);
-               return;
-       }
-
        if (hostdata->read_overruns) {
                p = hostdata->connected->SCp.phase;
                if (p & SR_IO) {
@@ -1126,15 +1017,11 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
                            (BASR_PHASE_MATCH|BASR_ACK)) {
                                saved_data = NCR5380_read(INPUT_DATA_REG);
                                overrun = 1;
-                               dprintk(NDEBUG_DMA, "scsi%d: read overrun handled\n", HOSTNO);
+                               dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
                        }
                }
        }
 
-       dprintk(NDEBUG_DMA, "scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
-                  HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
-                  NCR5380_read(STATUS_REG));
-
 #if defined(CONFIG_SUN3)
        if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
                pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n",
@@ -1153,9 +1040,9 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
        }
 #endif
 
-       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        NCR5380_write(MODE_REG, MR_BASE);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
        transferred = hostdata->dma_len - NCR5380_dma_residual(instance);
        hostdata->dma_len = 0;
@@ -1194,140 +1081,160 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
  * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
  * from the disconnected queue, and restarting NCR5380_main()
  * as required.
+ *
+ * The chip can assert IRQ in any of six different conditions. The IRQ flag
+ * is then cleared by reading the Reset Parity/Interrupt Register (RPIR).
+ * Three of these six conditions are latched in the Bus and Status Register:
+ * - End of DMA (cleared by ending DMA Mode)
+ * - Parity error (cleared by reading RPIR)
+ * - Loss of BSY (cleared by reading RPIR)
+ * Two conditions have flag bits that are not latched:
+ * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode)
+ * - Bus reset (non-maskable)
+ * The remaining condition has no flag bit at all:
+ * - Selection/reselection
+ *
+ * Hence, establishing the cause(s) of any interrupt is partly guesswork.
+ * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor
+ * claimed that "the design of the [DP8490] interrupt logic ensures
+ * interrupts will not be lost (they can be on the DP5380)."
+ * The L5380/53C80 datasheet from LOGIC Devices has more details.
+ *
+ * Checking for bus reset by reading RST is futile because of interrupt
+ * latency, but a bus reset will reset chip logic. Checking for parity error
+ * is unnecessary because that interrupt is never enabled. A Loss of BSY
+ * condition will clear DMA Mode. We can tell when this occurs because the
+ * the Busy Monitor interrupt is enabled together with DMA Mode.
  */
 
 static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
        struct Scsi_Host *instance = dev_id;
-       int done = 1, handled = 0;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       int handled = 0;
        unsigned char basr;
+       unsigned long flags;
 
-       dprintk(NDEBUG_INTR, "scsi%d: NCR5380 irq triggered\n", HOSTNO);
+       spin_lock_irqsave(&hostdata->lock, flags);
 
-       /* Look for pending interrupts */
        basr = NCR5380_read(BUS_AND_STATUS_REG);
-       dprintk(NDEBUG_INTR, "scsi%d: BASR=%02x\n", HOSTNO, basr);
-       /* dispatch to appropriate routine if found and done=0 */
        if (basr & BASR_IRQ) {
-               NCR5380_dprint(NDEBUG_INTR, instance);
-               if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
-                       done = 0;
-                       dprintk(NDEBUG_INTR, "scsi%d: SEL interrupt\n", HOSTNO);
-                       NCR5380_reselect(instance);
-                       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-               } else if (basr & BASR_PARITY_ERROR) {
-                       dprintk(NDEBUG_INTR, "scsi%d: PARITY interrupt\n", HOSTNO);
-                       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-               } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-                       dprintk(NDEBUG_INTR, "scsi%d: RESET interrupt\n", HOSTNO);
-                       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-               } else {
-                       /*
-                        * The rest of the interrupt conditions can occur only during a
-                        * DMA transfer
-                        */
+               unsigned char mr = NCR5380_read(MODE_REG);
+               unsigned char sr = NCR5380_read(STATUS_REG);
+
+               dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+                        irq, basr, sr, mr);
 
 #if defined(REAL_DMA)
-                       /*
-                        * We should only get PHASE MISMATCH and EOP interrupts if we have
-                        * DMA enabled, so do a sanity check based on the current setting
-                        * of the MODE register.
+               if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
+                       /* Probably End of DMA, Phase Mismatch or Loss of BSY.
+                        * We ack IRQ after clearing Mode Register. Workarounds
+                        * for End of DMA errata need to happen in DMA Mode.
                         */
 
-                       if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) &&
-                           ((basr & BASR_END_DMA_TRANSFER) ||
-                            !(basr & BASR_PHASE_MATCH))) {
+                       dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
 
-                               dprintk(NDEBUG_INTR, "scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
-                               NCR5380_dma_complete( instance );
-                               done = 0;
-                       } else
+                       if (hostdata->connected) {
+                               NCR5380_dma_complete(instance);
+                               queue_work(hostdata->work_q, &hostdata->main_task);
+                       } else {
+                               NCR5380_write(MODE_REG, MR_BASE);
+                               NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+                       }
+               } else
 #endif /* REAL_DMA */
-                       {
-/* MS: Ignore unknown phase mismatch interrupts (caused by EOP interrupt) */
-                               if (basr & BASR_PHASE_MATCH)
-                                       dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt, "
-                                              "BASR 0x%x, MR 0x%x, SR 0x%x\n",
-                                              HOSTNO, basr, NCR5380_read(MODE_REG),
-                                              NCR5380_read(STATUS_REG));
-                               (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+               if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
+                   (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
+                       /* Probably reselected */
+                       NCR5380_write(SELECT_ENABLE_REG, 0);
+                       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+                       dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
+
+                       if (!hostdata->connected) {
+                               NCR5380_reselect(instance);
+                               queue_work(hostdata->work_q, &hostdata->main_task);
+                       }
+                       if (!hostdata->connected)
+                               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+               } else {
+                       /* Probably Bus Reset */
+                       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+                       dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
 #ifdef SUN3_SCSI_VME
-                               dregs->csr |= CSR_DMA_ENABLE;
+                       dregs->csr |= CSR_DMA_ENABLE;
 #endif
-                       }
-               } /* if !(SELECTION || PARITY) */
+               }
                handled = 1;
-       } /* BASR & IRQ */ else {
-               printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
-                      "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
-                      NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-               (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+       } else {
+               shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
 #ifdef SUN3_SCSI_VME
                dregs->csr |= CSR_DMA_ENABLE;
 #endif
        }
 
-       if (!done) {
-               dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO);
-               /* Put a call to NCR5380_main() on the queue... */
-               queue_main(shost_priv(instance));
-       }
+       spin_unlock_irqrestore(&hostdata->lock, flags);
+
        return IRQ_RETVAL(handled);
 }
 
 /*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
- *                               struct scsi_cmnd *cmd)
+ * struct scsi_cmnd *cmd)
  *
  * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
- *     including ARBITRATION, SELECTION, and initial message out for
- *     IDENTIFY and queue messages.
+ * including ARBITRATION, SELECTION, and initial message out for
+ * IDENTIFY and queue messages.
  *
  * Inputs : instance - instantiation of the 5380 driver on which this
- *     target lives, cmd - SCSI command to execute.
+ * target lives, cmd - SCSI command to execute.
  *
- * Returns : -1 if selection could not execute for some reason,
- *     0 if selection succeeded or failed because the target
- *     did not respond.
+ * Returns cmd if selection failed but should be retried,
+ * NULL if selection failed and should not be retried, or
+ * NULL if selection succeeded (hostdata->connected == cmd).
  *
  * Side effects :
- *     If bus busy, arbitration failed, etc, NCR5380_select() will exit
- *             with registers as they should have been on entry - ie
- *             SELECT_ENABLE will be set appropriately, the NCR5380
- *             will cease to drive any SCSI bus signals.
+ * If bus busy, arbitration failed, etc, NCR5380_select() will exit
+ * with registers as they should have been on entry - ie
+ * SELECT_ENABLE will be set appropriately, the NCR5380
+ * will cease to drive any SCSI bus signals.
  *
- *     If successful : I_T_L or I_T_L_Q nexus will be established,
- *             instance->connected will be set to cmd.
- *             SELECT interrupt will be disabled.
+ * If successful : I_T_L or I_T_L_Q nexus will be established,
+ * instance->connected will be set to cmd.
+ * SELECT interrupt will be disabled.
  *
- *     If failed (no target) : cmd->scsi_done() will be called, and the
- *             cmd->result host byte set to DID_BAD_TARGET.
+ * If failed (no target) : cmd->scsi_done() will be called, and the
+ * cmd->result host byte set to DID_BAD_TARGET.
  */
 
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
+                                        struct scsi_cmnd *cmd)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char tmp[3], phase;
        unsigned char *data;
        int len;
-       unsigned long timeout;
-       unsigned long flags;
+       int err;
 
-       hostdata->restart_select = 0;
        NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-       dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
-                  instance->this_id);
+       dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+                instance->this_id);
+
+       /*
+        * Arbitration and selection phases are slow and involve dropping the
+        * lock, so we have to watch out for EH. An exception handler may
+        * change 'selecting' to NULL. This function will then return NULL
+        * so that the caller will forget about 'cmd'. (During information
+        * transfer phases, EH may change 'connected' to NULL.)
+        */
+       hostdata->selecting = cmd;
 
        /*
         * Set the phase bits to 0, otherwise the NCR5380 won't drive the
         * data bus during SELECTION.
         */
 
-       local_irq_save(flags);
-       if (hostdata->connected) {
-               local_irq_restore(flags);
-               return -1;
-       }
        NCR5380_write(TARGET_COMMAND_REG, 0);
 
        /*
@@ -1337,96 +1244,77 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
        NCR5380_write(MODE_REG, MR_ARBITRATE);
 
-       local_irq_restore(flags);
-
-       /* Wait for arbitration logic to complete */
-#if defined(NCR_TIMEOUT)
-       {
-               unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
+       /* The chip now waits for BUS FREE phase. Then after the 800 ns
+        * Bus Free Delay, arbitration will begin.
+        */
 
-               while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
-                      time_before(jiffies, timeout) && !hostdata->connected)
-                       ;
-               if (time_after_eq(jiffies, timeout)) {
-                       printk("scsi : arbitration timeout at %d\n", __LINE__);
-                       NCR5380_write(MODE_REG, MR_BASE);
-                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                       return -1;
-               }
+       spin_unlock_irq(&hostdata->lock);
+       err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+                       INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+                                              ICR_ARBITRATION_PROGRESS, HZ);
+       spin_lock_irq(&hostdata->lock);
+       if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+               /* Reselection interrupt */
+               goto out;
        }
-#else /* NCR_TIMEOUT */
-       while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
-              !hostdata->connected)
-               ;
-#endif
-
-       dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
-
-       if (hostdata->connected) {
+       if (err < 0) {
                NCR5380_write(MODE_REG, MR_BASE);
-               return -1;
+               shost_printk(KERN_ERR, instance,
+                            "select: arbitration timeout\n");
+               goto out;
        }
-       /*
-        * The arbitration delay is 2.2us, but this is a minimum and there is
-        * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-        * the integral nature of udelay().
-        *
-        */
+       spin_unlock_irq(&hostdata->lock);
 
+       /* The SCSI-2 arbitration delay is 2.4 us */
        udelay(3);
 
        /* Check for lost arbitration */
        if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
            (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
-           (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-           hostdata->connected) {
+           (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
                NCR5380_write(MODE_REG, MR_BASE);
-               dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
-                          HOSTNO);
-               return -1;
+               dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
+               spin_lock_irq(&hostdata->lock);
+               goto out;
        }
 
-       /* after/during arbitration, BSY should be asserted.
-          IBM DPES-31080 Version S31Q works now */
-       /* Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman) */
+       /* After/during arbitration, BSY should be asserted.
+        * IBM DPES-31080 Version S31Q works now
+        * Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman)
+        */
        NCR5380_write(INITIATOR_COMMAND_REG,
                      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-       if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-           hostdata->connected) {
-               NCR5380_write(MODE_REG, MR_BASE);
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
-                          HOSTNO);
-               return -1;
-       }
-
        /*
         * Again, bus clear + bus settle time is 1.2us, however, this is
         * a minimum so we'll udelay ceil(1.2)
         */
 
-#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-       /* ++roman: But some targets (see above :-) seem to need a bit more... */
-       udelay(15);
-#else
-       udelay(2);
-#endif
+       if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+               udelay(15);
+       else
+               udelay(2);
 
-       if (hostdata->connected) {
+       spin_lock_irq(&hostdata->lock);
+
+       /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+       if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
+               goto out;
+
+       if (!hostdata->selecting) {
                NCR5380_write(MODE_REG, MR_BASE);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               return -1;
+               goto out;
        }
 
-       dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
+       dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
        /*
         * Now that we have won arbitration, start Selection process, asserting
         * the host and target ID's on the SCSI bus.
         */
 
-       NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
+       NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
        /*
         * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1434,22 +1322,18 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
         * phase immediately after selection.
         */
 
-       NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
-                     ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+                     ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
        NCR5380_write(MODE_REG, MR_BASE);
 
        /*
         * Reselect interrupts must be turned off prior to the dropping of BSY,
         * otherwise we will trigger an interrupt.
         */
-
-       if (hostdata->connected) {
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               return -1;
-       }
-
        NCR5380_write(SELECT_ENABLE_REG, 0);
 
+       spin_unlock_irq(&hostdata->lock);
+
        /*
         * The initiator shall then wait at least two deskew delays and release
         * the BSY signal.
@@ -1457,8 +1341,8 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        udelay(1);        /* wingel -- wait two bus deskew delay >2*45ns */
 
        /* Reset BSY */
-       NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
-                     ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
+                     ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 
        /*
         * Something weird happens when we cease to drive BSY - looks
@@ -1479,45 +1363,39 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
        udelay(1);
 
-       dprintk(NDEBUG_SELECTION, "scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
+       dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
        /*
         * The SCSI specification calls for a 250 ms timeout for the actual
         * selection.
         */
 
-       timeout = jiffies + msecs_to_jiffies(250);
-
-       /*
-        * XXX very interesting - we're seeing a bounce where the BSY we
-        * asserted is being reflected / still asserted (propagation delay?)
-        * and it's detecting as true.  Sigh.
-        */
-
-#if 0
-       /* ++roman: If a target conformed to the SCSI standard, it wouldn't assert
-        * IO while SEL is true. But again, there are some disks out the in the
-        * world that do that nevertheless. (Somebody claimed that this announces
-        * reselection capability of the target.) So we better skip that test and
-        * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
-        */
-
-       while (time_before(jiffies, timeout) &&
-              !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
-               ;
+       err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+                                   msecs_to_jiffies(250));
 
        if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
+               spin_lock_irq(&hostdata->lock);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_reselect(instance);
-               printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
-                      HOSTNO);
+               if (!hostdata->connected)
+                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+               shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
+               goto out;
+       }
+
+       if (err < 0) {
+               spin_lock_irq(&hostdata->lock);
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               return -1;
+               /* Can't touch cmd if it has been reclaimed by the scsi ML */
+               if (hostdata->selecting) {
+                       cmd->result = DID_BAD_TARGET << 16;
+                       complete_cmd(instance, cmd);
+                       dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n");
+                       cmd = NULL;
+               }
+               goto out;
        }
-#else
-       while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
-               ;
-#endif
 
        /*
         * No less than two deskew delays after the initiator detects the
@@ -1525,32 +1403,9 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
         * change the DATA BUS.                                     -wingel
         */
 
-       udelay(1);
-
-       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
-       if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               if (hostdata->targets_present & (1 << cmd->device->id)) {
-                       printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
-                       if (hostdata->restart_select)
-                               printk(KERN_NOTICE "\trestart select\n");
-                       NCR5380_dprint(NDEBUG_ANY, instance);
-                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                       return -1;
-               }
-               cmd->result = DID_BAD_TARGET << 16;
-#ifdef SUPPORT_TAGS
-               cmd_free_tag(cmd);
-#endif
-               cmd->scsi_done(cmd);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
-               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-               return 0;
-       }
-
-       hostdata->targets_present |= (1 << cmd->device->id);
+       udelay(1);
+
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
        /*
         * Since we followed the SCSI spec, and raised ATN while SEL
@@ -1563,16 +1418,27 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
         * until it wraps back to 0.
         *
         * XXX - it turns out that there are some broken SCSI-II devices,
-        *           which claim to support tagged queuing but fail when more than
-        *           some number of commands are issued at once.
+        * which claim to support tagged queuing but fail when more than
+        * some number of commands are issued at once.
         */
 
        /* Wait for start of REQ/ACK handshake */
-       while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-               ;
 
-       dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
-                  HOSTNO, cmd->device->id);
+       err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+       spin_lock_irq(&hostdata->lock);
+       if (err < 0) {
+               shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+               NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+               goto out;
+       }
+       if (!hostdata->selecting) {
+               do_abort(instance);
+               goto out;
+       }
+
+       dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
+                scmd_id(cmd));
        tmp[0] = IDENTIFY(1, cmd->device->lun);
 
 #ifdef SUPPORT_TAGS
@@ -1591,11 +1457,12 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        data = tmp;
        phase = PHASE_MSGOUT;
        NCR5380_transfer_pio(instance, &phase, &len, &data);
-       dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
+       dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
        /* XXX need to handle errors here */
+
        hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
-       hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+       hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 #endif
 #ifdef SUN3_SCSI_VME
        dregs->csr |= CSR_INTR;
@@ -1603,24 +1470,30 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
        initialize_SCp(cmd);
 
-       return 0;
+       cmd = NULL;
+
+out:
+       if (!hostdata->selecting)
+               return NULL;
+       hostdata->selecting = NULL;
+       return cmd;
 }
 
 /*
  * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
- *      unsigned char *phase, int *count, unsigned char **data)
+ * unsigned char *phase, int *count, unsigned char **data)
  *
  * Purpose : transfers data in given phase using polled I/O
  *
  * Inputs : instance - instance of driver, *phase - pointer to
- *     what phase is expected, *count - pointer to number of
- *     bytes to transfer, **data - pointer to data pointer.
+ * what phase is expected, *count - pointer to number of
+ * bytes to transfer, **data - pointer to data pointer.
  *
  * Returns : -1 when different phase is entered without transferring
- *     maximum number of bytes, 0 if all bytes are transferred or exit
- *     is in same phase.
+ * maximum number of bytes, 0 if all bytes are transferred or exit
+ * is in same phase.
  *
- *     Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  *
  * XXX Note : handling for bus free may be useful.
  */
@@ -1635,9 +1508,9 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
                                unsigned char *phase, int *count,
                                unsigned char **data)
 {
-       register unsigned char p = *phase, tmp;
-       register int c = *count;
-       register unsigned char *d = *data;
+       unsigned char p = *phase, tmp;
+       int c = *count;
+       unsigned char *d = *data;
 
        /*
         * The NCR5380 chip will only drive the SCSI bus when the
@@ -1652,14 +1525,15 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
                 * Wait for assertion of REQ, after which the phase bits will be
                 * valid
                 */
-               while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-                       ;
 
-               dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
+               if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
+                       break;
+
+               dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
 
                /* Check for phase mismatch */
-               if ((tmp & PHASE_MASK) != p) {
-                       dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
+               if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
+                       dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
                        NCR5380_dprint_phase(NDEBUG_PIO, instance);
                        break;
                }
@@ -1684,35 +1558,36 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
                                NCR5380_dprint(NDEBUG_PIO, instance);
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-                                             ICR_ASSERT_DATA | ICR_ASSERT_ACK);
+                                             ICR_ASSERT_DATA | ICR_ASSERT_ACK);
                        } else {
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-                                             ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+                                             ICR_ASSERT_DATA | ICR_ASSERT_ATN);
                                NCR5380_dprint(NDEBUG_PIO, instance);
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-                                             ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+                                             ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
                        }
                } else {
                        NCR5380_dprint(NDEBUG_PIO, instance);
                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
                }
 
-               while (NCR5380_read(STATUS_REG) & SR_REQ)
-                       ;
+               if (NCR5380_poll_politely(instance,
+                                         STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+                       break;
 
-               dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
+               dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
 
-               /*
               * We have several special cases to consider during REQ/ACK handshaking :
               * 1.  We were in MSGOUT phase, and we are on the last byte of the
               *      message.  ATN must be dropped as ACK is dropped.
               *
               * 2.  We are in a MSGIN phase, and we are on the last byte of the
               *      message.  We must exit with ACK asserted, so that the calling
               *      code may raise ATN before dropping ACK to reject the message.
               *
               * 3.  ACK and ATN are clear and the target may proceed as normal.
               */
+/*
+ * We have several special cases to consider during REQ/ACK handshaking :
+ * 1.  We were in MSGOUT phase, and we are on the last byte of the
* message.  ATN must be dropped as ACK is dropped.
+ *
+ * 2.  We are in a MSGIN phase, and we are on the last byte of the
* message.  We must exit with ACK asserted, so that the calling
* code may raise ATN before dropping ACK to reject the message.
+ *
+ * 3.  ACK and ATN are clear and the target may proceed as normal.
+ */
                if (!(p == PHASE_MSGIN && c == 1)) {
                        if (p == PHASE_MSGOUT && c > 1)
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1721,16 +1596,16 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
                }
        } while (--c);
 
-       dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c);
+       dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
 
        *count = c;
        *data = d;
        tmp = NCR5380_read(STATUS_REG);
        /* The phase read from the bus is valid if either REQ is (already)
-        * asserted or if ACK hasn't been released yet. The latter is the case if
-        * we're in MSGIN and all wanted bytes have been received.
+        * asserted or if ACK hasn't been released yet. The latter applies if
+        * we're in MSG IN, DATA IN or STATUS and all bytes have been received.
         */
-       if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0))
+       if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
                *phase = tmp & PHASE_MASK;
        else
                *phase = PHASE_UNKNOWN;
@@ -1741,19 +1616,45 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
                return -1;
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
+/**
+ * do_reset - issue a reset command
+ * @instance: adapter to reset
+ *
+ * Issue a reset sequence to the NCR5380 and try and get the bus
+ * back into sane shape.
  *
- * Purpose : abort the currently established nexus.  Should only be
- *     called from a routine which can drop into a
+ * This clears the reset interrupt flag because there may be no handler for
+ * it. When the driver is initialized, the NCR5380_intr() handler has not yet
+ * been installed. And when in EH we may have released the ST DMA interrupt.
+ */
+
+static void do_reset(struct Scsi_Host *instance)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       NCR5380_write(TARGET_COMMAND_REG,
+                     PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
+       udelay(50);
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+       local_irq_restore(flags);
+}
+
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Returns 0 on success, -1 on failure.
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
 {
-       unsigned char tmp, *msgptr, phase;
+       unsigned char *msgptr, phase, tmp;
        int len;
+       int rc;
 
        /* Request message out phase */
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1768,16 +1669,20 @@ static int do_abort(struct Scsi_Host *instance)
         * the target sees, so we just handshake.
         */
 
-       while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-               ;
+       rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
+       if (rc < 0)
+               goto timeout;
+
+       tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
        NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-       if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-                             ICR_ASSERT_ACK);
-               while (NCR5380_read(STATUS_REG) & SR_REQ)
-                       ;
+       if (tmp != PHASE_MSGOUT) {
+               NCR5380_write(INITIATOR_COMMAND_REG,
+                             ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+               rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
+               if (rc < 0)
+                       goto timeout;
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
        }
 
@@ -1793,26 +1698,29 @@ static int do_abort(struct Scsi_Host *instance)
         */
 
        return len ? -1 : 0;
+
+timeout:
+       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+       return -1;
 }
 
 #if defined(REAL_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
- *      unsigned char *phase, int *count, unsigned char **data)
+ * unsigned char *phase, int *count, unsigned char **data)
  *
  * Purpose : transfers data in given phase using either real
- *     or pseudo DMA.
+ * or pseudo DMA.
  *
  * Inputs : instance - instance of driver, *phase - pointer to
- *     what phase is expected, *count - pointer to number of
- *     bytes to transfer, **data - pointer to data pointer.
+ * what phase is expected, *count - pointer to number of
+ * bytes to transfer, **data - pointer to data pointer.
  *
  * Returns : -1 when different phase is entered without transferring
- *     maximum number of bytes, 0 if all bytes or transferred or exit
- *     is in same phase.
- *
- *     Also, *phase, *count, *data are modified in place.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
+ * Also, *phase, *count, *data are modified in place.
  */
 
 
@@ -1820,10 +1728,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
                                unsigned char *phase, int *count,
                                unsigned char **data)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        register int c = *count;
        register unsigned char p = *phase;
-       unsigned long flags;
 
 #if defined(CONFIG_SUN3)
        /* sanity check */
@@ -1834,29 +1741,22 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
        }
        hostdata->dma_len = c;
 
-       dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
-               instance->host_no, (p & SR_IO) ? "reading" : "writing",
-               c, (p & SR_IO) ? "to" : "from", *data);
+       dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+                (p & SR_IO) ? "receive" : "send", c, *data);
 
        /* netbsd turns off ints here, why not be safe and do it too */
-       local_irq_save(flags);
 
        /* send start chain */
        sun3scsi_dma_start(c, *data);
 
+       NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
+                               MR_ENABLE_EOP_INTR);
        if (p & SR_IO) {
-               NCR5380_write(TARGET_COMMAND_REG, 1);
-               NCR5380_read(RESET_PARITY_INTERRUPT_REG);
                NCR5380_write(INITIATOR_COMMAND_REG, 0);
-               NCR5380_write(MODE_REG,
-                             (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
                NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
        } else {
-               NCR5380_write(TARGET_COMMAND_REG, 0);
-               NCR5380_read(RESET_PARITY_INTERRUPT_REG);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA);
-               NCR5380_write(MODE_REG,
-                             (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
                NCR5380_write(START_DMA_SEND_REG, 0);
        }
 
@@ -1864,8 +1764,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
        dregs->csr |= CSR_DMA_ENABLE;
 #endif
 
-       local_irq_restore(flags);
-
        sun3_dma_active = 1;
 
 #else /* !defined(CONFIG_SUN3) */
@@ -1880,25 +1778,20 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
        if (hostdata->read_overruns && (p & SR_IO))
                c -= hostdata->read_overruns;
 
-       dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
-                  HOSTNO, (p & SR_IO) ? "reading" : "writing",
-                  c, (p & SR_IO) ? "to" : "from", d);
+       dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+                (p & SR_IO) ? "receive" : "send", c, d);
 
        NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-#ifdef REAL_DMA
-       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
-#endif /* def REAL_DMA  */
+       NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
+                               MR_ENABLE_EOP_INTR);
 
        if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) {
                /* On the Medusa, it is a must to initialize the DMA before
                 * starting the NCR. This is also the cleaner way for the TT.
                 */
-               local_irq_save(flags);
                hostdata->dma_len = (p & SR_IO) ?
                        NCR5380_dma_read_setup(instance, d, c) :
                        NCR5380_dma_write_setup(instance, d, c);
-               local_irq_restore(flags);
        }
 
        if (p & SR_IO)
@@ -1912,11 +1805,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
                /* On the Falcon, the DMA setup must be done after the last */
                /* NCR access, else the DMA setup gets trashed!
                 */
-               local_irq_save(flags);
                hostdata->dma_len = (p & SR_IO) ?
                        NCR5380_dma_read_setup(instance, d, c) :
                        NCR5380_dma_write_setup(instance, d, c);
-               local_irq_restore(flags);
        }
 #endif /* !defined(CONFIG_SUN3) */
 
@@ -1928,23 +1819,22 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
  *
  * Purpose : run through the various SCSI phases and do as the target
- *     directs us to.  Operates on the currently connected command,
- *     instance->connected.
+ * directs us to.  Operates on the currently connected command,
+ * instance->connected.
  *
  * Inputs : instance, instance for which we are doing commands
  *
  * Side effects : SCSI things happen, the disconnected queue will be
- *     modified if a command disconnects, *instance->connected will
- *     change.
+ * modified if a command disconnects, *instance->connected will
+ * change.
  *
  * XXX Note : we need to watch for bus free or a reset condition here
- *     to recover from an unexpected bus free condition.
+ * to recover from an unexpected bus free condition.
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 {
-       SETUP_HOSTDATA(instance);
-       unsigned long flags;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char msgout = NOP;
        int sink = 0;
        int len;
@@ -1953,13 +1843,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 #endif
        unsigned char *data;
        unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-       struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+       struct scsi_cmnd *cmd;
 
 #ifdef SUN3_SCSI_VME
        dregs->csr |= CSR_INTR;
 #endif
 
-       while (1) {
+       while ((cmd = hostdata->connected)) {
+               struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
                tmp = NCR5380_read(STATUS_REG);
                /* We only have a valid SCSI phase when REQ is asserted */
                if (tmp & SR_REQ) {
@@ -1984,7 +1876,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                /* this command setup for dma yet? */
                                if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != cmd)) {
                                        if (cmd->request->cmd_type == REQ_TYPE_FS) {
-                                               sun3scsi_dma_setup(d, count,
+                                               sun3scsi_dma_setup(instance, d, count,
                                                                   rq_data_dir(cmd->request));
                                                sun3_dma_setup_done = cmd;
                                        }
@@ -2000,11 +1892,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-                                             ICR_ASSERT_ACK);
+                                             ICR_ASSERT_ACK);
                                while (NCR5380_read(STATUS_REG) & SR_REQ)
                                        ;
                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-                                             ICR_ASSERT_ATN);
+                                             ICR_ASSERT_ATN);
                                sink = 0;
                                continue;
                        }
@@ -2012,12 +1904,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                        switch (phase) {
                        case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-                               printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT "
-                                      "aborted\n", HOSTNO);
+                               shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
                                sink = 1;
                                do_abort(instance);
                                cmd->result = DID_ERROR << 16;
-                               cmd->scsi_done(cmd);
+                               complete_cmd(instance, cmd);
                                return;
 #endif
                        case PHASE_DATAIN:
@@ -2031,13 +1922,10 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        --cmd->SCp.buffers_residual;
                                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
                                        cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-                                       /* ++roman: Try to merge some scatter-buffers if
-                                        * they are at contiguous physical addresses.
-                                        */
                                        merge_contiguous_buffers(cmd);
-                                       dprintk(NDEBUG_INFORMATION, "scsi%d: %d bytes and %d buffers left\n",
-                                                  HOSTNO, cmd->SCp.this_residual,
-                                                  cmd->SCp.buffers_residual);
+                                       dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
+                                                cmd->SCp.this_residual,
+                                                cmd->SCp.buffers_residual);
                                }
 
                                /*
@@ -2051,16 +1939,18 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                 */
 
                                /* ++roman: I suggest, this should be
-                                *   #if def(REAL_DMA)
+                                * #if def(REAL_DMA)
                                 * instead of leaving REAL_DMA out.
                                 */
 
 #if defined(REAL_DMA)
-                               if (
 #if !defined(CONFIG_SUN3)
-                                   !cmd->device->borken &&
+                               transfersize = 0;
+                               if (!cmd->device->borken)
 #endif
-                                   (transfersize = NCR5380_dma_xfer_len(instance, cmd, phase)) >= DMA_MIN_SIZE) {
+                                       transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
+
+                               if (transfersize >= DMA_MIN_SIZE) {
                                        len = transfersize;
                                        cmd->SCp.phase = phase;
                                        if (NCR5380_transfer_dma(instance, &phase,
@@ -2068,16 +1958,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                                /*
                                                 * If the watchdog timer fires, all future
                                                 * accesses to this device will use the
-                                                * polled-IO. */
+                                                * polled-IO.
+                                                */
                                                scmd_printk(KERN_INFO, cmd,
                                                        "switching to slow handshake\n");
                                                cmd->device->borken = 1;
-                                               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-                                                       ICR_ASSERT_ATN);
                                                sink = 1;
                                                do_abort(instance);
                                                cmd->result = DID_ERROR << 16;
-                                               cmd->scsi_done(cmd);
+                                               complete_cmd(instance, cmd);
                                                /* XXX - need to source or sink data here, as appropriate */
                                        } else {
 #ifdef REAL_DMA
@@ -2093,9 +1982,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        }
                                } else
 #endif /* defined(REAL_DMA) */
+                               {
+                                       spin_unlock_irq(&hostdata->lock);
                                        NCR5380_transfer_pio(instance, &phase,
-                                                            (int *)&cmd->SCp.this_residual,
-                                                            (unsigned char **)&cmd->SCp.ptr);
+                                                            (int *)&cmd->SCp.this_residual,
+                                                            (unsigned char **)&cmd->SCp.ptr);
+                                       spin_lock_irq(&hostdata->lock);
+                               }
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
                                /* if we had intended to dma that command clear it */
                                if (sun3_dma_setup_done == cmd)
@@ -2105,162 +1998,64 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                        case PHASE_MSGIN:
                                len = 1;
                                data = &tmp;
-                               NCR5380_write(SELECT_ENABLE_REG, 0);    /* disable reselects */
                                NCR5380_transfer_pio(instance, &phase, &len, &data);
                                cmd->SCp.Message = tmp;
 
                                switch (tmp) {
-                               /*
-                                * Linking lets us reduce the time required to get the
-                                * next command out to the device, hopefully this will
-                                * mean we don't waste another revolution due to the delays
-                                * required by ARBITRATION and another SELECTION.
-                                *
-                                * In the current implementation proposal, low level drivers
-                                * merely have to start the next command, pointed to by
-                                * next_link, done() is called as with unlinked commands.
-                                */
-#ifdef LINKED
-                               case LINKED_CMD_COMPLETE:
-                               case LINKED_FLG_CMD_COMPLETE:
-                                       /* Accept message by clearing ACK */
-                                       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-                                       dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked command "
-                                                  "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
-
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                                       /*
-                                        * Sanity check : A linked command should only terminate
-                                        * with one of these messages if there are more linked
-                                        * commands available.
-                                        */
-
-                                       if (!cmd->next_link) {
-                                                printk(KERN_NOTICE "scsi%d: target %d lun %llu "
-                                                       "linked command complete, no next_link\n",
-                                                       HOSTNO, cmd->device->id, cmd->device->lun);
-                                               sink = 1;
-                                               do_abort(instance);
-                                               return;
-                                       }
-
-                                       initialize_SCp(cmd->next_link);
-                                       /* The next command is still part of this process; copy it
-                                        * and don't free it! */
-                                       cmd->next_link->tag = cmd->tag;
-                                       cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-                                       dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked request "
-                                                  "done, calling scsi_done().\n",
-                                                  HOSTNO, cmd->device->id, cmd->device->lun);
-                                       cmd->scsi_done(cmd);
-                                       cmd = hostdata->connected;
-                                       break;
-#endif /* def LINKED */
                                case ABORT:
                                case COMMAND_COMPLETE:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
-                                                 "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
+                                       dsprintk(NDEBUG_QUEUES, instance,
+                                                "COMMAND COMPLETE %p target %d lun %llu\n",
+                                                cmd, scmd_id(cmd), cmd->device->lun);
 
-                                       local_irq_save(flags);
-                                       hostdata->retain_dma_intr++;
                                        hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
                                        cmd_free_tag(cmd);
                                        if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-                                               /* Turn a QUEUE FULL status into BUSY, I think the
-                                                * mid level cannot handle QUEUE FULL :-( (The
-                                                * command is retried after BUSY). Also update our
-                                                * queue size to the number of currently issued
-                                                * commands now.
-                                                */
-                                               /* ++Andreas: the mid level code knows about
-                                                  QUEUE_FULL now. */
-                                               struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun];
-                                               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
-                                                          "QUEUE_FULL after %d commands\n",
-                                                          HOSTNO, cmd->device->id, cmd->device->lun,
-                                                          ta->nr_allocated);
+                                               u8 lun = cmd->device->lun;
+                                               struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
+
+                                               dsprintk(NDEBUG_TAGS, instance,
+                                                        "QUEUE_FULL %p target %d lun %d nr_allocated %d\n",
+                                                        cmd, scmd_id(cmd), lun, ta->nr_allocated);
                                                if (ta->queue_size > ta->nr_allocated)
-                                                       ta->nr_allocated = ta->queue_size;
+                                                       ta->queue_size = ta->nr_allocated;
                                        }
-#else
-                                       hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-
-                                       /*
-                                        * I'm not sure what the correct thing to do here is :
-                                        *
-                                        * If the command that just executed is NOT a request
-                                        * sense, the obvious thing to do is to set the result
-                                        * code to the values of the stored parameters.
-                                        *
-                                        * If it was a REQUEST SENSE command, we need some way to
-                                        * differentiate between the failure code of the original
-                                        * and the failure code of the REQUEST sense - the obvious
-                                        * case is success, where we fall through and leave the
-                                        * result code unchanged.
-                                        *
-                                        * The non-obvious place is where the REQUEST SENSE failed
-                                        */
-
-                                       if (cmd->cmnd[0] != REQUEST_SENSE)
-                                               cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-                                       else if (status_byte(cmd->SCp.Status) != GOOD)
-                                               cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-                                       if ((cmd->cmnd[0] == REQUEST_SENSE) &&
-                                               hostdata->ses.cmd_len) {
-                                               scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-                                               hostdata->ses.cmd_len = 0 ;
-                                       }
-
-                                       if ((cmd->cmnd[0] != REQUEST_SENSE) &&
-                                           (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
-                                               scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-                                               dprintk(NDEBUG_AUTOSENSE, "scsi%d: performing request sense\n", HOSTNO);
-
-                                               LIST(cmd,hostdata->issue_queue);
-                                               SET_NEXT(cmd, hostdata->issue_queue);
-                                               hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-                                               dprintk(NDEBUG_QUEUES, "scsi%d: REQUEST SENSE added to head of "
-                                                         "issue queue\n", H_NO(cmd));
-                                       } else {
-                                               cmd->scsi_done(cmd);
+                                       cmd->result &= ~0xffff;
+                                       cmd->result |= cmd->SCp.Status;
+                                       cmd->result |= cmd->SCp.Message << 8;
+
+                                       if (cmd->cmnd[0] == REQUEST_SENSE)
+                                               complete_cmd(instance, cmd);
+                                       else {
+                                               if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION ||
+                                                   cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) {
+                                                       dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n",
+                                                                cmd);
+                                                       list_add_tail(&ncmd->list,
+                                                                     &hostdata->autosense);
+                                               } else
+                                                       complete_cmd(instance, cmd);
                                        }
 
-                                       local_irq_restore(flags);
-
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        /*
                                         * Restore phase bits to 0 so an interrupted selection,
                                         * arbitration can resume.
                                         */
                                        NCR5380_write(TARGET_COMMAND_REG, 0);
 
-                                       while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-                                               barrier();
+                                       /* Enable reselect interrupts */
+                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
-                                       local_irq_save(flags);
-                                       hostdata->retain_dma_intr--;
-                                       /* ++roman: For Falcon SCSI, release the lock on the
-                                        * ST-DMA here if no other commands are waiting on the
-                                        * disconnected queue.
-                                        */
                                        maybe_release_dma_irq(instance);
-                                       local_irq_restore(flags);
                                        return;
                                case MESSAGE_REJECT:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        switch (hostdata->last_message) {
                                        case HEAD_OF_QUEUE_TAG:
                                        case ORDERED_QUEUE_TAG:
@@ -2274,27 +2069,20 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                                cmd->device->tagged_supported = 0;
                                                hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
                                                cmd->tag = TAG_NONE;
-                                               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected "
-                                                          "QUEUE_TAG message; tagged queuing "
-                                                          "disabled\n",
-                                                          HOSTNO, cmd->device->id, cmd->device->lun);
+                                               dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n",
+                                                        scmd_id(cmd), cmd->device->lun);
                                                break;
                                        }
                                        break;
                                case DISCONNECT:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       local_irq_save(flags);
-                                       cmd->device->disconnect = 1;
-                                       LIST(cmd,hostdata->disconnected_queue);
-                                       SET_NEXT(cmd, hostdata->disconnected_queue);
                                        hostdata->connected = NULL;
-                                       hostdata->disconnected_queue = cmd;
-                                       local_irq_restore(flags);
-                                       dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
-                                                 "moved from connected to the "
-                                                 "disconnected_queue\n", HOSTNO,
-                                                 cmd->device->id, cmd->device->lun);
+                                       list_add(&ncmd->list, &hostdata->disconnected);
+                                       dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
+                                                instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
+                                                cmd, scmd_id(cmd), cmd->device->lun);
+
                                        /*
                                         * Restore phase bits to 0 so an interrupted selection,
                                         * arbitration can resume.
@@ -2303,9 +2091,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 
                                        /* Enable reselect interrupts */
                                        NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-                                       /* Wait for bus free to avoid nasty timeouts */
-                                       while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-                                               barrier();
 #ifdef SUN3_SCSI_VME
                                        dregs->csr |= CSR_DMA_ENABLE;
 #endif
@@ -2324,37 +2109,30 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                case RESTORE_POINTERS:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        break;
                                case EXTENDED_MESSAGE:
                                        /*
-                                        * Extended messages are sent in the following format :
-                                        * Byte
-                                        * 0            EXTENDED_MESSAGE == 1
-                                        * 1            length (includes one byte for code, doesn't
-                                        *              include first two bytes)
-                                        * 2            code
-                                        * 3..length+1  arguments
-                                        *
-                                        * Start the extended message buffer with the EXTENDED_MESSAGE
+                                        * Start the message buffer with the EXTENDED_MESSAGE
                                         * byte, since spi_print_msg() wants the whole thing.
                                         */
                                        extended_msg[0] = EXTENDED_MESSAGE;
                                        /* Accept first byte by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
-                                       dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
+                                       spin_unlock_irq(&hostdata->lock);
+
+                                       dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
 
                                        len = 2;
                                        data = extended_msg + 1;
                                        phase = PHASE_MSGIN;
                                        NCR5380_transfer_pio(instance, &phase, &len, &data);
-                                       dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
-                                                  (int)extended_msg[1], (int)extended_msg[2]);
+                                       dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
+                                                (int)extended_msg[1],
+                                                (int)extended_msg[2]);
 
-                                       if (!len && extended_msg[1] <=
-                                           (sizeof(extended_msg) - 1)) {
+                                       if (!len && extended_msg[1] > 0 &&
+                                           extended_msg[1] <= sizeof(extended_msg) - 2) {
                                                /* Accept third byte by clearing ACK */
                                                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                                                len = extended_msg[1] - 1;
@@ -2362,8 +2140,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                                phase = PHASE_MSGIN;
 
                                                NCR5380_transfer_pio(instance, &phase, &len, &data);
-                                               dprintk(NDEBUG_EXTENDED, "scsi%d: message received, residual %d\n",
-                                                          HOSTNO, len);
+                                               dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+                                                        len);
 
                                                switch (extended_msg[2]) {
                                                case EXTENDED_SDTR:
@@ -2373,15 +2151,18 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                                        tmp = 0;
                                                }
                                        } else if (len) {
-                                               printk(KERN_NOTICE "scsi%d: error receiving "
-                                                      "extended message\n", HOSTNO);
+                                               shost_printk(KERN_ERR, instance, "error receiving extended message\n");
                                                tmp = 0;
                                        } else {
-                                               printk(KERN_NOTICE "scsi%d: extended message "
-                                                          "code %02x length %d is too long\n",
-                                                          HOSTNO, extended_msg[2], extended_msg[1]);
+                                               shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
+                                                            extended_msg[2], extended_msg[1]);
                                                tmp = 0;
                                        }
+
+                                       spin_lock_irq(&hostdata->lock);
+                                       if (!hostdata->connected)
+                                               return;
+
                                        /* Fall through to reject message */
 
                                        /*
@@ -2390,8 +2171,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                         */
                                default:
                                        if (!tmp) {
-                                               printk(KERN_INFO "scsi%d: rejecting message ",
-                                                      instance->host_no);
+                                               shost_printk(KERN_ERR, instance, "rejecting message ");
                                                spi_print_msg(extended_msg);
                                                printk("\n");
                                        } else if (tmp != EXTENDED_MESSAGE)
@@ -2414,18 +2194,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                hostdata->last_message = msgout;
                                NCR5380_transfer_pio(instance, &phase, &len, &data);
                                if (msgout == ABORT) {
-                                       local_irq_save(flags);
-#ifdef SUPPORT_TAGS
-                                       cmd_free_tag(cmd);
-#else
-                                       hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
                                        hostdata->connected = NULL;
                                        cmd->result = DID_ERROR << 16;
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+                                       complete_cmd(instance, cmd);
                                        maybe_release_dma_irq(instance);
-                                       local_irq_restore(flags);
-                                       cmd->scsi_done(cmd);
+                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        return;
                                }
                                msgout = NOP;
@@ -2447,22 +2220,25 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                cmd->SCp.Status = tmp;
                                break;
                        default:
-                               printk("scsi%d: unknown phase\n", HOSTNO);
+                               shost_printk(KERN_ERR, instance, "unknown phase\n");
                                NCR5380_dprint(NDEBUG_ANY, instance);
                        } /* switch(phase) */
-               } /* if (tmp * SR_REQ) */
-       } /* while (1) */
+               } else {
+                       spin_unlock_irq(&hostdata->lock);
+                       NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+                       spin_lock_irq(&hostdata->lock);
+               }
+       }
 }
 
 /*
  * Function : void NCR5380_reselect (struct Scsi_Host *instance)
  *
  * Purpose : does reselection, initializing the instance->connected
- *     field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
- *     nexus has been reestablished,
+ * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
+ * nexus has been reestablished,
  *
  * Inputs : instance - this instance of the NCR5380.
- *
  */
 
 
@@ -2471,7 +2247,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 
 static void NCR5380_reselect(struct Scsi_Host *instance)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char target_mask;
        unsigned char lun;
 #ifdef SUPPORT_TAGS
@@ -2480,7 +2256,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
        unsigned char msg[3];
        int __maybe_unused len;
        unsigned char __maybe_unused *data, __maybe_unused phase;
-       struct scsi_cmnd *tmp = NULL, *prev;
+       struct NCR5380_cmd *ncmd;
+       struct scsi_cmnd *tmp;
 
        /*
         * Disable arbitration, etc. since the host adapter obviously
@@ -2488,11 +2265,10 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
         */
 
        NCR5380_write(MODE_REG, MR_BASE);
-       hostdata->restart_select = 1;
 
        target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 
-       dprintk(NDEBUG_RESELECTION, "scsi%d: reselect\n", HOSTNO);
+       dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
 
        /*
         * At this point, we have detected that our SCSI ID is on the bus,
@@ -2504,17 +2280,22 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
         */
 
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-       while (NCR5380_read(STATUS_REG) & SR_SEL)
-               ;
+       if (NCR5380_poll_politely(instance,
+                                 STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
+               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+               return;
+       }
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
        /*
         * Wait for target to go into MSGIN.
         */
 
-       while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-               ;
+       if (NCR5380_poll_politely(instance,
+                                 STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+               do_abort(instance);
+               return;
+       }
 
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
        /* acknowledge toggle to MSGIN */
@@ -2527,15 +2308,21 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
        data = msg;
        phase = PHASE_MSGIN;
        NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+       if (len) {
+               do_abort(instance);
+               return;
+       }
 #endif
 
        if (!(msg[0] & 0x80)) {
-               printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
+               shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
                spi_print_msg(msg);
+               printk("\n");
                do_abort(instance);
                return;
        }
-       lun = (msg[0] & 0x07);
+       lun = msg[0] & 0x07;
 
 #if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3)
        /* If the phase is still MSGIN, the target wants to send some more
@@ -2551,8 +2338,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
                if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
                    msg[1] == SIMPLE_QUEUE_TAG)
                        tag = msg[2];
-               dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at "
-                          "reselection\n", HOSTNO, target_mask, lun, tag);
+               dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n",
+                        target_mask, lun, tag);
        }
 #endif
 
@@ -2561,36 +2348,34 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
         * just reestablished, and remove it from the disconnected queue.
         */
 
-       for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
-            tmp; prev = tmp, tmp = NEXT(tmp)) {
-               if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
+       tmp = NULL;
+       list_for_each_entry(ncmd, &hostdata->disconnected, list) {
+               struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+               if (target_mask == (1 << scmd_id(cmd)) &&
+                   lun == (u8)cmd->device->lun
 #ifdef SUPPORT_TAGS
-                   && (tag == tmp->tag)
+                   && (tag == cmd->tag)
 #endif
                    ) {
-                       if (prev) {
-                               REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
-                               SET_NEXT(prev, NEXT(tmp));
-                       } else {
-                               REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
-                               hostdata->disconnected_queue = NEXT(tmp);
-                       }
-                       SET_NEXT(tmp, NULL);
+                       list_del(&ncmd->list);
+                       tmp = cmd;
                        break;
                }
        }
 
-       if (!tmp) {
-               printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d "
-#ifdef SUPPORT_TAGS
-                      "tag %d "
-#endif
-                      "not in disconnected_queue.\n",
-                      HOSTNO, target_mask, lun
+       if (tmp) {
+               dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+                        "reselect: removed %p from disconnected queue\n", tmp);
+       } else {
+
 #ifdef SUPPORT_TAGS
-                      , tag
+               shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n",
+                            target_mask, lun, tag);
+#else
+               shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
+                            target_mask, lun);
 #endif
-                       );
                /*
                 * Since we have an established nexus that we can't do anything
                 * with, we must abort it.
@@ -2614,7 +2399,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
                }
                /* setup this command for dma if not already */
                if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) {
-                       sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request));
+                       sun3scsi_dma_setup(instance, d, count,
+                                          rq_data_dir(tmp->request));
                        sun3_dma_setup_done = tmp;
                }
        }
@@ -2639,235 +2425,196 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
                if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
                    msg[1] == SIMPLE_QUEUE_TAG)
                        tag = msg[2];
-               dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at reselection\n"
-                       HOSTNO, target_mask, lun, tag);
+               dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n"
+                        target_mask, lun, tag);
        }
 #endif
 
        hostdata->connected = tmp;
-       dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
-                  HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
+       dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+                scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
- *
- * Purpose : abort a command
- *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- *     host byte of the result field to, if zero DID_ABORTED is
- *     used.
- *
- * Returns : SUCCESS - success, FAILED on failure.
- *
- * XXX - there is no way to abort the command that is currently
- *      connected, you have to wait for it to complete.  If this is
- *      a problem, we could implement longjmp() / setjmp(), setjmp()
- *      called where the loop started in NCR5380_main().
+/**
+ * list_find_cmd - test for presence of a command in a linked list
+ * @haystack: list of commands
+ * @needle: command to search for
  */
 
-static
-int NCR5380_abort(struct scsi_cmnd *cmd)
+static bool list_find_cmd(struct list_head *haystack,
+                          struct scsi_cmnd *needle)
 {
-       struct Scsi_Host *instance = cmd->device->host;
-       SETUP_HOSTDATA(instance);
-       struct scsi_cmnd *tmp, **prev;
-       unsigned long flags;
+       struct NCR5380_cmd *ncmd;
 
-       scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
+       list_for_each_entry(ncmd, haystack, list)
+               if (NCR5380_to_scmd(ncmd) == needle)
+                       return true;
+       return false;
+}
 
-       NCR5380_print_status(instance);
+/**
+ * list_remove_cmd - remove a command from linked list
+ * @haystack: list of commands
+ * @needle: command to remove
+ */
 
-       local_irq_save(flags);
+static bool list_del_cmd(struct list_head *haystack,
+                         struct scsi_cmnd *needle)
+{
+       if (list_find_cmd(haystack, needle)) {
+               struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle);
 
-       dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
-                   NCR5380_read(BUS_AND_STATUS_REG),
-                   NCR5380_read(STATUS_REG));
+               list_del(&ncmd->list);
+               return true;
+       }
+       return false;
+}
 
-#if 1
-       /*
-        * Case 1 : If the command is the currently executing command,
-        * we'll set the aborted flag and return control so that
-        * information transfer routine can exit cleanly.
-        */
+/**
+ * NCR5380_abort - scsi host eh_abort_handler() method
+ * @cmd: the command to be aborted
+ *
+ * Try to abort a given command by removing it from queues and/or sending
+ * the target an abort message. This may not succeed in causing a target
+ * to abort the command. Nonetheless, the low-level driver must forget about
+ * the command because the mid-layer reclaims it and it may be re-issued.
+ *
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
+ *
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
+ *
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * If cmd was not found at all then presumably it has already been completed,
+ * in which case return SUCCESS to try to avoid further EH measures.
+ * If the command has not completed yet, we must not fail to find it.
+ */
 
-       if (hostdata->connected == cmd) {
+static int NCR5380_abort(struct scsi_cmnd *cmd)
+{
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       unsigned long flags;
+       int result = SUCCESS;
 
-               dprintk(NDEBUG_ABORT, "scsi%d: aborting connected command\n", HOSTNO);
-               /*
-                * We should perform BSY checking, and make sure we haven't slipped
-                * into BUS FREE.
-                */
+       spin_lock_irqsave(&hostdata->lock, flags);
 
-               /*      NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */
-               /*
-                * Since we can't change phases until we've completed the current
-                * handshake, we have to source or sink a byte of data if the current
-                * phase is not MSGOUT.
-                */
+#if (NDEBUG & NDEBUG_ANY)
+       scmd_printk(KERN_INFO, cmd, __func__);
+#endif
+       NCR5380_dprint(NDEBUG_ANY, instance);
+       NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-               /*
-                * Return control to the executing NCR drive so we can clear the
-                * aborted flag and get back into our main loop.
-                */
+       if (list_del_cmd(&hostdata->unissued, cmd)) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: removed %p from issue queue\n", cmd);
+               cmd->result = DID_ABORT << 16;
+               cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
+       }
 
-               if (do_abort(instance) == 0) {
-                       hostdata->aborted = 1;
-                       hostdata->connected = NULL;
-                       cmd->result = DID_ABORT << 16;
-#ifdef SUPPORT_TAGS
-                       cmd_free_tag(cmd);
-#else
-                       hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-                       maybe_release_dma_irq(instance);
-                       local_irq_restore(flags);
-                       cmd->scsi_done(cmd);
-                       return SUCCESS;
-               } else {
-                       local_irq_restore(flags);
-                       printk("scsi%d: abort of connected command failed!\n", HOSTNO);
-                       return FAILED;
-               }
+       if (hostdata->selecting == cmd) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: cmd %p == selecting\n", cmd);
+               hostdata->selecting = NULL;
+               cmd->result = DID_ABORT << 16;
+               complete_cmd(instance, cmd);
+               goto out;
        }
-#endif
 
-       /*
-        * Case 2 : If the command hasn't been issued yet, we simply remove it
-        *          from the issue queue.
-        */
-       for (prev = (struct scsi_cmnd **)&(hostdata->issue_queue),
-            tmp = (struct scsi_cmnd *)hostdata->issue_queue;
-            tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
-               if (cmd == tmp) {
-                       REMOVE(5, *prev, tmp, NEXT(tmp));
-                       (*prev) = NEXT(tmp);
-                       SET_NEXT(tmp, NULL);
-                       tmp->result = DID_ABORT << 16;
-                       maybe_release_dma_irq(instance);
-                       local_irq_restore(flags);
-                       dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
-                                   HOSTNO);
-                       /* Tagged queuing note: no tag to free here, hasn't been assigned
-                        * yet... */
-                       tmp->scsi_done(tmp);
-                       return SUCCESS;
+       if (list_del_cmd(&hostdata->disconnected, cmd)) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: removed %p from disconnected list\n", cmd);
+               cmd->result = DID_ERROR << 16;
+               if (!hostdata->connected)
+                       NCR5380_select(instance, cmd);
+               if (hostdata->connected != cmd) {
+                       complete_cmd(instance, cmd);
+                       result = FAILED;
+                       goto out;
                }
        }
 
-       /*
-        * Case 3 : If any commands are connected, we're going to fail the abort
-        *          and let the high level SCSI driver retry at a later time or
-        *          issue a reset.
-        *
-        *          Timeouts, and therefore aborted commands, will be highly unlikely
-        *          and handling them cleanly in this situation would make the common
-        *          case of noresets less efficient, and would pollute our code.  So,
-        *          we fail.
-        */
+       if (hostdata->connected == cmd) {
+               dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+               hostdata->connected = NULL;
+               if (do_abort(instance)) {
+                       set_host_byte(cmd, DID_ERROR);
+                       complete_cmd(instance, cmd);
+                       result = FAILED;
+                       goto out;
+               }
+               set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+               hostdata->dma_len = 0;
+#endif
+               if (cmd->cmnd[0] == REQUEST_SENSE)
+                       complete_cmd(instance, cmd);
+               else {
+                       struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
-       if (hostdata->connected) {
-               local_irq_restore(flags);
-               dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
-               return FAILED;
+                       /* Perform autosense for this command */
+                       list_add(&ncmd->list, &hostdata->autosense);
+               }
        }
 
-       /*
-        * Case 4: If the command is currently disconnected from the bus, and
-        *      there are no connected commands, we reconnect the I_T_L or
-        *      I_T_L_Q nexus associated with it, go into message out, and send
-        *      an abort message.
-        *
-        * This case is especially ugly. In order to reestablish the nexus, we
-        * need to call NCR5380_select().  The easiest way to implement this
-        * function was to abort if the bus was busy, and let the interrupt
-        * handler triggered on the SEL for reselect take care of lost arbitrations
-        * where necessary, meaning interrupts need to be enabled.
-        *
-        * When interrupts are enabled, the queues may change - so we
-        * can't remove it from the disconnected queue before selecting it
-        * because that could cause a failure in hashing the nexus if that
-        * device reselected.
-        *
-        * Since the queues may change, we can't use the pointers from when we
-        * first locate it.
-        *
-        * So, we must first locate the command, and if NCR5380_select()
-        * succeeds, then issue the abort, relocate the command and remove
-        * it from the disconnected queue.
-        */
-
-       for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
-            tmp = NEXT(tmp)) {
-               if (cmd == tmp) {
-                       local_irq_restore(flags);
-                       dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
-
-                       if (NCR5380_select(instance, cmd))
-                               return FAILED;
-
-                       dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
-
-                       do_abort(instance);
-
-                       local_irq_save(flags);
-                       for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
-                            tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
-                            tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
-                               if (cmd == tmp) {
-                                       REMOVE(5, *prev, tmp, NEXT(tmp));
-                                       *prev = NEXT(tmp);
-                                       SET_NEXT(tmp, NULL);
-                                       tmp->result = DID_ABORT << 16;
-                                       /* We must unlock the tag/LUN immediately here, since the
-                                        * target goes to BUS FREE and doesn't send us another
-                                        * message (COMMAND_COMPLETE or the like)
-                                        */
-#ifdef SUPPORT_TAGS
-                                       cmd_free_tag(tmp);
-#else
-                                       hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-                                       maybe_release_dma_irq(instance);
-                                       local_irq_restore(flags);
-                                       tmp->scsi_done(tmp);
-                                       return SUCCESS;
-                               }
-                       }
+       if (list_find_cmd(&hostdata->autosense, cmd)) {
+               dsprintk(NDEBUG_ABORT, instance,
+                        "abort: found %p on sense queue\n", cmd);
+               spin_unlock_irqrestore(&hostdata->lock, flags);
+               queue_work(hostdata->work_q, &hostdata->main_task);
+               msleep(1000);
+               spin_lock_irqsave(&hostdata->lock, flags);
+               if (list_del_cmd(&hostdata->autosense, cmd)) {
+                       dsprintk(NDEBUG_ABORT, instance,
+                                "abort: removed %p from sense queue\n", cmd);
+                       set_host_byte(cmd, DID_ABORT);
+                       complete_cmd(instance, cmd);
+                       goto out;
                }
        }
 
-       /* Maybe it is sufficient just to release the ST-DMA lock... (if
-        * possible at all) At least, we should check if the lock could be
-        * released after the abort, in case it is kept due to some bug.
-        */
-       maybe_release_dma_irq(instance);
-       local_irq_restore(flags);
+       if (hostdata->connected == cmd) {
+               dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+               hostdata->connected = NULL;
+               if (do_abort(instance)) {
+                       set_host_byte(cmd, DID_ERROR);
+                       complete_cmd(instance, cmd);
+                       result = FAILED;
+                       goto out;
+               }
+               set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+               hostdata->dma_len = 0;
+#endif
+               complete_cmd(instance, cmd);
+       }
 
-       /*
-        * Case 5 : If we reached this point, the command was not found in any of
-        *          the queues.
-        *
-        * We probably reached this point because of an unlikely race condition
-        * between the command completing successfully and the abortion code,
-        * so we won't panic, but we will notify the user in case something really
-        * broke.
-        */
+out:
+       if (result == FAILED)
+               dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd);
+       else
+               dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
 
-       printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
+       queue_work(hostdata->work_q, &hostdata->main_task);
+       maybe_release_dma_irq(instance);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
-       return FAILED;
+       return result;
 }
 
 
-/*
- * Function : int NCR5380_reset (struct scsi_cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS or FAILURE
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
@@ -2876,23 +2623,22 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int i;
        unsigned long flags;
+       struct NCR5380_cmd *ncmd;
 
-       NCR5380_print_status(instance);
+       spin_lock_irqsave(&hostdata->lock, flags);
+
+#if (NDEBUG & NDEBUG_ANY)
+       scmd_printk(KERN_INFO, cmd, __func__);
+#endif
+       NCR5380_dprint(NDEBUG_ANY, instance);
+       NCR5380_dprint_phase(NDEBUG_ANY, instance);
+
+       do_reset(instance);
 
-       /* get in phase */
-       NCR5380_write(TARGET_COMMAND_REG,
-                     PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-       /* assert RST */
-       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-       udelay(40);
        /* reset NCR registers */
-       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        NCR5380_write(MODE_REG, MR_BASE);
        NCR5380_write(TARGET_COMMAND_REG, 0);
        NCR5380_write(SELECT_ENABLE_REG, 0);
-       /* ++roman: reset interrupt condition! otherwise no interrupts don't get
-        * through anymore ... */
-       (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
        /* After the reset, there are no more connected or disconnected commands
         * and no busy units; so clear the low-level status here to avoid
@@ -2900,17 +2646,34 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
         * commands!
         */
 
-       if (hostdata->issue_queue)
-               dprintk(NDEBUG_ABORT, "scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
-       if (hostdata->connected)
-               dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd));
-       if (hostdata->disconnected_queue)
-               dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
+       hostdata->selecting = NULL;
+
+       list_for_each_entry(ncmd, &hostdata->disconnected, list) {
+               struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+               set_host_byte(cmd, DID_RESET);
+               cmd->scsi_done(cmd);
+       }
+
+       list_for_each_entry(ncmd, &hostdata->autosense, list) {
+               struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
+
+               set_host_byte(cmd, DID_RESET);
+               cmd->scsi_done(cmd);
+       }
+
+       if (hostdata->connected) {
+               set_host_byte(hostdata->connected, DID_RESET);
+               complete_cmd(instance, hostdata->connected);
+               hostdata->connected = NULL;
+       }
+
+       if (hostdata->sensing) {
+               set_host_byte(hostdata->connected, DID_RESET);
+               complete_cmd(instance, hostdata->sensing);
+               hostdata->sensing = NULL;
+       }
 
-       local_irq_save(flags);
-       hostdata->issue_queue = NULL;
-       hostdata->connected = NULL;
-       hostdata->disconnected_queue = NULL;
 #ifdef SUPPORT_TAGS
        free_all_tags(hostdata);
 #endif
@@ -2920,8 +2683,9 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
        hostdata->dma_len = 0;
 #endif
 
+       queue_work(hostdata->work_q, &hostdata->main_task);
        maybe_release_dma_irq(instance);
-       local_irq_restore(flags);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
        return SUCCESS;
 }
index 5ede3da..78d1b29 100644 (file)
@@ -66,7 +66,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -98,7 +97,6 @@
 
 #define NCR5380_queue_command           atari_scsi_queue_command
 #define NCR5380_abort                   atari_scsi_abort
-#define NCR5380_show_info               atari_scsi_show_info
 #define NCR5380_info                    atari_scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
@@ -161,23 +159,10 @@ static inline unsigned long SCSI_DMA_GETADR(void)
        return adr;
 }
 
-#define HOSTDATA_DMALEN                (((struct NCR5380_hostdata *) \
-                               (atari_scsi_host->hostdata))->dma_len)
-
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-#define        AFTER_RESET_DELAY       (HZ/2)
-#else
-#define        AFTER_RESET_DELAY       (5*HZ/2)
-#endif
-
 #ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
 #endif
 
-static struct Scsi_Host *atari_scsi_host;
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
 static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
 
@@ -208,12 +193,12 @@ static int setup_cmd_per_lun = -1;
 module_param(setup_cmd_per_lun, int, 0);
 static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
-#ifdef SUPPORT_TAGS
 static int setup_use_tagged_queuing = -1;
 module_param(setup_use_tagged_queuing, int, 0);
-#endif
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
 
 
 #if defined(REAL_DMA)
@@ -273,15 +258,17 @@ static void scsi_dma_buserr(int irq, void *dummy)
 #endif
 
 
-static irqreturn_t scsi_tt_intr(int irq, void *dummy)
+static irqreturn_t scsi_tt_intr(int irq, void *dev)
 {
 #ifdef REAL_DMA
+       struct Scsi_Host *instance = dev;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int dma_stat;
 
        dma_stat = tt_scsi_dma.dma_ctrl;
 
-       dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n",
-                  atari_scsi_host->host_no, dma_stat & 0xff);
+       dsprintk(NDEBUG_INTR, instance, "NCR5380 interrupt, DMA status = %02x\n",
+                dma_stat & 0xff);
 
        /* Look if it was the DMA that has interrupted: First possibility
         * is that a bus error occurred...
@@ -304,7 +291,8 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
         * data reg!
         */
        if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
-               atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
+               atari_dma_residual = hostdata->dma_len -
+                       (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
 
                dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
                           atari_dma_residual);
@@ -356,15 +344,17 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
 
 #endif /* REAL_DMA */
 
-       NCR5380_intr(irq, dummy);
+       NCR5380_intr(irq, dev);
 
        return IRQ_HANDLED;
 }
 
 
-static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
+static irqreturn_t scsi_falcon_intr(int irq, void *dev)
 {
 #ifdef REAL_DMA
+       struct Scsi_Host *instance = dev;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int dma_stat;
 
        /* Turn off DMA and select sector counter register before
@@ -399,7 +389,7 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
                        printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
                               "ST-DMA fifo\n", transferred & 15);
 
-               atari_dma_residual = HOSTDATA_DMALEN - transferred;
+               atari_dma_residual = hostdata->dma_len - transferred;
                dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
                           atari_dma_residual);
        } else
@@ -411,13 +401,14 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
                 * data to the original destination address.
                 */
                memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
-                      HOSTDATA_DMALEN - atari_dma_residual);
+                      hostdata->dma_len - atari_dma_residual);
                atari_dma_orig_addr = NULL;
        }
 
 #endif /* REAL_DMA */
 
-       NCR5380_intr(irq, dummy);
+       NCR5380_intr(irq, dev);
+
        return IRQ_HANDLED;
 }
 
@@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char *str)
         * Defaults depend on TT or Falcon, determined at run time.
         * Negative values mean don't change.
         */
-       int ints[6];
+       int ints[8];
 
        get_options(str, ARRAY_SIZE(ints), ints);
 
@@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char *str)
                setup_sg_tablesize = ints[3];
        if (ints[0] >= 4)
                setup_hostid = ints[4];
-#ifdef SUPPORT_TAGS
        if (ints[0] >= 5)
                setup_use_tagged_queuing = ints[5];
-#endif
+       /* ints[6] (use_pdma) is ignored */
+       if (ints[0] >= 7)
+               setup_toshiba_delay = ints[7];
 
        return 1;
 }
@@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
 
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-static void __init atari_scsi_reset_boot(void)
-{
-       unsigned long end;
-
-       /*
-        * Do a SCSI reset to clean up the bus during initialization. No messing
-        * with the queues, interrupts, or locks necessary here.
-        */
-
-       printk("Atari SCSI: resetting the SCSI bus...");
-
-       /* get in phase */
-       NCR5380_write(TARGET_COMMAND_REG,
-                     PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-
-       /* assert RST */
-       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-       /* The min. reset hold time is 25us, so 40us should be enough */
-       udelay(50);
-       /* reset RST and interrupt */
-       NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-       end = jiffies + AFTER_RESET_DELAY;
-       while (time_before(jiffies, end))
-               barrier();
-
-       printk(" done\n");
-}
-#endif
-
 #if defined(REAL_DMA)
 
 static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
@@ -815,14 +775,14 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
 static struct scsi_host_template atari_scsi_template = {
        .module                 = THIS_MODULE,
        .proc_name              = DRV_MODULE_NAME,
-       .show_info              = atari_scsi_show_info,
        .name                   = "Atari native SCSI",
        .info                   = atari_scsi_info,
        .queuecommand           = atari_scsi_queue_command,
        .eh_abort_handler       = atari_scsi_abort,
        .eh_bus_reset_handler   = atari_scsi_bus_reset,
        .this_id                = 7,
-       .use_clustering         = DISABLE_CLUSTERING
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
 };
 
 static int __init atari_scsi_probe(struct platform_device *pdev)
@@ -880,7 +840,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
        } else {
                /* Test if a host id is set in the NVRam */
                if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-                       unsigned char b = nvram_read_byte(14);
+                       unsigned char b = nvram_read_byte(16);
 
                        /* Arbitration enabled? (for TOS)
                         * If yes, use configured host ID
@@ -915,21 +875,18 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
                error = -ENOMEM;
                goto fail_alloc;
        }
-       atari_scsi_host = instance;
-
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-       atari_scsi_reset_boot();
-#endif
 
        instance->irq = irq->start;
 
        host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
-
 #ifdef SUPPORT_TAGS
        host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
 #endif
+       host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-       NCR5380_init(instance, host_flags);
+       error = NCR5380_init(instance, host_flags);
+       if (error)
+               goto fail_init;
 
        if (IS_A_TT()) {
                error = request_irq(instance->irq, scsi_tt_intr, 0,
@@ -975,6 +932,8 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
 #endif
        }
 
+       NCR5380_maybe_reset_bus(instance);
+
        error = scsi_add_host(instance, NULL);
        if (error)
                goto fail_host;
@@ -989,6 +948,7 @@ fail_host:
                free_irq(instance->irq, instance);
 fail_irq:
        NCR5380_exit(instance);
+fail_init:
        scsi_host_put(instance);
 fail_alloc:
        if (atari_dma_buffer)
index 4e7cad2..bad5f32 100644 (file)
@@ -3,6 +3,7 @@ config BE2ISCSI
        depends on PCI && SCSI && NET
        select SCSI_ISCSI_ATTRS
        select ISCSI_BOOT_SYSFS
+       select IRQ_POLL
 
        help
        This driver implements the iSCSI functionality for Emulex
index 77f992e..a41c643 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/pci.h>
 #include <linux/if_vlan.h>
-#include <linux/blk-iopoll.h>
+#include <linux/irq_poll.h>
 #define FW_VER_LEN     32
 #define MCC_Q_LEN      128
 #define MCC_CQ_LEN     256
@@ -101,7 +101,7 @@ struct be_eq_obj {
        struct beiscsi_hba *phba;
        struct be_queue_info *cq;
        struct work_struct work_cqs; /* Work Item */
-       struct blk_iopoll       iopoll;
+       struct irq_poll iopoll;
 };
 
 struct be_mcc_obj {
index b7087ba..022e87b 100644 (file)
@@ -1292,9 +1292,9 @@ static void beiscsi_flush_cq(struct beiscsi_hba *phba)
 
        for (i = 0; i < phba->num_cpus; i++) {
                pbe_eq = &phwi_context->be_eq[i];
-               blk_iopoll_disable(&pbe_eq->iopoll);
+               irq_poll_disable(&pbe_eq->iopoll);
                beiscsi_process_cq(pbe_eq);
-               blk_iopoll_enable(&pbe_eq->iopoll);
+               irq_poll_enable(&pbe_eq->iopoll);
        }
 }
 
index fe0c514..cb9072a 100644 (file)
@@ -910,8 +910,7 @@ static irqreturn_t be_isr_msix(int irq, void *dev_id)
        num_eq_processed = 0;
        while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
                                & EQE_VALID_MASK) {
-               if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
-                       blk_iopoll_sched(&pbe_eq->iopoll);
+               irq_poll_sched(&pbe_eq->iopoll);
 
                AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
                queue_tail_inc(eq);
@@ -972,8 +971,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
                        spin_unlock_irqrestore(&phba->isr_lock, flags);
                        num_mcceq_processed++;
                } else {
-                       if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
-                               blk_iopoll_sched(&pbe_eq->iopoll);
+                       irq_poll_sched(&pbe_eq->iopoll);
                        num_ioeq_processed++;
                }
                AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
@@ -2295,7 +2293,7 @@ void beiscsi_process_all_cqs(struct work_struct *work)
        hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
 }
 
-static int be_iopoll(struct blk_iopoll *iop, int budget)
+static int be_iopoll(struct irq_poll *iop, int budget)
 {
        unsigned int ret;
        struct beiscsi_hba *phba;
@@ -2306,7 +2304,7 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)
        pbe_eq->cq_count += ret;
        if (ret < budget) {
                phba = pbe_eq->phba;
-               blk_iopoll_complete(iop);
+               irq_poll_complete(iop);
                beiscsi_log(phba, KERN_INFO,
                            BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
                            "BM_%d : rearm pbe_eq->q.id =%d\n",
@@ -5293,7 +5291,7 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
 
        for (i = 0; i < phba->num_cpus; i++) {
                pbe_eq = &phwi_context->be_eq[i];
-               blk_iopoll_disable(&pbe_eq->iopoll);
+               irq_poll_disable(&pbe_eq->iopoll);
        }
 
        if (unload_state == BEISCSI_CLEAN_UNLOAD) {
@@ -5579,9 +5577,8 @@ static void beiscsi_eeh_resume(struct pci_dev *pdev)
 
        for (i = 0; i < phba->num_cpus; i++) {
                pbe_eq = &phwi_context->be_eq[i];
-               blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget,
+               irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget,
                                be_iopoll);
-               blk_iopoll_enable(&pbe_eq->iopoll);
        }
 
        i = (phba->msix_enabled) ? i : 0;
@@ -5752,9 +5749,8 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
 
        for (i = 0; i < phba->num_cpus; i++) {
                pbe_eq = &phwi_context->be_eq[i];
-               blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget,
+               irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget,
                                be_iopoll);
-               blk_iopoll_enable(&pbe_eq->iopoll);
        }
 
        i = (phba->msix_enabled) ? i : 0;
@@ -5795,7 +5791,7 @@ free_blkenbld:
        destroy_workqueue(phba->wq);
        for (i = 0; i < phba->num_cpus; i++) {
                pbe_eq = &phwi_context->be_eq[i];
-               blk_iopoll_disable(&pbe_eq->iopoll);
+               irq_poll_disable(&pbe_eq->iopoll);
        }
 free_twq:
        beiscsi_clean_port(phba);
index 0e2bee9..e22a268 100644 (file)
@@ -57,7 +57,7 @@ MODULE_PARM_DESC(cxgb3i_snd_win, "TCP send window in bytes (default=128KB)");
 
 static int cxgb3i_rx_credit_thres = 10 * 1024;
 module_param(cxgb3i_rx_credit_thres, int, 0644);
-MODULE_PARM_DESC(rx_credit_thres,
+MODULE_PARM_DESC(cxgb3i_rx_credit_thres,
                 "RX credits return threshold in bytes (default=10KB)");
 
 static unsigned int cxgb3i_max_connect = 8 * 1024;
index 3e08812..6c14e68 100644 (file)
 
 #define DONT_USE_INTR
 
-#define NCR5380_read(reg)              inb(port + reg)
-#define NCR5380_write(reg, value)      outb(value, port + reg)
+#define NCR5380_read(reg)              inb(instance->io_port + reg)
+#define NCR5380_write(reg, value)      outb(value, instance->io_port + reg)
 
 #define NCR5380_implementation_fields  /* none */
-#define NCR5380_local_declare()                unsigned int port
-#define NCR5380_setup(instance)                port = instance->io_port
-
-/*
- * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
- */
-#include <linux/delay.h>
 
 #include "NCR5380.h"
 #include "NCR5380.c"
@@ -56,6 +49,7 @@
 
 
 static struct scsi_host_template dmx3191d_driver_template = {
+       .module                 = THIS_MODULE,
        .proc_name              = DMX3191D_DRIVER_NAME,
        .name                   = "Domex DMX3191D",
        .info                   = NCR5380_info,
@@ -67,6 +61,8 @@ static struct scsi_host_template dmx3191d_driver_template = {
        .sg_tablesize           = SG_ALL,
        .cmd_per_lun            = 2,
        .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 
 static int dmx3191d_probe_one(struct pci_dev *pdev,
@@ -97,17 +93,25 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
         */
        shost->irq = NO_IRQ;
 
-       NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+       error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
+       if (error)
+               goto out_host_put;
+
+       NCR5380_maybe_reset_bus(shost);
 
        pci_set_drvdata(pdev, shost);
 
        error = scsi_add_host(shost, &pdev->dev);
        if (error)
-               goto out_release_region;
+               goto out_exit;
 
        scsi_scan_host(shost);
        return 0;
 
+out_exit:
+       NCR5380_exit(shost);
+out_host_put:
+       scsi_host_put(shost);
  out_release_region:
        release_region(io, DMX3191D_REGION_LEN);
  out_disable_device:
@@ -119,15 +123,14 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
 static void dmx3191d_remove_one(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
+       unsigned long io = shost->io_port;
 
        scsi_remove_host(shost);
 
        NCR5380_exit(shost);
-
-       release_region(shost->io_port, DMX3191D_REGION_LEN);
-       pci_disable_device(pdev);
-
        scsi_host_put(shost);
+       release_region(io, DMX3191D_REGION_LEN);
+       pci_disable_device(pdev);
 }
 
 static struct pci_device_id dmx3191d_pci_tbl[] = {
index 4c74c7b..6c736b0 100644 (file)
@@ -1,9 +1,5 @@
-
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define UNSAFE                 /* Leave interrupts enabled during pseudo-dma I/O */
-#define DMA_WORKS_RIGHT
-
 
 /*
  * DTC 3180/3280 driver, by
 
 
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <scsi/scsi_host.h>
+
 #include "dtc.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
@@ -150,7 +144,7 @@ static const struct signature {
 
 static int __init dtc_setup(char *str)
 {
-       static int commandline_current = 0;
+       static int commandline_current;
        int i;
        int ints[10];
 
@@ -188,7 +182,7 @@ __setup("dtc=", dtc_setup);
 
 static int __init dtc_detect(struct scsi_host_template * tpnt)
 {
-       static int current_override = 0, current_base = 0;
+       static int current_override, current_base;
        struct Scsi_Host *instance;
        unsigned int addr;
        void __iomem *base;
@@ -205,9 +199,8 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
                                addr = 0;
                } else
                        for (; !addr && (current_base < NO_BASES); ++current_base) {
-#if (DTCDEBUG & DTCDEBUG_INIT)
-                               printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
-#endif
+                               dprintk(NDEBUG_INIT, "dtc: probing address 0x%08x\n",
+                                       (unsigned int)bases[current_base].address);
                                if (bases[current_base].noauto)
                                        continue;
                                base = ioremap(bases[current_base].address, 0x2000);
@@ -216,18 +209,14 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
                                for (sig = 0; sig < NO_SIGNATURES; ++sig) {
                                        if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
                                                addr = bases[current_base].address;
-#if (DTCDEBUG & DTCDEBUG_INIT)
-                                               printk(KERN_DEBUG "scsi-dtc : detected board.\n");
-#endif
+                                               dprintk(NDEBUG_INIT, "dtc: detected board\n");
                                                goto found;
                                        }
                                }
                                iounmap(base);
                        }
 
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-               printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
-#endif
+               dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr);
 
                if (!addr)
                        break;
@@ -235,12 +224,15 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
 found:
                instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
                if (instance == NULL)
-                       break;
+                       goto out_unmap;
 
                instance->base = addr;
                ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-               NCR5380_init(instance, 0);
+               if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
+                       goto out_unregister;
+
+               NCR5380_maybe_reset_bus(instance);
 
                NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);  /* Enable int's */
                if (overrides[current_override].irq != IRQ_AUTO)
@@ -271,14 +263,19 @@ found:
                        printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
                instance->irq = NO_IRQ;
 #endif
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-               printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+               dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+                       instance->host_no, instance->irq);
 
                ++current_override;
                ++count;
        }
        return count;
+
+out_unregister:
+       scsi_unregister(instance);
+out_unmap:
+       iounmap(base);
+       return count;
 }
 
 /*
@@ -331,12 +328,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
        unsigned char *d = dst;
        int i;                  /* For counting time spent in the poll-loop */
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
 
        i = 0;
-       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-       NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
        if (instance->irq == NO_IRQ)
                NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
        else
@@ -348,7 +341,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
                while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
                        ++i;
                rtrc(3);
-               memcpy_fromio(d, base + DTC_DATA_BUF, 128);
+               memcpy_fromio(d, hostdata->base + DTC_DATA_BUF, 128);
                d += 128;
                len -= 128;
                rtrc(7);
@@ -358,9 +351,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
        rtrc(4);
        while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
                ++i;
-       NCR5380_write(MODE_REG, 0);     /* Clear the operating mode */
        rtrc(0);
-       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        if (i > hostdata->spin_max_r)
                hostdata->spin_max_r = i;
        return (0);
@@ -383,12 +374,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 {
        int i;
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
 
-       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-       NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
-       /* set direction (write) */
        if (instance->irq == NO_IRQ)
                NCR5380_write(DTC_CONTROL_REG, 0);
        else
@@ -400,7 +386,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
                while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
                        ++i;
                rtrc(3);
-               memcpy_toio(base + DTC_DATA_BUF, src, 128);
+               memcpy_toio(hostdata->base + DTC_DATA_BUF, src, 128);
                src += 128;
                len -= 128;
        }
@@ -413,47 +399,60 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
                ++i;
        rtrc(7);
        /* Check for parity error here. fixme. */
-       NCR5380_write(MODE_REG, 0);     /* Clear the operating mode */
        rtrc(0);
        if (i > hostdata->spin_max_w)
                hostdata->spin_max_w = i;
        return (0);
 }
 
+static int dtc_dma_xfer_len(struct scsi_cmnd *cmd)
+{
+       int transfersize = cmd->transfersize;
+
+       /* Limit transfers to 32K, for xx400 & xx406
+        * pseudoDMA that transfers in 128 bytes blocks.
+        */
+       if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
+           !(cmd->SCp.this_residual % transfersize))
+               transfersize = 32 * 1024;
+
+       return transfersize;
+}
+
 MODULE_LICENSE("GPL");
 
 #include "NCR5380.c"
 
 static int dtc_release(struct Scsi_Host *shost)
 {
-       NCR5380_local_declare();
-       NCR5380_setup(shost);
+       struct NCR5380_hostdata *hostdata = shost_priv(shost);
+
        if (shost->irq != NO_IRQ)
                free_irq(shost->irq, shost);
        NCR5380_exit(shost);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
        scsi_unregister(shost);
-       iounmap(base);
+       iounmap(hostdata->base);
        return 0;
 }
 
 static struct scsi_host_template driver_template = {
-       .name                           = "DTC 3180/3280 ",
-       .detect                         = dtc_detect,
-       .release                        = dtc_release,
-       .proc_name                      = "dtc3x80",
-       .show_info                      = dtc_show_info,
-       .write_info                     = dtc_write_info,
-       .info                           = dtc_info,
-       .queuecommand                   = dtc_queue_command,
-       .eh_abort_handler               = dtc_abort,
-       .eh_bus_reset_handler           = dtc_bus_reset,
-       .bios_param                     = dtc_biosparam,
-       .can_queue                      = CAN_QUEUE,
-       .this_id                        = 7,
-       .sg_tablesize                   = SG_ALL,
-       .cmd_per_lun                    = CMD_PER_LUN,
-       .use_clustering                 = DISABLE_CLUSTERING,
+       .name                   = "DTC 3180/3280",
+       .detect                 = dtc_detect,
+       .release                = dtc_release,
+       .proc_name              = "dtc3x80",
+       .show_info              = dtc_show_info,
+       .write_info             = dtc_write_info,
+       .info                   = dtc_info,
+       .queuecommand           = dtc_queue_command,
+       .eh_abort_handler       = dtc_abort,
+       .eh_bus_reset_handler   = dtc_bus_reset,
+       .bios_param             = dtc_biosparam,
+       .can_queue              = 32,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 2,
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 #include "scsi_module.c"
index 78a2332..56732cb 100644 (file)
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#define DTCDEBUG 0
-#define DTCDEBUG_INIT  0x1
-#define DTCDEBUG_TRANSFER 0x2
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
 #define NCR5380_implementation_fields \
     void __iomem *base
 
-#define NCR5380_local_declare() \
-    void __iomem *base
-
-#define NCR5380_setup(instance) \
-    base = ((struct NCR5380_hostdata *)(instance)->hostdata)->base
+#define DTC_address(reg) \
+       (((struct NCR5380_hostdata *)shost_priv(instance))->base + DTC_5380_OFFSET + reg)
 
-#define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
-
-#define dbNCR5380_read(reg)                                              \
-    (rval=readb(DTC_address(reg)), \
-     (((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\
-    , (reg), DTC_address(reg), rval)), rval ) )
-
-#define dbNCR5380_write(reg, value) do {                                  \
-    printk("DTC : write %02x to register %d at address %p\n",         \
-            (value), (reg), DTC_address(reg));     \
-    writeb(value, DTC_address(reg));} while(0)
-
-
-#if !(DTCDEBUG & DTCDEBUG_TRANSFER) 
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
-#else
-#define NCR5380_read(reg) (readb(DTC_address(reg)))
-#define xNCR5380_read(reg)                                             \
-    (((unsigned char) printk("DTC : read register %d at address %p\n"\
-    , (reg), DTC_address(reg))), readb(DTC_address(reg)))
 
-#define NCR5380_write(reg, value) do {                                 \
-    printk("DTC : write %02x to register %d at address %p\n",  \
-           (value), (reg), DTC_address(reg));  \
-    writeb(value, DTC_address(reg));} while(0)
-#endif
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        dtc_dma_xfer_len(cmd)
 
 #define NCR5380_intr                   dtc_intr
 #define NCR5380_queue_command          dtc_queue_command
index f8d2478..90091e6 100644 (file)
  *     
  */
 
-/* settings for DTC3181E card with only Mustek scanner attached */
-#define USLEEP_POLL    msecs_to_jiffies(10)
-#define USLEEP_SLEEP   msecs_to_jiffies(200)
-#define USLEEP_WAITLONG        msecs_to_jiffies(5000)
-
 #define AUTOPROBE_IRQ
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR53C400_PSEUDO_DMA 1
 #define PSEUDO_DMA
-#define NCR53C400
 #endif
 
 #include <asm/io.h>
-#include <linux/signal.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <scsi/scsi_host.h>
 #include "g_NCR5380.h"
 #include "NCR5380.h"
-#include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/isapnp.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
 
-#define NCR_NOT_SET 0
-static int ncr_irq = NCR_NOT_SET;
-static int ncr_dma = NCR_NOT_SET;
-static int ncr_addr = NCR_NOT_SET;
-static int ncr_5380 = NCR_NOT_SET;
-static int ncr_53c400 = NCR_NOT_SET;
-static int ncr_53c400a = NCR_NOT_SET;
-static int dtc_3181e = NCR_NOT_SET;
+static int ncr_irq;
+static int ncr_dma;
+static int ncr_addr;
+static int ncr_5380;
+static int ncr_53c400;
+static int ncr_53c400a;
+static int dtc_3181e;
+static int hp_c2502;
 
 static struct override {
        NCR5380_map_type NCR5380_map_name;
@@ -121,7 +112,7 @@ static struct override {
 
 static void __init internal_setup(int board, char *str, int *ints)
 {
-       static int commandline_current = 0;
+       static int commandline_current;
        switch (board) {
        case BOARD_NCR5380:
                if (ints[0] != 2 && ints[0] != 3) {
@@ -235,6 +226,30 @@ static int __init do_DTC3181E_setup(char *str)
 
 #endif
 
+#ifndef SCSI_G_NCR5380_MEM
+/*
+ * Configure I/O address of 53C400A or DTC436 by writing magic numbers
+ * to ports 0x779 and 0x379.
+ */
+static void magic_configure(int idx, u8 irq, u8 magic[])
+{
+       u8 cfg = 0;
+
+       outb(magic[0], 0x779);
+       outb(magic[1], 0x379);
+       outb(magic[2], 0x379);
+       outb(magic[3], 0x379);
+       outb(magic[4], 0x379);
+
+       /* allowed IRQs for HP C2502 */
+       if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
+               irq = 0;
+       if (idx >= 0 && idx <= 7)
+               cfg = 0x80 | idx | (irq << 4);
+       outb(cfg, 0x379);
+}
+#endif
+
 /**
  *     generic_NCR5380_detect  -       look for NCR5380 controllers
  *     @tpnt: the scsi template
@@ -243,19 +258,18 @@ static int __init do_DTC3181E_setup(char *str)
  *     and DTC436(ISAPnP) controllers. If overrides have been set we use
  *     them.
  *
- *     The caller supplied NCR5380_init function is invoked from here, before
- *     the interrupt line is taken.
- *
  *     Locks: none
  */
 
 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 {
-       static int current_override = 0;
+       static int current_override;
        int count;
        unsigned int *ports;
+       u8 *magic = NULL;
 #ifndef SCSI_G_NCR5380_MEM
        int i;
+       int port_idx = -1;
        unsigned long region_size = 16;
 #endif
        static unsigned int __initdata ncr_53c400a_ports[] = {
@@ -264,27 +278,36 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
        static unsigned int __initdata dtc_3181e_ports[] = {
                0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
        };
-       int flags = 0;
+       static u8 ncr_53c400a_magic[] __initdata = {    /* 53C400A & DTC436 */
+               0x59, 0xb9, 0xc5, 0xae, 0xa6
+       };
+       static u8 hp_c2502_magic[] __initdata = {       /* HP C2502 */
+               0x0f, 0x22, 0xf0, 0x20, 0x80
+       };
+       int flags;
        struct Scsi_Host *instance;
+       struct NCR5380_hostdata *hostdata;
 #ifdef SCSI_G_NCR5380_MEM
        unsigned long base;
        void __iomem *iomem;
 #endif
 
-       if (ncr_irq != NCR_NOT_SET)
+       if (ncr_irq)
                overrides[0].irq = ncr_irq;
-       if (ncr_dma != NCR_NOT_SET)
+       if (ncr_dma)
                overrides[0].dma = ncr_dma;
-       if (ncr_addr != NCR_NOT_SET)
+       if (ncr_addr)
                overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
-       if (ncr_5380 != NCR_NOT_SET)
+       if (ncr_5380)
                overrides[0].board = BOARD_NCR5380;
-       else if (ncr_53c400 != NCR_NOT_SET)
+       else if (ncr_53c400)
                overrides[0].board = BOARD_NCR53C400;
-       else if (ncr_53c400a != NCR_NOT_SET)
+       else if (ncr_53c400a)
                overrides[0].board = BOARD_NCR53C400A;
-       else if (dtc_3181e != NCR_NOT_SET)
+       else if (dtc_3181e)
                overrides[0].board = BOARD_DTC3181E;
+       else if (hp_c2502)
+               overrides[0].board = BOARD_HP_C2502;
 #ifndef SCSI_G_NCR5380_MEM
        if (!current_override && isapnp_present()) {
                struct pnp_dev *dev = NULL;
@@ -318,41 +341,45 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                }
        }
 #endif
-       tpnt->proc_name = "g_NCR5380";
 
        for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
                if (!(overrides[current_override].NCR5380_map_name))
                        continue;
 
                ports = NULL;
+               flags = 0;
                switch (overrides[current_override].board) {
                case BOARD_NCR5380:
                        flags = FLAG_NO_PSEUDO_DMA;
                        break;
                case BOARD_NCR53C400:
-                       flags = FLAG_NCR53C400;
+#ifdef PSEUDO_DMA
+                       flags = FLAG_NO_DMA_FIXUP;
+#endif
                        break;
                case BOARD_NCR53C400A:
-                       flags = FLAG_NO_PSEUDO_DMA;
+                       flags = FLAG_NO_DMA_FIXUP;
+                       ports = ncr_53c400a_ports;
+                       magic = ncr_53c400a_magic;
+                       break;
+               case BOARD_HP_C2502:
+                       flags = FLAG_NO_DMA_FIXUP;
                        ports = ncr_53c400a_ports;
+                       magic = hp_c2502_magic;
                        break;
                case BOARD_DTC3181E:
-                       flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
+                       flags = FLAG_NO_DMA_FIXUP;
                        ports = dtc_3181e_ports;
+                       magic = ncr_53c400a_magic;
                        break;
                }
 
 #ifndef SCSI_G_NCR5380_MEM
-               if (ports) {
+               if (ports && magic) {
                        /* wakeup sequence for the NCR53C400A and DTC3181E */
 
                        /* Disable the adapter and look for a free io port */
-                       outb(0x59, 0x779);
-                       outb(0xb9, 0x379);
-                       outb(0xc5, 0x379);
-                       outb(0xae, 0x379);
-                       outb(0xa6, 0x379);
-                       outb(0x00, 0x379);
+                       magic_configure(-1, 0, magic);
 
                        if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
                                for (i = 0; ports[i]; i++) {
@@ -371,17 +398,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                                }
                        if (ports[i]) {
                                /* At this point we have our region reserved */
-                               outb(0x59, 0x779);
-                               outb(0xb9, 0x379);
-                               outb(0xc5, 0x379);
-                               outb(0xae, 0x379);
-                               outb(0xa6, 0x379);
-                               outb(0x80 | i, 0x379);  /* set io port to be used */
+                               magic_configure(i, 0, magic); /* no IRQ yet */
                                outb(0xc0, ports[i] + 9);
                                if (inb(ports[i] + 9) != 0x80)
                                        continue;
-                               else
-                                       overrides[current_override].NCR5380_map_name = ports[i];
+                               overrides[current_override].NCR5380_map_name = ports[i];
+                               port_idx = i;
                        } else
                                continue;
                }
@@ -403,24 +425,65 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                }
 #endif
                instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
-               if (instance == NULL) {
-#ifndef SCSI_G_NCR5380_MEM
-                       release_region(overrides[current_override].NCR5380_map_name, region_size);
-#else
-                       iounmap(iomem);
-                       release_mem_region(base, NCR5380_region_size);
-#endif
-                       continue;
-               }
+               if (instance == NULL)
+                       goto out_release;
+               hostdata = shost_priv(instance);
 
-               instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
 #ifndef SCSI_G_NCR5380_MEM
+               instance->io_port = overrides[current_override].NCR5380_map_name;
                instance->n_io_port = region_size;
+               hostdata->io_width = 1; /* 8-bit PDMA by default */
+
+               /*
+                * On NCR53C400 boards, NCR5380 registers are mapped 8 past
+                * the base address.
+                */
+               switch (overrides[current_override].board) {
+               case BOARD_NCR53C400:
+                       instance->io_port += 8;
+                       hostdata->c400_ctl_status = 0;
+                       hostdata->c400_blk_cnt = 1;
+                       hostdata->c400_host_buf = 4;
+                       break;
+               case BOARD_DTC3181E:
+                       hostdata->io_width = 2; /* 16-bit PDMA */
+                       /* fall through */
+               case BOARD_NCR53C400A:
+               case BOARD_HP_C2502:
+                       hostdata->c400_ctl_status = 9;
+                       hostdata->c400_blk_cnt = 10;
+                       hostdata->c400_host_buf = 8;
+                       break;
+               }
 #else
-               ((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
+               instance->base = overrides[current_override].NCR5380_map_name;
+               hostdata->iomem = iomem;
+               switch (overrides[current_override].board) {
+               case BOARD_NCR53C400:
+                       hostdata->c400_ctl_status = 0x100;
+                       hostdata->c400_blk_cnt = 0x101;
+                       hostdata->c400_host_buf = 0x104;
+                       break;
+               case BOARD_DTC3181E:
+               case BOARD_NCR53C400A:
+               case BOARD_HP_C2502:
+                       pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
+                       goto out_unregister;
+               }
 #endif
 
-               NCR5380_init(instance, flags);
+               if (NCR5380_init(instance, flags))
+                       goto out_unregister;
+
+               switch (overrides[current_override].board) {
+               case BOARD_NCR53C400:
+               case BOARD_DTC3181E:
+               case BOARD_NCR53C400A:
+               case BOARD_HP_C2502:
+                       NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+               }
+
+               NCR5380_maybe_reset_bus(instance);
 
                if (overrides[current_override].irq != IRQ_AUTO)
                        instance->irq = overrides[current_override].irq;
@@ -431,12 +494,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                if (instance->irq == 255)
                        instance->irq = NO_IRQ;
 
-               if (instance->irq != NO_IRQ)
+               if (instance->irq != NO_IRQ) {
+#ifndef SCSI_G_NCR5380_MEM
+                       /* set IRQ for HP C2502 */
+                       if (overrides[current_override].board == BOARD_HP_C2502)
+                               magic_configure(port_idx, instance->irq, magic);
+#endif
                        if (request_irq(instance->irq, generic_NCR5380_intr,
                                        0, "NCR5380", instance)) {
                                printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
                                instance->irq = NO_IRQ;
                        }
+               }
 
                if (instance->irq == NO_IRQ) {
                        printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
@@ -447,6 +516,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                ++count;
        }
        return count;
+
+out_unregister:
+       scsi_unregister(instance);
+out_release:
+#ifndef SCSI_G_NCR5380_MEM
+       release_region(overrides[current_override].NCR5380_map_name, region_size);
+#else
+       iounmap(iomem);
+       release_mem_region(base, NCR5380_region_size);
+#endif
+       return count;
 }
 
 /**
@@ -460,21 +540,15 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
  
 static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
 {
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
-       
        if (instance->irq != NO_IRQ)
                free_irq(instance->irq, instance);
        NCR5380_exit(instance);
-
 #ifndef SCSI_G_NCR5380_MEM
-       release_region(instance->NCR5380_instance_name, instance->n_io_port);
+       release_region(instance->io_port, instance->n_io_port);
 #else
        iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-       release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
+       release_mem_region(instance->base, NCR5380_region_size);
 #endif
-
-
        return 0;
 }
 
@@ -507,7 +581,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 }
 #endif
 
-#ifdef NCR53C400_PSEUDO_DMA
+#ifdef PSEUDO_DMA
 
 /**
  *     NCR5380_pread           -       pseudo DMA read
@@ -521,75 +595,68 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int blocks = len / 128;
        int start = 0;
-       int bl;
-
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
 
-       NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
-       NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+       NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
+       NCR5380_write(hostdata->c400_blk_cnt, blocks);
        while (1) {
-               if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+               if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
                        break;
-               }
-               if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+               if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
                        printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
                        return -1;
                }
-               while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
+               while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
+                       ; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-               {
-                       int i;
-                       for (i = 0; i < 128; i++)
-                               dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
-               }
+               if (hostdata->io_width == 2)
+                       insw(instance->io_port + hostdata->c400_host_buf,
+                                                       dst + start, 64);
+               else
+                       insb(instance->io_port + hostdata->c400_host_buf,
+                                                       dst + start, 128);
 #else
                /* implies SCSI_G_NCR5380_MEM */
-               memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
+               memcpy_fromio(dst + start,
+                             hostdata->iomem + NCR53C400_host_buffer, 128);
 #endif
                start += 128;
                blocks--;
        }
 
        if (blocks) {
-               while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-               {
-                       // FIXME - no timeout
-               }
+               while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
+                       ; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-               {
-                       int i;  
-                       for (i = 0; i < 128; i++)
-                               dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
-               }
+               if (hostdata->io_width == 2)
+                       insw(instance->io_port + hostdata->c400_host_buf,
+                                                       dst + start, 64);
+               else
+                       insb(instance->io_port + hostdata->c400_host_buf,
+                                                       dst + start, 128);
 #else
                /* implies SCSI_G_NCR5380_MEM */
-               memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
+               memcpy_fromio(dst + start,
+                             hostdata->iomem + NCR53C400_host_buffer, 128);
 #endif
                start += 128;
                blocks--;
        }
 
-       if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+       if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
                printk("53C400r: no 53C80 gated irq after transfer");
 
-#if 0
-       /*
-        *      DON'T DO THIS - THEY NEVER ARRIVE!
-        */
-       printk("53C400r: Waiting for 53C80 registers\n");
-       while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
+       /* wait for 53C80 registers to be available */
+       while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
                ;
-#endif
+
        if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
                printk(KERN_ERR "53C400r: no end dma signal\n");
                
-       NCR5380_write(MODE_REG, MR_BASE);
-       NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        return 0;
 }
 
@@ -605,89 +672,91 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int blocks = len / 128;
        int start = 0;
-       int bl;
-       int i;
 
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
-
-       NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-       NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+       NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+       NCR5380_write(hostdata->c400_blk_cnt, blocks);
        while (1) {
-               if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+               if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
                        printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
                        return -1;
                }
 
-               if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+               if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
                        break;
-               }
-               while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+               while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
                        ; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-               {
-                       for (i = 0; i < 128; i++)
-                               NCR5380_write(C400_HOST_BUFFER, src[start + i]);
-               }
+               if (hostdata->io_width == 2)
+                       outsw(instance->io_port + hostdata->c400_host_buf,
+                                                       src + start, 64);
+               else
+                       outsb(instance->io_port + hostdata->c400_host_buf,
+                                                       src + start, 128);
 #else
                /* implies SCSI_G_NCR5380_MEM */
-               memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
+               memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+                           src + start, 128);
 #endif
                start += 128;
                blocks--;
        }
        if (blocks) {
-               while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+               while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
                        ; // FIXME - no timeout
 
 #ifndef SCSI_G_NCR5380_MEM
-               {
-                       for (i = 0; i < 128; i++)
-                               NCR5380_write(C400_HOST_BUFFER, src[start + i]);
-               }
+               if (hostdata->io_width == 2)
+                       outsw(instance->io_port + hostdata->c400_host_buf,
+                                                       src + start, 64);
+               else
+                       outsb(instance->io_port + hostdata->c400_host_buf,
+                                                       src + start, 128);
 #else
                /* implies SCSI_G_NCR5380_MEM */
-               memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
+               memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+                           src + start, 128);
 #endif
                start += 128;
                blocks--;
        }
 
-#if 0
-       printk("53C400w: waiting for registers to be available\n");
-       THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
-       printk("53C400w: Got em\n");
-#endif
-
-       /* Let's wait for this instead - could be ugly */
-       /* All documentation says to check for this. Maybe my hardware is too
-        * fast. Waiting for it seems to work fine! KLL
-        */
-       while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
-               ;       // FIXME - no timeout
-
-       /*
-        * I know. i is certainly != 0 here but the loop is new. See previous
-        * comment.
-        */
-       if (i) {
-               if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
-                       printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
-       } else
-               printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
+       /* wait for 53C80 registers to be available */
+       while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
+               udelay(4); /* DTC436 chip hangs without this */
+               /* FIXME - no timeout */
+       }
 
-#if 0
        if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
                printk(KERN_ERR "53C400w: no end dma signal\n");
        }
-#endif
+
        while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
                ;       // TIMEOUT
        return 0;
 }
-#endif                         /* PSEUDO_DMA */
+
+static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
+{
+       int transfersize = cmd->transfersize;
+
+       /* Limit transfers to 32K, for xx400 & xx406
+        * pseudoDMA that transfers in 128 bytes blocks.
+        */
+       if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
+           !(cmd->SCp.this_residual % transfersize))
+               transfersize = 32 * 1024;
+
+       /* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
+       if (transfersize % 128)
+               transfersize = 0;
+
+       return transfersize;
+}
+
+#endif /* PSEUDO_DMA */
 
 /*
  *     Include the NCR5380 core code that we build our driver around   
@@ -696,22 +765,24 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-       .show_info              = generic_NCR5380_show_info,
-       .name                   = "Generic NCR5380/NCR53C400 SCSI",
-       .detect                 = generic_NCR5380_detect,
-       .release                = generic_NCR5380_release_resources,
-       .info                   = generic_NCR5380_info,
-       .queuecommand           = generic_NCR5380_queue_command,
+       .proc_name              = DRV_MODULE_NAME,
+       .name                   = "Generic NCR5380/NCR53C400 SCSI",
+       .detect                 = generic_NCR5380_detect,
+       .release                = generic_NCR5380_release_resources,
+       .info                   = generic_NCR5380_info,
+       .queuecommand           = generic_NCR5380_queue_command,
        .eh_abort_handler       = generic_NCR5380_abort,
        .eh_bus_reset_handler   = generic_NCR5380_bus_reset,
-       .bios_param             = NCR5380_BIOSPARAM,
-       .can_queue              = CAN_QUEUE,
-        .this_id               = 7,
-        .sg_tablesize          = SG_ALL,
-       .cmd_per_lun            = CMD_PER_LUN,
-        .use_clustering                = DISABLE_CLUSTERING,
+       .bios_param             = NCR5380_BIOSPARAM,
+       .can_queue              = 16,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 2,
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
-#include <linux/module.h>
+
 #include "scsi_module.c"
 
 module_param(ncr_irq, int, 0);
@@ -721,6 +792,7 @@ module_param(ncr_5380, int, 0);
 module_param(ncr_53c400, int, 0);
 module_param(ncr_53c400a, int, 0);
 module_param(dtc_3181e, int, 0);
+module_param(hp_c2502, int, 0);
 MODULE_LICENSE("GPL");
 
 #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
index bea1a3b..6f3d2ac 100644 (file)
 #ifndef GENERIC_NCR5380_H
 #define GENERIC_NCR5380_H
 
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define BIOSPARAM
 #define NCR5380_BIOSPARAM generic_NCR5380_biosparam
 #else
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef ASM
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
 #define __STRVAL(x) #x
 #define STRVAL(x) __STRVAL(x)
 
 #ifndef SCSI_G_NCR5380_MEM
+#define DRV_MODULE_NAME "g_NCR5380"
 
-#define NCR5380_map_config port
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR5380_instance_name io_port
-#define NCR53C400_register_offset 0
-#define NCR53C400_address_adjust 8
 
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define NCR5380_region_size 16
 #else
 #define NCR5380_region_size 8
 #endif
 
-#define NCR5380_read(reg) (inb(NCR5380_map_name + (reg)))
-#define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg))))
+#define NCR5380_read(reg) \
+       inb(instance->io_port + (reg))
+#define NCR5380_write(reg, value) \
+       outb(value, instance->io_port + (reg))
 
 #define NCR5380_implementation_fields \
-    NCR5380_map_type NCR5380_map_name
-
-#define NCR5380_local_declare() \
-    register NCR5380_implementation_fields
-
-#define NCR5380_setup(instance) \
-    NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name)
+       int c400_ctl_status; \
+       int c400_blk_cnt; \
+       int c400_host_buf; \
+       int io_width;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
+#define DRV_MODULE_NAME "g_NCR5380_mmio"
 
-#define NCR5380_map_config memory
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR5380_instance_name base
-#define NCR53C400_register_offset 0x108
-#define NCR53C400_address_adjust 0
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00
 
-#define NCR5380_read(reg) readb(iomem + NCR53C400_mem_base + (reg))
-#define NCR5380_write(reg, value) writeb(value, iomem + NCR53C400_mem_base + (reg))
+#define NCR5380_read(reg) \
+       readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+             NCR53C400_mem_base + (reg))
+#define NCR5380_write(reg, value) \
+       writeb(value, ((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+              NCR53C400_mem_base + (reg))
 
 #define NCR5380_implementation_fields \
-    NCR5380_map_type NCR5380_map_name; \
-    void __iomem *iomem;
-
-#define NCR5380_local_declare() \
-    register void __iomem *iomem
-
-#define NCR5380_setup(instance) \
-    iomem = (((struct NCR5380_hostdata *)(instance)->hostdata)->iomem)
+       void __iomem *iomem; \
+       int c400_ctl_status; \
+       int c400_blk_cnt; \
+       int c400_host_buf;
 
 #endif
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        generic_NCR5380_dma_xfer_len(cmd)
+
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
 #define BOARD_NCR53C400        1
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E 3
+#define BOARD_HP_C2502 4
 
-#endif /* ndef ASM */
 #endif /* GENERIC_NCR5380_H */
 
index d543811..057fdeb 100644 (file)
 /* ITCT header */
 /* qw0 */
 #define ITCT_HDR_DEV_TYPE_OFF          0
-#define ITCT_HDR_DEV_TYPE_MSK          (0x3 << ITCT_HDR_DEV_TYPE_OFF)
+#define ITCT_HDR_DEV_TYPE_MSK          (0x3ULL << ITCT_HDR_DEV_TYPE_OFF)
 #define ITCT_HDR_VALID_OFF             2
-#define ITCT_HDR_VALID_MSK             (0x1 << ITCT_HDR_VALID_OFF)
-#define ITCT_HDR_BREAK_REPLY_ENA_OFF   3
-#define ITCT_HDR_BREAK_REPLY_ENA_MSK   (0x1 << ITCT_HDR_BREAK_REPLY_ENA_OFF)
+#define ITCT_HDR_VALID_MSK             (0x1ULL << ITCT_HDR_VALID_OFF)
 #define ITCT_HDR_AWT_CONTROL_OFF       4
-#define ITCT_HDR_AWT_CONTROL_MSK       (0x1 << ITCT_HDR_AWT_CONTROL_OFF)
+#define ITCT_HDR_AWT_CONTROL_MSK       (0x1ULL << ITCT_HDR_AWT_CONTROL_OFF)
 #define ITCT_HDR_MAX_CONN_RATE_OFF     5
-#define ITCT_HDR_MAX_CONN_RATE_MSK     (0xf << ITCT_HDR_MAX_CONN_RATE_OFF)
+#define ITCT_HDR_MAX_CONN_RATE_MSK     (0xfULL << ITCT_HDR_MAX_CONN_RATE_OFF)
 #define ITCT_HDR_VALID_LINK_NUM_OFF    9
-#define ITCT_HDR_VALID_LINK_NUM_MSK    (0xf << ITCT_HDR_VALID_LINK_NUM_OFF)
+#define ITCT_HDR_VALID_LINK_NUM_MSK    (0xfULL << ITCT_HDR_VALID_LINK_NUM_OFF)
 #define ITCT_HDR_PORT_ID_OFF           13
-#define ITCT_HDR_PORT_ID_MSK           (0x7 << ITCT_HDR_PORT_ID_OFF)
+#define ITCT_HDR_PORT_ID_MSK           (0x7ULL << ITCT_HDR_PORT_ID_OFF)
 #define ITCT_HDR_SMP_TIMEOUT_OFF       16
-#define ITCT_HDR_SMP_TIMEOUT_MSK       (0xffff << ITCT_HDR_SMP_TIMEOUT_OFF)
-#define ITCT_HDR_MAX_BURST_BYTES_OFF   16
-#define ITCT_HDR_MAX_BURST_BYTES_MSK   (0xffffffff << \
-                                       ITCT_MAX_BURST_BYTES_OFF)
+#define ITCT_HDR_SMP_TIMEOUT_MSK       (0xffffULL << ITCT_HDR_SMP_TIMEOUT_OFF)
 /* qw1 */
 #define ITCT_HDR_MAX_SAS_ADDR_OFF      0
 #define ITCT_HDR_MAX_SAS_ADDR_MSK      (0xffffffffffffffff << \
                                        ITCT_HDR_MAX_SAS_ADDR_OFF)
 /* qw2 */
 #define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF  0
-#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK  (0xffff << \
+#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK  (0xffffULL << \
                                        ITCT_HDR_IT_NEXUS_LOSS_TL_OFF)
 #define ITCT_HDR_BUS_INACTIVE_TL_OFF   16
-#define ITCT_HDR_BUS_INACTIVE_TL_MSK   (0xffff << \
+#define ITCT_HDR_BUS_INACTIVE_TL_MSK   (0xffffULL << \
                                        ITCT_HDR_BUS_INACTIVE_TL_OFF)
 #define ITCT_HDR_MAX_CONN_TL_OFF       32
-#define ITCT_HDR_MAX_CONN_TL_MSK       (0xffff << \
+#define ITCT_HDR_MAX_CONN_TL_MSK       (0xffffULL << \
                                        ITCT_HDR_MAX_CONN_TL_OFF)
 #define ITCT_HDR_REJ_OPEN_TL_OFF       48
-#define ITCT_HDR_REJ_OPEN_TL_MSK       (0xffff << \
-                                       ITCT_REJ_OPEN_TL_OFF)
+#define ITCT_HDR_REJ_OPEN_TL_MSK       (0xffffULL << \
+                                       ITCT_HDR_REJ_OPEN_TL_OFF)
 
 /* Err record header */
 #define ERR_HDR_DMA_TX_ERR_TYPE_OFF    0
@@ -533,10 +528,10 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba,
        itct->sas_addr = __swab64(itct->sas_addr);
 
        /* qw2 */
-       itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
-                               (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) |
-                               (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) |
-                               (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF));
+       itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
+                               (0xff00ULL << ITCT_HDR_BUS_INACTIVE_TL_OFF) |
+                               (0xff00ULL << ITCT_HDR_MAX_CONN_TL_OFF) |
+                               (0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF));
 }
 
 static void free_device_v1_hw(struct hisi_hba *hisi_hba,
@@ -544,7 +539,8 @@ static void free_device_v1_hw(struct hisi_hba *hisi_hba,
 {
        u64 dev_id = sas_dev->device_id;
        struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];
-       u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
+       u64 qw0;
+       u32 reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
 
        reg_val |= CFG_AGING_TIME_ITCT_REL_MSK;
        hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
index 4e1a632..f8b88fa 100644 (file)
@@ -43,6 +43,7 @@ typedef struct {
        unsigned dp:1;          /* Data phase present           */
        unsigned rd:1;          /* Read data in data phase      */
        unsigned wanted:1;      /* Parport sharing busy flag    */
+       unsigned int dev_no;    /* Device number                */
        wait_queue_head_t *waiting;
        struct Scsi_Host *host;
        struct list_head list;
@@ -1120,15 +1121,40 @@ static struct scsi_host_template imm_template = {
 
 static LIST_HEAD(imm_hosts);
 
+/*
+ * Finds the first available device number that can be alloted to the
+ * new imm device and returns the address of the previous node so that
+ * we can add to the tail and have a list in the ascending order.
+ */
+
+static inline imm_struct *find_parent(void)
+{
+       imm_struct *dev, *par = NULL;
+       unsigned int cnt = 0;
+
+       if (list_empty(&imm_hosts))
+               return NULL;
+
+       list_for_each_entry(dev, &imm_hosts, list) {
+               if (dev->dev_no != cnt)
+                       return par;
+               cnt++;
+               par = dev;
+       }
+
+       return par;
+}
+
 static int __imm_attach(struct parport *pb)
 {
        struct Scsi_Host *host;
-       imm_struct *dev;
+       imm_struct *dev, *temp;
        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
        DEFINE_WAIT(wait);
        int ports;
        int modes, ppb;
        int err = -ENOMEM;
+       struct pardev_cb imm_cb;
 
        init_waitqueue_head(&waiting);
 
@@ -1141,9 +1167,15 @@ static int __imm_attach(struct parport *pb)
        dev->mode = IMM_AUTODETECT;
        INIT_LIST_HEAD(&dev->list);
 
-       dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup,
-                                               NULL, 0, dev);
+       temp = find_parent();
+       if (temp)
+               dev->dev_no = temp->dev_no + 1;
+
+       memset(&imm_cb, 0, sizeof(imm_cb));
+       imm_cb.private = dev;
+       imm_cb.wakeup = imm_wakeup;
 
+       dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no);
        if (!dev->dev)
                goto out;
 
@@ -1207,7 +1239,10 @@ static int __imm_attach(struct parport *pb)
        host->unique_id = pb->number;
        *(imm_struct **)&host->hostdata = dev;
        dev->host = host;
-       list_add_tail(&dev->list, &imm_hosts);
+       if (!temp)
+               list_add_tail(&dev->list, &imm_hosts);
+       else
+               list_add_tail(&dev->list, &temp->list);
        err = scsi_add_host(host, NULL);
        if (err)
                goto out2;
@@ -1245,9 +1280,10 @@ static void imm_detach(struct parport *pb)
 }
 
 static struct parport_driver imm_driver = {
-       .name   = "imm",
-       .attach = imm_attach,
-       .detach = imm_detach,
+       .name           = "imm",
+       .match_port     = imm_attach,
+       .detach         = imm_detach,
+       .devmodel       = true,
 };
 
 static int __init imm_driver_init(void)
index 536cd5a..3b3e099 100644 (file)
@@ -3638,7 +3638,7 @@ static struct device_attribute ipr_ioa_reset_attr = {
        .store = ipr_store_reset_adapter
 };
 
-static int ipr_iopoll(struct blk_iopoll *iop, int budget);
+static int ipr_iopoll(struct irq_poll *iop, int budget);
  /**
  * ipr_show_iopoll_weight - Show ipr polling mode
  * @dev:       class device struct
@@ -3681,34 +3681,33 @@ static ssize_t ipr_store_iopoll_weight(struct device *dev,
        int i;
 
        if (!ioa_cfg->sis64) {
-               dev_info(&ioa_cfg->pdev->dev, "blk-iopoll not supported on this adapter\n");
+               dev_info(&ioa_cfg->pdev->dev, "irq_poll not supported on this adapter\n");
                return -EINVAL;
        }
        if (kstrtoul(buf, 10, &user_iopoll_weight))
                return -EINVAL;
 
        if (user_iopoll_weight > 256) {
-               dev_info(&ioa_cfg->pdev->dev, "Invalid blk-iopoll weight. It must be less than 256\n");
+               dev_info(&ioa_cfg->pdev->dev, "Invalid irq_poll weight. It must be less than 256\n");
                return -EINVAL;
        }
 
        if (user_iopoll_weight == ioa_cfg->iopoll_weight) {
-               dev_info(&ioa_cfg->pdev->dev, "Current blk-iopoll weight has the same weight\n");
+               dev_info(&ioa_cfg->pdev->dev, "Current irq_poll weight has the same weight\n");
                return strlen(buf);
        }
 
        if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
                for (i = 1; i < ioa_cfg->hrrq_num; i++)
-                       blk_iopoll_disable(&ioa_cfg->hrrq[i].iopoll);
+                       irq_poll_disable(&ioa_cfg->hrrq[i].iopoll);
        }
 
        spin_lock_irqsave(shost->host_lock, lock_flags);
        ioa_cfg->iopoll_weight = user_iopoll_weight;
        if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
                for (i = 1; i < ioa_cfg->hrrq_num; i++) {
-                       blk_iopoll_init(&ioa_cfg->hrrq[i].iopoll,
+                       irq_poll_init(&ioa_cfg->hrrq[i].iopoll,
                                        ioa_cfg->iopoll_weight, ipr_iopoll);
-                       blk_iopoll_enable(&ioa_cfg->hrrq[i].iopoll);
                }
        }
        spin_unlock_irqrestore(shost->host_lock, lock_flags);
@@ -4003,13 +4002,12 @@ static ssize_t ipr_store_update_fw(struct device *dev,
        struct ipr_sglist *sglist;
        char fname[100];
        char *src;
-       int len, result, dnld_size;
+       int result, dnld_size;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       len = snprintf(fname, 99, "%s", buf);
-       fname[len-1] = '\0';
+       snprintf(fname, sizeof(fname), "%s", buf);
 
        if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
                dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
@@ -5569,7 +5567,7 @@ static int ipr_process_hrrq(struct ipr_hrr_queue *hrr_queue, int budget,
        return num_hrrq;
 }
 
-static int ipr_iopoll(struct blk_iopoll *iop, int budget)
+static int ipr_iopoll(struct irq_poll *iop, int budget)
 {
        struct ipr_ioa_cfg *ioa_cfg;
        struct ipr_hrr_queue *hrrq;
@@ -5585,7 +5583,7 @@ static int ipr_iopoll(struct blk_iopoll *iop, int budget)
        completed_ops = ipr_process_hrrq(hrrq, budget, &doneq);
 
        if (completed_ops < budget)
-               blk_iopoll_complete(iop);
+               irq_poll_complete(iop);
        spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
 
        list_for_each_entry_safe(ipr_cmd, temp, &doneq, queue) {
@@ -5693,8 +5691,7 @@ static irqreturn_t ipr_isr_mhrrq(int irq, void *devp)
        if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
                if ((be32_to_cpu(*hrrq->hrrq_curr) & IPR_HRRQ_TOGGLE_BIT) ==
                       hrrq->toggle_bit) {
-                       if (!blk_iopoll_sched_prep(&hrrq->iopoll))
-                               blk_iopoll_sched(&hrrq->iopoll);
+                       irq_poll_sched(&hrrq->iopoll);
                        spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
                        return IRQ_HANDLED;
                }
@@ -10405,9 +10402,8 @@ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
 
        if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
                for (i = 1; i < ioa_cfg->hrrq_num; i++) {
-                       blk_iopoll_init(&ioa_cfg->hrrq[i].iopoll,
+                       irq_poll_init(&ioa_cfg->hrrq[i].iopoll,
                                        ioa_cfg->iopoll_weight, ipr_iopoll);
-                       blk_iopoll_enable(&ioa_cfg->hrrq[i].iopoll);
                }
        }
 
@@ -10436,7 +10432,7 @@ static void ipr_shutdown(struct pci_dev *pdev)
        if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
                ioa_cfg->iopoll_weight = 0;
                for (i = 1; i < ioa_cfg->hrrq_num; i++)
-                       blk_iopoll_disable(&ioa_cfg->hrrq[i].iopoll);
+                       irq_poll_disable(&ioa_cfg->hrrq[i].iopoll);
        }
 
        while (ioa_cfg->in_reset_reload) {
index a34c7a5..56c5706 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/libata.h>
 #include <linux/list.h>
 #include <linux/kref.h>
-#include <linux/blk-iopoll.h>
+#include <linux/irq_poll.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 
@@ -517,7 +517,7 @@ struct ipr_hrr_queue {
        u8 allow_cmds:1;
        u8 removing_ioa:1;
 
-       struct blk_iopoll iopoll;
+       struct irq_poll iopoll;
 };
 
 /* Command packet structure */
index d64a769..bb23813 100644 (file)
@@ -12,7 +12,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #define PSEUDO_DMA
 
 #define NCR5380_implementation_fields   unsigned char *pdma_base
-#define NCR5380_local_declare()         struct Scsi_Host *_instance
-#define NCR5380_setup(instance)         _instance = instance
 
-#define NCR5380_read(reg)               macscsi_read(_instance, reg)
-#define NCR5380_write(reg, value)       macscsi_write(_instance, reg, value)
+#define NCR5380_read(reg)               macscsi_read(instance, reg)
+#define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
 
 #define NCR5380_pread                   macscsi_pread
 #define NCR5380_pwrite                  macscsi_pwrite
+#define NCR5380_dma_xfer_len(instance, cmd, phase)     (cmd->transfersize)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -51,8 +49,6 @@
 
 #include "NCR5380.h"
 
-#define RESET_BOOT
-
 static int setup_can_queue = -1;
 module_param(setup_can_queue, int, 0);
 static int setup_cmd_per_lun = -1;
@@ -65,17 +61,8 @@ static int setup_use_tagged_queuing = -1;
 module_param(setup_use_tagged_queuing, int, 0);
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
-
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#define TOSHIBA_DELAY
-
-#ifdef TOSHIBA_DELAY
-#define        AFTER_RESET_DELAY       (5*HZ/2)
-#else
-#define        AFTER_RESET_DELAY       (HZ/2)
-#endif
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
 
 /*
  * NCR 5380 register access functions
@@ -94,12 +81,12 @@ static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value)
 #ifndef MODULE
 static int __init mac_scsi_setup(char *str)
 {
-       int ints[7];
+       int ints[8];
 
        (void)get_options(str, ARRAY_SIZE(ints), ints);
 
-       if (ints[0] < 1 || ints[0] > 6) {
-               pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
+       if (ints[0] < 1) {
+               pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,<toshiba_delay>]]]]]]\n");
                return 0;
        }
        if (ints[0] >= 1)
@@ -114,50 +101,14 @@ static int __init mac_scsi_setup(char *str)
                setup_use_tagged_queuing = ints[5];
        if (ints[0] >= 6)
                setup_use_pdma = ints[6];
+       if (ints[0] >= 7)
+               setup_toshiba_delay = ints[7];
        return 1;
 }
 
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-#ifdef RESET_BOOT
-/*
- * Our 'bus reset on boot' function
- */
-
-static void mac_scsi_reset_boot(struct Scsi_Host *instance)
-{
-       unsigned long end;
-
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
-       
-       /*
-        * Do a SCSI reset to clean up the bus during initialization. No messing
-        * with the queues, interrupts, or locks necessary here.
-        */
-
-       printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
-
-       /* get in phase */
-       NCR5380_write( TARGET_COMMAND_REG,
-                     PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
-       /* assert RST */
-       NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-       /* The min. reset hold time is 25us, so 40us should be enough */
-       udelay( 50 );
-       /* reset RST and interrupt */
-       NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
-       NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
-       for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
-               barrier();
-
-       printk(KERN_INFO " done\n" );
-}
-#endif
-
 #ifdef PSEUDO_DMA
 /* 
    Pseudo-DMA: (Ove Edlund)
@@ -235,9 +186,6 @@ static int macscsi_pread(struct Scsi_Host *instance,
        unsigned char *d;
        unsigned char *s;
 
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
-
        s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
        d = dst;
 
@@ -329,9 +277,6 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
        unsigned char *s;
        unsigned char *d;
 
-       NCR5380_local_declare();
-       NCR5380_setup(instance);
-
        s = src;
        d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
 
@@ -364,20 +309,22 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
 #define PFX                     DRV_MODULE_NAME ": "
 
 static struct scsi_host_template mac_scsi_template = {
-       .module                         = THIS_MODULE,
-       .proc_name                      = DRV_MODULE_NAME,
-       .show_info                      = macscsi_show_info,
-       .write_info                     = macscsi_write_info,
-       .name                           = "Macintosh NCR5380 SCSI",
-       .info                           = macscsi_info,
-       .queuecommand                   = macscsi_queue_command,
-       .eh_abort_handler               = macscsi_abort,
-       .eh_bus_reset_handler           = macscsi_bus_reset,
-       .can_queue                      = 16,
-       .this_id                        = 7,
-       .sg_tablesize                   = SG_ALL,
-       .cmd_per_lun                    = 2,
-       .use_clustering                 = DISABLE_CLUSTERING
+       .module                 = THIS_MODULE,
+       .proc_name              = DRV_MODULE_NAME,
+       .show_info              = macscsi_show_info,
+       .write_info             = macscsi_write_info,
+       .name                   = "Macintosh NCR5380 SCSI",
+       .info                   = macscsi_info,
+       .queuecommand           = macscsi_queue_command,
+       .eh_abort_handler       = macscsi_abort,
+       .eh_bus_reset_handler   = macscsi_bus_reset,
+       .can_queue              = 16,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 2,
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 
 static int __init mac_scsi_probe(struct platform_device *pdev)
@@ -432,15 +379,14 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
        } else
                host_flags |= FLAG_NO_PSEUDO_DMA;
 
-#ifdef RESET_BOOT
-       mac_scsi_reset_boot(instance);
-#endif
-
 #ifdef SUPPORT_TAGS
        host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
 #endif
+       host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-       NCR5380_init(instance, host_flags);
+       error = NCR5380_init(instance, host_flags);
+       if (error)
+               goto fail_init;
 
        if (instance->irq != NO_IRQ) {
                error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED,
@@ -449,6 +395,8 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
                        goto fail_irq;
        }
 
+       NCR5380_maybe_reset_bus(instance);
+
        error = scsi_add_host(instance, NULL);
        if (error)
                goto fail_host;
@@ -463,6 +411,7 @@ fail_host:
                free_irq(instance->irq, instance);
 fail_irq:
        NCR5380_exit(instance);
+fail_init:
        scsi_host_put(instance);
        return error;
 }
index a706927..4cf9ed9 100644 (file)
@@ -179,8 +179,12 @@ mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 
        /*
         * The following call will block till a kioc is available
+        * or return NULL if the list head is empty for the pointer
+        * of type mraid_mmapt passed to mraid_mm_alloc_kioc
         */
        kioc = mraid_mm_alloc_kioc(adp);
+       if (!kioc)
+               return -ENXIO;
 
        /*
         * User sent the old mimd_t ioctl packet. Convert it to uioc_t.
index e81eadd..512037e 100644 (file)
@@ -1,6 +1,4 @@
 #define PSEUDO_DMA
-#define UNSAFE  /* Not unsafe for PAS16 -- use it */
-#define PDEBUG 0
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
  
 #include <linux/module.h>
 
-#include <linux/signal.h>
-#include <linux/proc_fs.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/blkdev.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
 #include <linux/init.h>
 
 #include <scsi/scsi_host.h>
@@ -87,8 +81,8 @@
 #include "NCR5380.h"
 
 
-static unsigned short pas16_addr = 0;
-static int pas16_irq = 0;
+static unsigned short pas16_addr;
+static int pas16_irq;
  
 
 static const int scsi_irq_translate[] =
@@ -146,22 +140,6 @@ static const unsigned short  pas16_offset[ 8 ] =
                    * START_DMA_INITIATOR_RECEIVE_REG wo
                    */
     };
-/*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
- where something crashed or gets stuck at */
-/* 1 = blue
- 2 = green
- 3 = cyan
- 4 = red
- 5 = magenta
- 6 = yellow
- 7 = white
-*/
-#if 1
-#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
 
 
 /*
@@ -205,7 +183,7 @@ static void __init
        outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET );   /* Reset TC */
        outb( 0x01, io_port + WAIT_STATE );   /* 1 Wait state */
 
-       NCR5380_read( RESET_PARITY_INTERRUPT_REG );
+       inb(io_port + pas16_offset[RESET_PARITY_INTERRUPT_REG]);
 
        /* Set the SCSI interrupt pointer without mucking up the sound
         * interrupt pointer in the same byte.
@@ -280,13 +258,13 @@ static int __init
      * put in an additional test to try to weed them out.
      */
 
-    outb( 0x01, io_port + WAIT_STATE );        /* 1 Wait state */
-    NCR5380_write( MODE_REG, 0x20 );           /* Is it really SCSI? */
-    if( NCR5380_read( MODE_REG ) != 0x20 )     /* Write to a reg.    */
-       return 0;                               /* and try to read    */
-    NCR5380_write( MODE_REG, 0x00 );           /* it back.           */
-    if( NCR5380_read( MODE_REG ) != 0x00 )
-       return 0;
+       outb(0x01, io_port + WAIT_STATE);             /* 1 Wait state */
+       outb(0x20, io_port + pas16_offset[MODE_REG]); /* Is it really SCSI? */
+       if (inb(io_port + pas16_offset[MODE_REG]) != 0x20) /* Write to a reg. */
+               return 0;                                  /* and try to read */
+       outb(0x00, io_port + pas16_offset[MODE_REG]);      /* it back. */
+       if (inb(io_port + pas16_offset[MODE_REG]) != 0x00)
+               return 0;
 
     return 1;
 }
@@ -305,7 +283,7 @@ static int __init
 
 static int __init pas16_setup(char *str)
 {
-    static int commandline_current = 0;
+       static int commandline_current;
     int i;
     int ints[10];
 
@@ -344,8 +322,8 @@ __setup("pas16=", pas16_setup);
 
 static int __init pas16_detect(struct scsi_host_template *tpnt)
 {
-    static int current_override = 0;
-    static unsigned short current_base = 0;
+       static int current_override;
+       static unsigned short current_base;
     struct Scsi_Host *instance;
     unsigned short io_port;
     int  count;
@@ -377,34 +355,32 @@ static int __init pas16_detect(struct scsi_host_template *tpnt)
        }
        else
            for (; !io_port && (current_base < NO_BASES); ++current_base) {
-#if (PDEBUG & PDEBUG_INIT)
-    printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
-#endif
+               dprintk(NDEBUG_INIT, "pas16: probing io_port 0x%04x\n",
+                       (unsigned int)bases[current_base].io_port);
                if ( !bases[current_base].noauto &&
                     pas16_hw_detect( current_base ) ){
                        io_port = bases[current_base].io_port;
                        init_board( io_port, default_irqs[ current_base ], 0 ); 
-#if (PDEBUG & PDEBUG_INIT)
-                       printk("scsi-pas16 : detected board.\n");
-#endif
+                       dprintk(NDEBUG_INIT, "pas16: detected board\n");
                }
     }
 
-
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-       printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
-#endif
+       dprintk(NDEBUG_INIT, "pas16: io_port = 0x%04x\n",
+               (unsigned int)io_port);
 
        if (!io_port)
            break;
 
        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
        if(instance == NULL)
-               break;
+               goto out;
                
        instance->io_port = io_port;
 
-       NCR5380_init(instance, 0);
+       if (NCR5380_init(instance, 0))
+               goto out_unregister;
+
+       NCR5380_maybe_reset_bus(instance);
 
        if (overrides[current_override].irq != IRQ_AUTO)
            instance->irq = overrides[current_override].irq;
@@ -431,14 +407,18 @@ static int __init pas16_detect(struct scsi_host_template *tpnt)
            outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
        }
 
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-       printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+       dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+               instance->host_no, instance->irq);
 
        ++current_override;
        ++count;
     }
     return count;
+
+out_unregister:
+       scsi_unregister(instance);
+out:
+       return count;
 }
 
 /*
@@ -561,29 +541,29 @@ static int pas16_release(struct Scsi_Host *shost)
        if (shost->irq != NO_IRQ)
                free_irq(shost->irq, shost);
        NCR5380_exit(shost);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
        scsi_unregister(shost);
        return 0;
 }
 
 static struct scsi_host_template driver_template = {
-       .name           = "Pro Audio Spectrum-16 SCSI",
-       .detect         = pas16_detect,
-       .release        = pas16_release,
-       .proc_name      = "pas16",
-       .show_info      = pas16_show_info,
-       .write_info     = pas16_write_info,
-       .info           = pas16_info,
-       .queuecommand   = pas16_queue_command,
-       .eh_abort_handler = pas16_abort,
-       .eh_bus_reset_handler = pas16_bus_reset,
-       .bios_param     = pas16_biosparam, 
-       .can_queue      = CAN_QUEUE,
-       .this_id        = 7,
-       .sg_tablesize   = SG_ALL,
-       .cmd_per_lun    = CMD_PER_LUN,
-       .use_clustering = DISABLE_CLUSTERING,
+       .name                   = "Pro Audio Spectrum-16 SCSI",
+       .detect                 = pas16_detect,
+       .release                = pas16_release,
+       .proc_name              = "pas16",
+       .show_info              = pas16_show_info,
+       .write_info             = pas16_write_info,
+       .info                   = pas16_info,
+       .queuecommand           = pas16_queue_command,
+       .eh_abort_handler       = pas16_abort,
+       .eh_bus_reset_handler   = pas16_bus_reset,
+       .bios_param             = pas16_biosparam,
+       .can_queue              = 32,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 2,
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 #include "scsi_module.c"
 
index c6109c8..d375277 100644 (file)
@@ -24,9 +24,6 @@
 #ifndef PAS16_H
 #define PAS16_H
 
-#define PDEBUG_INIT    0x1
-#define PDEBUG_TRANSFER 0x2
-
 #define PAS16_DEFAULT_BASE_1  0x388
 #define PAS16_DEFAULT_BASE_2  0x384
 #define PAS16_DEFAULT_BASE_3  0x38c
 #define OPERATION_MODE_1 0xec03
 #define IO_CONFIG_3 0xf002
 
+#define NCR5380_implementation_fields /* none */
 
-#ifndef ASM
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
-#define NCR5380_implementation_fields \
-    volatile unsigned short io_port
-
-#define NCR5380_local_declare() \
-    volatile unsigned short io_port
+#define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)])
 
-#define NCR5380_setup(instance) \
-    io_port = (instance)->io_port
-
-#define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
-
-#if !(PDEBUG & PDEBUG_TRANSFER) 
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
-#else
-#define NCR5380_read(reg)                                              \
-    (((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\
-    , instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) )
-
-#define NCR5380_write(reg, value)                                      \
-    (printk("scsi%d : write %02x to register %d at io_port %04x\n",    \
-           instance->hostno, (value), (reg), PAS16_io_port(reg)),      \
-    outb( (value),PAS16_io_port(reg) ) )
-
-#endif
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)     (cmd->transfersize)
 
 #define NCR5380_intr pas16_intr
-#define do_NCR5380_intr do_pas16_intr
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
 #define NCR5380_bus_reset pas16_bus_reset
    
 #define PAS16_IRQS 0xd4a8 
 
-#endif /* ndef ASM */
 #endif /* PAS16_H */
index 6b942d9..6992ebc 100644 (file)
@@ -823,6 +823,41 @@ static struct bin_attribute sysfs_reset_attr = {
        .write = qla2x00_sysfs_write_reset,
 };
 
+static ssize_t
+qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
+                       struct bin_attribute *bin_attr,
+                       char *buf, loff_t off, size_t count)
+{
+       struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+           struct device, kobj)));
+       int type;
+       int rval = 0;
+       port_id_t did;
+
+       type = simple_strtol(buf, NULL, 10);
+
+       did.b.domain = (type & 0x00ff0000) >> 16;
+       did.b.area = (type & 0x0000ff00) >> 8;
+       did.b.al_pa = (type & 0x000000ff);
+
+       ql_log(ql_log_info, vha, 0x70e3, "portid=%02x%02x%02x done\n",
+           did.b.domain, did.b.area, did.b.al_pa);
+
+       ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
+
+       rval = qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, did);
+       return count;
+}
+
+static struct bin_attribute sysfs_issue_logo_attr = {
+       .attr = {
+               .name = "issue_logo",
+               .mode = S_IWUSR,
+       },
+       .size = 0,
+       .write = qla2x00_issue_logo,
+};
+
 static ssize_t
 qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj,
                       struct bin_attribute *bin_attr,
@@ -937,6 +972,7 @@ static struct sysfs_entry {
        { "vpd", &sysfs_vpd_attr, 1 },
        { "sfp", &sysfs_sfp_attr, 1 },
        { "reset", &sysfs_reset_attr, },
+       { "issue_logo", &sysfs_issue_logo_attr, },
        { "xgmac_stats", &sysfs_xgmac_stats_attr, 3 },
        { "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 },
        { NULL },
index 34dc9a3..cd0d94e 100644 (file)
  * | Module Init and Probe        |       0x017f       | 0x0146         |
  * |                              |                    | 0x015b-0x0160 |
  * |                              |                    | 0x016e-0x0170  |
- * | Mailbox commands             |       0x118d       | 0x1115-0x1116 |
- * |                              |                    | 0x111a-0x111b  |
+ * | Mailbox commands             |       0x1192       |               |
+ * |                              |                    |               |
  * | Device Discovery             |       0x2016       | 0x2020-0x2022, |
  * |                              |                    | 0x2011-0x2012, |
  * |                              |                    | 0x2099-0x20a4  |
- * | Queue Command and IO tracing |       0x3075       | 0x300b         |
+ * | Queue Command and IO tracing |       0x3074       | 0x300b         |
  * |                              |                    | 0x3027-0x3028  |
  * |                              |                    | 0x303d-0x3041  |
  * |                              |                    | 0x302d,0x3033  |
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a                |
  * | DPC Thread                   |       0x4023       | 0x4002,0x4013  |
- * | Async Events                 |       0x508a       | 0x502b-0x502f  |
- * |                              |                    | 0x5047                |
+ * | Async Events                 |       0x5089       | 0x502b-0x502f  |
  * |                              |                    | 0x5084,0x5075 |
  * |                              |                    | 0x503d,0x5044  |
  * |                              |                    | 0x507b,0x505f |
  * | Timer Routines               |       0x6012       |                |
- * | User Space Interactions      |       0x70e      | 0x7018,0x702e  |
+ * | User Space Interactions      |       0x70e65      | 0x7018,0x702e  |
  * |                             |                    | 0x7020,0x7024  |
  * |                              |                    | 0x7039,0x7045  |
  * |                              |                    | 0x7073-0x7075  |
  * |                              |                    | 0xb13c-0xb140  |
  * |                              |                    | 0xb149                |
  * | MultiQ                       |       0xc00c       |               |
- * | Misc                         |       0xd300       | 0xd016-0xd017 |
- * |                              |                    | 0xd021,0xd024 |
- * |                              |                    | 0xd025,0xd029 |
- * |                              |                    | 0xd02a,0xd02e |
- * |                              |                    | 0xd031-0xd0ff |
+ * | Misc                         |       0xd301       | 0xd031-0xd0ff |
  * |                              |                    | 0xd101-0xd1fe |
  * |                              |                    | 0xd214-0xd2fe |
  * | Target Mode                 |       0xe080       |                |
- * | Target Mode Management      |       0xf096       | 0xf002         |
+ * | Target Mode Management      |       0xf09b       | 0xf002         |
  * |                              |                    | 0xf046-0xf049  |
  * | Target Mode Task Management  |      0x1000d      |                |
  * ----------------------------------------------------------------------
index 388d790..9872f34 100644 (file)
 #define LOOP_DOWN_TIME                 255     /* 240 */
 #define        LOOP_DOWN_RESET                 (LOOP_DOWN_TIME - 30)
 
-#define DEFAULT_OUTSTANDING_COMMANDS   1024
+#define DEFAULT_OUTSTANDING_COMMANDS   4096
 #define MIN_OUTSTANDING_COMMANDS       128
 
 /* ISP request and response entry counts (37-65535) */
 #define REQUEST_ENTRY_CNT_2200         2048    /* Number of request entries. */
 #define REQUEST_ENTRY_CNT_24XX         2048    /* Number of request entries. */
 #define REQUEST_ENTRY_CNT_83XX         8192    /* Number of request entries. */
+#define RESPONSE_ENTRY_CNT_83XX                4096    /* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_2100                64      /* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_2300                512     /* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_MQ          128     /* Number of response entries.*/
 #define ATIO_ENTRY_CNT_24XX            4096    /* Number of ATIO entries. */
 #define RESPONSE_ENTRY_CNT_FX00                256     /* Number of response entries.*/
+#define EXTENDED_EXCH_ENTRY_CNT                32768   /* Entries for offload case */
 
 struct req_que;
 struct qla_tgt_sess;
@@ -309,6 +311,14 @@ struct srb_cmd {
 /* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
 #define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
 
+struct els_logo_payload {
+       uint8_t opcode;
+       uint8_t rsvd[3];
+       uint8_t s_id[3];
+       uint8_t rsvd1[1];
+       uint8_t wwpn[WWN_SIZE];
+};
+
 /*
  * SRB extensions.
  */
@@ -322,6 +332,15 @@ struct srb_iocb {
                        uint16_t data[2];
                } logio;
                struct {
+#define ELS_DCMD_TIMEOUT 20
+#define ELS_DCMD_LOGO 0x5
+                       uint32_t flags;
+                       uint32_t els_cmd;
+                       struct completion comp;
+                       struct els_logo_payload *els_logo_pyld;
+                       dma_addr_t els_logo_pyld_dma;
+               } els_logo;
+               struct {
                        /*
                         * Values for flags field below are as
                         * defined in tsk_mgmt_entry struct
@@ -382,7 +401,7 @@ struct srb_iocb {
 #define SRB_FXIOCB_DCMD        10
 #define SRB_FXIOCB_BCMD        11
 #define SRB_ABT_CMD    12
-
+#define SRB_ELS_DCMD   13
 
 typedef struct srb {
        atomic_t ref_count;
@@ -891,6 +910,7 @@ struct mbx_cmd_32 {
 #define MBC_DISABLE_VI                 0x24    /* Disable VI operation. */
 #define MBC_ENABLE_VI                  0x25    /* Enable VI operation. */
 #define MBC_GET_FIRMWARE_OPTION                0x28    /* Get Firmware Options. */
+#define MBC_GET_MEM_OFFLOAD_CNTRL_STAT 0x34    /* Memory Offload ctrl/Stat*/
 #define MBC_SET_FIRMWARE_OPTION                0x38    /* Set Firmware Options. */
 #define MBC_LOOP_PORT_BYPASS           0x40    /* Loop Port Bypass. */
 #define MBC_LOOP_PORT_ENABLE           0x41    /* Loop Port Enable. */
@@ -2695,11 +2715,16 @@ struct isp_operations {
 
 struct scsi_qla_host;
 
+
+#define QLA83XX_RSPQ_MSIX_ENTRY_NUMBER 1 /* refer to qla83xx_msix_entries */
+
 struct qla_msix_entry {
        int have_irq;
        uint32_t vector;
        uint16_t entry;
        struct rsp_que *rsp;
+       struct irq_affinity_notify irq_notify;
+       int cpuid;
 };
 
 #define        WATCH_INTERVAL          1       /* number of seconds */
@@ -2910,12 +2935,15 @@ struct qlt_hw_data {
        uint32_t num_qfull_cmds_dropped;
        spinlock_t q_full_lock;
        uint32_t leak_exchg_thresh_hold;
+       spinlock_t sess_lock;
+       int rspq_vector_cpuid;
+       spinlock_t atio_lock ____cacheline_aligned;
 };
 
 #define MAX_QFULL_CMDS_ALLOC   8192
 #define Q_FULL_THRESH_HOLD_PERCENT 90
 #define Q_FULL_THRESH_HOLD(ha) \
-       ((ha->fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
+       ((ha->cur_fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
 
 #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75      /* 75 percent */
 
@@ -2962,10 +2990,12 @@ struct qla_hw_data {
                uint32_t        isp82xx_no_md_cap:1;
                uint32_t        host_shutting_down:1;
                uint32_t        idc_compl_status:1;
-
                uint32_t        mr_reset_hdlr_active:1;
                uint32_t        mr_intr_valid:1;
+
                uint32_t        fawwpn_enabled:1;
+               uint32_t        exlogins_enabled:1;
+               uint32_t        exchoffld_enabled:1;
                /* 35 bits */
        } flags;
 
@@ -3237,6 +3267,21 @@ struct qla_hw_data {
        void            *async_pd;
        dma_addr_t      async_pd_dma;
 
+#define ENABLE_EXTENDED_LOGIN  BIT_7
+
+       /* Extended Logins  */
+       void            *exlogin_buf;
+       dma_addr_t      exlogin_buf_dma;
+       int             exlogin_size;
+
+#define ENABLE_EXCHANGE_OFFLD  BIT_2
+
+       /* Exchange Offload */
+       void            *exchoffld_buf;
+       dma_addr_t      exchoffld_buf_dma;
+       int             exchoffld_size;
+       int             exchoffld_count;
+
        void            *swl;
 
        /* These are used by mailbox operations. */
@@ -3279,8 +3324,14 @@ struct qla_hw_data {
 #define RISC_START_ADDRESS_2100 0x1000
 #define RISC_START_ADDRESS_2300 0x800
 #define RISC_START_ADDRESS_2400 0x100000
-       uint16_t        fw_xcb_count;
-       uint16_t        fw_iocb_count;
+
+       uint16_t        orig_fw_tgt_xcb_count;
+       uint16_t        cur_fw_tgt_xcb_count;
+       uint16_t        orig_fw_xcb_count;
+       uint16_t        cur_fw_xcb_count;
+       uint16_t        orig_fw_iocb_count;
+       uint16_t        cur_fw_iocb_count;
+       uint16_t        fw_max_fcf_count;
 
        uint32_t        fw_shared_ram_start;
        uint32_t        fw_shared_ram_end;
@@ -3323,6 +3374,9 @@ struct qla_hw_data {
        uint32_t        chain_offset;
        struct dentry *dfs_dir;
        struct dentry *dfs_fce;
+       struct dentry *dfs_tgt_counters;
+       struct dentry *dfs_fw_resource_cnt;
+
        dma_addr_t      fce_dma;
        void            *fce;
        uint32_t        fce_bufs;
@@ -3480,6 +3534,18 @@ struct qla_hw_data {
        int     allow_cna_fw_dump;
 };
 
+struct qla_tgt_counters {
+       uint64_t qla_core_sbt_cmd;
+       uint64_t core_qla_que_buf;
+       uint64_t qla_core_ret_ctio;
+       uint64_t core_qla_snd_status;
+       uint64_t qla_core_ret_sta_ctio;
+       uint64_t core_qla_free_cmd;
+       uint64_t num_q_full_sent;
+       uint64_t num_alloc_iocb_failed;
+       uint64_t num_term_xchg_sent;
+};
+
 /*
  * Qlogic scsi host structure
  */
@@ -3595,6 +3661,10 @@ typedef struct scsi_qla_host {
        atomic_t                generation_tick;
        /* Time when global fcport update has been scheduled */
        int                     total_fcport_update_gen;
+       /* List of pending LOGOs, protected by tgt_mutex */
+       struct list_head        logo_list;
+       /* List of pending PLOGI acks, protected by hw lock */
+       struct list_head        plogi_ack_list;
 
        uint32_t        vp_abort_cnt;
 
@@ -3632,6 +3702,7 @@ typedef struct scsi_qla_host {
 
        atomic_t        vref_count;
        struct qla8044_reset_template reset_tmplt;
+       struct qla_tgt_counters tgt_counters;
 } scsi_qla_host_t;
 
 #define SET_VP_IDX     1
index 15cf074..cd8b96a 100644 (file)
 static struct dentry *qla2x00_dfs_root;
 static atomic_t qla2x00_dfs_root_count;
 
+static int
+qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
+{
+       struct scsi_qla_host *vha = s->private;
+       struct qla_hw_data *ha = vha->hw;
+
+       seq_puts(s, "FW Resource count\n\n");
+       seq_printf(s, "Original TGT exchg count[%d]\n",
+           ha->orig_fw_tgt_xcb_count);
+       seq_printf(s, "current TGT exchg count[%d]\n",
+           ha->cur_fw_tgt_xcb_count);
+       seq_printf(s, "original Initiator Exchange count[%d]\n",
+           ha->orig_fw_xcb_count);
+       seq_printf(s, "Current Initiator Exchange count[%d]\n",
+           ha->cur_fw_xcb_count);
+       seq_printf(s, "Original IOCB count[%d]\n", ha->orig_fw_iocb_count);
+       seq_printf(s, "Current IOCB count[%d]\n", ha->cur_fw_iocb_count);
+       seq_printf(s, "MAX VP count[%d]\n", ha->max_npiv_vports);
+       seq_printf(s, "MAX FCF count[%d]\n", ha->fw_max_fcf_count);
+
+       return 0;
+}
+
+static int
+qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file)
+{
+       struct scsi_qla_host *vha = inode->i_private;
+       return single_open(file, qla_dfs_fw_resource_cnt_show, vha);
+}
+
+static const struct file_operations dfs_fw_resource_cnt_ops = {
+       .open           = qla_dfs_fw_resource_cnt_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int
+qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
+{
+       struct scsi_qla_host *vha = s->private;
+
+       seq_puts(s, "Target Counters\n");
+       seq_printf(s, "qla_core_sbt_cmd = %lld\n",
+               vha->tgt_counters.qla_core_sbt_cmd);
+       seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
+               vha->tgt_counters.qla_core_ret_sta_ctio);
+       seq_printf(s, "qla_core_ret_ctio = %lld\n",
+               vha->tgt_counters.qla_core_ret_ctio);
+       seq_printf(s, "core_qla_que_buf = %lld\n",
+               vha->tgt_counters.core_qla_que_buf);
+       seq_printf(s, "core_qla_snd_status = %lld\n",
+               vha->tgt_counters.core_qla_snd_status);
+       seq_printf(s, "core_qla_free_cmd = %lld\n",
+               vha->tgt_counters.core_qla_free_cmd);
+       seq_printf(s, "num alloc iocb failed = %lld\n",
+               vha->tgt_counters.num_alloc_iocb_failed);
+       seq_printf(s, "num term exchange sent = %lld\n",
+               vha->tgt_counters.num_term_xchg_sent);
+       seq_printf(s, "num Q full sent = %lld\n",
+               vha->tgt_counters.num_q_full_sent);
+
+       return 0;
+}
+
+static int
+qla_dfs_tgt_counters_open(struct inode *inode, struct file *file)
+{
+       struct scsi_qla_host *vha = inode->i_private;
+       return single_open(file, qla_dfs_tgt_counters_show, vha);
+}
+
+static const struct file_operations dfs_tgt_counters_ops = {
+       .open           = qla_dfs_tgt_counters_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static int
 qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
 {
@@ -146,6 +225,22 @@ create_dir:
        atomic_inc(&qla2x00_dfs_root_count);
 
 create_nodes:
+       ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
+           S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
+       if (!ha->dfs_fw_resource_cnt) {
+               ql_log(ql_log_warn, vha, 0x00fd,
+                   "Unable to create debugFS fw_resource_count node.\n");
+               goto out;
+       }
+
+       ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
+           ha->dfs_dir, vha, &dfs_tgt_counters_ops);
+       if (!ha->dfs_tgt_counters) {
+               ql_log(ql_log_warn, vha, 0xd301,
+                   "Unable to create debugFS tgt_counters node.\n");
+               goto out;
+       }
+
        ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
            &dfs_fce_ops);
        if (!ha->dfs_fce) {
@@ -161,6 +256,17 @@ int
 qla2x00_dfs_remove(scsi_qla_host_t *vha)
 {
        struct qla_hw_data *ha = vha->hw;
+
+       if (ha->dfs_fw_resource_cnt) {
+               debugfs_remove(ha->dfs_fw_resource_cnt);
+               ha->dfs_fw_resource_cnt = NULL;
+       }
+
+       if (ha->dfs_tgt_counters) {
+               debugfs_remove(ha->dfs_tgt_counters);
+               ha->dfs_tgt_counters = NULL;
+       }
+
        if (ha->dfs_fce) {
                debugfs_remove(ha->dfs_fce);
                ha->dfs_fce = NULL;
index 7686bfe..0103e46 100644 (file)
@@ -44,6 +44,8 @@ extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
 extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
 extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
 
+extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
+
 extern void qla2x00_update_fcports(scsi_qla_host_t *);
 
 extern int qla2x00_abort_isp(scsi_qla_host_t *);
@@ -117,6 +119,8 @@ extern int ql2xdontresethba;
 extern uint64_t ql2xmaxlun;
 extern int ql2xmdcapmask;
 extern int ql2xmdenable;
+extern int ql2xexlogins;
+extern int ql2xexchoffld;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -135,6 +139,10 @@ extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *,
     uint16_t *);
 extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *,
     fc_port_t *, uint16_t *);
+extern int qla2x00_set_exlogins_buffer(struct scsi_qla_host *);
+extern void qla2x00_free_exlogin_buffer(struct qla_hw_data *);
+extern int qla2x00_set_exchoffld_buffer(struct scsi_qla_host *);
+extern void qla2x00_free_exchoffld_buffer(struct qla_hw_data *);
 
 extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
 
@@ -323,8 +331,7 @@ extern int
 qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
 
 extern int
-qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
-    uint16_t *, uint16_t *, uint16_t *, uint16_t *);
+qla2x00_get_resource_cnts(scsi_qla_host_t *);
 
 extern int
 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
@@ -766,4 +773,11 @@ extern int qla8044_abort_isp(scsi_qla_host_t *);
 extern int qla8044_check_fw_alive(struct scsi_qla_host *);
 
 extern void qlt_host_reset_handler(struct qla_hw_data *ha);
+extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
+       uint16_t *);
+extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
+extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
+extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
+extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
+
 #endif /* _QLA_GBL_H */
index 16a1935..52a8765 100644 (file)
@@ -1766,10 +1766,10 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req)
            (ql2xmultique_tag || ql2xmaxqueues > 1)))
                req->num_outstanding_cmds = DEFAULT_OUTSTANDING_COMMANDS;
        else {
-               if (ha->fw_xcb_count <= ha->fw_iocb_count)
-                       req->num_outstanding_cmds = ha->fw_xcb_count;
+               if (ha->cur_fw_xcb_count <= ha->cur_fw_iocb_count)
+                       req->num_outstanding_cmds = ha->cur_fw_xcb_count;
                else
-                       req->num_outstanding_cmds = ha->fw_iocb_count;
+                       req->num_outstanding_cmds = ha->cur_fw_iocb_count;
        }
 
        req->outstanding_cmds = kzalloc(sizeof(srb_t *) *
@@ -1843,9 +1843,23 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
                        ql_dbg(ql_dbg_init, vha, 0x00ca,
                            "Starting firmware.\n");
 
+                       if (ql2xexlogins)
+                               ha->flags.exlogins_enabled = 1;
+
+                       if (ql2xexchoffld)
+                               ha->flags.exchoffld_enabled = 1;
+
                        rval = qla2x00_execute_fw(vha, srisc_address);
                        /* Retrieve firmware information. */
                        if (rval == QLA_SUCCESS) {
+                               rval = qla2x00_set_exlogins_buffer(vha);
+                               if (rval != QLA_SUCCESS)
+                                       goto failed;
+
+                               rval = qla2x00_set_exchoffld_buffer(vha);
+                               if (rval != QLA_SUCCESS)
+                                       goto failed;
+
 enable_82xx_npiv:
                                fw_major_version = ha->fw_major_version;
                                if (IS_P3P_TYPE(ha))
@@ -1864,9 +1878,7 @@ enable_82xx_npiv:
                                                ha->max_npiv_vports =
                                                    MIN_MULTI_ID_FABRIC - 1;
                                }
-                               qla2x00_get_resource_cnts(vha, NULL,
-                                   &ha->fw_xcb_count, NULL, &ha->fw_iocb_count,
-                                   &ha->max_npiv_vports, NULL);
+                               qla2x00_get_resource_cnts(vha);
 
                                /*
                                 * Allocate the array of outstanding commands
@@ -2248,7 +2260,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
        if (IS_FWI2_CAPABLE(ha)) {
                mid_init_cb->options = cpu_to_le16(BIT_1);
                mid_init_cb->init_cb.execution_throttle =
-                   cpu_to_le16(ha->fw_xcb_count);
+                   cpu_to_le16(ha->cur_fw_xcb_count);
                /* D-Port Status */
                if (IS_DPORT_CAPABLE(ha))
                        mid_init_cb->init_cb.firmware_options_1 |=
@@ -3053,6 +3065,26 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
                        atomic_set(&vha->loop_state, LOOP_READY);
                        ql_dbg(ql_dbg_disc, vha, 0x2069,
                            "LOOP READY.\n");
+
+                       /*
+                        * Process any ATIO queue entries that came in
+                        * while we weren't online.
+                        */
+                       if (qla_tgt_mode_enabled(vha)) {
+                               if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
+                                       spin_lock_irqsave(&ha->tgt.atio_lock,
+                                           flags);
+                                       qlt_24xx_process_atio_queue(vha, 0);
+                                       spin_unlock_irqrestore(
+                                           &ha->tgt.atio_lock, flags);
+                               } else {
+                                       spin_lock_irqsave(&ha->hardware_lock,
+                                           flags);
+                                       qlt_24xx_process_atio_queue(vha, 1);
+                                       spin_unlock_irqrestore(
+                                           &ha->hardware_lock, flags);
+                               }
+                       }
                }
        }
 
@@ -4907,7 +4939,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
        struct qla_hw_data *ha = vha->hw;
        struct req_que *req = ha->req_q_map[0];
        struct rsp_que *rsp = ha->rsp_q_map[0];
-       unsigned long flags;
 
        /* If firmware needs to be loaded */
        if (qla2x00_isp_firmware(vha)) {
@@ -4929,17 +4960,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
                        /* Issue a marker after FW becomes ready. */
                        qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
 
-                       vha->flags.online = 1;
-
-                       /*
-                        * Process any ATIO queue entries that came in
-                        * while we weren't online.
-                        */
-                       spin_lock_irqsave(&ha->hardware_lock, flags);
-                       if (qla_tgt_mode_enabled(vha))
-                               qlt_24xx_process_atio_queue(vha);
-                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
                }
 
index fee9eb7..a6b7f15 100644 (file)
@@ -258,6 +258,8 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
        if ((IS_QLAFX00(sp->fcport->vha->hw)) &&
            (sp->type == SRB_FXIOCB_DCMD))
                init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
+       if (sp->type == SRB_ELS_DCMD)
+               init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
 }
 
 static inline int
index c49df34..b41265a 100644 (file)
@@ -1868,6 +1868,7 @@ skip_cmd_array:
        }
 
 queuing_error:
+       vha->tgt_counters.num_alloc_iocb_failed++;
        return pkt;
 }
 
@@ -2009,6 +2010,190 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
        }
 }
 
+static void
+qla2x00_els_dcmd_sp_free(void *ptr, void *data)
+{
+       struct scsi_qla_host *vha = (scsi_qla_host_t *)ptr;
+       struct qla_hw_data *ha = vha->hw;
+       srb_t *sp = (srb_t *)data;
+       struct srb_iocb *elsio = &sp->u.iocb_cmd;
+
+       kfree(sp->fcport);
+
+       if (elsio->u.els_logo.els_logo_pyld)
+               dma_free_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
+                   elsio->u.els_logo.els_logo_pyld,
+                   elsio->u.els_logo.els_logo_pyld_dma);
+
+       del_timer(&elsio->timer);
+       qla2x00_rel_sp(vha, sp);
+}
+
+static void
+qla2x00_els_dcmd_iocb_timeout(void *data)
+{
+       srb_t *sp = (srb_t *)data;
+       struct srb_iocb *lio = &sp->u.iocb_cmd;
+       fc_port_t *fcport = sp->fcport;
+       struct scsi_qla_host *vha = fcport->vha;
+       struct qla_hw_data *ha = vha->hw;
+       unsigned long flags = 0;
+
+       ql_dbg(ql_dbg_io, vha, 0x3069,
+           "%s Timeout, hdl=%x, portid=%02x%02x%02x\n",
+           sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
+           fcport->d_id.b.al_pa);
+
+       /* Abort the exchange */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       if (ha->isp_ops->abort_command(sp)) {
+               ql_dbg(ql_dbg_io, vha, 0x3070,
+                   "mbx abort_command failed.\n");
+       } else {
+               ql_dbg(ql_dbg_io, vha, 0x3071,
+                   "mbx abort_command success.\n");
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       complete(&lio->u.els_logo.comp);
+}
+
+static void
+qla2x00_els_dcmd_sp_done(void *data, void *ptr, int res)
+{
+       srb_t *sp = (srb_t *)ptr;
+       fc_port_t *fcport = sp->fcport;
+       struct srb_iocb *lio = &sp->u.iocb_cmd;
+       struct scsi_qla_host *vha = fcport->vha;
+
+       ql_dbg(ql_dbg_io, vha, 0x3072,
+           "%s hdl=%x, portid=%02x%02x%02x done\n",
+           sp->name, sp->handle, fcport->d_id.b.domain,
+           fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+       complete(&lio->u.els_logo.comp);
+}
+
+int
+qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
+    port_id_t remote_did)
+{
+       srb_t *sp;
+       fc_port_t *fcport = NULL;
+       struct srb_iocb *elsio = NULL;
+       struct qla_hw_data *ha = vha->hw;
+       struct els_logo_payload logo_pyld;
+       int rval = QLA_SUCCESS;
+
+       fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
+       if (!fcport) {
+              ql_log(ql_log_info, vha, 0x70e5, "fcport allocation failed\n");
+              return -ENOMEM;
+       }
+
+       /* Alloc SRB structure */
+       sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+       if (!sp) {
+               kfree(fcport);
+               ql_log(ql_log_info, vha, 0x70e6,
+                "SRB allocation failed\n");
+               return -ENOMEM;
+       }
+
+       elsio = &sp->u.iocb_cmd;
+       fcport->loop_id = 0xFFFF;
+       fcport->d_id.b.domain = remote_did.b.domain;
+       fcport->d_id.b.area = remote_did.b.area;
+       fcport->d_id.b.al_pa = remote_did.b.al_pa;
+
+       ql_dbg(ql_dbg_io, vha, 0x3073, "portid=%02x%02x%02x done\n",
+           fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+       sp->type = SRB_ELS_DCMD;
+       sp->name = "ELS_DCMD";
+       sp->fcport = fcport;
+       qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
+       elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
+       sp->done = qla2x00_els_dcmd_sp_done;
+       sp->free = qla2x00_els_dcmd_sp_free;
+
+       elsio->u.els_logo.els_logo_pyld = dma_alloc_coherent(&ha->pdev->dev,
+                           DMA_POOL_SIZE, &elsio->u.els_logo.els_logo_pyld_dma,
+                           GFP_KERNEL);
+
+       if (!elsio->u.els_logo.els_logo_pyld) {
+               sp->free(vha, sp);
+               return QLA_FUNCTION_FAILED;
+       }
+
+       memset(&logo_pyld, 0, sizeof(struct els_logo_payload));
+
+       elsio->u.els_logo.els_cmd = els_opcode;
+       logo_pyld.opcode = els_opcode;
+       logo_pyld.s_id[0] = vha->d_id.b.al_pa;
+       logo_pyld.s_id[1] = vha->d_id.b.area;
+       logo_pyld.s_id[2] = vha->d_id.b.domain;
+       host_to_fcp_swap(logo_pyld.s_id, sizeof(uint32_t));
+       memcpy(&logo_pyld.wwpn, vha->port_name, WWN_SIZE);
+
+       memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld,
+           sizeof(struct els_logo_payload));
+
+       rval = qla2x00_start_sp(sp);
+       if (rval != QLA_SUCCESS) {
+               sp->free(vha, sp);
+               return QLA_FUNCTION_FAILED;
+       }
+
+       ql_dbg(ql_dbg_io, vha, 0x3074,
+           "%s LOGO sent, hdl=%x, loopid=%x, portid=%02x%02x%02x.\n",
+           sp->name, sp->handle, fcport->loop_id, fcport->d_id.b.domain,
+           fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+       wait_for_completion(&elsio->u.els_logo.comp);
+
+       sp->free(vha, sp);
+       return rval;
+}
+
+static void
+qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
+{
+       scsi_qla_host_t *vha = sp->fcport->vha;
+       struct srb_iocb *elsio = &sp->u.iocb_cmd;
+
+       els_iocb->entry_type = ELS_IOCB_TYPE;
+       els_iocb->entry_count = 1;
+       els_iocb->sys_define = 0;
+       els_iocb->entry_status = 0;
+       els_iocb->handle = sp->handle;
+       els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+       els_iocb->tx_dsd_count = 1;
+       els_iocb->vp_index = vha->vp_idx;
+       els_iocb->sof_type = EST_SOFI3;
+       els_iocb->rx_dsd_count = 0;
+       els_iocb->opcode = elsio->u.els_logo.els_cmd;
+
+       els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
+       els_iocb->port_id[1] = sp->fcport->d_id.b.area;
+       els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
+       els_iocb->control_flags = 0;
+
+       els_iocb->tx_byte_count = sizeof(struct els_logo_payload);
+       els_iocb->tx_address[0] =
+           cpu_to_le32(LSD(elsio->u.els_logo.els_logo_pyld_dma));
+       els_iocb->tx_address[1] =
+           cpu_to_le32(MSD(elsio->u.els_logo.els_logo_pyld_dma));
+       els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload));
+
+       els_iocb->rx_byte_count = 0;
+       els_iocb->rx_address[0] = 0;
+       els_iocb->rx_address[1] = 0;
+       els_iocb->rx_len = 0;
+
+       sp->fcport->vha->qla_stats.control_requests++;
+}
+
 static void
 qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
 {
@@ -2623,6 +2808,9 @@ qla2x00_start_sp(srb_t *sp)
                        qlafx00_abort_iocb(sp, pkt) :
                        qla24xx_abort_iocb(sp, pkt);
                break;
+       case SRB_ELS_DCMD:
+               qla24xx_els_logo_iocb(sp, pkt);
+               break;
        default:
                break;
        }
index ccf6a7f..d4d65eb 100644 (file)
@@ -18,6 +18,10 @@ static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
 static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
 static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
        sts_entry_t *);
+static void qla_irq_affinity_notify(struct irq_affinity_notify *,
+    const cpumask_t *);
+static void qla_irq_affinity_release(struct kref *);
+
 
 /**
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
@@ -1418,6 +1422,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
        case SRB_CT_CMD:
                type = "ct pass-through";
                break;
+       case SRB_ELS_DCMD:
+               type = "Driver ELS logo";
+               ql_dbg(ql_dbg_user, vha, 0x5047,
+                   "Completing %s: (%p) type=%d.\n", type, sp, sp->type);
+               sp->done(vha, sp, 0);
+               return;
        default:
                ql_dbg(ql_dbg_user, vha, 0x503e,
                    "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
@@ -2542,6 +2552,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
        if (!vha->flags.online)
                return;
 
+       if (rsp->msix->cpuid != smp_processor_id()) {
+               /* if kernel does not notify qla of IRQ's CPU change,
+                * then set it here.
+                */
+               rsp->msix->cpuid = smp_processor_id();
+               ha->tgt.rspq_vector_cpuid = rsp->msix->cpuid;
+       }
+
        while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
                pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
 
@@ -2587,8 +2605,14 @@ process_err:
                        qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
                        break;
                case ABTS_RECV_24XX:
-                       /* ensure that the ATIO queue is empty */
-                       qlt_24xx_process_atio_queue(vha);
+                       if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+                               /* ensure that the ATIO queue is empty */
+                               qlt_handle_abts_recv(vha, (response_t *)pkt);
+                               break;
+                       } else {
+                               /* drop through */
+                               qlt_24xx_process_atio_queue(vha, 1);
+                       }
                case ABTS_RESP_24XX:
                case CTIO_TYPE7:
                case NOTIFY_ACK_TYPE:
@@ -2755,13 +2779,22 @@ qla24xx_intr_handler(int irq, void *dev_id)
                case INTR_RSP_QUE_UPDATE_83XX:
                        qla24xx_process_response_queue(vha, rsp);
                        break;
-               case INTR_ATIO_QUE_UPDATE:
-                       qlt_24xx_process_atio_queue(vha);
+               case INTR_ATIO_QUE_UPDATE:{
+                       unsigned long flags2;
+                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+                       qlt_24xx_process_atio_queue(vha, 1);
+                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
                        break;
-               case INTR_ATIO_RSP_QUE_UPDATE:
-                       qlt_24xx_process_atio_queue(vha);
+               }
+               case INTR_ATIO_RSP_QUE_UPDATE: {
+                       unsigned long flags2;
+                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+                       qlt_24xx_process_atio_queue(vha, 1);
+                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
+
                        qla24xx_process_response_queue(vha, rsp);
                        break;
+               }
                default:
                        ql_dbg(ql_dbg_async, vha, 0x504f,
                            "Unrecognized interrupt type (%d).\n", stat * 0xff);
@@ -2920,13 +2953,22 @@ qla24xx_msix_default(int irq, void *dev_id)
                case INTR_RSP_QUE_UPDATE_83XX:
                        qla24xx_process_response_queue(vha, rsp);
                        break;
-               case INTR_ATIO_QUE_UPDATE:
-                       qlt_24xx_process_atio_queue(vha);
+               case INTR_ATIO_QUE_UPDATE:{
+                       unsigned long flags2;
+                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+                       qlt_24xx_process_atio_queue(vha, 1);
+                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
                        break;
-               case INTR_ATIO_RSP_QUE_UPDATE:
-                       qlt_24xx_process_atio_queue(vha);
+               }
+               case INTR_ATIO_RSP_QUE_UPDATE: {
+                       unsigned long flags2;
+                       spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
+                       qlt_24xx_process_atio_queue(vha, 1);
+                       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
+
                        qla24xx_process_response_queue(vha, rsp);
                        break;
+               }
                default:
                        ql_dbg(ql_dbg_async, vha, 0x5051,
                            "Unrecognized interrupt type (%d).\n", stat & 0xff);
@@ -2973,8 +3015,11 @@ qla24xx_disable_msix(struct qla_hw_data *ha)
 
        for (i = 0; i < ha->msix_count; i++) {
                qentry = &ha->msix_entries[i];
-               if (qentry->have_irq)
+               if (qentry->have_irq) {
+                       /* un-register irq cpu affinity notification */
+                       irq_set_affinity_notifier(qentry->vector, NULL);
                        free_irq(qentry->vector, qentry->rsp);
+               }
        }
        pci_disable_msix(ha->pdev);
        kfree(ha->msix_entries);
@@ -3037,6 +3082,9 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
                qentry->entry = entries[i].entry;
                qentry->have_irq = 0;
                qentry->rsp = NULL;
+               qentry->irq_notify.notify  = qla_irq_affinity_notify;
+               qentry->irq_notify.release = qla_irq_affinity_release;
+               qentry->cpuid = -1;
        }
 
        /* Enable MSI-X vectors for the base queue */
@@ -3055,6 +3103,18 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
                qentry->have_irq = 1;
                qentry->rsp = rsp;
                rsp->msix = qentry;
+
+               /* Register for CPU affinity notification. */
+               irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify);
+
+               /* Schedule work (ie. trigger a notification) to read cpu
+                * mask for this specific irq.
+                * kref_get is required because
+               * irq_affinity_notify() will do
+               * kref_put().
+               */
+               kref_get(&qentry->irq_notify.kref);
+               schedule_work(&qentry->irq_notify.work);
        }
 
        /*
@@ -3234,3 +3294,47 @@ int qla25xx_request_irq(struct rsp_que *rsp)
        msix->rsp = rsp;
        return ret;
 }
+
+
+/* irq_set_affinity/irqbalance will trigger notification of cpu mask update */
+static void qla_irq_affinity_notify(struct irq_affinity_notify *notify,
+       const cpumask_t *mask)
+{
+       struct qla_msix_entry *e =
+               container_of(notify, struct qla_msix_entry, irq_notify);
+       struct qla_hw_data *ha;
+       struct scsi_qla_host *base_vha;
+
+       /* user is recommended to set mask to just 1 cpu */
+       e->cpuid = cpumask_first(mask);
+
+       ha = e->rsp->hw;
+       base_vha = pci_get_drvdata(ha->pdev);
+
+       ql_dbg(ql_dbg_init, base_vha, 0xffff,
+           "%s: host %ld : vector %d cpu %d \n", __func__,
+           base_vha->host_no, e->vector, e->cpuid);
+
+       if (e->have_irq) {
+               if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) &&
+                   (e->entry == QLA83XX_RSPQ_MSIX_ENTRY_NUMBER)) {
+                       ha->tgt.rspq_vector_cpuid = e->cpuid;
+                       ql_dbg(ql_dbg_init, base_vha, 0xffff,
+                           "%s: host%ld: rspq vector %d cpu %d  runtime change\n",
+                           __func__, base_vha->host_no, e->vector, e->cpuid);
+               }
+       }
+}
+
+static void qla_irq_affinity_release(struct kref *ref)
+{
+       struct irq_affinity_notify *notify =
+               container_of(ref, struct irq_affinity_notify, kref);
+       struct qla_msix_entry *e =
+               container_of(notify, struct qla_msix_entry, irq_notify);
+       struct scsi_qla_host *base_vha = pci_get_drvdata(e->rsp->hw->pdev);
+
+       ql_dbg(ql_dbg_init, base_vha, 0xffff,
+           "%s: host%ld: vector %d cpu %d \n", __func__,
+           base_vha->host_no, e->vector, e->cpuid);
+}
index cb11e04..87e6758 100644 (file)
@@ -489,6 +489,13 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
                            EXTENDED_BB_CREDITS);
                } else
                        mcp->mb[4] = 0;
+
+               if (ha->flags.exlogins_enabled)
+                       mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
+
+               if (ha->flags.exchoffld_enabled)
+                       mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
+
                mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
                mcp->in_mb |= MBX_1;
        } else {
@@ -520,6 +527,226 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
        return rval;
 }
 
+/*
+ * qla_get_exlogin_status
+ *     Get extended login status
+ *     uses the memory offload control/status Mailbox
+ *
+ * Input:
+ *     ha:             adapter state pointer.
+ *     fwopt:          firmware options
+ *
+ * Returns:
+ *     qla2x00 local function status
+ *
+ * Context:
+ *     Kernel context.
+ */
+#define        FETCH_XLOGINS_STAT      0x8
+int
+qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
+       uint16_t *ex_logins_cnt)
+{
+       int rval;
+       mbx_cmd_t       mc;
+       mbx_cmd_t       *mcp = &mc;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
+           "Entered %s\n", __func__);
+
+       memset(mcp->mb, 0 , sizeof(mcp->mb));
+       mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+       mcp->mb[1] = FETCH_XLOGINS_STAT;
+       mcp->out_mb = MBX_1|MBX_0;
+       mcp->in_mb = MBX_10|MBX_4|MBX_0;
+       mcp->tov = MBX_TOV_SECONDS;
+       mcp->flags = 0;
+
+       rval = qla2x00_mailbox_command(vha, mcp);
+       if (rval != QLA_SUCCESS) {
+               ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
+       } else {
+               *buf_sz = mcp->mb[4];
+               *ex_logins_cnt = mcp->mb[10];
+
+               ql_log(ql_log_info, vha, 0x1190,
+                   "buffer size 0x%x, exchange login count=%d\n",
+                   mcp->mb[4], mcp->mb[10]);
+
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
+                   "Done %s.\n", __func__);
+       }
+
+       return rval;
+}
+
+/*
+ * qla_set_exlogin_mem_cfg
+ *     set extended login memory configuration
+ *     Mbx needs to be issues before init_cb is set
+ *
+ * Input:
+ *     ha:             adapter state pointer.
+ *     buffer:         buffer pointer
+ *     phys_addr:      physical address of buffer
+ *     size:           size of buffer
+ *     TARGET_QUEUE_LOCK must be released
+ *     ADAPTER_STATE_LOCK must be release
+ *
+ * Returns:
+ *     qla2x00 local funxtion status code.
+ *
+ * Context:
+ *     Kernel context.
+ */
+#define CONFIG_XLOGINS_MEM     0x3
+int
+qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
+{
+       int             rval;
+       mbx_cmd_t       mc;
+       mbx_cmd_t       *mcp = &mc;
+       struct qla_hw_data *ha = vha->hw;
+       int configured_count;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
+           "Entered %s.\n", __func__);
+
+       memset(mcp->mb, 0 , sizeof(mcp->mb));
+       mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+       mcp->mb[1] = CONFIG_XLOGINS_MEM;
+       mcp->mb[2] = MSW(phys_addr);
+       mcp->mb[3] = LSW(phys_addr);
+       mcp->mb[6] = MSW(MSD(phys_addr));
+       mcp->mb[7] = LSW(MSD(phys_addr));
+       mcp->mb[8] = MSW(ha->exlogin_size);
+       mcp->mb[9] = LSW(ha->exlogin_size);
+       mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+       mcp->in_mb = MBX_11|MBX_0;
+       mcp->tov = MBX_TOV_SECONDS;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(vha, mcp);
+       if (rval != QLA_SUCCESS) {
+               /*EMPTY*/
+               ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
+       } else {
+               configured_count = mcp->mb[11];
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
+                   "Done %s.\n", __func__);
+       }
+
+       return rval;
+}
+
+/*
+ * qla_get_exchoffld_status
+ *     Get exchange offload status
+ *     uses the memory offload control/status Mailbox
+ *
+ * Input:
+ *     ha:             adapter state pointer.
+ *     fwopt:          firmware options
+ *
+ * Returns:
+ *     qla2x00 local function status
+ *
+ * Context:
+ *     Kernel context.
+ */
+#define        FETCH_XCHOFFLD_STAT     0x2
+int
+qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
+       uint16_t *ex_logins_cnt)
+{
+       int rval;
+       mbx_cmd_t       mc;
+       mbx_cmd_t       *mcp = &mc;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
+           "Entered %s\n", __func__);
+
+       memset(mcp->mb, 0 , sizeof(mcp->mb));
+       mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+       mcp->mb[1] = FETCH_XCHOFFLD_STAT;
+       mcp->out_mb = MBX_1|MBX_0;
+       mcp->in_mb = MBX_10|MBX_4|MBX_0;
+       mcp->tov = MBX_TOV_SECONDS;
+       mcp->flags = 0;
+
+       rval = qla2x00_mailbox_command(vha, mcp);
+       if (rval != QLA_SUCCESS) {
+               ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
+       } else {
+               *buf_sz = mcp->mb[4];
+               *ex_logins_cnt = mcp->mb[10];
+
+               ql_log(ql_log_info, vha, 0x118e,
+                   "buffer size 0x%x, exchange offload count=%d\n",
+                   mcp->mb[4], mcp->mb[10]);
+
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
+                   "Done %s.\n", __func__);
+       }
+
+       return rval;
+}
+
+/*
+ * qla_set_exchoffld_mem_cfg
+ *     Set exchange offload memory configuration
+ *     Mbx needs to be issues before init_cb is set
+ *
+ * Input:
+ *     ha:             adapter state pointer.
+ *     buffer:         buffer pointer
+ *     phys_addr:      physical address of buffer
+ *     size:           size of buffer
+ *     TARGET_QUEUE_LOCK must be released
+ *     ADAPTER_STATE_LOCK must be release
+ *
+ * Returns:
+ *     qla2x00 local funxtion status code.
+ *
+ * Context:
+ *     Kernel context.
+ */
+#define CONFIG_XCHOFFLD_MEM    0x3
+int
+qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
+{
+       int             rval;
+       mbx_cmd_t       mc;
+       mbx_cmd_t       *mcp = &mc;
+       struct qla_hw_data *ha = vha->hw;
+
+       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
+           "Entered %s.\n", __func__);
+
+       memset(mcp->mb, 0 , sizeof(mcp->mb));
+       mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
+       mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
+       mcp->mb[2] = MSW(phys_addr);
+       mcp->mb[3] = LSW(phys_addr);
+       mcp->mb[6] = MSW(MSD(phys_addr));
+       mcp->mb[7] = LSW(MSD(phys_addr));
+       mcp->mb[8] = MSW(ha->exlogin_size);
+       mcp->mb[9] = LSW(ha->exlogin_size);
+       mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+       mcp->in_mb = MBX_11|MBX_0;
+       mcp->tov = MBX_TOV_SECONDS;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(vha, mcp);
+       if (rval != QLA_SUCCESS) {
+               /*EMPTY*/
+               ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
+       } else {
+               ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
+                   "Done %s.\n", __func__);
+       }
+
+       return rval;
+}
+
 /*
  * qla2x00_get_fw_version
  *     Get firmware version.
@@ -594,6 +821,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
                ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
                    "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
                    __func__, mcp->mb[17], mcp->mb[16]);
+
+               if (ha->fw_attributes_h & 0x4)
+                       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
+                           "%s: Firmware supports Extended Login 0x%x\n",
+                           __func__, ha->fw_attributes_h);
+
+               if (ha->fw_attributes_h & 0x8)
+                       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
+                           "%s: Firmware supports Exchange Offload 0x%x\n",
+                           __func__, ha->fw_attributes_h);
        }
 
        if (IS_QLA27XX(ha)) {
@@ -2383,10 +2620,9 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
  *     Kernel context.
  */
 int
-qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
-    uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
-    uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
+qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
 {
+       struct qla_hw_data *ha = vha->hw;
        int rval;
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
@@ -2414,19 +2650,16 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
                    mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
                    mcp->mb[11], mcp->mb[12]);
 
-               if (cur_xchg_cnt)
-                       *cur_xchg_cnt = mcp->mb[3];
-               if (orig_xchg_cnt)
-                       *orig_xchg_cnt = mcp->mb[6];
-               if (cur_iocb_cnt)
-                       *cur_iocb_cnt = mcp->mb[7];
-               if (orig_iocb_cnt)
-                       *orig_iocb_cnt = mcp->mb[10];
-               if (vha->hw->flags.npiv_supported && max_npiv_vports)
-                       *max_npiv_vports = mcp->mb[11];
-               if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) ||
-                   IS_QLA27XX(vha->hw)) && max_fcfs)
-                       *max_fcfs = mcp->mb[12];
+               ha->orig_fw_tgt_xcb_count =  mcp->mb[1];
+               ha->cur_fw_tgt_xcb_count = mcp->mb[2];
+               ha->cur_fw_xcb_count = mcp->mb[3];
+               ha->orig_fw_xcb_count = mcp->mb[6];
+               ha->cur_fw_iocb_count = mcp->mb[7];
+               ha->orig_fw_iocb_count = mcp->mb[10];
+               if (ha->flags.npiv_supported)
+                       ha->max_npiv_vports = mcp->mb[11];
+               if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+                       ha->fw_max_fcf_count = mcp->mb[12];
        }
 
        return (rval);
index 6be32fd..f1788db 100644 (file)
@@ -221,6 +221,18 @@ MODULE_PARM_DESC(ql2xmdenable,
                "0 - MiniDump disabled. "
                "1 (Default) - MiniDump enabled.");
 
+int ql2xexlogins = 0;
+module_param(ql2xexlogins, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xexlogins,
+                "Number of extended Logins. "
+                "0 (Default)- Disabled.");
+
+int ql2xexchoffld = 0;
+module_param(ql2xexchoffld, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xexchoffld,
+                "Number of exchanges to offload. "
+                "0 (Default)- Disabled.");
+
 /*
  * SCSI host template entry points
  */
@@ -2324,6 +2336,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->tgt.enable_class_2 = ql2xenableclass2;
        INIT_LIST_HEAD(&ha->tgt.q_full_list);
        spin_lock_init(&ha->tgt.q_full_lock);
+       spin_lock_init(&ha->tgt.sess_lock);
+       spin_lock_init(&ha->tgt.atio_lock);
+
 
        /* Clear our data area */
        ha->bars = bars;
@@ -2468,7 +2483,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
                req_length = REQUEST_ENTRY_CNT_83XX;
-               rsp_length = RESPONSE_ENTRY_CNT_2300;
+               rsp_length = RESPONSE_ENTRY_CNT_83XX;
                ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
                ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
                ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
@@ -2498,8 +2513,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->portnum = PCI_FUNC(ha->pdev->devfn);
                ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
-               req_length = REQUEST_ENTRY_CNT_24XX;
-               rsp_length = RESPONSE_ENTRY_CNT_2300;
+               req_length = REQUEST_ENTRY_CNT_83XX;
+               rsp_length = RESPONSE_ENTRY_CNT_83XX;
                ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
                ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
                ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
@@ -3128,6 +3143,14 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
        base_vha->flags.online = 0;
 
+       /* free DMA memory */
+       if (ha->exlogin_buf)
+               qla2x00_free_exlogin_buffer(ha);
+
+       /* free DMA memory */
+       if (ha->exchoffld_buf)
+               qla2x00_free_exchoffld_buffer(ha);
+
        qla2x00_destroy_deferred_work(ha);
 
        qlt_remove_target(ha, base_vha);
@@ -3587,6 +3610,140 @@ fail:
        return -ENOMEM;
 }
 
+int
+qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
+{
+       int rval;
+       uint16_t        size, max_cnt, temp;
+       struct qla_hw_data *ha = vha->hw;
+
+       /* Return if we don't need to alloacate any extended logins */
+       if (!ql2xexlogins)
+               return QLA_SUCCESS;
+
+       ql_log(ql_log_info, vha, 0xd021, "EXLOGIN count: %d.\n", ql2xexlogins);
+       max_cnt = 0;
+       rval = qla_get_exlogin_status(vha, &size, &max_cnt);
+       if (rval != QLA_SUCCESS) {
+               ql_log_pci(ql_log_fatal, ha->pdev, 0xd029,
+                   "Failed to get exlogin status.\n");
+               return rval;
+       }
+
+       temp = (ql2xexlogins > max_cnt) ? max_cnt : ql2xexlogins;
+       ha->exlogin_size = (size * temp);
+       ql_log(ql_log_info, vha, 0xd024,
+               "EXLOGIN: max_logins=%d, portdb=0x%x, total=%d.\n",
+               max_cnt, size, temp);
+
+       ql_log(ql_log_info, vha, 0xd025, "EXLOGIN: requested size=0x%x\n",
+               ha->exlogin_size);
+
+       /* Get consistent memory for extended logins */
+       ha->exlogin_buf = dma_alloc_coherent(&ha->pdev->dev,
+           ha->exlogin_size, &ha->exlogin_buf_dma, GFP_KERNEL);
+       if (!ha->exlogin_buf) {
+               ql_log_pci(ql_log_fatal, ha->pdev, 0xd02a,
+                   "Failed to allocate memory for exlogin_buf_dma.\n");
+               return -ENOMEM;
+       }
+
+       /* Now configure the dma buffer */
+       rval = qla_set_exlogin_mem_cfg(vha, ha->exlogin_buf_dma);
+       if (rval) {
+               ql_log(ql_log_fatal, vha, 0x00cf,
+                   "Setup extended login buffer  ****FAILED****.\n");
+               qla2x00_free_exlogin_buffer(ha);
+       }
+
+       return rval;
+}
+
+/*
+* qla2x00_free_exlogin_buffer
+*
+* Input:
+*      ha = adapter block pointer
+*/
+void
+qla2x00_free_exlogin_buffer(struct qla_hw_data *ha)
+{
+       if (ha->exlogin_buf) {
+               dma_free_coherent(&ha->pdev->dev, ha->exlogin_size,
+                   ha->exlogin_buf, ha->exlogin_buf_dma);
+               ha->exlogin_buf = NULL;
+               ha->exlogin_size = 0;
+       }
+}
+
+int
+qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
+{
+       int rval;
+       uint16_t        size, max_cnt, temp;
+       struct qla_hw_data *ha = vha->hw;
+
+       /* Return if we don't need to alloacate any extended logins */
+       if (!ql2xexchoffld)
+               return QLA_SUCCESS;
+
+       ql_log(ql_log_info, vha, 0xd014,
+           "Exchange offload count: %d.\n", ql2xexlogins);
+
+       max_cnt = 0;
+       rval = qla_get_exchoffld_status(vha, &size, &max_cnt);
+       if (rval != QLA_SUCCESS) {
+               ql_log_pci(ql_log_fatal, ha->pdev, 0xd012,
+                   "Failed to get exlogin status.\n");
+               return rval;
+       }
+
+       temp = (ql2xexchoffld > max_cnt) ? max_cnt : ql2xexchoffld;
+       ha->exchoffld_size = (size * temp);
+       ql_log(ql_log_info, vha, 0xd016,
+               "Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
+               max_cnt, size, temp);
+
+       ql_log(ql_log_info, vha, 0xd017,
+           "Exchange Buffers requested size = 0x%x\n", ha->exchoffld_size);
+
+       /* Get consistent memory for extended logins */
+       ha->exchoffld_buf = dma_alloc_coherent(&ha->pdev->dev,
+           ha->exchoffld_size, &ha->exchoffld_buf_dma, GFP_KERNEL);
+       if (!ha->exchoffld_buf) {
+               ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
+                   "Failed to allocate memory for exchoffld_buf_dma.\n");
+               return -ENOMEM;
+       }
+
+       /* Now configure the dma buffer */
+       rval = qla_set_exchoffld_mem_cfg(vha, ha->exchoffld_buf_dma);
+       if (rval) {
+               ql_log(ql_log_fatal, vha, 0xd02e,
+                   "Setup exchange offload buffer ****FAILED****.\n");
+               qla2x00_free_exchoffld_buffer(ha);
+       }
+
+       return rval;
+}
+
+/*
+* qla2x00_free_exchoffld_buffer
+*
+* Input:
+*      ha = adapter block pointer
+*/
+void
+qla2x00_free_exchoffld_buffer(struct qla_hw_data *ha)
+{
+       if (ha->exchoffld_buf) {
+               dma_free_coherent(&ha->pdev->dev, ha->exchoffld_size,
+                   ha->exchoffld_buf, ha->exchoffld_buf_dma);
+               ha->exchoffld_buf = NULL;
+               ha->exchoffld_size = 0;
+       }
+}
+
 /*
 * qla2x00_free_fw_dump
 *      Frees fw dump stuff.
@@ -3766,6 +3923,8 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
        INIT_LIST_HEAD(&vha->list);
        INIT_LIST_HEAD(&vha->qla_cmd_list);
        INIT_LIST_HEAD(&vha->qla_sess_op_cmd_list);
+       INIT_LIST_HEAD(&vha->logo_list);
+       INIT_LIST_HEAD(&vha->plogi_ack_list);
 
        spin_lock_init(&vha->work_lock);
        spin_lock_init(&vha->cmd_list_lock);
index 75514a1..8075a4c 100644 (file)
@@ -100,7 +100,7 @@ enum fcp_resp_rsp_codes {
  */
 /* Predefs for callbacks handed to qla2xxx LLD */
 static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha,
-       struct atio_from_isp *pkt);
+       struct atio_from_isp *pkt, uint8_t);
 static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
 static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
        int fn, void *iocb, int flags);
@@ -118,10 +118,13 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
        struct imm_ntfy_from_isp *ntfy,
        uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
        uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan);
+static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
+       struct imm_ntfy_from_isp *imm, int ha_locked);
 /*
  * Global Variables
  */
 static struct kmem_cache *qla_tgt_mgmt_cmd_cachep;
+static struct kmem_cache *qla_tgt_plogi_cachep;
 static mempool_t *qla_tgt_mgmt_cmd_mempool;
 static struct workqueue_struct *qla_tgt_wq;
 static DEFINE_MUTEX(qla_tgt_mutex);
@@ -226,8 +229,8 @@ static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha)
        spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
 }
 
-static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
-       struct atio_from_isp *atio)
+static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
+       struct atio_from_isp *atio, uint8_t ha_locked)
 {
        ql_dbg(ql_dbg_tgt, vha, 0xe072,
                "%s: qla_target(%d): type %x ox_id %04x\n",
@@ -248,7 +251,7 @@ static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
                            atio->u.isp24.fcp_hdr.d_id[2]);
                        break;
                }
-               qlt_24xx_atio_pkt(host, atio);
+               qlt_24xx_atio_pkt(host, atio, ha_locked);
                break;
        }
 
@@ -271,7 +274,7 @@ static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
                                break;
                        }
                }
-               qlt_24xx_atio_pkt(host, atio);
+               qlt_24xx_atio_pkt(host, atio, ha_locked);
                break;
        }
 
@@ -282,7 +285,7 @@ static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
                break;
        }
 
-       return;
+       return false;
 }
 
 void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
@@ -389,6 +392,131 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
 
 }
 
+/*
+ * All qlt_plogi_ack_t operations are protected by hardware_lock
+ */
+
+/*
+ * This is a zero-base ref-counting solution, since hardware_lock
+ * guarantees that ref_count is not modified concurrently.
+ * Upon successful return content of iocb is undefined
+ */
+static qlt_plogi_ack_t *
+qlt_plogi_ack_find_add(struct scsi_qla_host *vha, port_id_t *id,
+                      struct imm_ntfy_from_isp *iocb)
+{
+       qlt_plogi_ack_t *pla;
+
+       list_for_each_entry(pla, &vha->plogi_ack_list, list) {
+               if (pla->id.b24 == id->b24) {
+                       qlt_send_term_imm_notif(vha, &pla->iocb, 1);
+                       pla->iocb = *iocb;
+                       return pla;
+               }
+       }
+
+       pla = kmem_cache_zalloc(qla_tgt_plogi_cachep, GFP_ATOMIC);
+       if (!pla) {
+               ql_dbg(ql_dbg_async, vha, 0x5088,
+                      "qla_target(%d): Allocation of plogi_ack failed\n",
+                      vha->vp_idx);
+               return NULL;
+       }
+
+       pla->iocb = *iocb;
+       pla->id = *id;
+       list_add_tail(&pla->list, &vha->plogi_ack_list);
+
+       return pla;
+}
+
+static void qlt_plogi_ack_unref(struct scsi_qla_host *vha, qlt_plogi_ack_t *pla)
+{
+       BUG_ON(!pla->ref_count);
+       pla->ref_count--;
+
+       if (pla->ref_count)
+               return;
+
+       ql_dbg(ql_dbg_async, vha, 0x5089,
+           "Sending PLOGI ACK to wwn %8phC s_id %02x:%02x:%02x loop_id %#04x"
+           " exch %#x ox_id %#x\n", pla->iocb.u.isp24.port_name,
+           pla->iocb.u.isp24.port_id[2], pla->iocb.u.isp24.port_id[1],
+           pla->iocb.u.isp24.port_id[0],
+           le16_to_cpu(pla->iocb.u.isp24.nport_handle),
+           pla->iocb.u.isp24.exchange_address, pla->iocb.ox_id);
+       qlt_send_notify_ack(vha, &pla->iocb, 0, 0, 0, 0, 0, 0);
+
+       list_del(&pla->list);
+       kmem_cache_free(qla_tgt_plogi_cachep, pla);
+}
+
+static void
+qlt_plogi_ack_link(struct scsi_qla_host *vha, qlt_plogi_ack_t *pla,
+    struct qla_tgt_sess *sess, qlt_plogi_link_t link)
+{
+       /* Inc ref_count first because link might already be pointing at pla */
+       pla->ref_count++;
+
+       if (sess->plogi_link[link])
+               qlt_plogi_ack_unref(vha, sess->plogi_link[link]);
+
+       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf097,
+           "Linking sess %p [%d] wwn %8phC with PLOGI ACK to wwn %8phC"
+           " s_id %02x:%02x:%02x, ref=%d\n", sess, link, sess->port_name,
+           pla->iocb.u.isp24.port_name, pla->iocb.u.isp24.port_id[2],
+           pla->iocb.u.isp24.port_id[1], pla->iocb.u.isp24.port_id[0],
+           pla->ref_count);
+
+       sess->plogi_link[link] = pla;
+}
+
+typedef struct {
+       /* These fields must be initialized by the caller */
+       port_id_t id;
+       /*
+        * number of cmds dropped while we were waiting for
+        * initiator to ack LOGO initialize to 1 if LOGO is
+        * triggered by a command, otherwise, to 0
+        */
+       int cmd_count;
+
+       /* These fields are used by callee */
+       struct list_head list;
+} qlt_port_logo_t;
+
+static void
+qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
+{
+       qlt_port_logo_t *tmp;
+       int res;
+
+       mutex_lock(&vha->vha_tgt.tgt_mutex);
+
+       list_for_each_entry(tmp, &vha->logo_list, list) {
+               if (tmp->id.b24 == logo->id.b24) {
+                       tmp->cmd_count += logo->cmd_count;
+                       mutex_unlock(&vha->vha_tgt.tgt_mutex);
+                       return;
+               }
+       }
+
+       list_add_tail(&logo->list, &vha->logo_list);
+
+       mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
+       res = qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, logo->id);
+
+       mutex_lock(&vha->vha_tgt.tgt_mutex);
+       list_del(&logo->list);
+       mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
+       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf098,
+           "Finished LOGO to %02x:%02x:%02x, dropped %d cmds, res = %#x\n",
+           logo->id.b.domain, logo->id.b.area, logo->id.b.al_pa,
+           logo->cmd_count, res);
+}
+
 static void qlt_free_session_done(struct work_struct *work)
 {
        struct qla_tgt_sess *sess = container_of(work, struct qla_tgt_sess,
@@ -402,14 +530,21 @@ static void qlt_free_session_done(struct work_struct *work)
 
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084,
                "%s: se_sess %p / sess %p from port %8phC loop_id %#04x"
-               " s_id %02x:%02x:%02x logout %d keep %d plogi %d\n",
+               " s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n",
                __func__, sess->se_sess, sess, sess->port_name, sess->loop_id,
                sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
                sess->logout_on_delete, sess->keep_nport_handle,
-               sess->plogi_ack_needed);
+               sess->send_els_logo);
 
        BUG_ON(!tgt);
 
+       if (sess->send_els_logo) {
+               qlt_port_logo_t logo;
+               logo.id = sess->s_id;
+               logo.cmd_count = 0;
+               qlt_send_first_logo(vha, &logo);
+       }
+
        if (sess->logout_on_delete) {
                int rc;
 
@@ -455,9 +590,34 @@ static void qlt_free_session_done(struct work_struct *work)
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
-       if (sess->plogi_ack_needed)
-               qlt_send_notify_ack(vha, &sess->tm_iocb,
-                                   0, 0, 0, 0, 0, 0);
+       {
+               qlt_plogi_ack_t *own =
+                   sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
+               qlt_plogi_ack_t *con =
+                   sess->plogi_link[QLT_PLOGI_LINK_CONFLICT];
+
+               if (con) {
+                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf099,
+                           "se_sess %p / sess %p port %8phC is gone,"
+                           " %s (ref=%d), releasing PLOGI for %8phC (ref=%d)\n",
+                           sess->se_sess, sess, sess->port_name,
+                           own ? "releasing own PLOGI" :
+                           "no own PLOGI pending",
+                           own ? own->ref_count : -1,
+                           con->iocb.u.isp24.port_name, con->ref_count);
+                       qlt_plogi_ack_unref(vha, con);
+               } else {
+                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf09a,
+                           "se_sess %p / sess %p port %8phC is gone, %s (ref=%d)\n",
+                           sess->se_sess, sess, sess->port_name,
+                           own ? "releasing own PLOGI" :
+                           "no own PLOGI pending",
+                           own ? own->ref_count : -1);
+               }
+
+               if (own)
+                       qlt_plogi_ack_unref(vha, own);
+       }
 
        list_del(&sess->sess_list_entry);
 
@@ -476,7 +636,7 @@ static void qlt_free_session_done(struct work_struct *work)
                wake_up_all(&tgt->waitQ);
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 void qlt_unreg_sess(struct qla_tgt_sess *sess)
 {
        struct scsi_qla_host *vha = sess->vha;
@@ -492,7 +652,7 @@ void qlt_unreg_sess(struct qla_tgt_sess *sess)
 }
 EXPORT_SYMBOL(qlt_unreg_sess);
 
-/* ha->hardware_lock supposed to be held on entry */
+
 static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
 {
        struct qla_hw_data *ha = vha->hw;
@@ -502,12 +662,15 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
        int res = 0;
        struct imm_ntfy_from_isp *n = (struct imm_ntfy_from_isp *)iocb;
        struct atio_from_isp *a = (struct atio_from_isp *)iocb;
+       unsigned long flags;
 
        loop_id = le16_to_cpu(n->u.isp24.nport_handle);
        if (loop_id == 0xFFFF) {
                /* Global event */
                atomic_inc(&vha->vha_tgt.qla_tgt->tgt_global_resets_count);
+               spin_lock_irqsave(&ha->tgt.sess_lock, flags);
                qlt_clear_tgt_db(vha->vha_tgt.qla_tgt);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 #if 0 /* FIXME: do we need to choose a session here? */
                if (!list_empty(&ha->tgt.qla_tgt->sess_list)) {
                        sess = list_entry(ha->tgt.qla_tgt->sess_list.next,
@@ -534,7 +697,9 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
                        sess = NULL;
 #endif
        } else {
+               spin_lock_irqsave(&ha->tgt.sess_lock, flags);
                sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        }
 
        ql_dbg(ql_dbg_tgt, vha, 0xe000,
@@ -556,7 +721,7 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
            iocb, QLA24XX_MGMT_SEND_NACK);
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
        bool immediate)
 {
@@ -600,7 +765,7 @@ static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
                    sess->expires - jiffies);
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_clear_tgt_db(struct qla_tgt *tgt)
 {
        struct qla_tgt_sess *sess;
@@ -636,12 +801,12 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id,
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045,
                    "qla_target(%d): get_id_list() failed: %x\n",
                    vha->vp_idx, rc);
-               res = -1;
+               res = -EBUSY;
                goto out_free_id_list;
        }
 
        id_iter = (char *)gid_list;
-       res = -1;
+       res = -ENOENT;
        for (i = 0; i < entries; i++) {
                struct gid_list_info *gid = (struct gid_list_info *)id_iter;
                if ((gid->al_pa == s_id[2]) &&
@@ -660,7 +825,7 @@ out_free_id_list:
        return res;
 }
 
-/* ha->hardware_lock supposed to be held on entry */
+/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_undelete_sess(struct qla_tgt_sess *sess)
 {
        BUG_ON(sess->deleted != QLA_SESS_DELETION_PENDING);
@@ -678,7 +843,7 @@ static void qlt_del_sess_work_fn(struct delayed_work *work)
        struct qla_tgt_sess *sess;
        unsigned long flags, elapsed;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        while (!list_empty(&tgt->del_sess_list)) {
                sess = list_entry(tgt->del_sess_list.next, typeof(*sess),
                    del_list_entry);
@@ -699,7 +864,7 @@ static void qlt_del_sess_work_fn(struct delayed_work *work)
                        break;
                }
        }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 /*
@@ -717,7 +882,7 @@ static struct qla_tgt_sess *qlt_create_sess(
        unsigned char be_sid[3];
 
        /* Check to avoid double sessions */
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        list_for_each_entry(sess, &vha->vha_tgt.qla_tgt->sess_list,
                                sess_list_entry) {
                if (!memcmp(sess->port_name, fcport->port_name, WWN_SIZE)) {
@@ -732,7 +897,7 @@ static struct qla_tgt_sess *qlt_create_sess(
 
                        /* Cannot undelete at this point */
                        if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
-                               spin_unlock_irqrestore(&ha->hardware_lock,
+                               spin_unlock_irqrestore(&ha->tgt.sess_lock,
                                    flags);
                                return NULL;
                        }
@@ -749,12 +914,12 @@ static struct qla_tgt_sess *qlt_create_sess(
 
                        qlt_do_generation_tick(vha, &sess->generation);
 
-                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+                       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
                        return sess;
                }
        }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
        sess = kzalloc(sizeof(*sess), GFP_KERNEL);
        if (!sess) {
@@ -799,7 +964,7 @@ static struct qla_tgt_sess *qlt_create_sess(
        }
        /*
         * Take an extra reference to ->sess_kref here to handle qla_tgt_sess
-        * access across ->hardware_lock reaquire.
+        * access across ->tgt.sess_lock reaquire.
         */
        kref_get(&sess->se_sess->sess_kref);
 
@@ -807,11 +972,11 @@ static struct qla_tgt_sess *qlt_create_sess(
        BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name));
        memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name));
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        list_add_tail(&sess->sess_list_entry, &vha->vha_tgt.qla_tgt->sess_list);
        vha->vha_tgt.qla_tgt->sess_count++;
        qlt_do_generation_tick(vha, &sess->generation);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b,
            "qla_target(%d): %ssession for wwn %8phC (loop_id %d, "
@@ -842,23 +1007,23 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
        if (qla_ini_mode_enabled(vha))
                return;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        if (tgt->tgt_stop) {
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
                return;
        }
        sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
        if (!sess) {
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
                mutex_lock(&vha->vha_tgt.tgt_mutex);
                sess = qlt_create_sess(vha, fcport, false);
                mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-               spin_lock_irqsave(&ha->hardware_lock, flags);
+               spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        } else if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
                /* Point of no return */
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
                return;
        } else {
                kref_get(&sess->se_sess->sess_kref);
@@ -887,7 +1052,7 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
                sess->local = 0;
        }
        ha->tgt.tgt_ops->put_sess(sess);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 /*
@@ -899,6 +1064,7 @@ qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen)
 {
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        struct qla_tgt_sess *sess;
+       unsigned long flags;
 
        if (!vha->hw->tgt.tgt_ops)
                return;
@@ -906,15 +1072,19 @@ qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen)
        if (!tgt)
                return;
 
+       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
        if (tgt->tgt_stop) {
+               spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
                return;
        }
        sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
        if (!sess) {
+               spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
                return;
        }
 
        if (max_gen - sess->generation < 0) {
+               spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf092,
                    "Ignoring stale deletion request for se_sess %p / sess %p"
                    " for port %8phC, req_gen %d, sess_gen %d\n",
@@ -927,6 +1097,7 @@ qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen)
 
        sess->local = 1;
        qlt_schedule_sess_for_deletion(sess, false);
+       spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 }
 
 static inline int test_tgt_sess_count(struct qla_tgt *tgt)
@@ -984,10 +1155,10 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
         * Lock is needed, because we still can get an incoming packet.
         */
        mutex_lock(&vha->vha_tgt.tgt_mutex);
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        tgt->tgt_stop = 1;
        qlt_clear_tgt_db(tgt);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        mutex_unlock(&vha->vha_tgt.tgt_mutex);
        mutex_unlock(&qla_tgt_mutex);
 
@@ -1040,7 +1211,7 @@ void qlt_stop_phase2(struct qla_tgt *tgt)
 
        mutex_lock(&vha->vha_tgt.tgt_mutex);
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       while (tgt->irq_cmd_count != 0) {
+       while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) {
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
                udelay(2);
                spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1309,7 +1480,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
 
        list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
                if (tag == cmd->atio.u.isp24.exchange_addr) {
-                       cmd->state = QLA_TGT_STATE_ABORTED;
+                       cmd->aborted = 1;
                        spin_unlock(&vha->cmd_list_lock);
                        return 1;
                }
@@ -1351,7 +1522,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
                cmd_lun = scsilun_to_int(
                        (struct scsi_lun *)&cmd->atio.u.isp24.fcp_cmnd.lun);
                if (cmd_key == key && cmd_lun == lun)
-                       cmd->state = QLA_TGT_STATE_ABORTED;
+                       cmd->aborted = 1;
        }
        spin_unlock(&vha->cmd_list_lock);
 }
@@ -1435,6 +1606,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
        uint32_t tag = abts->exchange_addr_to_abort;
        uint8_t s_id[3];
        int rc;
+       unsigned long flags;
 
        if (le32_to_cpu(abts->fcp_hdr_le.parameter) & ABTS_PARAM_ABORT_SEQ) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053,
@@ -1462,6 +1634,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
        s_id[1] = abts->fcp_hdr_le.s_id[1];
        s_id[2] = abts->fcp_hdr_le.s_id[0];
 
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
        if (!sess) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012,
@@ -1469,12 +1642,17 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
                    vha->vp_idx);
                rc = qlt_sched_sess_work(vha->vha_tgt.qla_tgt,
                    QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts));
+
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
                if (rc != 0) {
                        qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED,
                            false);
                }
                return;
        }
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
 
        if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
                qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
@@ -1560,15 +1738,15 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
-       if (qla2x00_reset_active(vha) || mcmd->reset_count != ha->chip_reset) {
+       if (!vha->flags.online || mcmd->reset_count != ha->chip_reset) {
                /*
-                * Either a chip reset is active or this request was from
+                * Either the port is not online or this request was from
                 * previous life, just abort the processing.
                 */
                ql_dbg(ql_dbg_async, vha, 0xe100,
-                       "RESET-TMR active/old-count/new-count = %d/%d/%d.\n",
-                       qla2x00_reset_active(vha), mcmd->reset_count,
-                       ha->chip_reset);
+                       "RESET-TMR online/active/old-count/new-count = %d/%d/%d/%d.\n",
+                       vha->flags.online, qla2x00_reset_active(vha),
+                       mcmd->reset_count, ha->chip_reset);
                ha->tgt.tgt_ops->free_mcmd(mcmd);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
                return;
@@ -2510,17 +2688,22 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
-       if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
+       if (xmit_type == QLA_TGT_XMIT_STATUS)
+               vha->tgt_counters.core_qla_snd_status++;
+       else
+               vha->tgt_counters.core_qla_que_buf++;
+
+       if (!vha->flags.online || cmd->reset_count != ha->chip_reset) {
                /*
-                * Either a chip reset is active or this request was from
+                * Either the port is not online or this request was from
                 * previous life, just abort the processing.
                 */
                cmd->state = QLA_TGT_STATE_PROCESSED;
                qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
                ql_dbg(ql_dbg_async, vha, 0xe101,
-                       "RESET-RSP active/old-count/new-count = %d/%d/%d.\n",
-                       qla2x00_reset_active(vha), cmd->reset_count,
-                       ha->chip_reset);
+                       "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
+                       vha->flags.online, qla2x00_reset_active(vha),
+                       cmd->reset_count, ha->chip_reset);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
                return 0;
        }
@@ -2651,18 +2834,18 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
-       if (qla2x00_reset_active(vha) || (cmd->reset_count != ha->chip_reset) ||
+       if (!vha->flags.online || (cmd->reset_count != ha->chip_reset) ||
            (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)) {
                /*
-                * Either a chip reset is active or this request was from
+                * Either the port is not online or this request was from
                 * previous life, just abort the processing.
                 */
                cmd->state = QLA_TGT_STATE_NEED_DATA;
                qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
                ql_dbg(ql_dbg_async, vha, 0xe102,
-                       "RESET-XFR active/old-count/new-count = %d/%d/%d.\n",
-                       qla2x00_reset_active(vha), cmd->reset_count,
-                       ha->chip_reset);
+                       "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n",
+                       vha->flags.online, qla2x00_reset_active(vha),
+                       cmd->reset_count, ha->chip_reset);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
                return 0;
        }
@@ -2957,12 +3140,13 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
                        ret = 1;
        }
 
+       vha->tgt_counters.num_term_xchg_sent++;
        pkt->entry_count = 1;
        pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
 
        ctio24 = (struct ctio7_to_24xx *)pkt;
        ctio24->entry_type = CTIO_TYPE7;
-       ctio24->nport_handle = cmd ? cmd->loop_id : CTIO7_NHANDLE_UNRECOGNIZED;
+       ctio24->nport_handle = CTIO7_NHANDLE_UNRECOGNIZED;
        ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
        ctio24->vp_index = vha->vp_idx;
        ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
@@ -3009,7 +3193,7 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
                qlt_alloc_qfull_cmd(vha, atio, 0, 0);
 
 done:
-       if (cmd && ((cmd->state != QLA_TGT_STATE_ABORTED) ||
+       if (cmd && (!cmd->aborted ||
            !cmd->cmd_sent_to_fw)) {
                if (cmd->sg_mapped)
                        qlt_unmap_sg(vha, cmd);
@@ -3028,7 +3212,7 @@ static void qlt_init_term_exchange(struct scsi_qla_host *vha)
        struct qla_tgt_cmd *cmd, *tcmd;
 
        vha->hw->tgt.leak_exchg_thresh_hold =
-           (vha->hw->fw_xcb_count/100) * LEAK_EXCHG_THRESH_HOLD_PERCENT;
+           (vha->hw->cur_fw_xcb_count/100) * LEAK_EXCHG_THRESH_HOLD_PERCENT;
 
        cmd = tcmd = NULL;
        if (!list_empty(&vha->hw->tgt.q_full_list)) {
@@ -3058,7 +3242,7 @@ static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
 
                ql_dbg(ql_dbg_tgt, vha, 0xe079,
                    "Chip reset due to exchange starvation: %d/%d.\n",
-                   total_leaked, vha->hw->fw_xcb_count);
+                   total_leaked, vha->hw->cur_fw_xcb_count);
 
                if (IS_P3P_TYPE(vha->hw))
                        set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
@@ -3080,7 +3264,7 @@ void qlt_abort_cmd(struct qla_tgt_cmd *cmd)
            "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
            se_cmd->tag);
 
-       cmd->state = QLA_TGT_STATE_ABORTED;
+       cmd->aborted = 1;
        cmd->cmd_flags |= BIT_6;
 
        qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);
@@ -3300,9 +3484,6 @@ qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
 
                ha->tgt.tgt_ops->handle_data(cmd);
                return;
-       } else if (cmd->state == QLA_TGT_STATE_ABORTED) {
-               ql_dbg(ql_dbg_io, vha, 0xff02,
-                   "HOST-ABORT: handle=%d, state=ABORTED.\n", handle);
        } else {
                ql_dbg(ql_dbg_io, vha, 0xff03,
                    "HOST-ABORT: handle=%d, state=BAD(%d).\n", handle,
@@ -3398,13 +3579,26 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
 
                case CTIO_PORT_LOGGED_OUT:
                case CTIO_PORT_UNAVAILABLE:
+               {
+                       int logged_out = (status & 0xFFFF);
                        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059,
-                           "qla_target(%d): CTIO with PORT LOGGED "
-                           "OUT (29) or PORT UNAVAILABLE (28) status %x "
+                           "qla_target(%d): CTIO with %s status %x "
                            "received (state %x, se_cmd %p)\n", vha->vp_idx,
+                           (logged_out == CTIO_PORT_LOGGED_OUT) ?
+                           "PORT LOGGED OUT" : "PORT UNAVAILABLE",
                            status, cmd->state, se_cmd);
-                       break;
 
+                       if (logged_out && cmd->sess) {
+                               /*
+                                * Session is already logged out, but we need
+                                * to notify initiator, who's not aware of this
+                                */
+                               cmd->sess->logout_on_delete = 0;
+                               cmd->sess->send_els_logo = 1;
+                               qlt_schedule_sess_for_deletion(cmd->sess, true);
+                       }
+                       break;
+               }
                case CTIO_SRR_RECEIVED:
                        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05a,
                            "qla_target(%d): CTIO with SRR_RECEIVED"
@@ -3454,14 +3648,14 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
                }
 
 
-               /* "cmd->state == QLA_TGT_STATE_ABORTED" means
+               /* "cmd->aborted" means
                 * cmd is already aborted/terminated, we don't
                 * need to terminate again.  The exchange is already
                 * cleaned up/freed at FW level.  Just cleanup at driver
                 * level.
                 */
                if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
-                   (cmd->state != QLA_TGT_STATE_ABORTED)) {
+                   (!cmd->aborted)) {
                        cmd->cmd_flags |= BIT_13;
                        if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
                                return;
@@ -3479,7 +3673,7 @@ skip_term:
 
                ha->tgt.tgt_ops->handle_data(cmd);
                return;
-       } else if (cmd->state == QLA_TGT_STATE_ABORTED) {
+       } else if (cmd->aborted) {
                cmd->cmd_flags |= BIT_18;
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e,
                  "Aborted command %p (tag %lld) finished\n", cmd, se_cmd->tag);
@@ -3491,7 +3685,7 @@ skip_term:
        }
 
        if (unlikely(status != CTIO_SUCCESS) &&
-               (cmd->state != QLA_TGT_STATE_ABORTED)) {
+               !cmd->aborted) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n");
                dump_stack();
        }
@@ -3553,7 +3747,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
        if (tgt->tgt_stop)
                goto out_term;
 
-       if (cmd->state == QLA_TGT_STATE_ABORTED) {
+       if (cmd->aborted) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf082,
                    "cmd with tag %u is aborted\n",
                    cmd->atio.u.isp24.exchange_addr);
@@ -3589,9 +3783,9 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
        /*
         * Drop extra session reference from qla_tgt_handle_cmd_for_atio*(
         */
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        ha->tgt.tgt_ops->put_sess(sess);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        return;
 
 out_term:
@@ -3606,8 +3800,11 @@ out_term:
 
        qlt_decr_num_pend_cmds(vha);
        percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
-       ha->tgt.tgt_ops->put_sess(sess);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
+       ha->tgt.tgt_ops->put_sess(sess);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 static void qlt_do_work(struct work_struct *work)
@@ -3692,10 +3889,8 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
                goto out_term;
        }
 
-       mutex_lock(&vha->vha_tgt.tgt_mutex);
        sess = qlt_make_local_sess(vha, s_id);
        /* sess has an extra creation ref. */
-       mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
        if (!sess)
                goto out_term;
@@ -3787,13 +3982,24 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
 
        cmd->cmd_in_wq = 1;
        cmd->cmd_flags |= BIT_0;
+       cmd->se_cmd.cpuid = -1;
 
        spin_lock(&vha->cmd_list_lock);
        list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
        spin_unlock(&vha->cmd_list_lock);
 
        INIT_WORK(&cmd->work, qlt_do_work);
-       queue_work(qla_tgt_wq, &cmd->work);
+       if (ha->msix_count) {
+               cmd->se_cmd.cpuid = ha->tgt.rspq_vector_cpuid;
+               if (cmd->atio.u.isp24.fcp_cmnd.rddata)
+                       queue_work_on(smp_processor_id(), qla_tgt_wq,
+                           &cmd->work);
+               else
+                       queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq,
+                           &cmd->work);
+       } else {
+               queue_work(qla_tgt_wq, &cmd->work);
+       }
        return 0;
 
 }
@@ -3917,13 +4123,18 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb)
        struct qla_tgt_sess *sess;
        uint32_t lun, unpacked_lun;
        int fn;
+       unsigned long flags;
 
        tgt = vha->vha_tgt.qla_tgt;
 
        lun = a->u.isp24.fcp_cmnd.lun;
        fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
+
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
            a->u.isp24.fcp_hdr.s_id);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
        unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
 
        if (!sess) {
@@ -3987,10 +4198,14 @@ static int qlt_abort_task(struct scsi_qla_host *vha,
        struct qla_hw_data *ha = vha->hw;
        struct qla_tgt_sess *sess;
        int loop_id;
+       unsigned long flags;
 
        loop_id = GET_TARGET_ID(ha, (struct atio_from_isp *)iocb);
 
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
        if (sess == NULL) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf025,
                    "qla_target(%d): task abort for unexisting "
@@ -4022,15 +4237,6 @@ void qlt_logo_completion_handler(fc_port_t *fcport, int rc)
        }
 }
 
-static void qlt_swap_imm_ntfy_iocb(struct imm_ntfy_from_isp *a,
-    struct imm_ntfy_from_isp *b)
-{
-       struct imm_ntfy_from_isp tmp;
-       memcpy(&tmp, a, sizeof(struct imm_ntfy_from_isp));
-       memcpy(a, b, sizeof(struct imm_ntfy_from_isp));
-       memcpy(b, &tmp, sizeof(struct imm_ntfy_from_isp));
-}
-
 /*
 * ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list)
 *
@@ -4040,11 +4246,13 @@ static void qlt_swap_imm_ntfy_iocb(struct imm_ntfy_from_isp *a,
 */
 static struct qla_tgt_sess *
 qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn,
-    port_id_t port_id, uint16_t loop_id)
+    port_id_t port_id, uint16_t loop_id, struct qla_tgt_sess **conflict_sess)
 {
        struct qla_tgt_sess *sess = NULL, *other_sess;
        uint64_t other_wwn;
 
+       *conflict_sess = NULL;
+
        list_for_each_entry(other_sess, &tgt->sess_list, sess_list_entry) {
 
                other_wwn = wwn_to_u64(other_sess->port_name);
@@ -4072,9 +4280,10 @@ qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn,
                        } else {
                                /*
                                 * Another wwn used to have our s_id/loop_id
-                                * combo - kill the session, but don't log out
+                                * kill the session, but don't free the loop_id
                                 */
-                               sess->logout_on_delete = 0;
+                               other_sess->keep_nport_handle = 1;
+                               *conflict_sess = other_sess;
                                qlt_schedule_sess_for_deletion(other_sess,
                                    true);
                        }
@@ -4119,7 +4328,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id)
        list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
                uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
                if (cmd_key == key) {
-                       cmd->state = QLA_TGT_STATE_ABORTED;
+                       cmd->aborted = 1;
                        count++;
                }
        }
@@ -4136,12 +4345,14 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 {
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        struct qla_hw_data *ha = vha->hw;
-       struct qla_tgt_sess *sess = NULL;
+       struct qla_tgt_sess *sess = NULL, *conflict_sess = NULL;
        uint64_t wwn;
        port_id_t port_id;
        uint16_t loop_id;
        uint16_t wd3_lo;
        int res = 0;
+       qlt_plogi_ack_t *pla;
+       unsigned long flags;
 
        wwn = wwn_to_u64(iocb->u.isp24.port_name);
 
@@ -4165,27 +4376,20 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
                /* Mark all stale commands in qla_tgt_wq for deletion */
                abort_cmds_for_s_id(vha, &port_id);
 
-               if (wwn)
+               if (wwn) {
+                       spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags);
                        sess = qlt_find_sess_invalidate_other(tgt, wwn,
-                           port_id, loop_id);
+                           port_id, loop_id, &conflict_sess);
+                       spin_unlock_irqrestore(&tgt->ha->tgt.sess_lock, flags);
+               }
 
-               if (!sess || IS_SW_RESV_ADDR(sess->s_id)) {
+               if (IS_SW_RESV_ADDR(port_id) || (!sess && !conflict_sess)) {
                        res = 1;
                        break;
                }
 
-               if (sess->plogi_ack_needed) {
-                       /*
-                        * Initiator sent another PLOGI before last PLOGI could
-                        * finish. Swap plogi iocbs and terminate old one
-                        * without acking, new one will get acked when session
-                        * deletion completes.
-                        */
-                       ql_log(ql_log_warn, sess->vha, 0xf094,
-                           "sess %p received double plogi.\n", sess);
-
-                       qlt_swap_imm_ntfy_iocb(iocb, &sess->tm_iocb);
-
+               pla = qlt_plogi_ack_find_add(vha, &port_id, iocb);
+               if (!pla) {
                        qlt_send_term_imm_notif(vha, iocb, 1);
 
                        res = 0;
@@ -4194,13 +4398,14 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 
                res = 0;
 
-               /*
-                * Save immediate Notif IOCB for Ack when sess is done
-                * and being deleted.
-                */
-               memcpy(&sess->tm_iocb, iocb, sizeof(sess->tm_iocb));
-               sess->plogi_ack_needed  = 1;
+               if (conflict_sess)
+                       qlt_plogi_ack_link(vha, pla, conflict_sess,
+                           QLT_PLOGI_LINK_CONFLICT);
+
+               if (!sess)
+                       break;
 
+               qlt_plogi_ack_link(vha, pla, sess, QLT_PLOGI_LINK_SAME_WWN);
                 /*
                  * Under normal circumstances we want to release nport handle
                  * during LOGO process to avoid nport handle leaks inside FW.
@@ -4227,9 +4432,21 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
        case ELS_PRLI:
                wd3_lo = le16_to_cpu(iocb->u.isp24.u.prli.wd3_lo);
 
-               if (wwn)
+               if (wwn) {
+                       spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags);
                        sess = qlt_find_sess_invalidate_other(tgt, wwn, port_id,
-                           loop_id);
+                           loop_id, &conflict_sess);
+                       spin_unlock_irqrestore(&tgt->ha->tgt.sess_lock, flags);
+               }
+
+               if (conflict_sess) {
+                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf09b,
+                           "PRLI with conflicting sess %p port %8phC\n",
+                           conflict_sess, conflict_sess->port_name);
+                       qlt_send_term_imm_notif(vha, iocb, 1);
+                       res = 0;
+                       break;
+               }
 
                if (sess != NULL) {
                        if (sess->deleted) {
@@ -4899,9 +5116,12 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
        struct qla_hw_data *ha = vha->hw;
        request_t *pkt;
        struct qla_tgt_sess *sess = NULL;
+       unsigned long flags;
 
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
            atio->u.isp24.fcp_hdr.s_id);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        if (!sess) {
                qlt_send_term_exchange(vha, NULL, atio, 1);
                return 0;
@@ -4916,6 +5136,7 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
                return -ENOMEM;
        }
 
+       vha->tgt_counters.num_q_full_sent++;
        pkt->entry_count = 1;
        pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
 
@@ -5129,11 +5350,12 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
 /* ha->hardware_lock supposed to be held on entry */
 /* called via callback from qla2xxx */
 static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
-       struct atio_from_isp *atio)
+       struct atio_from_isp *atio, uint8_t ha_locked)
 {
        struct qla_hw_data *ha = vha->hw;
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        int rc;
+       unsigned long flags;
 
        if (unlikely(tgt == NULL)) {
                ql_dbg(ql_dbg_io, vha, 0x3064,
@@ -5145,7 +5367,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
         * Otherwise, some commands can stuck.
         */
 
-       tgt->irq_cmd_count++;
+       tgt->atio_irq_cmd_count++;
 
        switch (atio->u.raw.entry_type) {
        case ATIO_TYPE7:
@@ -5155,7 +5377,11 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                            "qla_target(%d): ATIO_TYPE7 "
                            "received with UNKNOWN exchange address, "
                            "sending QUEUE_FULL\n", vha->vp_idx);
+                       if (!ha_locked)
+                               spin_lock_irqsave(&ha->hardware_lock, flags);
                        qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL);
+                       if (!ha_locked)
+                               spin_unlock_irqrestore(&ha->hardware_lock, flags);
                        break;
                }
 
@@ -5164,7 +5390,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
                        rc = qlt_chk_qfull_thresh_hold(vha, atio);
                        if (rc != 0) {
-                               tgt->irq_cmd_count--;
+                               tgt->atio_irq_cmd_count--;
                                return;
                        }
                        rc = qlt_handle_cmd_for_atio(vha, atio);
@@ -5173,11 +5399,20 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                }
                if (unlikely(rc != 0)) {
                        if (rc == -ESRCH) {
+                               if (!ha_locked)
+                                       spin_lock_irqsave
+                                               (&ha->hardware_lock, flags);
+
 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
                                qlt_send_busy(vha, atio, SAM_STAT_BUSY);
 #else
                                qlt_send_term_exchange(vha, NULL, atio, 1);
 #endif
+
+                               if (!ha_locked)
+                                       spin_unlock_irqrestore
+                                               (&ha->hardware_lock, flags);
+
                        } else {
                                if (tgt->tgt_stop) {
                                        ql_dbg(ql_dbg_tgt, vha, 0xe059,
@@ -5189,7 +5424,13 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                                            "qla_target(%d): Unable to send "
                                            "command to target, sending BUSY "
                                            "status.\n", vha->vp_idx);
+                                       if (!ha_locked)
+                                               spin_lock_irqsave(
+                                                   &ha->hardware_lock, flags);
                                        qlt_send_busy(vha, atio, SAM_STAT_BUSY);
+                                       if (!ha_locked)
+                                               spin_unlock_irqrestore(
+                                                   &ha->hardware_lock, flags);
                                }
                        }
                }
@@ -5206,7 +5447,12 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                        break;
                }
                ql_dbg(ql_dbg_tgt, vha, 0xe02e, "%s", "IMMED_NOTIFY ATIO");
+
+               if (!ha_locked)
+                       spin_lock_irqsave(&ha->hardware_lock, flags);
                qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)atio);
+               if (!ha_locked)
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
                break;
        }
 
@@ -5217,7 +5463,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                break;
        }
 
-       tgt->irq_cmd_count--;
+       tgt->atio_irq_cmd_count--;
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -5534,12 +5780,16 @@ static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *vha,
        int rc, global_resets;
        uint16_t loop_id = 0;
 
+       mutex_lock(&vha->vha_tgt.tgt_mutex);
+
 retry:
        global_resets =
            atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count);
 
        rc = qla24xx_get_loop_id(vha, s_id, &loop_id);
        if (rc != 0) {
+               mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
                if ((s_id[0] == 0xFF) &&
                    (s_id[1] == 0xFC)) {
                        /*
@@ -5550,17 +5800,27 @@ retry:
                            "Unable to find initiator with S_ID %x:%x:%x",
                            s_id[0], s_id[1], s_id[2]);
                } else
-                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf071,
+                       ql_log(ql_log_info, vha, 0xf071,
                            "qla_target(%d): Unable to find "
                            "initiator with S_ID %x:%x:%x",
                            vha->vp_idx, s_id[0], s_id[1],
                            s_id[2]);
+
+               if (rc == -ENOENT) {
+                       qlt_port_logo_t logo;
+                       sid_to_portid(s_id, &logo.id);
+                       logo.cmd_count = 1;
+                       qlt_send_first_logo(vha, &logo);
+               }
+
                return NULL;
        }
 
        fcport = qlt_get_port_database(vha, loop_id);
-       if (!fcport)
+       if (!fcport) {
+               mutex_unlock(&vha->vha_tgt.tgt_mutex);
                return NULL;
+       }
 
        if (global_resets !=
            atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count)) {
@@ -5575,6 +5835,8 @@ retry:
 
        sess = qlt_create_sess(vha, fcport, true);
 
+       mutex_unlock(&vha->vha_tgt.tgt_mutex);
+
        kfree(fcport);
        return sess;
 }
@@ -5585,15 +5847,15 @@ static void qlt_abort_work(struct qla_tgt *tgt,
        struct scsi_qla_host *vha = tgt->vha;
        struct qla_hw_data *ha = vha->hw;
        struct qla_tgt_sess *sess = NULL;
-       unsigned long flags;
+       unsigned long flags = 0, flags2 = 0;
        uint32_t be_s_id;
        uint8_t s_id[3];
        int rc;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags2);
 
        if (tgt->tgt_stop)
-               goto out_term;
+               goto out_term2;
 
        s_id[0] = prm->abts.fcp_hdr_le.s_id[2];
        s_id[1] = prm->abts.fcp_hdr_le.s_id[1];
@@ -5602,41 +5864,47 @@ static void qlt_abort_work(struct qla_tgt *tgt,
        sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
            (unsigned char *)&be_s_id);
        if (!sess) {
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 
-               mutex_lock(&vha->vha_tgt.tgt_mutex);
                sess = qlt_make_local_sess(vha, s_id);
                /* sess has got an extra creation ref */
-               mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-               spin_lock_irqsave(&ha->hardware_lock, flags);
+               spin_lock_irqsave(&ha->tgt.sess_lock, flags2);
                if (!sess)
-                       goto out_term;
+                       goto out_term2;
        } else {
                if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
                        sess = NULL;
-                       goto out_term;
+                       goto out_term2;
                }
 
                kref_get(&sess->se_sess->sess_kref);
        }
 
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
        if (tgt->tgt_stop)
                goto out_term;
 
        rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess);
        if (rc != 0)
                goto out_term;
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        ha->tgt.tgt_ops->put_sess(sess);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
        return;
 
+out_term2:
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
 out_term:
        qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
        if (sess)
                ha->tgt.tgt_ops->put_sess(sess);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 }
 
 static void qlt_tmr_work(struct qla_tgt *tgt,
@@ -5653,7 +5921,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
        int fn;
        void *iocb;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 
        if (tgt->tgt_stop)
                goto out_term;
@@ -5661,14 +5929,12 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
        s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id;
        sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
        if (!sess) {
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
-               mutex_lock(&vha->vha_tgt.tgt_mutex);
                sess = qlt_make_local_sess(vha, s_id);
                /* sess has got an extra creation ref */
-               mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-               spin_lock_irqsave(&ha->hardware_lock, flags);
+               spin_lock_irqsave(&ha->tgt.sess_lock, flags);
                if (!sess)
                        goto out_term;
        } else {
@@ -5690,14 +5956,14 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
                goto out_term;
 
        ha->tgt.tgt_ops->put_sess(sess);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        return;
 
 out_term:
-       qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1);
+       qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 0);
        if (sess)
                ha->tgt.tgt_ops->put_sess(sess);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 static void qlt_sess_work_fn(struct work_struct *work)
@@ -6002,6 +6268,7 @@ qlt_enable_vha(struct scsi_qla_host *vha)
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        unsigned long flags;
        scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+       int rspq_ent = QLA83XX_RSPQ_MSIX_ENTRY_NUMBER;
 
        if (!tgt) {
                ql_dbg(ql_dbg_tgt, vha, 0xe069,
@@ -6020,6 +6287,17 @@ qlt_enable_vha(struct scsi_qla_host *vha)
                qla24xx_disable_vp(vha);
                qla24xx_enable_vp(vha);
        } else {
+               if (ha->msix_entries) {
+                       ql_dbg(ql_dbg_tgt, vha, 0xffff,
+                           "%s: host%ld : vector %d cpu %d\n",
+                           __func__, vha->host_no,
+                           ha->msix_entries[rspq_ent].vector,
+                           ha->msix_entries[rspq_ent].cpuid);
+
+                       ha->tgt.rspq_vector_cpuid =
+                           ha->msix_entries[rspq_ent].cpuid;
+               }
+
                set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
                qla2xxx_wake_dpc(base_vha);
                qla2x00_wait_for_hba_online(base_vha);
@@ -6131,7 +6409,7 @@ qlt_init_atio_q_entries(struct scsi_qla_host *vha)
  * @ha: SCSI driver HA context
  */
 void
-qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
+qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
 {
        struct qla_hw_data *ha = vha->hw;
        struct atio_from_isp *pkt;
@@ -6144,7 +6422,8 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha)
                pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr;
                cnt = pkt->u.raw.entry_count;
 
-               qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt);
+               qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt,
+                   ha_locked);
 
                for (i = 0; i < cnt; i++) {
                        ha->tgt.atio_ring_index++;
@@ -6265,10 +6544,21 @@ qlt_24xx_config_nvram_stage2(struct scsi_qla_host *vha,
 {
        struct qla_hw_data *ha = vha->hw;
 
+       if (!QLA_TGT_MODE_ENABLED())
+               return;
+
        if (ha->tgt.node_name_set) {
                memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
                icb->firmware_options_1 |= cpu_to_le32(BIT_14);
        }
+
+       /* disable ZIO at start time. */
+       if (!vha->flags.init_done) {
+               uint32_t tmp;
+               tmp = le32_to_cpu(icb->firmware_options_2);
+               tmp &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
+               icb->firmware_options_2 = cpu_to_le32(tmp);
+       }
 }
 
 void
@@ -6359,6 +6649,15 @@ qlt_81xx_config_nvram_stage2(struct scsi_qla_host *vha,
                memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
                icb->firmware_options_1 |= cpu_to_le32(BIT_14);
        }
+
+       /* disable ZIO at start time. */
+       if (!vha->flags.init_done) {
+               uint32_t tmp;
+               tmp = le32_to_cpu(icb->firmware_options_2);
+               tmp &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
+               icb->firmware_options_2 = cpu_to_le32(tmp);
+       }
+
 }
 
 void
@@ -6428,16 +6727,59 @@ qla83xx_msix_atio_q(int irq, void *dev_id)
        ha = rsp->hw;
        vha = pci_get_drvdata(ha->pdev);
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.atio_lock, flags);
 
-       qlt_24xx_process_atio_queue(vha);
-       qla24xx_process_response_queue(vha, rsp);
+       qlt_24xx_process_atio_queue(vha, 0);
 
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
 
        return IRQ_HANDLED;
 }
 
+static void
+qlt_handle_abts_recv_work(struct work_struct *work)
+{
+       struct qla_tgt_sess_op *op = container_of(work,
+               struct qla_tgt_sess_op, work);
+       scsi_qla_host_t *vha = op->vha;
+       struct qla_hw_data *ha = vha->hw;
+       unsigned long flags;
+
+       if (qla2x00_reset_active(vha) || (op->chip_reset != ha->chip_reset))
+               return;
+
+       spin_lock_irqsave(&ha->tgt.atio_lock, flags);
+       qlt_24xx_process_atio_queue(vha, 0);
+       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       qlt_response_pkt_all_vps(vha, (response_t *)&op->atio);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+void
+qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt)
+{
+       struct qla_tgt_sess_op *op;
+
+       op = kzalloc(sizeof(*op), GFP_ATOMIC);
+
+       if (!op) {
+               /* do not reach for ATIO queue here.  This is best effort err
+                * recovery at this point.
+                */
+               qlt_response_pkt_all_vps(vha, pkt);
+               return;
+       }
+
+       memcpy(&op->atio, pkt, sizeof(*pkt));
+       op->vha = vha;
+       op->chip_reset = vha->hw->chip_reset;
+       INIT_WORK(&op->work, qlt_handle_abts_recv_work);
+       queue_work(qla_tgt_wq, &op->work);
+       return;
+}
+
 int
 qlt_mem_alloc(struct qla_hw_data *ha)
 {
@@ -6532,13 +6874,25 @@ int __init qlt_init(void)
                return -ENOMEM;
        }
 
+       qla_tgt_plogi_cachep = kmem_cache_create("qla_tgt_plogi_cachep",
+                                                sizeof(qlt_plogi_ack_t),
+                                                __alignof__(qlt_plogi_ack_t),
+                                                0, NULL);
+
+       if (!qla_tgt_plogi_cachep) {
+               ql_log(ql_log_fatal, NULL, 0xe06d,
+                   "kmem_cache_create for qla_tgt_plogi_cachep failed\n");
+               ret = -ENOMEM;
+               goto out_mgmt_cmd_cachep;
+       }
+
        qla_tgt_mgmt_cmd_mempool = mempool_create(25, mempool_alloc_slab,
            mempool_free_slab, qla_tgt_mgmt_cmd_cachep);
        if (!qla_tgt_mgmt_cmd_mempool) {
                ql_log(ql_log_fatal, NULL, 0xe06e,
                    "mempool_create for qla_tgt_mgmt_cmd_mempool failed\n");
                ret = -ENOMEM;
-               goto out_mgmt_cmd_cachep;
+               goto out_plogi_cachep;
        }
 
        qla_tgt_wq = alloc_workqueue("qla_tgt_wq", 0, 0);
@@ -6555,6 +6909,8 @@ int __init qlt_init(void)
 
 out_cmd_mempool:
        mempool_destroy(qla_tgt_mgmt_cmd_mempool);
+out_plogi_cachep:
+       kmem_cache_destroy(qla_tgt_plogi_cachep);
 out_mgmt_cmd_cachep:
        kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep);
        return ret;
@@ -6567,5 +6923,6 @@ void qlt_exit(void)
 
        destroy_workqueue(qla_tgt_wq);
        mempool_destroy(qla_tgt_mgmt_cmd_mempool);
+       kmem_cache_destroy(qla_tgt_plogi_cachep);
        kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep);
 }
index bca584a..71b2865 100644 (file)
@@ -787,7 +787,7 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
 #define QLA_TGT_STATE_NEED_DATA                1 /* target needs data to continue */
 #define QLA_TGT_STATE_DATA_IN          2 /* Data arrived + target processing */
 #define QLA_TGT_STATE_PROCESSED                3 /* target done processing */
-#define QLA_TGT_STATE_ABORTED          4 /* Command aborted */
+
 
 /* Special handles */
 #define QLA_TGT_NULL_HANDLE    0
@@ -835,6 +835,7 @@ struct qla_tgt {
         * HW lock.
         */
        int irq_cmd_count;
+       int atio_irq_cmd_count;
 
        int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
 
@@ -883,6 +884,7 @@ struct qla_tgt {
 
 struct qla_tgt_sess_op {
        struct scsi_qla_host *vha;
+       uint32_t chip_reset;
        struct atio_from_isp atio;
        struct work_struct work;
        struct list_head cmd_list;
@@ -896,6 +898,19 @@ enum qla_sess_deletion {
        QLA_SESS_DELETION_IN_PROGRESS   = 2,
 };
 
+typedef enum {
+       QLT_PLOGI_LINK_SAME_WWN,
+       QLT_PLOGI_LINK_CONFLICT,
+       QLT_PLOGI_LINK_MAX
+} qlt_plogi_link_t;
+
+typedef struct {
+       struct list_head                list;
+       struct imm_ntfy_from_isp        iocb;
+       port_id_t                       id;
+       int                             ref_count;
+} qlt_plogi_ack_t;
+
 /*
  * Equivilant to IT Nexus (Initiator-Target)
  */
@@ -907,8 +922,8 @@ struct qla_tgt_sess {
        unsigned int deleted:2;
        unsigned int local:1;
        unsigned int logout_on_delete:1;
-       unsigned int plogi_ack_needed:1;
        unsigned int keep_nport_handle:1;
+       unsigned int send_els_logo:1;
 
        unsigned char logout_completed;
 
@@ -925,9 +940,7 @@ struct qla_tgt_sess {
        uint8_t port_name[WWN_SIZE];
        struct work_struct free_work;
 
-       union {
-               struct imm_ntfy_from_isp tm_iocb;
-       };
+       qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
 };
 
 struct qla_tgt_cmd {
@@ -949,6 +962,7 @@ struct qla_tgt_cmd {
        unsigned int term_exchg:1;
        unsigned int cmd_sent_to_fw:1;
        unsigned int cmd_in_wq:1;
+       unsigned int aborted:1;
 
        struct scatterlist *sg; /* cmd data buffer SG vector */
        int sg_cnt;             /* SG segments count */
@@ -1120,6 +1134,14 @@ static inline uint32_t sid_to_key(const uint8_t *s_id)
        return key;
 }
 
+static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p)
+{
+       memset(p, 0, sizeof(*p));
+       p->b.domain = s_id[0];
+       p->b.area = s_id[1];
+       p->b.al_pa = s_id[2];
+}
+
 /*
  * Exported symbols from qla_target.c LLD logic used by qla2xxx code..
  */
@@ -1135,7 +1157,7 @@ extern void qlt_enable_vha(struct scsi_qla_host *);
 extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
 extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *);
 extern void qlt_init_atio_q_entries(struct scsi_qla_host *);
-extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *);
+extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *, uint8_t);
 extern void qlt_24xx_config_rings(struct scsi_qla_host *);
 extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *,
        struct nvram_24xx *);
index 81af294..faf0a12 100644 (file)
@@ -284,6 +284,7 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
 
        WARN_ON(cmd->cmd_flags &  BIT_16);
 
+       cmd->vha->tgt_counters.qla_core_ret_sta_ctio++;
        cmd->cmd_flags |= BIT_16;
        transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
@@ -295,9 +296,10 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
  */
 static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
 {
+       cmd->vha->tgt_counters.core_qla_free_cmd++;
        cmd->cmd_in_wq = 1;
        INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
-       queue_work(tcm_qla2xxx_free_wq, &cmd->work);
+       queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
 }
 
 /*
@@ -342,9 +344,9 @@ static int tcm_qla2xxx_shutdown_session(struct se_session *se_sess)
        BUG_ON(!sess);
        vha = sess->vha;
 
-       spin_lock_irqsave(&vha->hw->hardware_lock, flags);
+       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
        target_sess_cmd_list_set_waiting(se_sess);
-       spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+       spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
        return 1;
 }
@@ -358,9 +360,9 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
        BUG_ON(!sess);
        vha = sess->vha;
 
-       spin_lock_irqsave(&vha->hw->hardware_lock, flags);
+       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
        qlt_unreg_sess(sess);
-       spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+       spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 }
 
 static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
@@ -454,6 +456,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
                return -EINVAL;
        }
 
+       cmd->vha->tgt_counters.qla_core_sbt_cmd++;
        return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
                                cmd->unpacked_lun, data_length, fcp_task_attr,
                                data_dir, flags);
@@ -469,6 +472,7 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
         */
        cmd->cmd_in_wq = 0;
        cmd->cmd_flags |= BIT_11;
+       cmd->vha->tgt_counters.qla_core_ret_ctio++;
        if (!cmd->write_data_transferred) {
                /*
                 * Check if se_cmd has already been aborted via LUN_RESET, and
@@ -500,7 +504,7 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
        cmd->cmd_flags |= BIT_10;
        cmd->cmd_in_wq = 1;
        INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
-       queue_work(tcm_qla2xxx_free_wq, &cmd->work);
+       queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
 }
 
 static void tcm_qla2xxx_handle_dif_work(struct work_struct *work)
@@ -643,7 +647,7 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
                        struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *);
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess)
 {
@@ -697,13 +701,13 @@ static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess)
        if (!sess)
                return;
 
-       assert_spin_locked(&sess->vha->hw->hardware_lock);
+       assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
        kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session);
 }
 
 static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess)
 {
-       assert_spin_locked(&sess->vha->hw->hardware_lock);
+       assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
        target_sess_cmd_list_set_waiting(sess->se_sess);
 }
 
@@ -1077,7 +1081,7 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg(
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
        scsi_qla_host_t *vha,
@@ -1116,7 +1120,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static void tcm_qla2xxx_set_sess_by_s_id(
        struct tcm_qla2xxx_lport *lport,
@@ -1182,7 +1186,7 @@ static void tcm_qla2xxx_set_sess_by_s_id(
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id(
        scsi_qla_host_t *vha,
@@ -1221,7 +1225,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id(
 }
 
 /*
- * Expected to be called with struct qla_hw_data->hardware_lock held
+ * Expected to be called with struct qla_hw_data->tgt.sess_lock held
  */
 static void tcm_qla2xxx_set_sess_by_loop_id(
        struct tcm_qla2xxx_lport *lport,
@@ -1285,7 +1289,7 @@ static void tcm_qla2xxx_set_sess_by_loop_id(
 }
 
 /*
- * Should always be called with qla_hw_data->hardware_lock held.
+ * Should always be called with qla_hw_data->tgt.sess_lock held.
  */
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport,
                struct tcm_qla2xxx_nacl *nacl, struct qla_tgt_sess *sess)
@@ -1353,7 +1357,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
        struct qla_tgt_sess *sess = qla_tgt_sess;
        unsigned char port_name[36];
        unsigned long flags;
-       int num_tags = (ha->fw_xcb_count) ? ha->fw_xcb_count :
+       int num_tags = (ha->cur_fw_xcb_count) ? ha->cur_fw_xcb_count :
                       TCM_QLA2XXX_DEFAULT_TAGS;
 
        lport = vha->vha_tgt.target_lport_ptr;
@@ -1401,12 +1405,12 @@ static int tcm_qla2xxx_check_initiator_node_acl(
         * And now setup the new se_nacl and session pointers into our HW lport
         * mappings for fabric S_ID and LOOP_ID.
         */
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess,
                        qla_tgt_sess, s_id);
        tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl, se_sess,
                        qla_tgt_sess, loop_id);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        /*
         * Finally register the new FC Nexus with TCM
         */
index 2c1160c..47b9d13 100644 (file)
@@ -227,6 +227,7 @@ static struct {
        {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
        {"Promise", "", NULL, BLIST_SPARSELUN},
        {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
+       {"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
        {"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
        {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
        {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
index ec163d0..bb669d3 100644 (file)
@@ -3268,8 +3268,8 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
        int ret = 0;
 
-       if (!sdkp)
-               return 0;       /* this can happen */
+       if (!sdkp)      /* E.g.: runtime suspend following sd_remove() */
+               return 0;
 
        if (sdkp->WCE && sdkp->media_present) {
                sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
@@ -3308,6 +3308,9 @@ static int sd_resume(struct device *dev)
 {
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
 
+       if (!sdkp)      /* E.g.: runtime resume at the start of sd_probe() */
+               return 0;
+
        if (!sdkp->device->manage_start_stop)
                return 0;
 
index 8bd54a6..64c8674 100644 (file)
@@ -144,6 +144,9 @@ static int sr_runtime_suspend(struct device *dev)
 {
        struct scsi_cd *cd = dev_get_drvdata(dev);
 
+       if (!cd)        /* E.g.: runtime suspend following sr_remove() */
+               return 0;
+
        if (cd->media_present)
                return -EBUSY;
        else
@@ -985,6 +988,7 @@ static int sr_remove(struct device *dev)
        scsi_autopm_get_device(cd->device);
 
        del_gendisk(cd->disk);
+       dev_set_drvdata(dev, NULL);
 
        mutex_lock(&sr_ref_mutex);
        kref_put(&cd->kref, sr_kref_release);
index 41c115c..55627d0 100644 (file)
@@ -390,7 +390,7 @@ module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
 
 module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
-MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
+MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
 /*
  * Timeout in seconds for all devices managed by this driver.
  */
index 22a4283..b9de487 100644 (file)
 #define NCR5380_queue_command           sun3scsi_queue_command
 #define NCR5380_bus_reset               sun3scsi_bus_reset
 #define NCR5380_abort                   sun3scsi_abort
-#define NCR5380_show_info               sun3scsi_show_info
 #define NCR5380_info                    sun3scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
-        sun3scsi_dma_setup(data, count, 0)
+        sun3scsi_dma_setup(instance, data, count, 0)
 #define NCR5380_dma_write_setup(instance, data, count) \
-        sun3scsi_dma_setup(data, count, 1)
+        sun3scsi_dma_setup(instance, data, count, 1)
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
@@ -86,10 +85,6 @@ module_param(setup_use_tagged_queuing, int, 0);
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
-/* #define RESET_BOOT */
-
-#define        AFTER_RESET_DELAY       (HZ/2)
-
 /* ms to wait after hitting dma regs */
 #define SUN3_DMA_DELAY 10
 
@@ -100,11 +95,10 @@ static struct scsi_cmnd *sun3_dma_setup_done;
 static unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
 static struct sun3_udc_regs *udc_regs;
-static unsigned char *sun3_dma_orig_addr = NULL;
-static unsigned long sun3_dma_orig_count = 0;
-static int sun3_dma_active = 0;
-static unsigned long last_residual = 0;
-static struct Scsi_Host *default_instance;
+static unsigned char *sun3_dma_orig_addr;
+static unsigned long sun3_dma_orig_count;
+static int sun3_dma_active;
+static unsigned long last_residual;
 
 /*
  * NCR 5380 register access functions
@@ -144,50 +138,12 @@ static inline void sun3_udc_write(unsigned short val, unsigned char reg)
 }
 #endif
 
-#ifdef RESET_BOOT
-static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
-{
-       unsigned long end;
-       
-       /*
-        * Do a SCSI reset to clean up the bus during initialization. No
-        * messing with the queues, interrupts, or locks necessary here.
-        */
-
-       printk( "Sun3 SCSI: resetting the SCSI bus..." );
-
-       /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-//             sun3_disable_irq( IRQ_SUN3_SCSI );
-
-       /* get in phase */
-       NCR5380_write( TARGET_COMMAND_REG,
-                     PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
-       /* assert RST */
-       NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-
-       /* The min. reset hold time is 25us, so 40us should be enough */
-       udelay( 50 );
-
-       /* reset RST and interrupt */
-       NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
-       NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
-       for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
-               barrier();
-
-       /* switch on SCSI IRQ again */
-//             sun3_enable_irq( IRQ_SUN3_SCSI );
-
-       printk( " done\n" );
-}
-#endif
-
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
+static irqreturn_t scsi_sun3_intr(int irq, void *dev)
 {
+       struct Scsi_Host *instance = dev;
        unsigned short csr = dregs->csr;
        int handled = 0;
 
@@ -196,46 +152,24 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
 #endif
 
        if(csr & ~CSR_GOOD) {
-               if(csr & CSR_DMA_BUSERR) {
-                       printk("scsi%d: bus error in dma\n", default_instance->host_no);
-               }
-
-               if(csr & CSR_DMA_CONFLICT) {
-                       printk("scsi%d: dma conflict\n", default_instance->host_no);
-               }
+               if (csr & CSR_DMA_BUSERR)
+                       shost_printk(KERN_ERR, instance, "bus error in DMA\n");
+               if (csr & CSR_DMA_CONFLICT)
+                       shost_printk(KERN_ERR, instance, "DMA conflict\n");
                handled = 1;
        }
 
        if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
-               NCR5380_intr(irq, dummy);
+               NCR5380_intr(irq, dev);
                handled = 1;
        }
 
        return IRQ_RETVAL(handled);
 }
 
-/*
- * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 
- * reentering NCR5380_print_status seems to have ugly side effects
- */
-
-/* this doesn't seem to get used at all -- sam */
-#if 0
-void sun3_sun3_debug (void)
-{
-       unsigned long flags;
-
-       if (default_instance) {
-                       local_irq_save(flags);
-                       NCR5380_print_status(default_instance);
-                       local_irq_restore(flags);
-       }
-}
-#endif
-
-
 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
-static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag)
+static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
+                                void *data, unsigned long count, int write_flag)
 {
        void *addr;
 
@@ -287,10 +221,9 @@ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int wri
        dregs->csr |= CSR_FIFO;
        
        if(dregs->fifo_count != count) { 
-               printk("scsi%d: fifo_mismatch %04x not %04x\n",
-                      default_instance->host_no, dregs->fifo_count,
-                      (unsigned int) count);
-               NCR5380_dprint(NDEBUG_DMA, default_instance);
+               shost_printk(KERN_ERR, instance, "FIFO mismatch %04x not %04x\n",
+                            dregs->fifo_count, (unsigned int) count);
+               NCR5380_dprint(NDEBUG_DMA, instance);
        }
 
        /* setup udc */
@@ -325,21 +258,6 @@ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int wri
 
 }
 
-#ifndef SUN3_SCSI_VME
-static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance)
-{
-       unsigned short resid;
-
-       dregs->udc_addr = 0x32; 
-       udelay(SUN3_DMA_DELAY);
-       resid = dregs->udc_data;
-       udelay(SUN3_DMA_DELAY);
-       resid *= 2;
-
-       return (unsigned long) resid;
-}
-#endif
-
 static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
 {
        return last_residual;
@@ -437,7 +355,10 @@ static int sun3scsi_dma_finish(int write_flag)
                }
        }
 
-       count = sun3scsi_dma_count(default_instance);
+       dregs->udc_addr = 0x32;
+       udelay(SUN3_DMA_DELAY);
+       count = 2 * dregs->udc_data;
+       udelay(SUN3_DMA_DELAY);
 
        fifo = dregs->fifo_count;
        last_residual = fifo;
@@ -502,17 +423,17 @@ static int sun3scsi_dma_finish(int write_flag)
 static struct scsi_host_template sun3_scsi_template = {
        .module                 = THIS_MODULE,
        .proc_name              = DRV_MODULE_NAME,
-       .show_info              = sun3scsi_show_info,
        .name                   = SUN3_SCSI_NAME,
        .info                   = sun3scsi_info,
        .queuecommand           = sun3scsi_queue_command,
-       .eh_abort_handler       = sun3scsi_abort,
-       .eh_bus_reset_handler   = sun3scsi_bus_reset,
+       .eh_abort_handler       = sun3scsi_abort,
+       .eh_bus_reset_handler   = sun3scsi_bus_reset,
        .can_queue              = 16,
        .this_id                = 7,
        .sg_tablesize           = SG_NONE,
        .cmd_per_lun            = 2,
-       .use_clustering         = DISABLE_CLUSTERING
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
 };
 
 static int __init sun3_scsi_probe(struct platform_device *pdev)
@@ -591,7 +512,6 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
                error = -ENOMEM;
                goto fail_alloc;
        }
-       default_instance = instance;
 
        instance->io_port = (unsigned long)ioaddr;
        instance->irq = irq->start;
@@ -600,7 +520,9 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
        host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
 #endif
 
-       NCR5380_init(instance, host_flags);
+       error = NCR5380_init(instance, host_flags);
+       if (error)
+               goto fail_init;
 
        error = request_irq(instance->irq, scsi_sun3_intr, 0,
                            "NCR5380", instance);
@@ -631,9 +553,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
        dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
 #endif
 
-#ifdef RESET_BOOT
-       sun3_scsi_reset_boot(instance);
-#endif
+       NCR5380_maybe_reset_bus(instance);
 
        error = scsi_add_host(instance, NULL);
        if (error)
@@ -649,6 +569,7 @@ fail_host:
                free_irq(instance->irq, instance);
 fail_irq:
        NCR5380_exit(instance);
+fail_init:
        scsi_host_put(instance);
 fail_alloc:
        if (udc_regs)
index 87828ac..4615fda 100644 (file)
  * 15 9-11
  */
  
-#include <linux/signal.h>
 #include <linux/io.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/delay.h>
 
 #include <scsi/scsi_host.h>
 #include "t128.h"
@@ -126,7 +123,7 @@ static struct signature {
 
 static int __init t128_setup(char *str)
 {
-    static int commandline_current = 0;
+       static int commandline_current;
     int i;
     int ints[10];
 
@@ -165,7 +162,7 @@ __setup("t128=", t128_setup);
 
 static int __init t128_detect(struct scsi_host_template *tpnt)
 {
-    static int current_override = 0, current_base = 0;
+       static int current_override, current_base;
     struct Scsi_Host *instance;
     unsigned long base;
     void __iomem *p;
@@ -182,9 +179,8 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
                base = 0;
        } else 
            for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (TDEBUG & TDEBUG_INIT)
-    printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
-#endif
+               dprintk(NDEBUG_INIT, "t128: probing address 0x%08x\n",
+                       bases[current_base].address);
                if (bases[current_base].noauto)
                        continue;
                p = ioremap(bases[current_base].address, 0x2000);
@@ -195,17 +191,13 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
                                        signatures[sig].string,
                                        strlen(signatures[sig].string))) {
                        base = bases[current_base].address;
-#if (TDEBUG & TDEBUG_INIT)
-                       printk("scsi-t128 : detected board.\n");
-#endif
+                       dprintk(NDEBUG_INIT, "t128: detected board\n");
                        goto found;
                    }
                iounmap(p);
            }
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-       printk("scsi-t128 : base = %08x\n", (unsigned int) base);
-#endif
+       dprintk(NDEBUG_INIT, "t128: base = 0x%08x\n", (unsigned int)base);
 
        if (!base)
            break;
@@ -213,12 +205,15 @@ static int __init t128_detect(struct scsi_host_template *tpnt)
 found:
        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
        if(instance == NULL)
-               break;
-               
+               goto out_unmap;
+
        instance->base = base;
        ((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-       NCR5380_init(instance, 0);
+       if (NCR5380_init(instance, 0))
+               goto out_unregister;
+
+       NCR5380_maybe_reset_bus(instance);
 
        if (overrides[current_override].irq != IRQ_AUTO)
            instance->irq = overrides[current_override].irq;
@@ -242,27 +237,30 @@ found:
            printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
        }
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-       printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+       dprintk(NDEBUG_INIT, "scsi%d: irq = %d\n",
+               instance->host_no, instance->irq);
 
        ++current_override;
        ++count;
     }
     return count;
+
+out_unregister:
+       scsi_unregister(instance);
+out_unmap:
+       iounmap(p);
+       return count;
 }
 
 static int t128_release(struct Scsi_Host *shost)
 {
-       NCR5380_local_declare();
-       NCR5380_setup(shost);
+       struct NCR5380_hostdata *hostdata = shost_priv(shost);
+
        if (shost->irq != NO_IRQ)
                free_irq(shost->irq, shost);
        NCR5380_exit(shost);
-       if (shost->io_port && shost->n_io_port)
-               release_region(shost->io_port, shost->n_io_port);
        scsi_unregister(shost);
-       iounmap(base);
+       iounmap(hostdata->base);
        return 0;
 }
 
@@ -308,14 +306,14 @@ static int t128_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  *     timeout.
  */
 
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
-    int len) {
-    NCR5380_local_declare();
-    void __iomem *reg;
+static inline int
+NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       void __iomem *reg, *base = hostdata->base;
     unsigned char *d = dst;
     register int i = len;
 
-    NCR5380_setup(instance);
     reg = base + T_DATA_REG_OFFSET;
 
 #if 0
@@ -354,14 +352,14 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
  *     timeout.
  */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
-    int len) {
-    NCR5380_local_declare();
-    void __iomem *reg;
+static inline int
+NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+{
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
+       void __iomem *reg, *base = hostdata->base;
     unsigned char *s = src;
     register int i = len;
 
-    NCR5380_setup(instance);
     reg = base + T_DATA_REG_OFFSET;
 
 #if 0
@@ -392,21 +390,23 @@ MODULE_LICENSE("GPL");
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-       .name           = "Trantor T128/T128F/T228",
-       .detect         = t128_detect,
-       .release        = t128_release,
-       .proc_name      = "t128",
-       .show_info      = t128_show_info,
-       .write_info     = t128_write_info,
-       .info           = t128_info,
-       .queuecommand   = t128_queue_command,
-       .eh_abort_handler = t128_abort,
-       .eh_bus_reset_handler    = t128_bus_reset,
-       .bios_param     = t128_biosparam,
-       .can_queue      = CAN_QUEUE,
-        .this_id        = 7,
-       .sg_tablesize   = SG_ALL,
-       .cmd_per_lun    = CMD_PER_LUN,
-       .use_clustering = DISABLE_CLUSTERING,
+       .name                   = "Trantor T128/T128F/T228",
+       .detect                 = t128_detect,
+       .release                = t128_release,
+       .proc_name              = "t128",
+       .show_info              = t128_show_info,
+       .write_info             = t128_write_info,
+       .info                   = t128_info,
+       .queuecommand           = t128_queue_command,
+       .eh_abort_handler       = t128_abort,
+       .eh_bus_reset_handler   = t128_bus_reset,
+       .bios_param             = t128_biosparam,
+       .can_queue              = 32,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 2,
+       .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_size               = NCR5380_CMD_SIZE,
+       .max_sectors            = 128,
 };
 #include "scsi_module.c"
index 2c73714..dd16d85 100644 (file)
 #ifndef T128_H
 #define T128_H
 
-#define TDEBUG         0
-#define TDEBUG_INIT    0x1
-#define TDEBUG_TRANSFER 0x2
-
 /*
  * The trantor boards are memory mapped. They use an NCR5380 or
  * equivalent (my sample board had part second sourced from ZILOG).
 
 #define T_DATA_REG_OFFSET      0x1e00  /* rw 512 bytes long */
 
-#ifndef ASM
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32
-#endif
-
 #define NCR5380_implementation_fields \
     void __iomem *base
 
-#define NCR5380_local_declare() \
-    void __iomem *base
-
-#define NCR5380_setup(instance) \
-    base = ((struct NCR5380_hostdata *)(instance->hostdata))->base
+#define T128_address(reg) \
+       (((struct NCR5380_hostdata *)shost_priv(instance))->base + T_5380_OFFSET + ((reg) * 0x20))
 
-#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
-
-#if !(TDEBUG & TDEBUG_TRANSFER)
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
-#else
-#define NCR5380_read(reg)                                              \
-    (((unsigned char) printk("scsi%d : read register %d at address %08x\n"\
-    , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg)))
-
-#define NCR5380_write(reg, value) {                                    \
-    printk("scsi%d : write %02x to register %d at address %08x\n",     \
-           instance->hostno, (value), (reg), T128_address(reg));       \
-    writeb((value), (T128_address(reg)));                              \
-}
-#endif
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase)     (cmd->transfersize)
 
 #define NCR5380_intr t128_intr
-#define do_NCR5380_intr do_t128_intr
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort
 #define NCR5380_bus_reset t128_bus_reset
 
 #define T128_IRQS 0xc4a8
 
-#endif /* ndef ASM */
 #endif /* T128_H */
index be56b22..92863e3 100644 (file)
@@ -469,6 +469,9 @@ void clk_enable_init_clocks(void)
 
 unsigned long clk_get_rate(struct clk *clk)
 {
+       if (!clk)
+               return 0;
+
        return clk->rate;
 }
 EXPORT_SYMBOL_GPL(clk_get_rate);
@@ -478,6 +481,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        int ret = -EOPNOTSUPP;
        unsigned long flags;
 
+       if (!clk)
+               return 0;
+
        spin_lock_irqsave(&clock_lock, flags);
 
        if (likely(clk->ops && clk->ops->set_rate)) {
@@ -535,12 +541,18 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
 
 struct clk *clk_get_parent(struct clk *clk)
 {
+       if (!clk)
+               return NULL;
+
        return clk->parent;
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
 
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
+       if (!clk)
+               return 0;
+
        if (likely(clk->ops && clk->ops->round_rate)) {
                unsigned long flags, rounded;
 
@@ -555,94 +567,6 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
-long clk_round_parent(struct clk *clk, unsigned long target,
-                     unsigned long *best_freq, unsigned long *parent_freq,
-                     unsigned int div_min, unsigned int div_max)
-{
-       struct cpufreq_frequency_table *freq, *best = NULL;
-       unsigned long error = ULONG_MAX, freq_high, freq_low, div;
-       struct clk *parent = clk_get_parent(clk);
-
-       if (!parent) {
-               *parent_freq = 0;
-               *best_freq = clk_round_rate(clk, target);
-               return abs(target - *best_freq);
-       }
-
-       cpufreq_for_each_valid_entry(freq, parent->freq_table) {
-               if (unlikely(freq->frequency / target <= div_min - 1)) {
-                       unsigned long freq_max;
-
-                       freq_max = (freq->frequency + div_min / 2) / div_min;
-                       if (error > target - freq_max) {
-                               error = target - freq_max;
-                               best = freq;
-                               if (best_freq)
-                                       *best_freq = freq_max;
-                       }
-
-                       pr_debug("too low freq %u, error %lu\n", freq->frequency,
-                                target - freq_max);
-
-                       if (!error)
-                               break;
-
-                       continue;
-               }
-
-               if (unlikely(freq->frequency / target >= div_max)) {
-                       unsigned long freq_min;
-
-                       freq_min = (freq->frequency + div_max / 2) / div_max;
-                       if (error > freq_min - target) {
-                               error = freq_min - target;
-                               best = freq;
-                               if (best_freq)
-                                       *best_freq = freq_min;
-                       }
-
-                       pr_debug("too high freq %u, error %lu\n", freq->frequency,
-                                freq_min - target);
-
-                       if (!error)
-                               break;
-
-                       continue;
-               }
-
-               div = freq->frequency / target;
-               freq_high = freq->frequency / div;
-               freq_low = freq->frequency / (div + 1);
-
-               if (freq_high - target < error) {
-                       error = freq_high - target;
-                       best = freq;
-                       if (best_freq)
-                               *best_freq = freq_high;
-               }
-
-               if (target - freq_low < error) {
-                       error = target - freq_low;
-                       best = freq;
-                       if (best_freq)
-                               *best_freq = freq_low;
-               }
-
-               pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n",
-                        freq->frequency, div, freq_high, div + 1, freq_low,
-                        *best_freq, best->frequency);
-
-               if (!error)
-                       break;
-       }
-
-       if (parent_freq)
-               *parent_freq = best->frequency;
-
-       return error;
-}
-EXPORT_SYMBOL_GPL(clk_round_parent);
-
 #ifdef CONFIG_PM
 static void clks_core_resume(void)
 {
index ad0df75..8826020 100644 (file)
@@ -1,11 +1,13 @@
 menu "SOC (System On Chip) specific Drivers"
 
+source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/brcmstb/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
 source "drivers/soc/rockchip/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
+source "drivers/soc/tegra/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
 
index 9536b80..2afdc74 100644 (file)
@@ -2,7 +2,9 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-y                          += bcm/
 obj-$(CONFIG_SOC_BRCMSTB)      += brcmstb/
+obj-$(CONFIG_ARCH_DOVE)                += dove/
 obj-$(CONFIG_MACH_DOVE)                += dove/
 obj-y                          += fsl/
 obj-$(CONFIG_ARCH_MEDIATEK)    += mediatek/
diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig
new file mode 100644 (file)
index 0000000..3066ede
--- /dev/null
@@ -0,0 +1,9 @@
+config RASPBERRYPI_POWER
+       bool "Raspberry Pi power domain driver"
+       depends on ARCH_BCM2835 || COMPILE_TEST
+       depends on RASPBERRYPI_FIRMWARE=y
+       select PM_GENERIC_DOMAINS if PM
+       select PM_GENERIC_DOMAINS_OF if PM
+       help
+         This enables support for the RPi power domains which can be enabled
+         or disabled via the RPi firmware.
diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile
new file mode 100644 (file)
index 0000000..63aa3eb
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_RASPBERRYPI_POWER)        += raspberrypi-power.o
diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c
new file mode 100644 (file)
index 0000000..fe96a8b
--- /dev/null
@@ -0,0 +1,247 @@
+/* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Authors:
+ * Alexander Aring <aar@pengutronix.de>
+ * Eric Anholt <eric@anholt.net>
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <dt-bindings/power/raspberrypi-power.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+/*
+ * Firmware indices for the old power domains interface.  Only a few
+ * of them were actually implemented.
+ */
+#define RPI_OLD_POWER_DOMAIN_USB               3
+#define RPI_OLD_POWER_DOMAIN_V3D               10
+
+struct rpi_power_domain {
+       u32 domain;
+       bool enabled;
+       bool old_interface;
+       struct generic_pm_domain base;
+       struct rpi_firmware *fw;
+};
+
+struct rpi_power_domains {
+       bool has_new_interface;
+       struct genpd_onecell_data xlate;
+       struct rpi_firmware *fw;
+       struct rpi_power_domain domains[RPI_POWER_DOMAIN_COUNT];
+};
+
+/*
+ * Packet definition used by RPI_FIRMWARE_SET_POWER_STATE and
+ * RPI_FIRMWARE_SET_DOMAIN_STATE
+ */
+struct rpi_power_domain_packet {
+       u32 domain;
+       u32 on;
+} __packet;
+
+/*
+ * Asks the firmware to enable or disable power on a specific power
+ * domain.
+ */
+static int rpi_firmware_set_power(struct rpi_power_domain *rpi_domain, bool on)
+{
+       struct rpi_power_domain_packet packet;
+
+       packet.domain = rpi_domain->domain;
+       packet.on = on;
+       return rpi_firmware_property(rpi_domain->fw,
+                                    rpi_domain->old_interface ?
+                                    RPI_FIRMWARE_SET_POWER_STATE :
+                                    RPI_FIRMWARE_SET_DOMAIN_STATE,
+                                    &packet, sizeof(packet));
+}
+
+static int rpi_domain_off(struct generic_pm_domain *domain)
+{
+       struct rpi_power_domain *rpi_domain =
+               container_of(domain, struct rpi_power_domain, base);
+
+       return rpi_firmware_set_power(rpi_domain, false);
+}
+
+static int rpi_domain_on(struct generic_pm_domain *domain)
+{
+       struct rpi_power_domain *rpi_domain =
+               container_of(domain, struct rpi_power_domain, base);
+
+       return rpi_firmware_set_power(rpi_domain, true);
+}
+
+static void rpi_common_init_power_domain(struct rpi_power_domains *rpi_domains,
+                                        int xlate_index, const char *name)
+{
+       struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
+
+       dom->fw = rpi_domains->fw;
+
+       dom->base.name = name;
+       dom->base.power_on = rpi_domain_on;
+       dom->base.power_off = rpi_domain_off;
+
+       /*
+        * Treat all power domains as off at boot.
+        *
+        * The firmware itself may be keeping some domains on, but
+        * from Linux's perspective all we control is the refcounts
+        * that we give to the firmware, and we can't ask the firmware
+        * to turn off something that we haven't ourselves turned on.
+        */
+       pm_genpd_init(&dom->base, NULL, true);
+
+       rpi_domains->xlate.domains[xlate_index] = &dom->base;
+}
+
+static void rpi_init_power_domain(struct rpi_power_domains *rpi_domains,
+                                 int xlate_index, const char *name)
+{
+       struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
+
+       if (!rpi_domains->has_new_interface)
+               return;
+
+       /* The DT binding index is the firmware's domain index minus one. */
+       dom->domain = xlate_index + 1;
+
+       rpi_common_init_power_domain(rpi_domains, xlate_index, name);
+}
+
+static void rpi_init_old_power_domain(struct rpi_power_domains *rpi_domains,
+                                     int xlate_index, int domain,
+                                     const char *name)
+{
+       struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
+
+       dom->old_interface = true;
+       dom->domain = domain;
+
+       rpi_common_init_power_domain(rpi_domains, xlate_index, name);
+}
+
+/*
+ * Detects whether the firmware supports the new power domains interface.
+ *
+ * The firmware doesn't actually return an error on an unknown tag,
+ * and just skips over it, so we do the detection by putting an
+ * unexpected value in the return field and checking if it was
+ * unchanged.
+ */
+static bool
+rpi_has_new_domain_support(struct rpi_power_domains *rpi_domains)
+{
+       struct rpi_power_domain_packet packet;
+       int ret;
+
+       packet.domain = RPI_POWER_DOMAIN_ARM;
+       packet.on = ~0;
+
+       ret = rpi_firmware_property(rpi_domains->fw,
+                                   RPI_FIRMWARE_GET_DOMAIN_STATE,
+                                   &packet, sizeof(packet));
+
+       return ret == 0 && packet.on != ~0;
+}
+
+static int rpi_power_probe(struct platform_device *pdev)
+{
+       struct device_node *fw_np;
+       struct device *dev = &pdev->dev;
+       struct rpi_power_domains *rpi_domains;
+
+       rpi_domains = devm_kzalloc(dev, sizeof(*rpi_domains), GFP_KERNEL);
+       if (!rpi_domains)
+               return -ENOMEM;
+
+       rpi_domains->xlate.domains =
+               devm_kzalloc(dev, sizeof(*rpi_domains->xlate.domains) *
+                            RPI_POWER_DOMAIN_COUNT, GFP_KERNEL);
+       if (!rpi_domains->xlate.domains)
+               return -ENOMEM;
+
+       rpi_domains->xlate.num_domains = RPI_POWER_DOMAIN_COUNT;
+
+       fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
+       if (!fw_np) {
+               dev_err(&pdev->dev, "no firmware node\n");
+               return -ENODEV;
+       }
+
+       rpi_domains->fw = rpi_firmware_get(fw_np);
+       of_node_put(fw_np);
+       if (!rpi_domains->fw)
+               return -EPROBE_DEFER;
+
+       rpi_domains->has_new_interface =
+               rpi_has_new_domain_support(rpi_domains);
+
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C0, "I2C0");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C1, "I2C1");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C2, "I2C2");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VIDEO_SCALER,
+                             "VIDEO_SCALER");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VPU1, "VPU1");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_HDMI, "HDMI");
+
+       /*
+        * Use the old firmware interface for USB power, so that we
+        * can turn it on even if the firmware hasn't been updated.
+        */
+       rpi_init_old_power_domain(rpi_domains, RPI_POWER_DOMAIN_USB,
+                                 RPI_OLD_POWER_DOMAIN_USB, "USB");
+
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VEC, "VEC");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_JPEG, "JPEG");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_H264, "H264");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_V3D, "V3D");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ISP, "ISP");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM0, "UNICAM0");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM1, "UNICAM1");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2RX, "CCP2RX");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CSI2, "CSI2");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CPI, "CPI");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI0, "DSI0");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI1, "DSI1");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_TRANSPOSER,
+                             "TRANSPOSER");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2TX, "CCP2TX");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CDP, "CDP");
+       rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ARM, "ARM");
+
+       of_genpd_add_provider_onecell(dev->of_node, &rpi_domains->xlate);
+
+       platform_set_drvdata(pdev, rpi_domains);
+
+       return 0;
+}
+
+static const struct of_device_id rpi_power_of_match[] = {
+       { .compatible = "raspberrypi,bcm2835-power", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, rpi_power_of_match);
+
+static struct platform_driver rpi_power_driver = {
+       .driver = {
+               .name = "raspberrypi-power",
+               .of_match_table = rpi_power_of_match,
+       },
+       .probe          = rpi_power_probe,
+};
+builtin_platform_driver(rpi_power_driver);
+
+MODULE_AUTHOR("Alexander Aring <aar@pengutronix.de>");
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("Raspberry Pi power domain driver");
+MODULE_LICENSE("GPL v2");
index abd0879..039374e 100644 (file)
@@ -305,6 +305,49 @@ static int __init dove_init_pmu_irq(struct pmu_data *pmu, int irq)
        return 0;
 }
 
+int __init dove_init_pmu_legacy(const struct dove_pmu_initdata *initdata)
+{
+       const struct dove_pmu_domain_initdata *domain_initdata;
+       struct pmu_data *pmu;
+       int ret;
+
+       pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
+       if (!pmu)
+               return -ENOMEM;
+
+       spin_lock_init(&pmu->lock);
+       pmu->pmc_base = initdata->pmc_base;
+       pmu->pmu_base = initdata->pmu_base;
+
+       pmu_reset_init(pmu);
+       for (domain_initdata = initdata->domains; domain_initdata->name;
+            domain_initdata++) {
+               struct pmu_domain *domain;
+
+               domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+               if (domain) {
+                       domain->pmu = pmu;
+                       domain->pwr_mask = domain_initdata->pwr_mask;
+                       domain->rst_mask = domain_initdata->rst_mask;
+                       domain->iso_mask = domain_initdata->iso_mask;
+                       domain->base.name = domain_initdata->name;
+
+                       __pmu_domain_register(domain, NULL);
+               }
+       }
+
+       ret = dove_init_pmu_irq(pmu, initdata->irq);
+       if (ret)
+               pr_err("dove_init_pmu_irq() failed: %d\n", ret);
+
+       if (pmu->irq_domain)
+               irq_domain_associate_many(pmu->irq_domain,
+                                         initdata->irq_domain_start,
+                                         0, NR_PMU_IRQS);
+
+       return 0;
+}
+
 /*
  * pmu: power-manager@d0000 {
  *     compatible = "marvell,dove-pmu";
index 4d4203c..0221387 100644 (file)
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/infracfg.h>
+#include <linux/regulator/consumer.h>
 #include <dt-bindings/power/mt8173-power.h>
 
 #define SPM_VDE_PWR_CON                        0x0210
@@ -179,6 +180,7 @@ struct scp_domain {
        u32 sram_pdn_ack_bits;
        u32 bus_prot_mask;
        bool active_wakeup;
+       struct regulator *supply;
 };
 
 struct scp {
@@ -221,6 +223,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        int ret;
        int i;
 
+       if (scpd->supply) {
+               ret = regulator_enable(scpd->supply);
+               if (ret)
+                       return ret;
+       }
+
        for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
                ret = clk_prepare_enable(scpd->clk[i]);
                if (ret) {
@@ -299,6 +307,9 @@ err_pwr_ack:
                        clk_disable_unprepare(scpd->clk[i]);
        }
 err_clk:
+       if (scpd->supply)
+               regulator_disable(scpd->supply);
+
        dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
 
        return ret;
@@ -379,6 +390,9 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
                clk_disable_unprepare(scpd->clk[i]);
 
+       if (scpd->supply)
+               regulator_disable(scpd->supply);
+
        return 0;
 
 out:
@@ -448,6 +462,19 @@ static int __init scpsys_probe(struct platform_device *pdev)
                return PTR_ERR(scp->infracfg);
        }
 
+       for (i = 0; i < NUM_DOMAINS; i++) {
+               struct scp_domain *scpd = &scp->domains[i];
+               const struct scp_domain_data *data = &scp_domain_data[i];
+
+               scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
+               if (IS_ERR(scpd->supply)) {
+                       if (PTR_ERR(scpd->supply) == -ENODEV)
+                               scpd->supply = NULL;
+                       else
+                               return PTR_ERR(scpd->supply);
+               }
+       }
+
        pd_data->num_domains = NUM_DOMAINS;
 
        for (i = 0; i < NUM_DOMAINS; i++) {
@@ -521,5 +548,4 @@ static struct platform_driver scpsys_drv = {
                .of_match_table = of_match_ptr(of_scpsys_match_tbl),
        },
 };
-
-module_platform_driver_probe(scpsys_drv, scpsys_probe);
+builtin_platform_driver_probe(scpsys_drv, scpsys_probe);
index eec7614..461b387 100644 (file)
@@ -13,6 +13,7 @@ config QCOM_GSBI
 config QCOM_PM
        bool "Qualcomm Power Management"
        depends on ARCH_QCOM && !ARM64
+       select ARM_CPU_SUSPEND
        select QCOM_SCM
        help
          QCOM Platform specific power driver to manage cores and L2 low power
@@ -49,3 +50,29 @@ config QCOM_SMD_RPM
 
          Say M here if you want to include support for the Qualcomm RPM as a
          module. This will build a module called "qcom-smd-rpm".
+
+config QCOM_SMEM_STATE
+       bool
+
+config QCOM_SMP2P
+       tristate "Qualcomm Shared Memory Point to Point support"
+       depends on QCOM_SMEM
+       select QCOM_SMEM_STATE
+       help
+         Say yes here to support the Qualcomm Shared Memory Point to Point
+         protocol.
+
+config QCOM_SMSM
+       tristate "Qualcomm Shared Memory State Machine"
+       depends on QCOM_SMEM
+       select QCOM_SMEM_STATE
+       help
+         Say yes here to support the Qualcomm Shared Memory State Machine.
+         The state machine is represented by bits in shared memory.
+
+config QCOM_WCNSS_CTRL
+       tristate "Qualcomm WCNSS control driver"
+       depends on QCOM_SMD
+       help
+         Client driver for the WCNSS_CTRL SMD channel, used to download nv
+         firmware to a newly booted WCNSS chip.
index 10a93d1..fdd664e 100644 (file)
@@ -3,3 +3,7 @@ obj-$(CONFIG_QCOM_PM)   +=      spm.o
 obj-$(CONFIG_QCOM_SMD) +=      smd.o
 obj-$(CONFIG_QCOM_SMD_RPM)     += smd-rpm.o
 obj-$(CONFIG_QCOM_SMEM) +=     smem.o
+obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
+obj-$(CONFIG_QCOM_SMP2P)       += smp2p.o
+obj-$(CONFIG_QCOM_SMSM)        += smsm.o
+obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
index 2969321..731fa06 100644 (file)
@@ -219,6 +219,8 @@ static void qcom_smd_rpm_remove(struct qcom_smd_device *sdev)
 }
 
 static const struct of_device_id qcom_smd_rpm_of_match[] = {
+       { .compatible = "qcom,rpm-apq8084" },
+       { .compatible = "qcom,rpm-msm8916" },
        { .compatible = "qcom,rpm-msm8974" },
        {}
 };
index 86b598c..498fd05 100644 (file)
@@ -434,20 +434,15 @@ static void smd_copy_to_fifo(void __iomem *dst,
 /*
  * Copy count bytes of data using 32bit accesses, if that is required.
  */
-static void smd_copy_from_fifo(void *_dst,
-                              const void __iomem *_src,
+static void smd_copy_from_fifo(void *dst,
+                              const void __iomem *src,
                               size_t count,
                               bool word_aligned)
 {
-       u32 *dst = (u32 *)_dst;
-       u32 *src = (u32 *)_src;
-
        if (word_aligned) {
-               count /= sizeof(u32);
-               while (count--)
-                       *dst++ = __raw_readl(src++);
+               __ioread32_copy(dst, src, count / sizeof(u32));
        } else {
-               memcpy_fromio(_dst, _src, count);
+               memcpy_fromio(dst, src, count);
        }
 }
 
diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c
new file mode 100644 (file)
index 0000000..54261de
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/device.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem_state.h>
+
+static LIST_HEAD(smem_states);
+static DEFINE_MUTEX(list_lock);
+
+/**
+ * struct qcom_smem_state - state context
+ * @refcount:  refcount for the state
+ * @orphan:    boolean indicator that this state has been unregistered
+ * @list:      entry in smem_states list
+ * @of_node:   of_node to use for matching the state in DT
+ * @priv:      implementation private data
+ * @ops:       ops for the state
+ */
+struct qcom_smem_state {
+       struct kref refcount;
+       bool orphan;
+
+       struct list_head list;
+       struct device_node *of_node;
+
+       void *priv;
+
+       struct qcom_smem_state_ops ops;
+};
+
+/**
+ * qcom_smem_state_update_bits() - update the masked bits in state with value
+ * @state:     state handle acquired by calling qcom_smem_state_get()
+ * @mask:      bit mask for the change
+ * @value:     new value for the masked bits
+ *
+ * Returns 0 on success, otherwise negative errno.
+ */
+int qcom_smem_state_update_bits(struct qcom_smem_state *state,
+                               u32 mask,
+                               u32 value)
+{
+       if (state->orphan)
+               return -ENXIO;
+
+       if (!state->ops.update_bits)
+               return -ENOTSUPP;
+
+       return state->ops.update_bits(state->priv, mask, value);
+}
+EXPORT_SYMBOL_GPL(qcom_smem_state_update_bits);
+
+static struct qcom_smem_state *of_node_to_state(struct device_node *np)
+{
+       struct qcom_smem_state *state;
+
+       mutex_lock(&list_lock);
+
+       list_for_each_entry(state, &smem_states, list) {
+               if (state->of_node == np) {
+                       kref_get(&state->refcount);
+                       goto unlock;
+               }
+       }
+       state = ERR_PTR(-EPROBE_DEFER);
+
+unlock:
+       mutex_unlock(&list_lock);
+
+       return state;
+}
+
+/**
+ * qcom_smem_state_get() - acquire handle to a state
+ * @dev:       client device pointer
+ * @con_id:    name of the state to lookup
+ * @bit:       flags from the state reference, indicating which bit's affected
+ *
+ * Returns handle to the state, or ERR_PTR(). qcom_smem_state_put() must be
+ * called to release the returned state handle.
+ */
+struct qcom_smem_state *qcom_smem_state_get(struct device *dev,
+                                           const char *con_id,
+                                           unsigned *bit)
+{
+       struct qcom_smem_state *state;
+       struct of_phandle_args args;
+       int index = 0;
+       int ret;
+
+       if (con_id) {
+               index = of_property_match_string(dev->of_node,
+                                                "qcom,state-names",
+                                                con_id);
+               if (index < 0) {
+                       dev_err(dev, "missing qcom,state-names\n");
+                       return ERR_PTR(index);
+               }
+       }
+
+       ret = of_parse_phandle_with_args(dev->of_node,
+                                        "qcom,state",
+                                        "#qcom,state-cells",
+                                        index,
+                                        &args);
+       if (ret) {
+               dev_err(dev, "failed to parse qcom,state property\n");
+               return ERR_PTR(ret);
+       }
+
+       if (args.args_count != 1) {
+               dev_err(dev, "invalid #qcom,state-cells\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       state = of_node_to_state(args.np);
+       if (IS_ERR(state))
+               goto put;
+
+       *bit = args.args[0];
+
+put:
+       of_node_put(args.np);
+       return state;
+}
+EXPORT_SYMBOL_GPL(qcom_smem_state_get);
+
+static void qcom_smem_state_release(struct kref *ref)
+{
+       struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount);
+
+       list_del(&state->list);
+       kfree(state);
+}
+
+/**
+ * qcom_smem_state_put() - release state handle
+ * @state:     state handle to be released
+ */
+void qcom_smem_state_put(struct qcom_smem_state *state)
+{
+       mutex_lock(&list_lock);
+       kref_put(&state->refcount, qcom_smem_state_release);
+       mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL_GPL(qcom_smem_state_put);
+
+/**
+ * qcom_smem_state_register() - register a new state
+ * @of_node:   of_node used for matching client lookups
+ * @ops:       implementation ops
+ * @priv:      implementation specific private data
+ */
+struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node,
+                                                const struct qcom_smem_state_ops *ops,
+                                                void *priv)
+{
+       struct qcom_smem_state *state;
+
+       state = kzalloc(sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return ERR_PTR(-ENOMEM);
+
+       kref_init(&state->refcount);
+
+       state->of_node = of_node;
+       state->ops = *ops;
+       state->priv = priv;
+
+       mutex_lock(&list_lock);
+       list_add(&state->list, &smem_states);
+       mutex_unlock(&list_lock);
+
+       return state;
+}
+EXPORT_SYMBOL_GPL(qcom_smem_state_register);
+
+/**
+ * qcom_smem_state_unregister() - unregister a registered state
+ * @state:     state handle to be unregistered
+ */
+void qcom_smem_state_unregister(struct qcom_smem_state *state)
+{
+       state->orphan = true;
+       qcom_smem_state_put(state);
+}
+EXPORT_SYMBOL_GPL(qcom_smem_state_unregister);
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
new file mode 100644 (file)
index 0000000..f1eed7f
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications AB.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/interrupt.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/soc/qcom/smem_state.h>
+#include <linux/spinlock.h>
+
+/*
+ * The Shared Memory Point to Point (SMP2P) protocol facilitates communication
+ * of a single 32-bit value between two processors.  Each value has a single
+ * writer (the local side) and a single reader (the remote side). Values are
+ * uniquely identified in the system by the directed edge (local processor ID
+ * to remote processor ID) and a string identifier.
+ *
+ * Each processor is responsible for creating the outgoing SMEM items and each
+ * item is writable by the local processor and readable by the remote
+ * processor.  By using two separate SMEM items that are single-reader and
+ * single-writer, SMP2P does not require any remote locking mechanisms.
+ *
+ * The driver uses the Linux GPIO and interrupt framework to expose a virtual
+ * GPIO for each outbound entry and a virtual interrupt controller for each
+ * inbound entry.
+ */
+
+#define SMP2P_MAX_ENTRY 16
+#define SMP2P_MAX_ENTRY_NAME 16
+
+#define SMP2P_FEATURE_SSR_ACK 0x1
+
+#define SMP2P_MAGIC 0x504d5324
+
+/**
+ * struct smp2p_smem_item - in memory communication structure
+ * @magic:             magic number
+ * @version:           version - must be 1
+ * @features:          features flag - currently unused
+ * @local_pid:         processor id of sending end
+ * @remote_pid:                processor id of receiving end
+ * @total_entries:     number of entries - always SMP2P_MAX_ENTRY
+ * @valid_entries:     number of allocated entries
+ * @flags:
+ * @entries:           individual communication entries
+ *     @name:          name of the entry
+ *     @value:         content of the entry
+ */
+struct smp2p_smem_item {
+       u32 magic;
+       u8 version;
+       unsigned features:24;
+       u16 local_pid;
+       u16 remote_pid;
+       u16 total_entries;
+       u16 valid_entries;
+       u32 flags;
+
+       struct {
+               u8 name[SMP2P_MAX_ENTRY_NAME];
+               u32 value;
+       } entries[SMP2P_MAX_ENTRY];
+} __packed;
+
+/**
+ * struct smp2p_entry - driver context matching one entry
+ * @node:      list entry to keep track of allocated entries
+ * @smp2p:     reference to the device driver context
+ * @name:      name of the entry, to match against smp2p_smem_item
+ * @value:     pointer to smp2p_smem_item entry value
+ * @last_value:        last handled value
+ * @domain:    irq_domain for inbound entries
+ * @irq_enabled:bitmap to track enabled irq bits
+ * @irq_rising:        bitmap to mark irq bits for rising detection
+ * @irq_falling:bitmap to mark irq bits for falling detection
+ * @state:     smem state handle
+ * @lock:      spinlock to protect read-modify-write of the value
+ */
+struct smp2p_entry {
+       struct list_head node;
+       struct qcom_smp2p *smp2p;
+
+       const char *name;
+       u32 *value;
+       u32 last_value;
+
+       struct irq_domain *domain;
+       DECLARE_BITMAP(irq_enabled, 32);
+       DECLARE_BITMAP(irq_rising, 32);
+       DECLARE_BITMAP(irq_falling, 32);
+
+       struct qcom_smem_state *state;
+
+       spinlock_t lock;
+};
+
+#define SMP2P_INBOUND  0
+#define SMP2P_OUTBOUND 1
+
+/**
+ * struct qcom_smp2p - device driver context
+ * @dev:       device driver handle
+ * @in:                pointer to the inbound smem item
+ * @smem_items:        ids of the two smem items
+ * @valid_entries: already scanned inbound entries
+ * @local_pid: processor id of the inbound edge
+ * @remote_pid:        processor id of the outbound edge
+ * @ipc_regmap:        regmap for the outbound ipc
+ * @ipc_offset:        offset within the regmap
+ * @ipc_bit:   bit in regmap@offset to kick to signal remote processor
+ * @inbound:   list of inbound entries
+ * @outbound:  list of outbound entries
+ */
+struct qcom_smp2p {
+       struct device *dev;
+
+       struct smp2p_smem_item *in;
+       struct smp2p_smem_item *out;
+
+       unsigned smem_items[SMP2P_OUTBOUND + 1];
+
+       unsigned valid_entries;
+
+       unsigned local_pid;
+       unsigned remote_pid;
+
+       struct regmap *ipc_regmap;
+       int ipc_offset;
+       int ipc_bit;
+
+       struct list_head inbound;
+       struct list_head outbound;
+};
+
+static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
+{
+       /* Make sure any updated data is written before the kick */
+       wmb();
+       regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit));
+}
+
+/**
+ * qcom_smp2p_intr() - interrupt handler for incoming notifications
+ * @irq:       unused
+ * @data:      smp2p driver context
+ *
+ * Handle notifications from the remote side to handle newly allocated entries
+ * or any changes to the state bits of existing entries.
+ */
+static irqreturn_t qcom_smp2p_intr(int irq, void *data)
+{
+       struct smp2p_smem_item *in;
+       struct smp2p_entry *entry;
+       struct qcom_smp2p *smp2p = data;
+       unsigned smem_id = smp2p->smem_items[SMP2P_INBOUND];
+       unsigned pid = smp2p->remote_pid;
+       size_t size;
+       int irq_pin;
+       u32 status;
+       char buf[SMP2P_MAX_ENTRY_NAME];
+       u32 val;
+       int i;
+
+       in = smp2p->in;
+
+       /* Acquire smem item, if not already found */
+       if (!in) {
+               in = qcom_smem_get(pid, smem_id, &size);
+               if (IS_ERR(in)) {
+                       dev_err(smp2p->dev,
+                               "Unable to acquire remote smp2p item\n");
+                       return IRQ_HANDLED;
+               }
+
+               smp2p->in = in;
+       }
+
+       /* Match newly created entries */
+       for (i = smp2p->valid_entries; i < in->valid_entries; i++) {
+               list_for_each_entry(entry, &smp2p->inbound, node) {
+                       memcpy_fromio(buf, in->entries[i].name, sizeof(buf));
+                       if (!strcmp(buf, entry->name)) {
+                               entry->value = &in->entries[i].value;
+                               break;
+                       }
+               }
+       }
+       smp2p->valid_entries = i;
+
+       /* Fire interrupts based on any value changes */
+       list_for_each_entry(entry, &smp2p->inbound, node) {
+               /* Ignore entries not yet allocated by the remote side */
+               if (!entry->value)
+                       continue;
+
+               val = readl(entry->value);
+
+               status = val ^ entry->last_value;
+               entry->last_value = val;
+
+               /* No changes of this entry? */
+               if (!status)
+                       continue;
+
+               for_each_set_bit(i, entry->irq_enabled, 32) {
+                       if (!(status & BIT(i)))
+                               continue;
+
+                       if ((val & BIT(i) && test_bit(i, entry->irq_rising)) ||
+                           (!(val & BIT(i)) && test_bit(i, entry->irq_falling))) {
+                               irq_pin = irq_find_mapping(entry->domain, i);
+                               handle_nested_irq(irq_pin);
+                       }
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static void smp2p_mask_irq(struct irq_data *irqd)
+{
+       struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd);
+       irq_hw_number_t irq = irqd_to_hwirq(irqd);
+
+       clear_bit(irq, entry->irq_enabled);
+}
+
+static void smp2p_unmask_irq(struct irq_data *irqd)
+{
+       struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd);
+       irq_hw_number_t irq = irqd_to_hwirq(irqd);
+
+       set_bit(irq, entry->irq_enabled);
+}
+
+static int smp2p_set_irq_type(struct irq_data *irqd, unsigned int type)
+{
+       struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd);
+       irq_hw_number_t irq = irqd_to_hwirq(irqd);
+
+       if (!(type & IRQ_TYPE_EDGE_BOTH))
+               return -EINVAL;
+
+       if (type & IRQ_TYPE_EDGE_RISING)
+               set_bit(irq, entry->irq_rising);
+       else
+               clear_bit(irq, entry->irq_rising);
+
+       if (type & IRQ_TYPE_EDGE_FALLING)
+               set_bit(irq, entry->irq_falling);
+       else
+               clear_bit(irq, entry->irq_falling);
+
+       return 0;
+}
+
+static struct irq_chip smp2p_irq_chip = {
+       .name           = "smp2p",
+       .irq_mask       = smp2p_mask_irq,
+       .irq_unmask     = smp2p_unmask_irq,
+       .irq_set_type   = smp2p_set_irq_type,
+};
+
+static int smp2p_irq_map(struct irq_domain *d,
+                        unsigned int irq,
+                        irq_hw_number_t hw)
+{
+       struct smp2p_entry *entry = d->host_data;
+
+       irq_set_chip_and_handler(irq, &smp2p_irq_chip, handle_level_irq);
+       irq_set_chip_data(irq, entry);
+       irq_set_nested_thread(irq, 1);
+       irq_set_noprobe(irq);
+
+       return 0;
+}
+
+static const struct irq_domain_ops smp2p_irq_ops = {
+       .map = smp2p_irq_map,
+       .xlate = irq_domain_xlate_twocell,
+};
+
+static int qcom_smp2p_inbound_entry(struct qcom_smp2p *smp2p,
+                                   struct smp2p_entry *entry,
+                                   struct device_node *node)
+{
+       entry->domain = irq_domain_add_linear(node, 32, &smp2p_irq_ops, entry);
+       if (!entry->domain) {
+               dev_err(smp2p->dev, "failed to add irq_domain\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static int smp2p_update_bits(void *data, u32 mask, u32 value)
+{
+       struct smp2p_entry *entry = data;
+       u32 orig;
+       u32 val;
+
+       spin_lock(&entry->lock);
+       val = orig = readl(entry->value);
+       val &= ~mask;
+       val |= value;
+       writel(val, entry->value);
+       spin_unlock(&entry->lock);
+
+       if (val != orig)
+               qcom_smp2p_kick(entry->smp2p);
+
+       return 0;
+}
+
+static const struct qcom_smem_state_ops smp2p_state_ops = {
+       .update_bits = smp2p_update_bits,
+};
+
+static int qcom_smp2p_outbound_entry(struct qcom_smp2p *smp2p,
+                                    struct smp2p_entry *entry,
+                                    struct device_node *node)
+{
+       struct smp2p_smem_item *out = smp2p->out;
+       char buf[SMP2P_MAX_ENTRY_NAME] = {};
+
+       /* Allocate an entry from the smem item */
+       strlcpy(buf, entry->name, SMP2P_MAX_ENTRY_NAME);
+       memcpy_toio(out->entries[out->valid_entries].name, buf, SMP2P_MAX_ENTRY_NAME);
+       out->valid_entries++;
+
+       /* Make the logical entry reference the physical value */
+       entry->value = &out->entries[out->valid_entries].value;
+
+       entry->state = qcom_smem_state_register(node, &smp2p_state_ops, entry);
+       if (IS_ERR(entry->state)) {
+               dev_err(smp2p->dev, "failed to register qcom_smem_state\n");
+               return PTR_ERR(entry->state);
+       }
+
+       return 0;
+}
+
+static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p)
+{
+       struct smp2p_smem_item *out;
+       unsigned smem_id = smp2p->smem_items[SMP2P_OUTBOUND];
+       unsigned pid = smp2p->remote_pid;
+       int ret;
+
+       ret = qcom_smem_alloc(pid, smem_id, sizeof(*out));
+       if (ret < 0 && ret != -EEXIST) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(smp2p->dev,
+                               "unable to allocate local smp2p item\n");
+               return ret;
+       }
+
+       out = qcom_smem_get(pid, smem_id, NULL);
+       if (IS_ERR(out)) {
+               dev_err(smp2p->dev, "Unable to acquire local smp2p item\n");
+               return PTR_ERR(out);
+       }
+
+       memset(out, 0, sizeof(*out));
+       out->magic = SMP2P_MAGIC;
+       out->local_pid = smp2p->local_pid;
+       out->remote_pid = smp2p->remote_pid;
+       out->total_entries = SMP2P_MAX_ENTRY;
+       out->valid_entries = 0;
+
+       /*
+        * Make sure the rest of the header is written before we validate the
+        * item by writing a valid version number.
+        */
+       wmb();
+       out->version = 1;
+
+       qcom_smp2p_kick(smp2p);
+
+       smp2p->out = out;
+
+       return 0;
+}
+
+static int smp2p_parse_ipc(struct qcom_smp2p *smp2p)
+{
+       struct device_node *syscon;
+       struct device *dev = smp2p->dev;
+       const char *key;
+       int ret;
+
+       syscon = of_parse_phandle(dev->of_node, "qcom,ipc", 0);
+       if (!syscon) {
+               dev_err(dev, "no qcom,ipc node\n");
+               return -ENODEV;
+       }
+
+       smp2p->ipc_regmap = syscon_node_to_regmap(syscon);
+       if (IS_ERR(smp2p->ipc_regmap))
+               return PTR_ERR(smp2p->ipc_regmap);
+
+       key = "qcom,ipc";
+       ret = of_property_read_u32_index(dev->of_node, key, 1, &smp2p->ipc_offset);
+       if (ret < 0) {
+               dev_err(dev, "no offset in %s\n", key);
+               return -EINVAL;
+       }
+
+       ret = of_property_read_u32_index(dev->of_node, key, 2, &smp2p->ipc_bit);
+       if (ret < 0) {
+               dev_err(dev, "no bit in %s\n", key);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int qcom_smp2p_probe(struct platform_device *pdev)
+{
+       struct smp2p_entry *entry;
+       struct device_node *node;
+       struct qcom_smp2p *smp2p;
+       const char *key;
+       int irq;
+       int ret;
+
+       smp2p = devm_kzalloc(&pdev->dev, sizeof(*smp2p), GFP_KERNEL);
+       if (!smp2p)
+               return -ENOMEM;
+
+       smp2p->dev = &pdev->dev;
+       INIT_LIST_HEAD(&smp2p->inbound);
+       INIT_LIST_HEAD(&smp2p->outbound);
+
+       platform_set_drvdata(pdev, smp2p);
+
+       ret = smp2p_parse_ipc(smp2p);
+       if (ret)
+               return ret;
+
+       key = "qcom,smem";
+       ret = of_property_read_u32_array(pdev->dev.of_node, key,
+                                        smp2p->smem_items, 2);
+       if (ret)
+               return ret;
+
+       key = "qcom,local-pid";
+       ret = of_property_read_u32(pdev->dev.of_node, key, &smp2p->local_pid);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to read %s\n", key);
+               return -EINVAL;
+       }
+
+       key = "qcom,remote-pid";
+       ret = of_property_read_u32(pdev->dev.of_node, key, &smp2p->remote_pid);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to read %s\n", key);
+               return -EINVAL;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "unable to acquire smp2p interrupt\n");
+               return irq;
+       }
+
+       ret = qcom_smp2p_alloc_outbound_item(smp2p);
+       if (ret < 0)
+               return ret;
+
+       for_each_available_child_of_node(pdev->dev.of_node, node) {
+               entry = devm_kzalloc(&pdev->dev, sizeof(*entry), GFP_KERNEL);
+               if (!entry) {
+                       ret = -ENOMEM;
+                       goto unwind_interfaces;
+               }
+
+               entry->smp2p = smp2p;
+               spin_lock_init(&entry->lock);
+
+               ret = of_property_read_string(node, "qcom,entry-name", &entry->name);
+               if (ret < 0)
+                       goto unwind_interfaces;
+
+               if (of_property_read_bool(node, "interrupt-controller")) {
+                       ret = qcom_smp2p_inbound_entry(smp2p, entry, node);
+                       if (ret < 0)
+                               goto unwind_interfaces;
+
+                       list_add(&entry->node, &smp2p->inbound);
+               } else  {
+                       ret = qcom_smp2p_outbound_entry(smp2p, entry, node);
+                       if (ret < 0)
+                               goto unwind_interfaces;
+
+                       list_add(&entry->node, &smp2p->outbound);
+               }
+       }
+
+       /* Kick the outgoing edge after allocating entries */
+       qcom_smp2p_kick(smp2p);
+
+       ret = devm_request_threaded_irq(&pdev->dev, irq,
+                                       NULL, qcom_smp2p_intr,
+                                       IRQF_ONESHOT,
+                                       "smp2p", (void *)smp2p);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request interrupt\n");
+               goto unwind_interfaces;
+       }
+
+
+       return 0;
+
+unwind_interfaces:
+       list_for_each_entry(entry, &smp2p->inbound, node)
+               irq_domain_remove(entry->domain);
+
+       list_for_each_entry(entry, &smp2p->outbound, node)
+               qcom_smem_state_unregister(entry->state);
+
+       smp2p->out->valid_entries = 0;
+
+       return ret;
+}
+
+static int qcom_smp2p_remove(struct platform_device *pdev)
+{
+       struct qcom_smp2p *smp2p = platform_get_drvdata(pdev);
+       struct smp2p_entry *entry;
+
+       list_for_each_entry(entry, &smp2p->inbound, node)
+               irq_domain_remove(entry->domain);
+
+       list_for_each_entry(entry, &smp2p->outbound, node)
+               qcom_smem_state_unregister(entry->state);
+
+       smp2p->out->valid_entries = 0;
+
+       return 0;
+}
+
+static const struct of_device_id qcom_smp2p_of_match[] = {
+       { .compatible = "qcom,smp2p" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, qcom_smp2p_of_match);
+
+static struct platform_driver qcom_smp2p_driver = {
+       .probe = qcom_smp2p_probe,
+       .remove = qcom_smp2p_remove,
+       .driver  = {
+               .name  = "qcom_smp2p",
+               .of_match_table = qcom_smp2p_of_match,
+       },
+};
+module_platform_driver(qcom_smp2p_driver);
+
+MODULE_DESCRIPTION("Qualcomm Shared Memory Point to Point driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
new file mode 100644 (file)
index 0000000..6b777af
--- /dev/null
@@ -0,0 +1,625 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/soc/qcom/smem_state.h>
+
+/*
+ * This driver implements the Qualcomm Shared Memory State Machine, a mechanism
+ * for communicating single bit state information to remote processors.
+ *
+ * The implementation is based on two sections of shared memory; the first
+ * holding the state bits and the second holding a matrix of subscription bits.
+ *
+ * The state bits are structured in entries of 32 bits, each belonging to one
+ * system in the SoC. The entry belonging to the local system is considered
+ * read-write, while the rest should be considered read-only.
+ *
+ * The subscription matrix consists of N bitmaps per entry, denoting interest
+ * in updates of the entry for each of the N hosts. Upon updating a state bit
+ * each host's subscription bitmap should be queried and the remote system
+ * should be interrupted if they request so.
+ *
+ * The subscription matrix is laid out in entry-major order:
+ * entry0: [host0 ... hostN]
+ *     .
+ *     .
+ * entryM: [host0 ... hostN]
+ *
+ * A third, optional, shared memory region might contain information regarding
+ * the number of entries in the state bitmap as well as number of columns in
+ * the subscription matrix.
+ */
+
+/*
+ * Shared memory identifiers, used to acquire handles to respective memory
+ * region.
+ */
+#define SMEM_SMSM_SHARED_STATE         85
+#define SMEM_SMSM_CPU_INTR_MASK                333
+#define SMEM_SMSM_SIZE_INFO            419
+
+/*
+ * Default sizes, in case SMEM_SMSM_SIZE_INFO is not found.
+ */
+#define SMSM_DEFAULT_NUM_ENTRIES       8
+#define SMSM_DEFAULT_NUM_HOSTS         3
+
+struct smsm_entry;
+struct smsm_host;
+
+/**
+ * struct qcom_smsm - smsm driver context
+ * @dev:       smsm device pointer
+ * @local_host:        column in the subscription matrix representing this system
+ * @num_hosts: number of columns in the subscription matrix
+ * @num_entries: number of entries in the state map and rows in the subscription
+ *             matrix
+ * @local_state: pointer to the local processor's state bits
+ * @subscription: pointer to local processor's row in subscription matrix
+ * @state:     smem state handle
+ * @lock:      spinlock for read-modify-write of the outgoing state
+ * @entries:   context for each of the entries
+ * @hosts:     context for each of the hosts
+ */
+struct qcom_smsm {
+       struct device *dev;
+
+       u32 local_host;
+
+       u32 num_hosts;
+       u32 num_entries;
+
+       u32 *local_state;
+       u32 *subscription;
+       struct qcom_smem_state *state;
+
+       spinlock_t lock;
+
+       struct smsm_entry *entries;
+       struct smsm_host *hosts;
+};
+
+/**
+ * struct smsm_entry - per remote processor entry context
+ * @smsm:      back-reference to driver context
+ * @domain:    IRQ domain for this entry, if representing a remote system
+ * @irq_enabled: bitmap of which state bits IRQs are enabled
+ * @irq_rising:        bitmap tracking if rising bits should be propagated
+ * @irq_falling: bitmap tracking if falling bits should be propagated
+ * @last_value:        snapshot of state bits last time the interrupts where propagated
+ * @remote_state: pointer to this entry's state bits
+ * @subscription: pointer to a row in the subscription matrix representing this
+ *             entry
+ */
+struct smsm_entry {
+       struct qcom_smsm *smsm;
+
+       struct irq_domain *domain;
+       DECLARE_BITMAP(irq_enabled, 32);
+       DECLARE_BITMAP(irq_rising, 32);
+       DECLARE_BITMAP(irq_falling, 32);
+       u32 last_value;
+
+       u32 *remote_state;
+       u32 *subscription;
+};
+
+/**
+ * struct smsm_host - representation of a remote host
+ * @ipc_regmap:        regmap for outgoing interrupt
+ * @ipc_offset:        offset in @ipc_regmap for outgoing interrupt
+ * @ipc_bit:   bit in @ipc_regmap + @ipc_offset for outgoing interrupt
+ */
+struct smsm_host {
+       struct regmap *ipc_regmap;
+       int ipc_offset;
+       int ipc_bit;
+};
+
+/**
+ * smsm_update_bits() - change bit in outgoing entry and inform subscribers
+ * @data:      smsm context pointer
+ * @offset:    bit in the entry
+ * @value:     new value
+ *
+ * Used to set and clear the bits in the outgoing/local entry and inform
+ * subscribers about the change.
+ */
+static int smsm_update_bits(void *data, u32 mask, u32 value)
+{
+       struct qcom_smsm *smsm = data;
+       struct smsm_host *hostp;
+       unsigned long flags;
+       u32 changes;
+       u32 host;
+       u32 orig;
+       u32 val;
+
+       spin_lock_irqsave(&smsm->lock, flags);
+
+       /* Update the entry */
+       val = orig = readl(smsm->local_state);
+       val &= ~mask;
+       val |= value;
+
+       /* Don't signal if we didn't change the value */
+       changes = val ^ orig;
+       if (!changes) {
+               spin_unlock_irqrestore(&smsm->lock, flags);
+               goto done;
+       }
+
+       /* Write out the new value */
+       writel(val, smsm->local_state);
+       spin_unlock_irqrestore(&smsm->lock, flags);
+
+       /* Make sure the value update is ordered before any kicks */
+       wmb();
+
+       /* Iterate over all hosts to check whom wants a kick */
+       for (host = 0; host < smsm->num_hosts; host++) {
+               hostp = &smsm->hosts[host];
+
+               val = readl(smsm->subscription + host);
+               if (val & changes && hostp->ipc_regmap) {
+                       regmap_write(hostp->ipc_regmap,
+                                    hostp->ipc_offset,
+                                    BIT(hostp->ipc_bit));
+               }
+       }
+
+done:
+       return 0;
+}
+
+static const struct qcom_smem_state_ops smsm_state_ops = {
+       .update_bits = smsm_update_bits,
+};
+
+/**
+ * smsm_intr() - cascading IRQ handler for SMSM
+ * @irq:       unused
+ * @data:      entry related to this IRQ
+ *
+ * This function cascades an incoming interrupt from a remote system, based on
+ * the state bits and configuration.
+ */
+static irqreturn_t smsm_intr(int irq, void *data)
+{
+       struct smsm_entry *entry = data;
+       unsigned i;
+       int irq_pin;
+       u32 changed;
+       u32 val;
+
+       val = readl(entry->remote_state);
+       changed = val ^ entry->last_value;
+       entry->last_value = val;
+
+       for_each_set_bit(i, entry->irq_enabled, 32) {
+               if (!(changed & BIT(i)))
+                       continue;
+
+               if (val & BIT(i)) {
+                       if (test_bit(i, entry->irq_rising)) {
+                               irq_pin = irq_find_mapping(entry->domain, i);
+                               handle_nested_irq(irq_pin);
+                       }
+               } else {
+                       if (test_bit(i, entry->irq_falling)) {
+                               irq_pin = irq_find_mapping(entry->domain, i);
+                               handle_nested_irq(irq_pin);
+                       }
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * smsm_mask_irq() - un-subscribe from cascades of IRQs of a certain staus bit
+ * @irqd:      IRQ handle to be masked
+ *
+ * This un-subscribes the local CPU from interrupts upon changes to the defines
+ * status bit. The bit is also cleared from cascading.
+ */
+static void smsm_mask_irq(struct irq_data *irqd)
+{
+       struct smsm_entry *entry = irq_data_get_irq_chip_data(irqd);
+       irq_hw_number_t irq = irqd_to_hwirq(irqd);
+       struct qcom_smsm *smsm = entry->smsm;
+       u32 val;
+
+       if (entry->subscription) {
+               val = readl(entry->subscription + smsm->local_host);
+               val &= ~BIT(irq);
+               writel(val, entry->subscription + smsm->local_host);
+       }
+
+       clear_bit(irq, entry->irq_enabled);
+}
+
+/**
+ * smsm_unmask_irq() - subscribe to cascades of IRQs of a certain status bit
+ * @irqd:      IRQ handle to be unmasked
+ *
+
+ * This subscribes the local CPU to interrupts upon changes to the defined
+ * status bit. The bit is also marked for cascading.
+
+ */
+static void smsm_unmask_irq(struct irq_data *irqd)
+{
+       struct smsm_entry *entry = irq_data_get_irq_chip_data(irqd);
+       irq_hw_number_t irq = irqd_to_hwirq(irqd);
+       struct qcom_smsm *smsm = entry->smsm;
+       u32 val;
+
+       set_bit(irq, entry->irq_enabled);
+
+       if (entry->subscription) {
+               val = readl(entry->subscription + smsm->local_host);
+               val |= BIT(irq);
+               writel(val, entry->subscription + smsm->local_host);
+       }
+}
+
+/**
+ * smsm_set_irq_type() - updates the requested IRQ type for the cascading
+ * @irqd:      consumer interrupt handle
+ * @type:      requested flags
+ */
+static int smsm_set_irq_type(struct irq_data *irqd, unsigned int type)
+{
+       struct smsm_entry *entry = irq_data_get_irq_chip_data(irqd);
+       irq_hw_number_t irq = irqd_to_hwirq(irqd);
+
+       if (!(type & IRQ_TYPE_EDGE_BOTH))
+               return -EINVAL;
+
+       if (type & IRQ_TYPE_EDGE_RISING)
+               set_bit(irq, entry->irq_rising);
+       else
+               clear_bit(irq, entry->irq_rising);
+
+       if (type & IRQ_TYPE_EDGE_FALLING)
+               set_bit(irq, entry->irq_falling);
+       else
+               clear_bit(irq, entry->irq_falling);
+
+       return 0;
+}
+
+static struct irq_chip smsm_irq_chip = {
+       .name           = "smsm",
+       .irq_mask       = smsm_mask_irq,
+       .irq_unmask     = smsm_unmask_irq,
+       .irq_set_type   = smsm_set_irq_type,
+};
+
+/**
+ * smsm_irq_map() - sets up a mapping for a cascaded IRQ
+ * @d:         IRQ domain representing an entry
+ * @irq:       IRQ to set up
+ * @hw:                unused
+ */
+static int smsm_irq_map(struct irq_domain *d,
+                       unsigned int irq,
+                       irq_hw_number_t hw)
+{
+       struct smsm_entry *entry = d->host_data;
+
+       irq_set_chip_and_handler(irq, &smsm_irq_chip, handle_level_irq);
+       irq_set_chip_data(irq, entry);
+       irq_set_nested_thread(irq, 1);
+
+       return 0;
+}
+
+static const struct irq_domain_ops smsm_irq_ops = {
+       .map = smsm_irq_map,
+       .xlate = irq_domain_xlate_twocell,
+};
+
+/**
+ * smsm_parse_ipc() - parses a qcom,ipc-%d device tree property
+ * @smsm:      smsm driver context
+ * @host_id:   index of the remote host to be resolved
+ *
+ * Parses device tree to acquire the information needed for sending the
+ * outgoing interrupts to a remote host - identified by @host_id.
+ */
+static int smsm_parse_ipc(struct qcom_smsm *smsm, unsigned host_id)
+{
+       struct device_node *syscon;
+       struct device_node *node = smsm->dev->of_node;
+       struct smsm_host *host = &smsm->hosts[host_id];
+       char key[16];
+       int ret;
+
+       snprintf(key, sizeof(key), "qcom,ipc-%d", host_id);
+       syscon = of_parse_phandle(node, key, 0);
+       if (!syscon)
+               return 0;
+
+       host->ipc_regmap = syscon_node_to_regmap(syscon);
+       if (IS_ERR(host->ipc_regmap))
+               return PTR_ERR(host->ipc_regmap);
+
+       ret = of_property_read_u32_index(node, key, 1, &host->ipc_offset);
+       if (ret < 0) {
+               dev_err(smsm->dev, "no offset in %s\n", key);
+               return -EINVAL;
+       }
+
+       ret = of_property_read_u32_index(node, key, 2, &host->ipc_bit);
+       if (ret < 0) {
+               dev_err(smsm->dev, "no bit in %s\n", key);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * smsm_inbound_entry() - parse DT and set up an entry representing a remote system
+ * @smsm:      smsm driver context
+ * @entry:     entry context to be set up
+ * @node:      dt node containing the entry's properties
+ */
+static int smsm_inbound_entry(struct qcom_smsm *smsm,
+                             struct smsm_entry *entry,
+                             struct device_node *node)
+{
+       int ret;
+       int irq;
+
+       irq = irq_of_parse_and_map(node, 0);
+       if (!irq) {
+               dev_err(smsm->dev, "failed to parse smsm interrupt\n");
+               return -EINVAL;
+       }
+
+       ret = devm_request_threaded_irq(smsm->dev, irq,
+                                       NULL, smsm_intr,
+                                       IRQF_ONESHOT,
+                                       "smsm", (void *)entry);
+       if (ret) {
+               dev_err(smsm->dev, "failed to request interrupt\n");
+               return ret;
+       }
+
+       entry->domain = irq_domain_add_linear(node, 32, &smsm_irq_ops, entry);
+       if (!entry->domain) {
+               dev_err(smsm->dev, "failed to add irq_domain\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/**
+ * smsm_get_size_info() - parse the optional memory segment for sizes
+ * @smsm:      smsm driver context
+ *
+ * Attempt to acquire the number of hosts and entries from the optional shared
+ * memory location. Not being able to find this segment should indicate that
+ * we're on a older system where these values was hard coded to
+ * SMSM_DEFAULT_NUM_ENTRIES and SMSM_DEFAULT_NUM_HOSTS.
+ *
+ * Returns 0 on success, negative errno on failure.
+ */
+static int smsm_get_size_info(struct qcom_smsm *smsm)
+{
+       size_t size;
+       struct {
+               u32 num_hosts;
+               u32 num_entries;
+               u32 reserved0;
+               u32 reserved1;
+       } *info;
+
+       info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SIZE_INFO, &size);
+       if (PTR_ERR(info) == -ENOENT || size != sizeof(*info)) {
+               dev_warn(smsm->dev, "no smsm size info, using defaults\n");
+               smsm->num_entries = SMSM_DEFAULT_NUM_ENTRIES;
+               smsm->num_hosts = SMSM_DEFAULT_NUM_HOSTS;
+               return 0;
+       } else if (IS_ERR(info)) {
+               dev_err(smsm->dev, "unable to retrieve smsm size info\n");
+               return PTR_ERR(info);
+       }
+
+       smsm->num_entries = info->num_entries;
+       smsm->num_hosts = info->num_hosts;
+
+       dev_dbg(smsm->dev,
+               "found custom size of smsm: %d entries %d hosts\n",
+               smsm->num_entries, smsm->num_hosts);
+
+       return 0;
+}
+
+static int qcom_smsm_probe(struct platform_device *pdev)
+{
+       struct device_node *local_node;
+       struct device_node *node;
+       struct smsm_entry *entry;
+       struct qcom_smsm *smsm;
+       u32 *intr_mask;
+       size_t size;
+       u32 *states;
+       u32 id;
+       int ret;
+
+       smsm = devm_kzalloc(&pdev->dev, sizeof(*smsm), GFP_KERNEL);
+       if (!smsm)
+               return -ENOMEM;
+       smsm->dev = &pdev->dev;
+       spin_lock_init(&smsm->lock);
+
+       ret = smsm_get_size_info(smsm);
+       if (ret)
+               return ret;
+
+       smsm->entries = devm_kcalloc(&pdev->dev,
+                                    smsm->num_entries,
+                                    sizeof(struct smsm_entry),
+                                    GFP_KERNEL);
+       if (!smsm->entries)
+               return -ENOMEM;
+
+       smsm->hosts = devm_kcalloc(&pdev->dev,
+                                  smsm->num_hosts,
+                                  sizeof(struct smsm_host),
+                                  GFP_KERNEL);
+       if (!smsm->hosts)
+               return -ENOMEM;
+
+       local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,state-cells");
+       if (!local_node) {
+               dev_err(&pdev->dev, "no state entry\n");
+               return -EINVAL;
+       }
+
+       of_property_read_u32(pdev->dev.of_node,
+                            "qcom,local-host",
+                            &smsm->local_host);
+
+       /* Parse the host properties */
+       for (id = 0; id < smsm->num_hosts; id++) {
+               ret = smsm_parse_ipc(smsm, id);
+               if (ret < 0)
+                       return ret;
+       }
+
+       /* Acquire the main SMSM state vector */
+       ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE,
+                             smsm->num_entries * sizeof(u32));
+       if (ret < 0 && ret != -EEXIST) {
+               dev_err(&pdev->dev, "unable to allocate shared state entry\n");
+               return ret;
+       }
+
+       states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL);
+       if (IS_ERR(states)) {
+               dev_err(&pdev->dev, "Unable to acquire shared state entry\n");
+               return PTR_ERR(states);
+       }
+
+       /* Acquire the list of interrupt mask vectors */
+       size = smsm->num_entries * smsm->num_hosts * sizeof(u32);
+       ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size);
+       if (ret < 0 && ret != -EEXIST) {
+               dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n");
+               return ret;
+       }
+
+       intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL);
+       if (IS_ERR(intr_mask)) {
+               dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n");
+               return PTR_ERR(intr_mask);
+       }
+
+       /* Setup the reference to the local state bits */
+       smsm->local_state = states + smsm->local_host;
+       smsm->subscription = intr_mask + smsm->local_host * smsm->num_hosts;
+
+       /* Register the outgoing state */
+       smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm);
+       if (IS_ERR(smsm->state)) {
+               dev_err(smsm->dev, "failed to register qcom_smem_state\n");
+               return PTR_ERR(smsm->state);
+       }
+
+       /* Register handlers for remote processor entries of interest. */
+       for_each_available_child_of_node(pdev->dev.of_node, node) {
+               if (!of_property_read_bool(node, "interrupt-controller"))
+                       continue;
+
+               ret = of_property_read_u32(node, "reg", &id);
+               if (ret || id >= smsm->num_entries) {
+                       dev_err(&pdev->dev, "invalid reg of entry\n");
+                       if (!ret)
+                               ret = -EINVAL;
+                       goto unwind_interfaces;
+               }
+               entry = &smsm->entries[id];
+
+               entry->smsm = smsm;
+               entry->remote_state = states + id;
+
+               /* Setup subscription pointers and unsubscribe to any kicks */
+               entry->subscription = intr_mask + id * smsm->num_hosts;
+               writel(0, entry->subscription + smsm->local_host);
+
+               ret = smsm_inbound_entry(smsm, entry, node);
+               if (ret < 0)
+                       goto unwind_interfaces;
+       }
+
+       platform_set_drvdata(pdev, smsm);
+
+       return 0;
+
+unwind_interfaces:
+       for (id = 0; id < smsm->num_entries; id++)
+               if (smsm->entries[id].domain)
+                       irq_domain_remove(smsm->entries[id].domain);
+
+       qcom_smem_state_unregister(smsm->state);
+
+       return ret;
+}
+
+static int qcom_smsm_remove(struct platform_device *pdev)
+{
+       struct qcom_smsm *smsm = platform_get_drvdata(pdev);
+       unsigned id;
+
+       for (id = 0; id < smsm->num_entries; id++)
+               if (smsm->entries[id].domain)
+                       irq_domain_remove(smsm->entries[id].domain);
+
+       qcom_smem_state_unregister(smsm->state);
+
+       return 0;
+}
+
+static const struct of_device_id qcom_smsm_of_match[] = {
+       { .compatible = "qcom,smsm" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, qcom_smsm_of_match);
+
+static struct platform_driver qcom_smsm_driver = {
+       .probe = qcom_smsm_probe,
+       .remove = qcom_smsm_remove,
+       .driver  = {
+               .name  = "qcom-smsm",
+               .of_match_table = qcom_smsm_of_match,
+       },
+};
+module_platform_driver(qcom_smsm_driver);
+
+MODULE_DESCRIPTION("Qualcomm Shared Memory State Machine driver");
+MODULE_LICENSE("GPL v2");
index 0ad66fa..5548a31 100644 (file)
@@ -288,7 +288,7 @@ static struct spm_driver_data *spm_get_drv(struct platform_device *pdev,
        struct spm_driver_data *drv = NULL;
        struct device_node *cpu_node, *saw_node;
        int cpu;
-       bool found;
+       bool found = 0;
 
        for_each_possible_cpu(cpu) {
                cpu_node = of_cpu_device_node_get(cpu);
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
new file mode 100644 (file)
index 0000000..7a986f8
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications 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 and
+ * only 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/firmware.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smd.h>
+
+#define WCNSS_REQUEST_TIMEOUT  (5 * HZ)
+
+#define NV_FRAGMENT_SIZE       3072
+#define NVBIN_FILE             "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/**
+ * struct wcnss_ctrl - driver context
+ * @dev:       device handle
+ * @channel:   SMD channel handle
+ * @ack:       completion for outstanding requests
+ * @ack_status:        status of the outstanding request
+ * @download_nv_work: worker for uploading nv binary
+ */
+struct wcnss_ctrl {
+       struct device *dev;
+       struct qcom_smd_channel *channel;
+
+       struct completion ack;
+       int ack_status;
+
+       struct work_struct download_nv_work;
+};
+
+/* message types */
+enum {
+       WCNSS_VERSION_REQ = 0x01000000,
+       WCNSS_VERSION_RESP,
+       WCNSS_DOWNLOAD_NV_REQ,
+       WCNSS_DOWNLOAD_NV_RESP,
+       WCNSS_UPLOAD_CAL_REQ,
+       WCNSS_UPLOAD_CAL_RESP,
+       WCNSS_DOWNLOAD_CAL_REQ,
+       WCNSS_DOWNLOAD_CAL_RESP,
+};
+
+/**
+ * struct wcnss_msg_hdr - common packet header for requests and responses
+ * @type:      packet message type
+ * @len:       total length of the packet, including this header
+ */
+struct wcnss_msg_hdr {
+       u32 type;
+       u32 len;
+} __packed;
+
+/**
+ * struct wcnss_version_resp - version request response
+ * @hdr:       common packet wcnss_msg_hdr header
+ */
+struct wcnss_version_resp {
+       struct wcnss_msg_hdr hdr;
+       u8 major;
+       u8 minor;
+       u8 version;
+       u8 revision;
+} __packed;
+
+/**
+ * struct wcnss_download_nv_req - firmware fragment request
+ * @hdr:       common packet wcnss_msg_hdr header
+ * @seq:       sequence number of this fragment
+ * @last:      boolean indicator of this being the last fragment of the binary
+ * @frag_size: length of this fragment
+ * @fragment:  fragment data
+ */
+struct wcnss_download_nv_req {
+       struct wcnss_msg_hdr hdr;
+       u16 seq;
+       u16 last;
+       u32 frag_size;
+       u8 fragment[];
+} __packed;
+
+/**
+ * struct wcnss_download_nv_resp - firmware download response
+ * @hdr:       common packet wcnss_msg_hdr header
+ * @status:    boolean to indicate success of the download
+ */
+struct wcnss_download_nv_resp {
+       struct wcnss_msg_hdr hdr;
+       u8 status;
+} __packed;
+
+/**
+ * wcnss_ctrl_smd_callback() - handler from SMD responses
+ * @qsdev:     smd device handle
+ * @data:      pointer to the incoming data packet
+ * @count:     size of the incoming data packet
+ *
+ * Handles any incoming packets from the remote WCNSS_CTRL service.
+ */
+static int wcnss_ctrl_smd_callback(struct qcom_smd_device *qsdev,
+                                  const void *data,
+                                  size_t count)
+{
+       struct wcnss_ctrl *wcnss = dev_get_drvdata(&qsdev->dev);
+       const struct wcnss_download_nv_resp *nvresp;
+       const struct wcnss_version_resp *version;
+       const struct wcnss_msg_hdr *hdr = data;
+
+       switch (hdr->type) {
+       case WCNSS_VERSION_RESP:
+               if (count != sizeof(*version)) {
+                       dev_err(wcnss->dev,
+                               "invalid size of version response\n");
+                       break;
+               }
+
+               version = data;
+               dev_info(wcnss->dev, "WCNSS Version %d.%d %d.%d\n",
+                        version->major, version->minor,
+                        version->version, version->revision);
+
+               schedule_work(&wcnss->download_nv_work);
+               break;
+       case WCNSS_DOWNLOAD_NV_RESP:
+               if (count != sizeof(*nvresp)) {
+                       dev_err(wcnss->dev,
+                               "invalid size of download response\n");
+                       break;
+               }
+
+               nvresp = data;
+               wcnss->ack_status = nvresp->status;
+               complete(&wcnss->ack);
+               break;
+       default:
+               dev_info(wcnss->dev, "unknown message type %d\n", hdr->type);
+               break;
+       }
+
+       return 0;
+}
+
+/**
+ * wcnss_request_version() - send a version request to WCNSS
+ * @wcnss:     wcnss ctrl driver context
+ */
+static int wcnss_request_version(struct wcnss_ctrl *wcnss)
+{
+       struct wcnss_msg_hdr msg;
+
+       msg.type = WCNSS_VERSION_REQ;
+       msg.len = sizeof(msg);
+
+       return qcom_smd_send(wcnss->channel, &msg, sizeof(msg));
+}
+
+/**
+ * wcnss_download_nv() - send nv binary to WCNSS
+ * @work:      work struct to acquire wcnss context
+ */
+static void wcnss_download_nv(struct work_struct *work)
+{
+       struct wcnss_ctrl *wcnss = container_of(work, struct wcnss_ctrl, download_nv_work);
+       struct wcnss_download_nv_req *req;
+       const struct firmware *fw;
+       const void *data;
+       ssize_t left;
+       int ret;
+
+       req = kzalloc(sizeof(*req) + NV_FRAGMENT_SIZE, GFP_KERNEL);
+       if (!req)
+               return;
+
+       ret = request_firmware(&fw, NVBIN_FILE, wcnss->dev);
+       if (ret) {
+               dev_err(wcnss->dev, "Failed to load nv file %s: %d\n",
+                       NVBIN_FILE, ret);
+               goto free_req;
+       }
+
+       data = fw->data;
+       left = fw->size;
+
+       req->hdr.type = WCNSS_DOWNLOAD_NV_REQ;
+       req->hdr.len = sizeof(*req) + NV_FRAGMENT_SIZE;
+
+       req->last = 0;
+       req->frag_size = NV_FRAGMENT_SIZE;
+
+       req->seq = 0;
+       do {
+               if (left <= NV_FRAGMENT_SIZE) {
+                       req->last = 1;
+                       req->frag_size = left;
+                       req->hdr.len = sizeof(*req) + left;
+               }
+
+               memcpy(req->fragment, data, req->frag_size);
+
+               ret = qcom_smd_send(wcnss->channel, req, req->hdr.len);
+               if (ret) {
+                       dev_err(wcnss->dev, "failed to send smd packet\n");
+                       goto release_fw;
+               }
+
+               /* Increment for next fragment */
+               req->seq++;
+
+               data += req->hdr.len;
+               left -= NV_FRAGMENT_SIZE;
+       } while (left > 0);
+
+       ret = wait_for_completion_timeout(&wcnss->ack, WCNSS_REQUEST_TIMEOUT);
+       if (!ret)
+               dev_err(wcnss->dev, "timeout waiting for nv upload ack\n");
+       else if (wcnss->ack_status != 1)
+               dev_err(wcnss->dev, "nv upload response failed err: %d\n",
+                       wcnss->ack_status);
+
+release_fw:
+       release_firmware(fw);
+free_req:
+       kfree(req);
+}
+
+static int wcnss_ctrl_probe(struct qcom_smd_device *sdev)
+{
+       struct wcnss_ctrl *wcnss;
+
+       wcnss = devm_kzalloc(&sdev->dev, sizeof(*wcnss), GFP_KERNEL);
+       if (!wcnss)
+               return -ENOMEM;
+
+       wcnss->dev = &sdev->dev;
+       wcnss->channel = sdev->channel;
+
+       init_completion(&wcnss->ack);
+       INIT_WORK(&wcnss->download_nv_work, wcnss_download_nv);
+
+       dev_set_drvdata(&sdev->dev, wcnss);
+
+       return wcnss_request_version(wcnss);
+}
+
+static const struct qcom_smd_id wcnss_ctrl_smd_match[] = {
+       { .name = "WCNSS_CTRL" },
+       {}
+};
+
+static struct qcom_smd_driver wcnss_ctrl_driver = {
+       .probe = wcnss_ctrl_probe,
+       .callback = wcnss_ctrl_smd_callback,
+       .smd_match_table = wcnss_ctrl_smd_match,
+       .driver  = {
+               .name  = "qcom_wcnss_ctrl",
+               .owner = THIS_MODULE,
+       },
+};
+
+module_qcom_smd_driver(wcnss_ctrl_driver);
+
+MODULE_DESCRIPTION("Qualcomm WCNSS control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
new file mode 100644 (file)
index 0000000..d0c3c3e
--- /dev/null
@@ -0,0 +1,83 @@
+if ARCH_TEGRA
+
+# 32-bit ARM SoCs
+if ARM
+
+config ARCH_TEGRA_2x_SOC
+       bool "Enable support for Tegra20 family"
+       select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+       select ARM_ERRATA_720789
+       select ARM_ERRATA_754327 if SMP
+       select ARM_ERRATA_764369 if SMP
+       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
+
+config ARCH_TEGRA_3x_SOC
+       bool "Enable support for Tegra30 family"
+       select ARM_ERRATA_754322
+       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
+
+config ARCH_TEGRA_114_SOC
+       bool "Enable support for Tegra114 family"
+       select ARM_ERRATA_798181 if SMP
+       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
+
+config ARCH_TEGRA_124_SOC
+       bool "Enable support for Tegra124 family"
+       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
+
+endif
+
+# 64-bit ARM SoCs
+if ARM64
+
+config ARCH_TEGRA_132_SOC
+       bool "NVIDIA Tegra132 SoC"
+       select PINCTRL_TEGRA124
+       help
+         Enable support for NVIDIA Tegra132 SoC, based on the Denver
+         ARMv8 CPU.  The Tegra132 SoC is similar to the Tegra124 SoC,
+         but contains an NVIDIA Denver CPU complex in place of
+         Tegra124's "4+1" Cortex-A15 CPU complex.
+
+config ARCH_TEGRA_210_SOC
+       bool "NVIDIA Tegra210 SoC"
+       select PINCTRL_TEGRA210
+       help
+         Enable support for the NVIDIA Tegra210 SoC. Also known as Tegra X1,
+         the Tegra210 has four Cortex-A57 cores paired with four Cortex-A53
+         cores in a switched configuration. It features a GPU of the Maxwell
+         architecture with support for DX11, SM4, OpenGL 4.5, OpenGL ES 3.1
+         and providing 256 CUDA cores. It supports hardware-accelerated en-
+         and decoding of various video standards including H.265, H.264 and
+         VP8 at 4K resolution and up to 60 fps.
+
+         Besides the multimedia features it also comes with a variety of I/O
+         controllers, such as GPIO, I2C, SPI, SDHCI, PCIe, SATA and XHCI, to
+         name only a few.
+
+endif
+endif
index 7266b21..3557c5e 100644 (file)
@@ -28,4 +28,14 @@ config KEYSTONE_NAVIGATOR_DMA
 
          If unsure, say N.
 
+config WKUP_M3_IPC
+       tristate "TI AMx3 Wkup-M3 IPC Driver"
+       depends on WKUP_M3_RPROC
+       depends on OMAP2PLUS_MBOX
+       help
+         TI AM33XX and AM43XX have a Cortex M3, the Wakeup M3, to handle
+         low power transitions. This IPC driver provides the necessary API
+         to communicate and use the Wakeup M3 for PM features like suspend
+         resume and boots it using wkup_m3_rproc driver.
+
 endif # SOC_TI
index 135bdad..48ff3a7 100644 (file)
@@ -4,3 +4,4 @@
 obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS)  += knav_qmss.o
 knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o
 obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA)   += knav_dma.o
+obj-$(CONFIG_WKUP_M3_IPC)              += wkup_m3_ipc.o
diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c
new file mode 100644 (file)
index 0000000..8823cc8
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * AMx3 Wkup M3 IPC driver
+ *
+ * Copyright (C) 2015 Texas Instruments, Inc.
+ *
+ * Dave Gerlach <d-gerlach@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.
+ *
+ * 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/err.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/omap-mailbox.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/suspend.h>
+#include <linux/wkup_m3_ipc.h>
+
+#define AM33XX_CTRL_IPC_REG_COUNT      0x8
+#define AM33XX_CTRL_IPC_REG_OFFSET(m)  (0x4 + 4 * (m))
+
+/* AM33XX M3_TXEV_EOI register */
+#define AM33XX_CONTROL_M3_TXEV_EOI     0x00
+
+#define AM33XX_M3_TXEV_ACK             (0x1 << 0)
+#define AM33XX_M3_TXEV_ENABLE          (0x0 << 0)
+
+#define IPC_CMD_DS0                    0x4
+#define IPC_CMD_STANDBY                        0xc
+#define IPC_CMD_IDLE                   0x10
+#define IPC_CMD_RESET                  0xe
+#define DS_IPC_DEFAULT                 0xffffffff
+#define M3_VERSION_UNKNOWN             0x0000ffff
+#define M3_BASELINE_VERSION            0x191
+#define M3_STATUS_RESP_MASK            (0xffff << 16)
+#define M3_FW_VERSION_MASK             0xffff
+
+#define M3_STATE_UNKNOWN               0
+#define M3_STATE_RESET                 1
+#define M3_STATE_INITED                        2
+#define M3_STATE_MSG_FOR_LP            3
+#define M3_STATE_MSG_FOR_RESET         4
+
+static struct wkup_m3_ipc *m3_ipc_state;
+
+static void am33xx_txev_eoi(struct wkup_m3_ipc *m3_ipc)
+{
+       writel(AM33XX_M3_TXEV_ACK,
+              m3_ipc->ipc_mem_base + AM33XX_CONTROL_M3_TXEV_EOI);
+}
+
+static void am33xx_txev_enable(struct wkup_m3_ipc *m3_ipc)
+{
+       writel(AM33XX_M3_TXEV_ENABLE,
+              m3_ipc->ipc_mem_base + AM33XX_CONTROL_M3_TXEV_EOI);
+}
+
+static void wkup_m3_ctrl_ipc_write(struct wkup_m3_ipc *m3_ipc,
+                                  u32 val, int ipc_reg_num)
+{
+       if (WARN(ipc_reg_num < 0 || ipc_reg_num > AM33XX_CTRL_IPC_REG_COUNT,
+                "ipc register operation out of range"))
+               return;
+
+       writel(val, m3_ipc->ipc_mem_base +
+              AM33XX_CTRL_IPC_REG_OFFSET(ipc_reg_num));
+}
+
+static unsigned int wkup_m3_ctrl_ipc_read(struct wkup_m3_ipc *m3_ipc,
+                                         int ipc_reg_num)
+{
+       if (WARN(ipc_reg_num < 0 || ipc_reg_num > AM33XX_CTRL_IPC_REG_COUNT,
+                "ipc register operation out of range"))
+               return 0;
+
+       return readl(m3_ipc->ipc_mem_base +
+                    AM33XX_CTRL_IPC_REG_OFFSET(ipc_reg_num));
+}
+
+static int wkup_m3_fw_version_read(struct wkup_m3_ipc *m3_ipc)
+{
+       int val;
+
+       val = wkup_m3_ctrl_ipc_read(m3_ipc, 2);
+
+       return val & M3_FW_VERSION_MASK;
+}
+
+static irqreturn_t wkup_m3_txev_handler(int irq, void *ipc_data)
+{
+       struct wkup_m3_ipc *m3_ipc = ipc_data;
+       struct device *dev = m3_ipc->dev;
+       int ver = 0;
+
+       am33xx_txev_eoi(m3_ipc);
+
+       switch (m3_ipc->state) {
+       case M3_STATE_RESET:
+               ver = wkup_m3_fw_version_read(m3_ipc);
+
+               if (ver == M3_VERSION_UNKNOWN ||
+                   ver < M3_BASELINE_VERSION) {
+                       dev_warn(dev, "CM3 Firmware Version %x not supported\n",
+                                ver);
+               } else {
+                       dev_info(dev, "CM3 Firmware Version = 0x%x\n", ver);
+               }
+
+               m3_ipc->state = M3_STATE_INITED;
+               complete(&m3_ipc->sync_complete);
+               break;
+       case M3_STATE_MSG_FOR_RESET:
+               m3_ipc->state = M3_STATE_INITED;
+               complete(&m3_ipc->sync_complete);
+               break;
+       case M3_STATE_MSG_FOR_LP:
+               complete(&m3_ipc->sync_complete);
+               break;
+       case M3_STATE_UNKNOWN:
+               dev_warn(dev, "Unknown CM3 State\n");
+       }
+
+       am33xx_txev_enable(m3_ipc);
+
+       return IRQ_HANDLED;
+}
+
+static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc)
+{
+       struct device *dev = m3_ipc->dev;
+       mbox_msg_t dummy_msg = 0;
+       int ret;
+
+       if (!m3_ipc->mbox) {
+               dev_err(dev,
+                       "No IPC channel to communicate with wkup_m3!\n");
+               return -EIO;
+       }
+
+       /*
+        * Write a dummy message to the mailbox in order to trigger the RX
+        * interrupt to alert the M3 that data is available in the IPC
+        * registers. We must enable the IRQ here and disable it after in
+        * the RX callback to avoid multiple interrupts being received
+        * by the CM3.
+        */
+       ret = mbox_send_message(m3_ipc->mbox, &dummy_msg);
+       if (ret < 0) {
+               dev_err(dev, "%s: mbox_send_message() failed: %d\n",
+                       __func__, ret);
+               return ret;
+       }
+
+       ret = wait_for_completion_timeout(&m3_ipc->sync_complete,
+                                         msecs_to_jiffies(500));
+       if (!ret) {
+               dev_err(dev, "MPU<->CM3 sync failure\n");
+               m3_ipc->state = M3_STATE_UNKNOWN;
+               return -EIO;
+       }
+
+       mbox_client_txdone(m3_ipc->mbox, 0);
+       return 0;
+}
+
+static int wkup_m3_ping_noirq(struct wkup_m3_ipc *m3_ipc)
+{
+       struct device *dev = m3_ipc->dev;
+       mbox_msg_t dummy_msg = 0;
+       int ret;
+
+       if (!m3_ipc->mbox) {
+               dev_err(dev,
+                       "No IPC channel to communicate with wkup_m3!\n");
+               return -EIO;
+       }
+
+       ret = mbox_send_message(m3_ipc->mbox, &dummy_msg);
+       if (ret < 0) {
+               dev_err(dev, "%s: mbox_send_message() failed: %d\n",
+                       __func__, ret);
+               return ret;
+       }
+
+       mbox_client_txdone(m3_ipc->mbox, 0);
+       return 0;
+}
+
+static int wkup_m3_is_available(struct wkup_m3_ipc *m3_ipc)
+{
+       return ((m3_ipc->state != M3_STATE_RESET) &&
+               (m3_ipc->state != M3_STATE_UNKNOWN));
+}
+
+/* Public functions */
+/**
+ * wkup_m3_set_mem_type - Pass wkup_m3 which type of memory is in use
+ * @mem_type: memory type value read directly from emif
+ *
+ * wkup_m3 must know what memory type is in use to properly suspend
+ * and resume.
+ */
+static void wkup_m3_set_mem_type(struct wkup_m3_ipc *m3_ipc, int mem_type)
+{
+       m3_ipc->mem_type = mem_type;
+}
+
+/**
+ * wkup_m3_set_resume_address - Pass wkup_m3 resume address
+ * @addr: Physical address from which resume code should execute
+ */
+static void wkup_m3_set_resume_address(struct wkup_m3_ipc *m3_ipc, void *addr)
+{
+       m3_ipc->resume_addr = (unsigned long)addr;
+}
+
+/**
+ * wkup_m3_request_pm_status - Retrieve wkup_m3 status code after suspend
+ *
+ * Returns code representing the status of a low power mode transition.
+ *     0 - Successful transition
+ *     1 - Failure to transition to low power state
+ */
+static int wkup_m3_request_pm_status(struct wkup_m3_ipc *m3_ipc)
+{
+       unsigned int i;
+       int val;
+
+       val = wkup_m3_ctrl_ipc_read(m3_ipc, 1);
+
+       i = M3_STATUS_RESP_MASK & val;
+       i >>= __ffs(M3_STATUS_RESP_MASK);
+
+       return i;
+}
+
+/**
+ * wkup_m3_prepare_low_power - Request preparation for transition to
+ *                            low power state
+ * @state: A kernel suspend state to enter, either MEM or STANDBY
+ *
+ * Returns 0 if preparation was successful, otherwise returns error code
+ */
+static int wkup_m3_prepare_low_power(struct wkup_m3_ipc *m3_ipc, int state)
+{
+       struct device *dev = m3_ipc->dev;
+       int m3_power_state;
+       int ret = 0;
+
+       if (!wkup_m3_is_available(m3_ipc))
+               return -ENODEV;
+
+       switch (state) {
+       case WKUP_M3_DEEPSLEEP:
+               m3_power_state = IPC_CMD_DS0;
+               break;
+       case WKUP_M3_STANDBY:
+               m3_power_state = IPC_CMD_STANDBY;
+               break;
+       case WKUP_M3_IDLE:
+               m3_power_state = IPC_CMD_IDLE;
+               break;
+       default:
+               return 1;
+       }
+
+       /* Program each required IPC register then write defaults to others */
+       wkup_m3_ctrl_ipc_write(m3_ipc, m3_ipc->resume_addr, 0);
+       wkup_m3_ctrl_ipc_write(m3_ipc, m3_power_state, 1);
+       wkup_m3_ctrl_ipc_write(m3_ipc, m3_ipc->mem_type, 4);
+
+       wkup_m3_ctrl_ipc_write(m3_ipc, DS_IPC_DEFAULT, 2);
+       wkup_m3_ctrl_ipc_write(m3_ipc, DS_IPC_DEFAULT, 3);
+       wkup_m3_ctrl_ipc_write(m3_ipc, DS_IPC_DEFAULT, 5);
+       wkup_m3_ctrl_ipc_write(m3_ipc, DS_IPC_DEFAULT, 6);
+       wkup_m3_ctrl_ipc_write(m3_ipc, DS_IPC_DEFAULT, 7);
+
+       m3_ipc->state = M3_STATE_MSG_FOR_LP;
+
+       if (state == WKUP_M3_IDLE)
+               ret = wkup_m3_ping_noirq(m3_ipc);
+       else
+               ret = wkup_m3_ping(m3_ipc);
+
+       if (ret) {
+               dev_err(dev, "Unable to ping CM3\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * wkup_m3_finish_low_power - Return m3 to reset state
+ *
+ * Returns 0 if reset was successful, otherwise returns error code
+ */
+static int wkup_m3_finish_low_power(struct wkup_m3_ipc *m3_ipc)
+{
+       struct device *dev = m3_ipc->dev;
+       int ret = 0;
+
+       if (!wkup_m3_is_available(m3_ipc))
+               return -ENODEV;
+
+       wkup_m3_ctrl_ipc_write(m3_ipc, IPC_CMD_RESET, 1);
+       wkup_m3_ctrl_ipc_write(m3_ipc, DS_IPC_DEFAULT, 2);
+
+       m3_ipc->state = M3_STATE_MSG_FOR_RESET;
+
+       ret = wkup_m3_ping(m3_ipc);
+       if (ret) {
+               dev_err(dev, "Unable to ping CM3\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct wkup_m3_ipc_ops ipc_ops = {
+       .set_mem_type = wkup_m3_set_mem_type,
+       .set_resume_address = wkup_m3_set_resume_address,
+       .prepare_low_power = wkup_m3_prepare_low_power,
+       .finish_low_power = wkup_m3_finish_low_power,
+       .request_pm_status = wkup_m3_request_pm_status,
+};
+
+/**
+ * wkup_m3_ipc_get - Return handle to wkup_m3_ipc
+ *
+ * Returns NULL if the wkup_m3 is not yet available, otherwise returns
+ * pointer to wkup_m3_ipc struct.
+ */
+struct wkup_m3_ipc *wkup_m3_ipc_get(void)
+{
+       if (m3_ipc_state)
+               get_device(m3_ipc_state->dev);
+       else
+               return NULL;
+
+       return m3_ipc_state;
+}
+EXPORT_SYMBOL_GPL(wkup_m3_ipc_get);
+
+/**
+ * wkup_m3_ipc_put - Free handle to wkup_m3_ipc returned from wkup_m3_ipc_get
+ * @m3_ipc: A pointer to wkup_m3_ipc struct returned by wkup_m3_ipc_get
+ */
+void wkup_m3_ipc_put(struct wkup_m3_ipc *m3_ipc)
+{
+       if (m3_ipc_state)
+               put_device(m3_ipc_state->dev);
+}
+EXPORT_SYMBOL_GPL(wkup_m3_ipc_put);
+
+static void wkup_m3_rproc_boot_thread(struct wkup_m3_ipc *m3_ipc)
+{
+       struct device *dev = m3_ipc->dev;
+       int ret;
+
+       wait_for_completion(&m3_ipc->rproc->firmware_loading_complete);
+
+       init_completion(&m3_ipc->sync_complete);
+
+       ret = rproc_boot(m3_ipc->rproc);
+       if (ret)
+               dev_err(dev, "rproc_boot failed\n");
+
+       do_exit(0);
+}
+
+static int wkup_m3_ipc_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       int irq, ret;
+       phandle rproc_phandle;
+       struct rproc *m3_rproc;
+       struct resource *res;
+       struct task_struct *task;
+       struct wkup_m3_ipc *m3_ipc;
+
+       m3_ipc = devm_kzalloc(dev, sizeof(*m3_ipc), GFP_KERNEL);
+       if (!m3_ipc)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       m3_ipc->ipc_mem_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(m3_ipc->ipc_mem_base)) {
+               dev_err(dev, "could not ioremap ipc_mem\n");
+               return PTR_ERR(m3_ipc->ipc_mem_base);
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (!irq) {
+               dev_err(&pdev->dev, "no irq resource\n");
+               return -ENXIO;
+       }
+
+       ret = devm_request_irq(dev, irq, wkup_m3_txev_handler,
+                              0, "wkup_m3_txev", m3_ipc);
+       if (ret) {
+               dev_err(dev, "request_irq failed\n");
+               return ret;
+       }
+
+       m3_ipc->mbox_client.dev = dev;
+       m3_ipc->mbox_client.tx_done = NULL;
+       m3_ipc->mbox_client.tx_prepare = NULL;
+       m3_ipc->mbox_client.rx_callback = NULL;
+       m3_ipc->mbox_client.tx_block = false;
+       m3_ipc->mbox_client.knows_txdone = false;
+
+       m3_ipc->mbox = mbox_request_channel(&m3_ipc->mbox_client, 0);
+
+       if (IS_ERR(m3_ipc->mbox)) {
+               dev_err(dev, "IPC Request for A8->M3 Channel failed! %ld\n",
+                       PTR_ERR(m3_ipc->mbox));
+               return PTR_ERR(m3_ipc->mbox);
+       }
+
+       if (of_property_read_u32(dev->of_node, "ti,rproc", &rproc_phandle)) {
+               dev_err(&pdev->dev, "could not get rproc phandle\n");
+               ret = -ENODEV;
+               goto err_free_mbox;
+       }
+
+       m3_rproc = rproc_get_by_phandle(rproc_phandle);
+       if (!m3_rproc) {
+               dev_err(&pdev->dev, "could not get rproc handle\n");
+               ret = -EPROBE_DEFER;
+               goto err_free_mbox;
+       }
+
+       m3_ipc->rproc = m3_rproc;
+       m3_ipc->dev = dev;
+       m3_ipc->state = M3_STATE_RESET;
+
+       m3_ipc->ops = &ipc_ops;
+
+       /*
+        * Wait for firmware loading completion in a thread so we
+        * can boot the wkup_m3 as soon as it's ready without holding
+        * up kernel boot
+        */
+       task = kthread_run((void *)wkup_m3_rproc_boot_thread, m3_ipc,
+                          "wkup_m3_rproc_loader");
+
+       if (IS_ERR(task)) {
+               dev_err(dev, "can't create rproc_boot thread\n");
+               goto err_put_rproc;
+       }
+
+       m3_ipc_state = m3_ipc;
+
+       return 0;
+
+err_put_rproc:
+       rproc_put(m3_rproc);
+err_free_mbox:
+       mbox_free_channel(m3_ipc->mbox);
+       return ret;
+}
+
+static int wkup_m3_ipc_remove(struct platform_device *pdev)
+{
+       mbox_free_channel(m3_ipc_state->mbox);
+
+       rproc_shutdown(m3_ipc_state->rproc);
+       rproc_put(m3_ipc_state->rproc);
+
+       m3_ipc_state = NULL;
+
+       return 0;
+}
+
+static const struct of_device_id wkup_m3_ipc_of_match[] = {
+       { .compatible = "ti,am3352-wkup-m3-ipc", },
+       { .compatible = "ti,am4372-wkup-m3-ipc", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, wkup_m3_ipc_of_match);
+
+static struct platform_driver wkup_m3_ipc_driver = {
+       .probe = wkup_m3_ipc_probe,
+       .remove = wkup_m3_ipc_remove,
+       .driver = {
+               .name = "wkup_m3_ipc",
+               .of_match_table = wkup_m3_ipc_of_match,
+       },
+};
+
+module_platform_driver(wkup_m3_ipc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("wkup m3 remote processor ipc driver");
+MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
index e642c45..c337764 100644 (file)
@@ -36,6 +36,8 @@ static const char *realview_board_str(u32 id)
        switch ((id >> 16) & 0xfff) {
        case 0x0147:
                return "HBI-0147";
+       case 0x0159:
+               return "HBI-0159";
        default:
                return "Unknown";
        }
@@ -44,6 +46,8 @@ static const char *realview_board_str(u32 id)
 static const char *realview_arch_str(u32 id)
 {
        switch ((id >> 8) & 0xf) {
+       case 0x04:
+               return "AHB";
        case 0x05:
                return "Multi-layer AXI";
        default:
index 9c41652..912c96b 100644 (file)
@@ -97,7 +97,7 @@ static const struct board_staging_dev armadillo800eva_devices[] __initconst = {
 
 static void __init armadillo800eva_init(void)
 {
-       board_staging_gic_setup_xlate("arm,cortex-a9-gic", 32);
+       board_staging_gic_setup_xlate("arm,pl390", 32);
        board_staging_register_devices(armadillo800eva_devices,
                                       ARRAY_SIZE(armadillo800eva_devices));
 }
index 8d1eb09..05a6d43 100644 (file)
@@ -11,7 +11,7 @@ static struct resource usbs1_res[] __initdata = {
 
 static void __init kzm9d_init(void)
 {
-       board_staging_gic_setup_xlate("arm,cortex-a9-gic", 32);
+       board_staging_gic_setup_xlate("arm,pl390", 32);
 
        if (!board_staging_dt_node_available(usbs1_res,
                                             ARRAY_SIZE(usbs1_res))) {
index d6273e1..a80d993 100644 (file)
@@ -151,16 +151,12 @@ do {                                                                          \
 
 #define LIBCFS_FREE(ptr, size)                                   \
 do {                                                               \
-       int s = (size);                                          \
        if (unlikely((ptr) == NULL)) {                            \
                CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at "    \
-                      "%s:%d\n", s, __FILE__, __LINE__);              \
+                      "%s:%d\n", (int)(size), __FILE__, __LINE__);     \
                break;                                            \
        }                                                              \
-       if (unlikely(s > LIBCFS_VMALLOC_SIZE))                    \
-               vfree(ptr);                                 \
-       else                                                        \
-               kfree(ptr);                                       \
+       kvfree(ptr);                                      \
 } while (0)
 
 /******************************************************************************/
index 72af486..cb74ae7 100644 (file)
@@ -2070,32 +2070,13 @@ static int kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts)
 
 static int kiblnd_hdev_get_attr(kib_hca_dev_t *hdev)
 {
-       struct ib_device_attr *attr;
-       int rc;
-
        /* It's safe to assume a HCA can handle a page size
         * matching that of the native system */
        hdev->ibh_page_shift = PAGE_SHIFT;
        hdev->ibh_page_size  = 1 << PAGE_SHIFT;
        hdev->ibh_page_mask  = ~((__u64)hdev->ibh_page_size - 1);
 
-       LIBCFS_ALLOC(attr, sizeof(*attr));
-       if (attr == NULL) {
-               CERROR("Out of memory\n");
-               return -ENOMEM;
-       }
-
-       rc = ib_query_device(hdev->ibh_ibdev, attr);
-       if (rc == 0)
-               hdev->ibh_mr_size = attr->max_mr_size;
-
-       LIBCFS_FREE(attr, sizeof(*attr));
-
-       if (rc != 0) {
-               CERROR("Failed to query IB device: %d\n", rc);
-               return rc;
-       }
-
+       hdev->ibh_mr_size = hdev->ibh_ibdev->attrs.max_mr_size;
        if (hdev->ibh_mr_size == ~0ULL) {
                hdev->ibh_mr_shift = 64;
                return 0;
index 7b35531..8982f7d 100644 (file)
@@ -1858,7 +1858,7 @@ static loff_t ll_dir_seek(struct file *file, loff_t offset, int origin)
        int api32 = ll_need_32bit_api(sbi);
        loff_t ret = -EINVAL;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        switch (origin) {
        case SEEK_SET:
                break;
@@ -1896,7 +1896,7 @@ static loff_t ll_dir_seek(struct file *file, loff_t offset, int origin)
        goto out;
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index c92d58b..39e2ffd 100644 (file)
@@ -2082,17 +2082,17 @@ putgl:
        /* update time if requested */
        rc = 0;
        if (llss->ia2.ia_valid != 0) {
-               mutex_lock(&llss->inode1->i_mutex);
+               inode_lock(llss->inode1);
                rc = ll_setattr(file1->f_path.dentry, &llss->ia2);
-               mutex_unlock(&llss->inode1->i_mutex);
+               inode_unlock(llss->inode1);
        }
 
        if (llss->ia1.ia_valid != 0) {
                int rc1;
 
-               mutex_lock(&llss->inode2->i_mutex);
+               inode_lock(llss->inode2);
                rc1 = ll_setattr(file2->f_path.dentry, &llss->ia1);
-               mutex_unlock(&llss->inode2->i_mutex);
+               inode_unlock(llss->inode2);
                if (rc == 0)
                        rc = rc1;
        }
@@ -2179,13 +2179,13 @@ static int ll_hsm_import(struct inode *inode, struct file *file,
                         ATTR_MTIME | ATTR_MTIME_SET |
                         ATTR_ATIME | ATTR_ATIME_SET;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        rc = ll_setattr_raw(file->f_path.dentry, attr, true);
        if (rc == -ENODATA)
                rc = 0;
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        kfree(attr);
 free_hss:
@@ -2609,7 +2609,7 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FSYNC, 1);
 
        rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* catch async errors that were recorded back when async writeback
         * failed for pages in this mapping. */
@@ -2641,7 +2641,7 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                        fd->fd_write_failed = false;
        }
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return rc;
 }
 
index ee8a1d6..845e992 100644 (file)
@@ -631,8 +631,6 @@ struct ll_file_data {
 
 struct lov_stripe_md;
 
-extern spinlock_t inode_lock;
-
 extern struct dentry *llite_root;
 extern struct kset *llite_kset;
 
index 1db93af..b2fc5b3 100644 (file)
@@ -1277,7 +1277,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
                return -ENOMEM;
 
        if (!S_ISDIR(inode->i_mode))
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
        memcpy(&op_data->op_attr, attr, sizeof(*attr));
 
@@ -1358,7 +1358,7 @@ out:
        ll_finish_md_op_data(op_data);
 
        if (!S_ISDIR(inode->i_mode)) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if ((attr->ia_valid & ATTR_SIZE) && !hsm_import)
                        inode_dio_wait(inode);
        }
index e578a11..18aab25 100644 (file)
@@ -245,9 +245,9 @@ static int ll_get_name(struct dentry *dentry, char *name,
                goto out;
        }
 
-       mutex_lock(&dir->i_mutex);
+       inode_lock(dir);
        rc = ll_dir_read(dir, &lgd.ctx);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        if (!rc && !lgd.lgd_found)
                rc = -ENOENT;
 out:
index 420d391..871924b 100644 (file)
@@ -257,9 +257,9 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
         *    be asked to write less pages once, this purely depends on
         *    implementation. Anyway, we should be careful to avoid deadlocking.
         */
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        bytes = ll_direct_rw_pages(env, io, rw, inode, pvec);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        cl_io_fini(env, io);
        return (bytes == pvec->ldp_size) ? 0 : (int)bytes;
 }
index 95cdb0c..f355474 100644 (file)
@@ -115,8 +115,8 @@ static struct ll_cl_context *ll_cl_init(struct file *file,
                struct inode *inode = vmpage->mapping->host;
                loff_t pos;
 
-               if (mutex_trylock(&inode->i_mutex)) {
-                       mutex_unlock(&(inode)->i_mutex);
+               if (inode_trylock(inode)) {
+                       inode_unlock((inode));
 
                        /* this is too bad. Someone is trying to write the
                         * page w/o holding inode mutex. This means we can
index 39fa13b..711fda9 100644 (file)
@@ -403,7 +403,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter,
         * 1. Need inode mutex to operate transient pages.
         */
        if (iov_iter_rw(iter) == READ)
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
 
        LASSERT(obj->cob_transient_pages == 0);
        while (iov_iter_count(iter)) {
@@ -454,7 +454,7 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter,
 out:
        LASSERT(obj->cob_transient_pages == 0);
        if (iov_iter_rw(iter) == READ)
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
        if (tot_bytes > 0) {
                if (iov_iter_rw(iter) == WRITE) {
index f68e972..0920ac6 100644 (file)
@@ -439,7 +439,7 @@ static int vvp_io_setattr_start(const struct lu_env *env,
        struct inode    *inode = ccc_object_inode(io->ci_obj);
        int result = 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        if (cl_io_is_trunc(io))
                result = vvp_io_setattr_trunc(env, ios, inode,
                                        io->u.ci_setattr.sa_attr.lvb_size);
@@ -459,7 +459,7 @@ static void vvp_io_setattr_end(const struct lu_env *env,
                 * because osc has already notified to destroy osc_extents. */
                vvp_do_vmtruncate(inode, io->u.ci_setattr.sa_attr.lvb_size);
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 }
 
 static void vvp_io_setattr_fini(const struct lu_env *env,
index 99c0d7a..a133475 100644 (file)
@@ -428,7 +428,7 @@ static void vvp_transient_page_verify(const struct cl_page *page)
 {
        struct inode *inode = ccc_object_inode(page->cp_obj);
 
-       LASSERT(!mutex_trylock(&inode->i_mutex));
+       LASSERT(!inode_trylock(inode));
 }
 
 static int vvp_transient_page_own(const struct lu_env *env,
@@ -480,9 +480,9 @@ static int vvp_transient_page_is_vmlocked(const struct lu_env *env,
        struct inode    *inode = ccc_object_inode(slice->cpl_obj);
        int     locked;
 
-       locked = !mutex_trylock(&inode->i_mutex);
+       locked = !inode_trylock(inode);
        if (!locked)
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        return locked ? -EBUSY : -ENODATA;
 }
 
@@ -502,7 +502,7 @@ static void vvp_transient_page_fini(const struct lu_env *env,
        struct ccc_object *clobj = cl2ccc(clp->cp_obj);
 
        vvp_page_fini_common(cp);
-       LASSERT(!mutex_trylock(&clobj->cob_inode->i_mutex));
+       LASSERT(!inode_trylock(clobj->cob_inode));
        clobj->cob_transient_pages--;
 }
 
@@ -548,7 +548,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
        } else {
                struct ccc_object *clobj = cl2ccc(obj);
 
-               LASSERT(!mutex_trylock(&clobj->cob_inode->i_mutex));
+               LASSERT(!inode_trylock(clobj->cob_inode));
                cl_page_slice_add(page, &cpg->cpg_cl, obj,
                                &vvp_transient_page_ops);
                clobj->cob_transient_pages++;
index 3ef881f..7ad0c08 100644 (file)
@@ -173,9 +173,6 @@ static inline int c2_poll_one(struct c2_dev *c2dev,
        case C2_WR_TYPE_RDMA_READ:
                entry->opcode = IB_WC_RDMA_READ;
                break;
-       case C2_WR_TYPE_BIND_MW:
-               entry->opcode = IB_WC_BIND_MW;
-               break;
        case C2_WR_TYPE_RECV:
                entry->byte_len = be32_to_cpu(ce->bytes_rcvd);
                entry->opcode = IB_WC_RECV;
index a092ac7..de8d10e 100644 (file)
@@ -337,43 +337,21 @@ static inline u32 c2_convert_access(int acc)
            C2_ACF_LOCAL_READ | C2_ACF_WINDOW_BIND;
 }
 
-static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
-                                   struct ib_phys_buf *buffer_list,
-                                   int num_phys_buf, int acc, u64 * iova_start)
+static struct ib_mr *c2_get_dma_mr(struct ib_pd *pd, int acc)
 {
        struct c2_mr *mr;
        u64 *page_list;
-       u32 total_len;
-       int err, i, j, k, page_shift, pbl_depth;
+       const u32 total_len = 0xffffffff;       /* AMSO1100 limit */
+       int err, page_shift, pbl_depth, i;
+       u64 kva = 0;
 
-       pbl_depth = 0;
-       total_len = 0;
+       pr_debug("%s:%u\n", __func__, __LINE__);
 
-       page_shift = PAGE_SHIFT;
        /*
-        * If there is only 1 buffer we assume this could
-        * be a map of all phy mem...use a 32k page_shift.
+        * This is a map of all phy mem...use a 32k page_shift.
         */
-       if (num_phys_buf == 1)
-               page_shift += 3;
-
-       for (i = 0; i < num_phys_buf; i++) {
-
-               if (offset_in_page(buffer_list[i].addr)) {
-                       pr_debug("Unaligned Memory Buffer: 0x%x\n",
-                               (unsigned int) buffer_list[i].addr);
-                       return ERR_PTR(-EINVAL);
-               }
-
-               if (!buffer_list[i].size) {
-                       pr_debug("Invalid Buffer Size\n");
-                       return ERR_PTR(-EINVAL);
-               }
-
-               total_len += buffer_list[i].size;
-               pbl_depth += ALIGN(buffer_list[i].size,
-                                  BIT(page_shift)) >> page_shift;
-       }
+       page_shift = PAGE_SHIFT + 3;
+       pbl_depth = ALIGN(total_len, BIT(page_shift)) >> page_shift;
 
        page_list = vmalloc(sizeof(u64) * pbl_depth);
        if (!page_list) {
@@ -382,16 +360,8 @@ static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
                return ERR_PTR(-ENOMEM);
        }
 
-       for (i = 0, j = 0; i < num_phys_buf; i++) {
-
-               int naddrs;
-
-               naddrs = ALIGN(buffer_list[i].size,
-                              BIT(page_shift)) >> page_shift;
-               for (k = 0; k < naddrs; k++)
-                       page_list[j++] = (buffer_list[i].addr +
-                                                    (k << page_shift));
-       }
+       for (i = 0; i < pbl_depth; i++)
+               page_list[i] = (i << page_shift);
 
        mr = kmalloc(sizeof(*mr), GFP_KERNEL);
        if (!mr) {
@@ -399,17 +369,17 @@ static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
                return ERR_PTR(-ENOMEM);
        }
 
-       mr->pd = to_c2pd(ib_pd);
+       mr->pd = to_c2pd(pd);
        mr->umem = NULL;
        pr_debug("%s - page shift %d, pbl_depth %d, total_len %u, "
                "*iova_start %llx, first pa %llx, last pa %llx\n",
                __func__, page_shift, pbl_depth, total_len,
-               (unsigned long long) *iova_start,
+               (unsigned long long) kva,
                (unsigned long long) page_list[0],
                (unsigned long long) page_list[pbl_depth-1]);
-       err = c2_nsmr_register_phys_kern(to_c2dev(ib_pd->device), page_list,
+       err = c2_nsmr_register_phys_kern(to_c2dev(pd->device), page_list,
                                         BIT(page_shift), pbl_depth,
-                                        total_len, 0, iova_start,
+                                        total_len, 0, &kva,
                                         c2_convert_access(acc), mr);
        vfree(page_list);
        if (err) {
@@ -420,19 +390,6 @@ static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd,
        return &mr->ibmr;
 }
 
-static struct ib_mr *c2_get_dma_mr(struct ib_pd *pd, int acc)
-{
-       struct ib_phys_buf bl;
-       u64 kva = 0;
-
-       pr_debug("%s:%u\n", __func__, __LINE__);
-
-       /* AMSO1100 limit */
-       bl.size = 0xffffffff;
-       bl.addr = 0;
-       return c2_reg_phys_mr(pd, &bl, 1, acc, &kva);
-}
-
 static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                    u64 virt, int acc, struct ib_udata *udata)
 {
@@ -840,7 +797,6 @@ int c2_register_device(struct c2_dev *dev)
        dev->ibdev.destroy_cq = c2_destroy_cq;
        dev->ibdev.poll_cq = c2_poll_cq;
        dev->ibdev.get_dma_mr = c2_get_dma_mr;
-       dev->ibdev.reg_phys_mr = c2_reg_phys_mr;
        dev->ibdev.reg_user_mr = c2_reg_user_mr;
        dev->ibdev.dereg_mr = c2_dereg_mr;
        dev->ibdev.get_port_immutable = c2_port_immutable;
index bd45e0f..e8c3387 100644 (file)
@@ -316,9 +316,8 @@ struct ehca_mr_pginfo {
 
        union {
                struct { /* type EHCA_MR_PGI_PHYS section */
-                       int num_phys_buf;
-                       struct ib_phys_buf *phys_buf_array;
-                       u64 next_buf;
+                       u64 addr;
+                       u16 size;
                } phy;
                struct { /* type EHCA_MR_PGI_USER section */
                        struct ib_umem *region;
index 80e6a3d..cca5933 100644 (file)
@@ -80,30 +80,14 @@ int ehca_destroy_ah(struct ib_ah *ah);
 
 struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
 
-struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
-                              struct ib_phys_buf *phys_buf_array,
-                              int num_phys_buf,
-                              int mr_access_flags, u64 *iova_start);
-
 struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                               u64 virt, int mr_access_flags,
                               struct ib_udata *udata);
 
-int ehca_rereg_phys_mr(struct ib_mr *mr,
-                      int mr_rereg_mask,
-                      struct ib_pd *pd,
-                      struct ib_phys_buf *phys_buf_array,
-                      int num_phys_buf, int mr_access_flags, u64 *iova_start);
-
-int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr);
-
 int ehca_dereg_mr(struct ib_mr *mr);
 
 struct ib_mw *ehca_alloc_mw(struct ib_pd *pd, enum ib_mw_type type);
 
-int ehca_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
-                struct ib_mw_bind *mw_bind);
-
 int ehca_dealloc_mw(struct ib_mw *mw);
 
 struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
index 860b974..832f22f 100644 (file)
@@ -511,13 +511,9 @@ static int ehca_init_device(struct ehca_shca *shca)
        shca->ib_device.req_notify_cq       = ehca_req_notify_cq;
        /* shca->ib_device.req_ncomp_notif  = ehca_req_ncomp_notif; */
        shca->ib_device.get_dma_mr          = ehca_get_dma_mr;
-       shca->ib_device.reg_phys_mr         = ehca_reg_phys_mr;
        shca->ib_device.reg_user_mr         = ehca_reg_user_mr;
-       shca->ib_device.query_mr            = ehca_query_mr;
        shca->ib_device.dereg_mr            = ehca_dereg_mr;
-       shca->ib_device.rereg_phys_mr       = ehca_rereg_phys_mr;
        shca->ib_device.alloc_mw            = ehca_alloc_mw;
-       shca->ib_device.bind_mw             = ehca_bind_mw;
        shca->ib_device.dealloc_mw          = ehca_dealloc_mw;
        shca->ib_device.alloc_fmr           = ehca_alloc_fmr;
        shca->ib_device.map_phys_fmr        = ehca_map_phys_fmr;
index 553e883..3367205 100644 (file)
@@ -196,120 +196,6 @@ get_dma_mr_exit0:
 
 /*----------------------------------------------------------------------*/
 
-struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
-                              struct ib_phys_buf *phys_buf_array,
-                              int num_phys_buf,
-                              int mr_access_flags,
-                              u64 *iova_start)
-{
-       struct ib_mr *ib_mr;
-       int ret;
-       struct ehca_mr *e_mr;
-       struct ehca_shca *shca =
-               container_of(pd->device, struct ehca_shca, ib_device);
-       struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
-
-       u64 size;
-
-       if ((num_phys_buf <= 0) || !phys_buf_array) {
-               ehca_err(pd->device, "bad input values: num_phys_buf=%x "
-                        "phys_buf_array=%p", num_phys_buf, phys_buf_array);
-               ib_mr = ERR_PTR(-EINVAL);
-               goto reg_phys_mr_exit0;
-       }
-       if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
-            !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)) ||
-           ((mr_access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
-            !(mr_access_flags & IB_ACCESS_LOCAL_WRITE))) {
-               /*
-                * Remote Write Access requires Local Write Access
-                * Remote Atomic Access requires Local Write Access
-                */
-               ehca_err(pd->device, "bad input values: mr_access_flags=%x",
-                        mr_access_flags);
-               ib_mr = ERR_PTR(-EINVAL);
-               goto reg_phys_mr_exit0;
-       }
-
-       /* check physical buffer list and calculate size */
-       ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array, num_phys_buf,
-                                           iova_start, &size);
-       if (ret) {
-               ib_mr = ERR_PTR(ret);
-               goto reg_phys_mr_exit0;
-       }
-       if ((size == 0) ||
-           (((u64)iova_start + size) < (u64)iova_start)) {
-               ehca_err(pd->device, "bad input values: size=%llx iova_start=%p",
-                        size, iova_start);
-               ib_mr = ERR_PTR(-EINVAL);
-               goto reg_phys_mr_exit0;
-       }
-
-       e_mr = ehca_mr_new();
-       if (!e_mr) {
-               ehca_err(pd->device, "out of memory");
-               ib_mr = ERR_PTR(-ENOMEM);
-               goto reg_phys_mr_exit0;
-       }
-
-       /* register MR on HCA */
-       if (ehca_mr_is_maxmr(size, iova_start)) {
-               e_mr->flags |= EHCA_MR_FLAG_MAXMR;
-               ret = ehca_reg_maxmr(shca, e_mr, iova_start, mr_access_flags,
-                                    e_pd, &e_mr->ib.ib_mr.lkey,
-                                    &e_mr->ib.ib_mr.rkey);
-               if (ret) {
-                       ib_mr = ERR_PTR(ret);
-                       goto reg_phys_mr_exit1;
-               }
-       } else {
-               struct ehca_mr_pginfo pginfo;
-               u32 num_kpages;
-               u32 num_hwpages;
-               u64 hw_pgsize;
-
-               num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size,
-                                       PAGE_SIZE);
-               /* for kernel space we try most possible pgsize */
-               hw_pgsize = ehca_get_max_hwpage_size(shca);
-               num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size,
-                                        hw_pgsize);
-               memset(&pginfo, 0, sizeof(pginfo));
-               pginfo.type = EHCA_MR_PGI_PHYS;
-               pginfo.num_kpages = num_kpages;
-               pginfo.hwpage_size = hw_pgsize;
-               pginfo.num_hwpages = num_hwpages;
-               pginfo.u.phy.num_phys_buf = num_phys_buf;
-               pginfo.u.phy.phys_buf_array = phys_buf_array;
-               pginfo.next_hwpage =
-                       ((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
-
-               ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
-                                 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
-                                 &e_mr->ib.ib_mr.rkey, EHCA_REG_MR);
-               if (ret) {
-                       ib_mr = ERR_PTR(ret);
-                       goto reg_phys_mr_exit1;
-               }
-       }
-
-       /* successful registration of all pages */
-       return &e_mr->ib.ib_mr;
-
-reg_phys_mr_exit1:
-       ehca_mr_delete(e_mr);
-reg_phys_mr_exit0:
-       if (IS_ERR(ib_mr))
-               ehca_err(pd->device, "h_ret=%li pd=%p phys_buf_array=%p "
-                        "num_phys_buf=%x mr_access_flags=%x iova_start=%p",
-                        PTR_ERR(ib_mr), pd, phys_buf_array,
-                        num_phys_buf, mr_access_flags, iova_start);
-       return ib_mr;
-} /* end ehca_reg_phys_mr() */
-
-/*----------------------------------------------------------------------*/
-
 struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                               u64 virt, int mr_access_flags,
                               struct ib_udata *udata)
@@ -437,207 +323,6 @@ reg_user_mr_exit0:
 
 /*----------------------------------------------------------------------*/
 
-int ehca_rereg_phys_mr(struct ib_mr *mr,
-                      int mr_rereg_mask,
-                      struct ib_pd *pd,
-                      struct ib_phys_buf *phys_buf_array,
-                      int num_phys_buf,
-                      int mr_access_flags,
-                      u64 *iova_start)
-{
-       int ret;
-
-       struct ehca_shca *shca =
-               container_of(mr->device, struct ehca_shca, ib_device);
-       struct ehca_mr *e_mr = container_of(mr, struct ehca_mr, ib.ib_mr);
-       u64 new_size;
-       u64 *new_start;
-       u32 new_acl;
-       struct ehca_pd *new_pd;
-       u32 tmp_lkey, tmp_rkey;
-       unsigned long sl_flags;
-       u32 num_kpages = 0;
-       u32 num_hwpages = 0;
-       struct ehca_mr_pginfo pginfo;
-
-       if (!(mr_rereg_mask & IB_MR_REREG_TRANS)) {
-               /* TODO not supported, because PHYP rereg hCall needs pages */
-               ehca_err(mr->device, "rereg without IB_MR_REREG_TRANS not "
-                        "supported yet, mr_rereg_mask=%x", mr_rereg_mask);
-               ret = -EINVAL;
-               goto rereg_phys_mr_exit0;
-       }
-
-       if (mr_rereg_mask & IB_MR_REREG_PD) {
-               if (!pd) {
-                       ehca_err(mr->device, "rereg with bad pd, pd=%p "
-                                "mr_rereg_mask=%x", pd, mr_rereg_mask);
-                       ret = -EINVAL;
-                       goto rereg_phys_mr_exit0;
-               }
-       }
-
-       if ((mr_rereg_mask &
-            ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS)) ||
-           (mr_rereg_mask == 0)) {
-               ret = -EINVAL;
-               goto rereg_phys_mr_exit0;
-       }
-
-       /* check other parameters */
-       if (e_mr == shca->maxmr) {
-               /* should be impossible, however reject to be sure */
-               ehca_err(mr->device, "rereg internal max-MR impossible, mr=%p "
-                        "shca->maxmr=%p mr->lkey=%x",
-                        mr, shca->maxmr, mr->lkey);
-               ret = -EINVAL;
-               goto rereg_phys_mr_exit0;
-       }
-       if (mr_rereg_mask & IB_MR_REREG_TRANS) { /* transl., i.e. addr/size */
-               if (e_mr->flags & EHCA_MR_FLAG_FMR) {
-                       ehca_err(mr->device, "not supported for FMR, mr=%p "
-                                "flags=%x", mr, e_mr->flags);
-                       ret = -EINVAL;
-                       goto rereg_phys_mr_exit0;
-               }
-               if (!phys_buf_array || num_phys_buf <= 0) {
-                       ehca_err(mr->device, "bad input values mr_rereg_mask=%x"
-                                " phys_buf_array=%p num_phys_buf=%x",
-                                mr_rereg_mask, phys_buf_array, num_phys_buf);
-                       ret = -EINVAL;
-                       goto rereg_phys_mr_exit0;
-               }
-       }
-       if ((mr_rereg_mask & IB_MR_REREG_ACCESS) &&     /* change ACL */
-           (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
-             !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)) ||
-            ((mr_access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
-             !(mr_access_flags & IB_ACCESS_LOCAL_WRITE)))) {
-               /*
-                * Remote Write Access requires Local Write Access
-                * Remote Atomic Access requires Local Write Access
-                */
-               ehca_err(mr->device, "bad input values: mr_rereg_mask=%x "
-                        "mr_access_flags=%x", mr_rereg_mask, mr_access_flags);
-               ret = -EINVAL;
-               goto rereg_phys_mr_exit0;
-       }
-
-       /* set requested values dependent on rereg request */
-       spin_lock_irqsave(&e_mr->mrlock, sl_flags);
-       new_start = e_mr->start;
-       new_size = e_mr->size;
-       new_acl = e_mr->acl;
-       new_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
-
-       if (mr_rereg_mask & IB_MR_REREG_TRANS) {
-               u64 hw_pgsize = ehca_get_max_hwpage_size(shca);
-
-               new_start = iova_start; /* change address */
-               /* check physical buffer list and calculate size */
-               ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array,
-                                                   num_phys_buf, iova_start,
-                                                   &new_size);
-               if (ret)
-                       goto rereg_phys_mr_exit1;
-               if ((new_size == 0) ||
-                   (((u64)iova_start + new_size) < (u64)iova_start)) {
-                       ehca_err(mr->device, "bad input values: new_size=%llx "
-                                "iova_start=%p", new_size, iova_start);
-                       ret = -EINVAL;
-                       goto rereg_phys_mr_exit1;
-               }
-               num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) +
-                                       new_size, PAGE_SIZE);
-               num_hwpages = NUM_CHUNKS(((u64)new_start % hw_pgsize) +
-                                        new_size, hw_pgsize);
-               memset(&pginfo, 0, sizeof(pginfo));
-               pginfo.type = EHCA_MR_PGI_PHYS;
-               pginfo.num_kpages = num_kpages;
-               pginfo.hwpage_size = hw_pgsize;
-               pginfo.num_hwpages = num_hwpages;
-               pginfo.u.phy.num_phys_buf = num_phys_buf;
-               pginfo.u.phy.phys_buf_array = phys_buf_array;
-               pginfo.next_hwpage =
-                       ((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
-       }
-       if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-               new_acl = mr_access_flags;
-       if (mr_rereg_mask & IB_MR_REREG_PD)
-               new_pd = container_of(pd, struct ehca_pd, ib_pd);
-
-       ret = ehca_rereg_mr(shca, e_mr, new_start, new_size, new_acl,
-                           new_pd, &pginfo, &tmp_lkey, &tmp_rkey);
-       if (ret)
-               goto rereg_phys_mr_exit1;
-
-       /* successful reregistration */
-       if (mr_rereg_mask & IB_MR_REREG_PD)
-               mr->pd = pd;
-       mr->lkey = tmp_lkey;
-       mr->rkey = tmp_rkey;
-
-rereg_phys_mr_exit1:
-       spin_unlock_irqrestore(&e_mr->mrlock, sl_flags);
-rereg_phys_mr_exit0:
-       if (ret)
-               ehca_err(mr->device, "ret=%i mr=%p mr_rereg_mask=%x pd=%p "
-                        "phys_buf_array=%p num_phys_buf=%x mr_access_flags=%x "
-                        "iova_start=%p",
-                        ret, mr, mr_rereg_mask, pd, phys_buf_array,
-                        num_phys_buf, mr_access_flags, iova_start);
-       return ret;
-} /* end ehca_rereg_phys_mr() */
-
-/*----------------------------------------------------------------------*/
-
-int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
-{
-       int ret = 0;
-       u64 h_ret;
-       struct ehca_shca *shca =
-               container_of(mr->device, struct ehca_shca, ib_device);
-       struct ehca_mr *e_mr = container_of(mr, struct ehca_mr, ib.ib_mr);
-       unsigned long sl_flags;
-       struct ehca_mr_hipzout_parms hipzout;
-
-       if ((e_mr->flags & EHCA_MR_FLAG_FMR)) {
-               ehca_err(mr->device, "not supported for FMR, mr=%p e_mr=%p "
-                        "e_mr->flags=%x", mr, e_mr, e_mr->flags);
-               ret = -EINVAL;
-               goto query_mr_exit0;
-       }
-
-       memset(mr_attr, 0, sizeof(struct ib_mr_attr));
-       spin_lock_irqsave(&e_mr->mrlock, sl_flags);
-
-       h_ret = hipz_h_query_mr(shca->ipz_hca_handle, e_mr, &hipzout);
-       if (h_ret != H_SUCCESS) {
-               ehca_err(mr->device, "hipz_mr_query failed, h_ret=%lli mr=%p "
-                        "hca_hndl=%llx mr_hndl=%llx lkey=%x",
-                        h_ret, mr, shca->ipz_hca_handle.handle,
-                        e_mr->ipz_mr_handle.handle, mr->lkey);
-               ret = ehca2ib_return_code(h_ret);
-               goto query_mr_exit1;
-       }
-       mr_attr->pd = mr->pd;
-       mr_attr->device_virt_addr = hipzout.vaddr;
-       mr_attr->size = hipzout.len;
-       mr_attr->lkey = hipzout.lkey;
-       mr_attr->rkey = hipzout.rkey;
-       ehca_mrmw_reverse_map_acl(&hipzout.acl, &mr_attr->mr_access_flags);
-
-query_mr_exit1:
-       spin_unlock_irqrestore(&e_mr->mrlock, sl_flags);
-query_mr_exit0:
-       if (ret)
-               ehca_err(mr->device, "ret=%i mr=%p mr_attr=%p",
-                        ret, mr, mr_attr);
-       return ret;
-} /* end ehca_query_mr() */
-
-/*----------------------------------------------------------------------*/
-
 int ehca_dereg_mr(struct ib_mr *mr)
 {
        int ret = 0;
@@ -728,18 +413,6 @@ alloc_mw_exit0:
 
 /*----------------------------------------------------------------------*/
 
-int ehca_bind_mw(struct ib_qp *qp,
-                struct ib_mw *mw,
-                struct ib_mw_bind *mw_bind)
-{
-       /* TODO: not supported up to now */
-       ehca_gen_err("bind MW currently not supported by HCAD");
-
-       return -EPERM;
-} /* end ehca_bind_mw() */
-
-/*----------------------------------------------------------------------*/
-
 int ehca_dealloc_mw(struct ib_mw *mw)
 {
        u64 h_ret;
@@ -1616,7 +1289,6 @@ int ehca_reg_internal_maxmr(
        u64 *iova_start;
        u64 size_maxmr;
        struct ehca_mr_pginfo pginfo;
-       struct ib_phys_buf ib_pbuf;
        u32 num_kpages;
        u32 num_hwpages;
        u64 hw_pgsize;
@@ -1637,8 +1309,6 @@ int ehca_reg_internal_maxmr(
        /* register internal max-MR on HCA */
        size_maxmr = ehca_mr_len;
        iova_start = (u64 *)ehca_map_vaddr((void *)(KERNELBASE + PHYSICAL_START));
-       ib_pbuf.addr = 0;
-       ib_pbuf.size = size_maxmr;
        num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
                                PAGE_SIZE);
        hw_pgsize = ehca_get_max_hwpage_size(shca);
@@ -1650,8 +1320,8 @@ int ehca_reg_internal_maxmr(
        pginfo.num_kpages = num_kpages;
        pginfo.num_hwpages = num_hwpages;
        pginfo.hwpage_size = hw_pgsize;
-       pginfo.u.phy.num_phys_buf = 1;
-       pginfo.u.phy.phys_buf_array = &ib_pbuf;
+       pginfo.u.phy.addr = 0;
+       pginfo.u.phy.size = size_maxmr;
 
        ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd,
                          &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -1669,7 +1339,6 @@ int ehca_reg_internal_maxmr(
        e_mr->ib.ib_mr.pd = &e_pd->ib_pd;
        e_mr->ib.ib_mr.uobject = NULL;
        atomic_inc(&(e_pd->ib_pd.usecnt));
-       atomic_set(&(e_mr->ib.ib_mr.usecnt), 0);
        *e_maxmr = e_mr;
        return 0;
 
@@ -1762,61 +1431,6 @@ ehca_dereg_internal_maxmr_exit0:
 
 /*----------------------------------------------------------------------*/
 
-/*
- * check physical buffer array of MR verbs for validness and
- * calculates MR size
- */
-int ehca_mr_chk_buf_and_calc_size(struct ib_phys_buf *phys_buf_array,
-                                 int num_phys_buf,
-                                 u64 *iova_start,
-                                 u64 *size)
-{
-       struct ib_phys_buf *pbuf = phys_buf_array;
-       u64 size_count = 0;
-       u32 i;
-
-       if (num_phys_buf == 0) {
-               ehca_gen_err("bad phys buf array len, num_phys_buf=0");
-               return -EINVAL;
-       }
-       /* check first buffer */
-       if (((u64)iova_start & ~PAGE_MASK) != (pbuf->addr & ~PAGE_MASK)) {
-               ehca_gen_err("iova_start/addr mismatch, iova_start=%p "
-                            "pbuf->addr=%llx pbuf->size=%llx",
-                            iova_start, pbuf->addr, pbuf->size);
-               return -EINVAL;
-       }
-       if (((pbuf->addr + pbuf->size) % PAGE_SIZE) &&
-           (num_phys_buf > 1)) {
-               ehca_gen_err("addr/size mismatch in 1st buf, pbuf->addr=%llx "
-                            "pbuf->size=%llx", pbuf->addr, pbuf->size);
-               return -EINVAL;
-       }
-
-       for (i = 0; i < num_phys_buf; i++) {
-               if ((i > 0) && (pbuf->addr % PAGE_SIZE)) {
-                       ehca_gen_err("bad address, i=%x pbuf->addr=%llx "
-                                    "pbuf->size=%llx",
-                                    i, pbuf->addr, pbuf->size);
-                       return -EINVAL;
-               }
-               if (((i > 0) && /* not 1st */
-                    (i < (num_phys_buf - 1)) &&        /* not last */
-                    (pbuf->size % PAGE_SIZE)) || (pbuf->size == 0)) {
-                       ehca_gen_err("bad size, i=%x pbuf->size=%llx",
-                                    i, pbuf->size);
-                       return -EINVAL;
-               }
-               size_count += pbuf->size;
-               pbuf++;
-       }
-
-       *size = size_count;
-       return 0;
-} /* end ehca_mr_chk_buf_and_calc_size() */
-
-/*----------------------------------------------------------------------*/
-
 /* check page list of map FMR verb for validness */
 int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
                             u64 *page_list,
@@ -2002,57 +1616,54 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
                                 u32 number, u64 *kpage)
 {
        int ret = 0;
-       struct ib_phys_buf *pbuf;
+       u64 addr = pginfo->u.phy.addr;
+       u64 size = pginfo->u.phy.size;
        u64 num_hw, offs_hw;
        u32 i = 0;
 
-       /* loop over desired phys_buf_array entries */
-       while (i < number) {
-               pbuf   = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf;
-               num_hw  = NUM_CHUNKS((pbuf->addr % pginfo->hwpage_size) +
-                                    pbuf->size, pginfo->hwpage_size);
-               offs_hw = (pbuf->addr & ~(pginfo->hwpage_size - 1)) /
-                       pginfo->hwpage_size;
-               while (pginfo->next_hwpage < offs_hw + num_hw) {
-                       /* sanity check */
-                       if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
-                           (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
-                               ehca_gen_err("kpage_cnt >= num_kpages, "
-                                            "kpage_cnt=%llx num_kpages=%llx "
-                                            "hwpage_cnt=%llx "
-                                            "num_hwpages=%llx i=%x",
-                                            pginfo->kpage_cnt,
-                                            pginfo->num_kpages,
-                                            pginfo->hwpage_cnt,
-                                            pginfo->num_hwpages, i);
-                               return -EFAULT;
-                       }
-                       *kpage = (pbuf->addr & ~(pginfo->hwpage_size - 1)) +
-                                (pginfo->next_hwpage * pginfo->hwpage_size);
-                       if ( !(*kpage) && pbuf->addr ) {
-                               ehca_gen_err("pbuf->addr=%llx pbuf->size=%llx "
-                                            "next_hwpage=%llx", pbuf->addr,
-                                            pbuf->size, pginfo->next_hwpage);
-                               return -EFAULT;
-                       }
-                       (pginfo->hwpage_cnt)++;
-                       (pginfo->next_hwpage)++;
-                       if (PAGE_SIZE >= pginfo->hwpage_size) {
-                               if (pginfo->next_hwpage %
-                                   (PAGE_SIZE / pginfo->hwpage_size) == 0)
-                                       (pginfo->kpage_cnt)++;
-                       } else
-                               pginfo->kpage_cnt += pginfo->hwpage_size /
-                                       PAGE_SIZE;
-                       kpage++;
-                       i++;
-                       if (i >= number) break;
+       num_hw  = NUM_CHUNKS((addr % pginfo->hwpage_size) + size,
+                               pginfo->hwpage_size);
+       offs_hw = (addr & ~(pginfo->hwpage_size - 1)) / pginfo->hwpage_size;
+
+       while (pginfo->next_hwpage < offs_hw + num_hw) {
+               /* sanity check */
+               if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
+                   (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
+                       ehca_gen_err("kpage_cnt >= num_kpages, "
+                                    "kpage_cnt=%llx num_kpages=%llx "
+                                    "hwpage_cnt=%llx "
+                                    "num_hwpages=%llx i=%x",
+                                    pginfo->kpage_cnt,
+                                    pginfo->num_kpages,
+                                    pginfo->hwpage_cnt,
+                                    pginfo->num_hwpages, i);
+                       return -EFAULT;
                }
-               if (pginfo->next_hwpage >= offs_hw + num_hw) {
-                       (pginfo->u.phy.next_buf)++;
-                       pginfo->next_hwpage = 0;
+               *kpage = (addr & ~(pginfo->hwpage_size - 1)) +
+                        (pginfo->next_hwpage * pginfo->hwpage_size);
+               if ( !(*kpage) && addr ) {
+                       ehca_gen_err("addr=%llx size=%llx "
+                                    "next_hwpage=%llx", addr,
+                                    size, pginfo->next_hwpage);
+                       return -EFAULT;
                }
+               (pginfo->hwpage_cnt)++;
+               (pginfo->next_hwpage)++;
+               if (PAGE_SIZE >= pginfo->hwpage_size) {
+                       if (pginfo->next_hwpage %
+                           (PAGE_SIZE / pginfo->hwpage_size) == 0)
+                               (pginfo->kpage_cnt)++;
+               } else
+                       pginfo->kpage_cnt += pginfo->hwpage_size /
+                               PAGE_SIZE;
+               kpage++;
+               i++;
+               if (i >= number) break;
        }
+       if (pginfo->next_hwpage >= offs_hw + num_hw) {
+               pginfo->next_hwpage = 0;
+       }
+
        return ret;
 }
 
index 50d8b51..52bfa95 100644 (file)
@@ -98,11 +98,6 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
 
 int ehca_dereg_internal_maxmr(struct ehca_shca *shca);
 
-int ehca_mr_chk_buf_and_calc_size(struct ib_phys_buf *phys_buf_array,
-                                 int num_phys_buf,
-                                 u64 *iova_start,
-                                 u64 *size);
-
 int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
                             u64 *page_list,
                             int list_len);
index 10e2074..11813b8 100644 (file)
@@ -614,7 +614,6 @@ int ehca_post_srq_recv(struct ib_srq *srq,
 static const u8 ib_wc_opcode[255] = {
        [0x01] = IB_WC_RECV+1,
        [0x02] = IB_WC_RECV_RDMA_WITH_IMM+1,
-       [0x04] = IB_WC_BIND_MW+1,
        [0x08] = IB_WC_FETCH_ADD+1,
        [0x10] = IB_WC_COMP_SWAP+1,
        [0x20] = IB_WC_RDMA_WRITE+1,
index 568f185..a3f8b88 100644 (file)
@@ -167,10 +167,7 @@ static struct hfi1_mr *alloc_mr(int count, struct ib_pd *pd)
        rval = init_mregion(&mr->mr, pd, count);
        if (rval)
                goto bail;
-       /*
-        * ib_reg_phys_mr() will initialize mr->ibmr except for
-        * lkey and rkey.
-        */
+
        rval = hfi1_alloc_lkey(&mr->mr, 0);
        if (rval)
                goto bail_mregion;
@@ -187,52 +184,6 @@ bail:
        goto done;
 }
 
-/**
- * hfi1_reg_phys_mr - register a physical memory region
- * @pd: protection domain for this memory region
- * @buffer_list: pointer to the list of physical buffers to register
- * @num_phys_buf: the number of physical buffers to register
- * @iova_start: the starting address passed over IB which maps to this MR
- *
- * Returns the memory region on success, otherwise returns an errno.
- */
-struct ib_mr *hfi1_reg_phys_mr(struct ib_pd *pd,
-                              struct ib_phys_buf *buffer_list,
-                              int num_phys_buf, int acc, u64 *iova_start)
-{
-       struct hfi1_mr *mr;
-       int n, m, i;
-       struct ib_mr *ret;
-
-       mr = alloc_mr(num_phys_buf, pd);
-       if (IS_ERR(mr)) {
-               ret = (struct ib_mr *)mr;
-               goto bail;
-       }
-
-       mr->mr.user_base = *iova_start;
-       mr->mr.iova = *iova_start;
-       mr->mr.access_flags = acc;
-
-       m = 0;
-       n = 0;
-       for (i = 0; i < num_phys_buf; i++) {
-               mr->mr.map[m]->segs[n].vaddr = (void *) buffer_list[i].addr;
-               mr->mr.map[m]->segs[n].length = buffer_list[i].size;
-               mr->mr.length += buffer_list[i].size;
-               n++;
-               if (n == HFI1_SEGSZ) {
-                       m++;
-                       n = 0;
-               }
-       }
-
-       ret = &mr->ibmr;
-
-bail:
-       return ret;
-}
-
 /**
  * hfi1_reg_user_mr - register a userspace memory region
  * @pd: protection domain for this memory region
index ef0feaa..09b8d41 100644 (file)
@@ -2052,7 +2052,6 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
        ibdev->poll_cq = hfi1_poll_cq;
        ibdev->req_notify_cq = hfi1_req_notify_cq;
        ibdev->get_dma_mr = hfi1_get_dma_mr;
-       ibdev->reg_phys_mr = hfi1_reg_phys_mr;
        ibdev->reg_user_mr = hfi1_reg_user_mr;
        ibdev->dereg_mr = hfi1_dereg_mr;
        ibdev->alloc_mr = hfi1_alloc_mr;
index 72106e5..286e468 100644 (file)
@@ -1024,10 +1024,6 @@ int hfi1_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
 
 struct ib_mr *hfi1_get_dma_mr(struct ib_pd *pd, int acc);
 
-struct ib_mr *hfi1_reg_phys_mr(struct ib_pd *pd,
-                              struct ib_phys_buf *buffer_list,
-                              int num_phys_buf, int acc, u64 *iova_start);
-
 struct ib_mr *hfi1_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                               u64 virt_addr, int mr_access_flags,
                               struct ib_udata *udata);
index 796af68..476fcdf 100644 (file)
@@ -82,14 +82,14 @@ static int create_file(const char *name, umode_t mode,
 {
        int error;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        *dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(*dentry))
                error = ipathfs_mknod(d_inode(parent), *dentry,
                                      mode, fops, data);
        else
                error = PTR_ERR(*dentry);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
 
        return error;
 }
@@ -295,7 +295,7 @@ static int remove_device_files(struct super_block *sb,
        int ret;
 
        root = dget(sb->s_root);
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
        snprintf(unit, sizeof unit, "%02d", dd->ipath_unit);
        dir = lookup_one_len(unit, root, strlen(unit));
 
@@ -311,7 +311,7 @@ static int remove_device_files(struct super_block *sb,
        ret = simple_rmdir(d_inode(root), dir);
 
 bail:
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        dput(root);
        return ret;
 }
index c7278f6..b76b0ce 100644 (file)
@@ -98,10 +98,6 @@ static struct ipath_mr *alloc_mr(int count,
        }
        mr->mr.mapsz = m;
 
-       /*
-        * ib_reg_phys_mr() will initialize mr->ibmr except for
-        * lkey and rkey.
-        */
        if (!ipath_alloc_lkey(lk_table, &mr->mr))
                goto bail;
        mr->ibmr.rkey = mr->ibmr.lkey = mr->mr.lkey;
@@ -120,57 +116,6 @@ done:
        return mr;
 }
 
-/**
- * ipath_reg_phys_mr - register a physical memory region
- * @pd: protection domain for this memory region
- * @buffer_list: pointer to the list of physical buffers to register
- * @num_phys_buf: the number of physical buffers to register
- * @iova_start: the starting address passed over IB which maps to this MR
- *
- * Returns the memory region on success, otherwise returns an errno.
- */
-struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
-                               struct ib_phys_buf *buffer_list,
-                               int num_phys_buf, int acc, u64 *iova_start)
-{
-       struct ipath_mr *mr;
-       int n, m, i;
-       struct ib_mr *ret;
-
-       mr = alloc_mr(num_phys_buf, &to_idev(pd->device)->lk_table);
-       if (mr == NULL) {
-               ret = ERR_PTR(-ENOMEM);
-               goto bail;
-       }
-
-       mr->mr.pd = pd;
-       mr->mr.user_base = *iova_start;
-       mr->mr.iova = *iova_start;
-       mr->mr.length = 0;
-       mr->mr.offset = 0;
-       mr->mr.access_flags = acc;
-       mr->mr.max_segs = num_phys_buf;
-       mr->umem = NULL;
-
-       m = 0;
-       n = 0;
-       for (i = 0; i < num_phys_buf; i++) {
-               mr->mr.map[m]->segs[n].vaddr = (void *) buffer_list[i].addr;
-               mr->mr.map[m]->segs[n].length = buffer_list[i].size;
-               mr->mr.length += buffer_list[i].size;
-               n++;
-               if (n == IPATH_SEGSZ) {
-                       m++;
-                       n = 0;
-               }
-       }
-
-       ret = &mr->ibmr;
-
-bail:
-       return ret;
-}
-
 /**
  * ipath_reg_user_mr - register a userspace memory region
  * @pd: protection domain for this memory region
index 1778dee..53f9dca 100644 (file)
@@ -2201,7 +2201,6 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
        dev->poll_cq = ipath_poll_cq;
        dev->req_notify_cq = ipath_req_notify_cq;
        dev->get_dma_mr = ipath_get_dma_mr;
-       dev->reg_phys_mr = ipath_reg_phys_mr;
        dev->reg_user_mr = ipath_reg_user_mr;
        dev->dereg_mr = ipath_dereg_mr;
        dev->alloc_fmr = ipath_alloc_fmr;
index 0a90a56..6c70a89 100644 (file)
@@ -828,10 +828,6 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
 
 struct ib_mr *ipath_get_dma_mr(struct ib_pd *pd, int acc);
 
-struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
-                               struct ib_phys_buf *buffer_list,
-                               int num_phys_buf, int acc, u64 *iova_start);
-
 struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                u64 virt_addr, int mr_access_flags,
                                struct ib_udata *udata);
index 72204fb..576a7a4 100644 (file)
@@ -1333,7 +1333,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
                        /*
                         * Check if a delayed TASK_ABORTED status needs to
                         * be sent now if the ISCSI_FLAG_CMD_FINAL has been
-                        * received with the unsolicitied data out.
+                        * received with the unsolicited data out.
                         */
                        if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
                                iscsit_stop_dataout_timer(cmd);
@@ -3435,7 +3435,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
 
                        if ((tpg->tpg_attrib.generate_node_acls == 0) &&
                            (tpg->tpg_attrib.demo_mode_discovery == 0) &&
-                           (!core_tpg_get_initiator_node_acl(&tpg->tpg_se_tpg,
+                           (!target_tpg_has_node_acl(&tpg->tpg_se_tpg,
                                cmd->conn->sess->sess_ops->InitiatorName))) {
                                continue;
                        }
@@ -4459,9 +4459,6 @@ int iscsit_close_connection(
 
                return 0;
        }
-       spin_unlock_bh(&sess->conn_lock);
-
-       return 0;
 }
 
 int iscsit_close_session(struct iscsi_session *sess)
index 255204c..2f821de 100644 (file)
@@ -725,11 +725,8 @@ static ssize_t lio_target_nacl_cmdsn_depth_store(struct config_item *item,
 
        if (iscsit_get_tpg(tpg) < 0)
                return -EINVAL;
-       /*
-        * iscsit_tpg_set_initiator_node_queue_depth() assumes force=1
-        */
-       ret = iscsit_tpg_set_initiator_node_queue_depth(tpg,
-                               config_item_name(acl_ci), cmdsn_depth, 1);
+
+       ret = core_tpg_set_initiator_node_queue_depth(se_nacl, cmdsn_depth);
 
        pr_debug("LIO_Target_ConfigFS: %s/%s Set CmdSN Window: %u for"
                "InitiatorName: %s\n", config_item_name(wwn_ci),
@@ -1593,28 +1590,30 @@ static int lio_tpg_check_prot_fabric_only(
 }
 
 /*
- * Called with spin_lock_bh(struct se_portal_group->session_lock) held..
- *
- * Also, this function calls iscsit_inc_session_usage_count() on the
+ * This function calls iscsit_inc_session_usage_count() on the
  * struct iscsi_session in question.
  */
 static int lio_tpg_shutdown_session(struct se_session *se_sess)
 {
        struct iscsi_session *sess = se_sess->fabric_sess_ptr;
+       struct se_portal_group *se_tpg = &sess->tpg->tpg_se_tpg;
 
+       spin_lock_bh(&se_tpg->session_lock);
        spin_lock(&sess->conn_lock);
        if (atomic_read(&sess->session_fall_back_to_erl0) ||
            atomic_read(&sess->session_logout) ||
            (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
                spin_unlock(&sess->conn_lock);
+               spin_unlock_bh(&se_tpg->session_lock);
                return 0;
        }
        atomic_set(&sess->session_reinstatement, 1);
        spin_unlock(&sess->conn_lock);
 
        iscsit_stop_time2retain_timer(sess);
-       iscsit_stop_session(sess, 1, 1);
+       spin_unlock_bh(&se_tpg->session_lock);
 
+       iscsit_stop_session(sess, 1, 1);
        return 1;
 }
 
index 2e561de..9214c9d 100644 (file)
@@ -160,8 +160,7 @@ static int iscsit_handle_r2t_snack(
                        " protocol error.\n", cmd->init_task_tag, begrun,
                        (begrun + runlength), cmd->acked_data_sn);
 
-                       return iscsit_reject_cmd(cmd,
-                                       ISCSI_REASON_PROTOCOL_ERROR, buf);
+               return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
        }
 
        if (runlength) {
@@ -628,8 +627,8 @@ int iscsit_dataout_datapduinorder_no_fbit(
                        if (cmd->pdu_list[i].seq_no == pdu->seq_no) {
                                if (!first_pdu)
                                        first_pdu = &cmd->pdu_list[i];
-                                xfer_len += cmd->pdu_list[i].length;
-                                pdu_count++;
+                               xfer_len += cmd->pdu_list[i].length;
+                               pdu_count++;
                        } else if (pdu_count)
                                break;
                }
index 2cbea2a..3a1f9a7 100644 (file)
@@ -1668,7 +1668,7 @@ void iscsi_set_session_parameters(
                                param->value);
                } else if (!strcmp(param->name, INITIALR2T)) {
                        ops->InitialR2T = !strcmp(param->value, YES);
-                        pr_debug("InitialR2T:                   %s\n",
+                       pr_debug("InitialR2T:                   %s\n",
                                param->value);
                } else if (!strcmp(param->name, IMMEDIATEDATA)) {
                        ops->ImmediateData = !strcmp(param->value, YES);
index 11320df..3d63705 100644 (file)
@@ -82,7 +82,7 @@ int iscsit_tmr_task_warm_reset(
                pr_err("TMR Opcode TARGET_WARM_RESET authorization"
                        " failed for Initiator Node: %s\n",
                        sess->se_sess->se_node_acl->initiatorname);
-                return -1;
+               return -1;
        }
        /*
         * Do the real work in transport_generic_do_tmr().
index 23c95cd..0814e58 100644 (file)
@@ -590,16 +590,6 @@ int iscsit_tpg_del_network_portal(
        return iscsit_tpg_release_np(tpg_np, tpg, np);
 }
 
-int iscsit_tpg_set_initiator_node_queue_depth(
-       struct iscsi_portal_group *tpg,
-       unsigned char *initiatorname,
-       u32 queue_depth,
-       int force)
-{
-       return core_tpg_set_initiator_node_queue_depth(&tpg->tpg_se_tpg,
-               initiatorname, queue_depth, force);
-}
-
 int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
 {
        unsigned char buf1[256], buf2[256], *none = NULL;
index 9db32bd..2da2119 100644 (file)
@@ -26,8 +26,6 @@ extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_gr
                        int);
 extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *,
                        struct iscsi_tpg_np *);
-extern int iscsit_tpg_set_initiator_node_queue_depth(struct iscsi_portal_group *,
-                       unsigned char *, u32, int);
 extern int iscsit_ta_authentication(struct iscsi_portal_group *, u32);
 extern int iscsit_ta_login_timeout(struct iscsi_portal_group *, u32);
 extern int iscsit_ta_netif_timeout(struct iscsi_portal_group *, u32);
index 4fb0eca..d41a5c3 100644 (file)
@@ -1036,12 +1036,26 @@ static ssize_t tcm_loop_tpg_transport_status_store(struct config_item *item,
        return -EINVAL;
 }
 
+static ssize_t tcm_loop_tpg_address_show(struct config_item *item,
+                                        char *page)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+       struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
+                       struct tcm_loop_tpg, tl_se_tpg);
+       struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
+
+       return snprintf(page, PAGE_SIZE, "%d:0:%d\n",
+                       tl_hba->sh->host_no, tl_tpg->tl_tpgt);
+}
+
 CONFIGFS_ATTR(tcm_loop_tpg_, nexus);
 CONFIGFS_ATTR(tcm_loop_tpg_, transport_status);
+CONFIGFS_ATTR_RO(tcm_loop_tpg_, address);
 
 static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
        &tcm_loop_tpg_attr_nexus,
        &tcm_loop_tpg_attr_transport_status,
+       &tcm_loop_tpg_attr_address,
        NULL,
 };
 
index 35f7d31..3072f1a 100644 (file)
@@ -39,8 +39,6 @@
 
 #include "sbp_target.h"
 
-static const struct target_core_fabric_ops sbp_ops;
-
 /* FireWire address region for management and command block address handlers */
 static const struct fw_address_region sbp_register_region = {
        .start  = CSR_REGISTER_BASE + 0x10000,
index b9b9ffd..3327c49 100644 (file)
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(target_depend_item);
 
 void target_undepend_item(struct config_item *item)
 {
-       return configfs_undepend_item(&target_core_fabrics, item);
+       return configfs_undepend_item(item);
 }
 EXPORT_SYMBOL(target_undepend_item);
 
@@ -499,6 +499,7 @@ DEF_CONFIGFS_ATTRIB_SHOW(max_unmap_lba_count);
 DEF_CONFIGFS_ATTRIB_SHOW(max_unmap_block_desc_count);
 DEF_CONFIGFS_ATTRIB_SHOW(unmap_granularity);
 DEF_CONFIGFS_ATTRIB_SHOW(unmap_granularity_alignment);
+DEF_CONFIGFS_ATTRIB_SHOW(unmap_zeroes_data);
 DEF_CONFIGFS_ATTRIB_SHOW(max_write_same_len);
 
 #define DEF_CONFIGFS_ATTRIB_STORE_U32(_name)                           \
@@ -548,7 +549,8 @@ static ssize_t _name##_store(struct config_item *item, const char *page,\
                size_t count)                                           \
 {                                                                      \
        printk_once(KERN_WARNING                                        \
-               "ignoring deprecated ##_name## attribute\n");   \
+               "ignoring deprecated %s attribute\n",                   \
+               __stringify(_name));                                    \
        return count;                                                   \
 }
 
@@ -866,6 +868,39 @@ static ssize_t emulate_rest_reord_store(struct config_item *item,
        return count;
 }
 
+static ssize_t unmap_zeroes_data_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct se_dev_attrib *da = to_attrib(item);
+       bool flag;
+       int ret;
+
+       ret = strtobool(page, &flag);
+       if (ret < 0)
+               return ret;
+
+       if (da->da_dev->export_count) {
+               pr_err("dev[%p]: Unable to change SE Device"
+                      " unmap_zeroes_data while export_count is %d\n",
+                      da->da_dev, da->da_dev->export_count);
+               return -EINVAL;
+       }
+       /*
+        * We expect this value to be non-zero when generic Block Layer
+        * Discard supported is detected iblock_configure_device().
+        */
+       if (flag && !da->max_unmap_block_desc_count) {
+               pr_err("dev[%p]: Thin Provisioning LBPRZ will not be set"
+                      " because max_unmap_block_desc_count is zero\n",
+                      da->da_dev);
+               return -ENOSYS;
+       }
+       da->unmap_zeroes_data = flag;
+       pr_debug("dev[%p]: SE Device Thin Provisioning LBPRZ bit: %d\n",
+                da->da_dev, flag);
+       return 0;
+}
+
 /*
  * Note, this can only be called on unexported SE Device Object.
  */
@@ -998,6 +1033,7 @@ CONFIGFS_ATTR(, max_unmap_lba_count);
 CONFIGFS_ATTR(, max_unmap_block_desc_count);
 CONFIGFS_ATTR(, unmap_granularity);
 CONFIGFS_ATTR(, unmap_granularity_alignment);
+CONFIGFS_ATTR(, unmap_zeroes_data);
 CONFIGFS_ATTR(, max_write_same_len);
 
 /*
@@ -1034,6 +1070,7 @@ struct configfs_attribute *sbc_attrib_attrs[] = {
        &attr_max_unmap_block_desc_count,
        &attr_unmap_granularity,
        &attr_unmap_granularity_alignment,
+       &attr_unmap_zeroes_data,
        &attr_max_write_same_len,
        NULL,
 };
@@ -1980,14 +2017,14 @@ static ssize_t target_dev_lba_map_store(struct config_item *item,
        struct se_device *dev = to_device(item);
        struct t10_alua_lba_map *lba_map = NULL;
        struct list_head lba_list;
-       char *map_entries, *ptr;
+       char *map_entries, *orig, *ptr;
        char state;
        int pg_num = -1, pg;
        int ret = 0, num = 0, pg_id, alua_state;
        unsigned long start_lba = -1, end_lba = -1;
        unsigned long segment_size = -1, segment_mult = -1;
 
-       map_entries = kstrdup(page, GFP_KERNEL);
+       orig = map_entries = kstrdup(page, GFP_KERNEL);
        if (!map_entries)
                return -ENOMEM;
 
@@ -2085,7 +2122,7 @@ out:
        } else
                core_alua_set_lba_map(dev, &lba_list,
                                      segment_size, segment_mult);
-       kfree(map_entries);
+       kfree(orig);
        return count;
 }
 
index 88ea4e4..cacd97a 100644 (file)
@@ -813,6 +813,8 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
        dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT;
        dev->dev_attrib.unmap_granularity_alignment =
                                DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
+       dev->dev_attrib.unmap_zeroes_data =
+                               DA_UNMAP_ZEROES_DATA_DEFAULT;
        dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN;
 
        xcopy_lun = &dev->xcopy_lun;
index f29c691..5a2899f 100644 (file)
@@ -138,6 +138,8 @@ static int iblock_configure_device(struct se_device *dev)
                                q->limits.discard_granularity >> 9;
                dev->dev_attrib.unmap_granularity_alignment =
                                q->limits.discard_alignment;
+               dev->dev_attrib.unmap_zeroes_data =
+                               q->limits.discard_zeroes_data;
 
                pr_debug("IBLOCK: BLOCK Discard support available,"
                                " disabled by default\n");
@@ -613,9 +615,9 @@ iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio)
        }
 
        bip = bio_integrity_alloc(bio, GFP_NOIO, cmd->t_prot_nents);
-       if (!bip) {
+       if (IS_ERR(bip)) {
                pr_err("Unable to allocate bio_integrity_payload\n");
-               return -ENOMEM;
+               return PTR_ERR(bip);
        }
 
        bip->bip_iter.bi_size = (cmd->data_length / dev->dev_attrib.block_size) *
index e793311..b179573 100644 (file)
@@ -1457,8 +1457,7 @@ static void core_scsi3_nodeacl_undepend_item(struct se_node_acl *nacl)
 static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve)
 {
        struct se_lun_acl *lun_acl;
-       struct se_node_acl *nacl;
-       struct se_portal_group *tpg;
+
        /*
         * For nacl->dynamic_node_acl=1
         */
@@ -1467,17 +1466,13 @@ static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve)
        if (!lun_acl)
                return 0;
 
-       nacl = lun_acl->se_lun_nacl;
-       tpg = nacl->se_tpg;
-
        return target_depend_item(&lun_acl->se_lun_group.cg_item);
 }
 
 static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
 {
        struct se_lun_acl *lun_acl;
-       struct se_node_acl *nacl;
-       struct se_portal_group *tpg;
+
        /*
         * For nacl->dynamic_node_acl=1
         */
@@ -1487,8 +1482,6 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
                kref_put(&se_deve->pr_kref, target_pr_kref_release);
                return;
        }
-       nacl = lun_acl->se_lun_nacl;
-       tpg = nacl->se_tpg;
 
        target_undepend_item(&lun_acl->se_lun_group.cg_item);
        kref_put(&se_deve->pr_kref, target_pr_kref_release);
index 98698d8..a9057aa 100644 (file)
@@ -141,9 +141,17 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
         * Set Thin Provisioning Enable bit following sbc3r22 in section
         * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
         */
-       if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws)
+       if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws) {
                buf[14] |= 0x80;
 
+               /*
+                * LBPRZ signifies that zeroes will be read back from an LBA after
+                * an UNMAP or WRITE SAME w/ unmap bit (sbc3r36 5.16.2)
+                */
+               if (dev->dev_attrib.unmap_zeroes_data)
+                       buf[14] |= 0x40;
+       }
+
        rbuf = transport_kmap_data_sg(cmd);
        if (rbuf) {
                memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
index 9413e1a..0aa47ba 100644 (file)
@@ -635,6 +635,18 @@ spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
        if (dev->dev_attrib.emulate_tpws != 0)
                buf[5] |= 0x40 | 0x20;
 
+       /*
+        * The unmap_zeroes_data set means that the underlying device supports
+        * REQ_DISCARD and has the discard_zeroes_data bit set. This satisfies
+        * the SBC requirements for LBPRZ, meaning that a subsequent read
+        * will return zeroes after an UNMAP or WRITE SAME (16) to an LBA
+        * See sbc4r36 6.6.4.
+        */
+       if (((dev->dev_attrib.emulate_tpu != 0) ||
+            (dev->dev_attrib.emulate_tpws != 0)) &&
+            (dev->dev_attrib.unmap_zeroes_data != 0))
+               buf[5] |= 0x04;
+
        return 0;
 }
 
index 28fb301..fcdcb11 100644 (file)
@@ -201,7 +201,7 @@ static void core_tmr_drain_tmr_list(
                /*
                 * If this function was called with a valid pr_res_key
                 * parameter (eg: for PROUT PREEMPT_AND_ABORT service action
-                * skip non regisration key matching TMRs.
+                * skip non registration key matching TMRs.
                 */
                if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
                        continue;
index 5fb9dd7..3608b1b 100644 (file)
@@ -75,9 +75,21 @@ struct se_node_acl *core_tpg_get_initiator_node_acl(
        unsigned char *initiatorname)
 {
        struct se_node_acl *acl;
-
+       /*
+        * Obtain se_node_acl->acl_kref using fabric driver provided
+        * initiatorname[] during node acl endpoint lookup driven by
+        * new se_session login.
+        *
+        * The reference is held until se_session shutdown -> release
+        * occurs via fabric driver invoked transport_deregister_session()
+        * or transport_free_session() code.
+        */
        mutex_lock(&tpg->acl_node_mutex);
        acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname);
+       if (acl) {
+               if (!kref_get_unless_zero(&acl->acl_kref))
+                       acl = NULL;
+       }
        mutex_unlock(&tpg->acl_node_mutex);
 
        return acl;
@@ -157,28 +169,25 @@ void core_tpg_add_node_to_devs(
        mutex_unlock(&tpg->tpg_lun_mutex);
 }
 
-/*      core_set_queue_depth_for_node():
- *
- *
- */
-static int core_set_queue_depth_for_node(
-       struct se_portal_group *tpg,
-       struct se_node_acl *acl)
+static void
+target_set_nacl_queue_depth(struct se_portal_group *tpg,
+                           struct se_node_acl *acl, u32 queue_depth)
 {
+       acl->queue_depth = queue_depth;
+
        if (!acl->queue_depth) {
-               pr_err("Queue depth for %s Initiator Node: %s is 0,"
+               pr_warn("Queue depth for %s Initiator Node: %s is 0,"
                        "defaulting to 1.\n", tpg->se_tpg_tfo->get_fabric_name(),
                        acl->initiatorname);
                acl->queue_depth = 1;
        }
-
-       return 0;
 }
 
 static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg,
                const unsigned char *initiatorname)
 {
        struct se_node_acl *acl;
+       u32 queue_depth;
 
        acl = kzalloc(max(sizeof(*acl), tpg->se_tpg_tfo->node_acl_size),
                        GFP_KERNEL);
@@ -193,24 +202,20 @@ static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg,
        spin_lock_init(&acl->nacl_sess_lock);
        mutex_init(&acl->lun_entry_mutex);
        atomic_set(&acl->acl_pr_ref_count, 0);
+
        if (tpg->se_tpg_tfo->tpg_get_default_depth)
-               acl->queue_depth = tpg->se_tpg_tfo->tpg_get_default_depth(tpg);
+               queue_depth = tpg->se_tpg_tfo->tpg_get_default_depth(tpg);
        else
-               acl->queue_depth = 1;
+               queue_depth = 1;
+       target_set_nacl_queue_depth(tpg, acl, queue_depth);
+
        snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname);
        acl->se_tpg = tpg;
        acl->acl_index = scsi_get_new_index(SCSI_AUTH_INTR_INDEX);
 
        tpg->se_tpg_tfo->set_default_node_attributes(acl);
 
-       if (core_set_queue_depth_for_node(tpg, acl) < 0)
-               goto out_free_acl;
-
        return acl;
-
-out_free_acl:
-       kfree(acl);
-       return NULL;
 }
 
 static void target_add_node_acl(struct se_node_acl *acl)
@@ -219,7 +224,6 @@ static void target_add_node_acl(struct se_node_acl *acl)
 
        mutex_lock(&tpg->acl_node_mutex);
        list_add_tail(&acl->acl_list, &tpg->acl_node_list);
-       tpg->num_node_acls++;
        mutex_unlock(&tpg->acl_node_mutex);
 
        pr_debug("%s_TPG[%hu] - Added %s ACL with TCQ Depth: %d for %s"
@@ -232,6 +236,25 @@ static void target_add_node_acl(struct se_node_acl *acl)
                acl->initiatorname);
 }
 
+bool target_tpg_has_node_acl(struct se_portal_group *tpg,
+                            const char *initiatorname)
+{
+       struct se_node_acl *acl;
+       bool found = false;
+
+       mutex_lock(&tpg->acl_node_mutex);
+       list_for_each_entry(acl, &tpg->acl_node_list, acl_list) {
+               if (!strcmp(acl->initiatorname, initiatorname)) {
+                       found = true;
+                       break;
+               }
+       }
+       mutex_unlock(&tpg->acl_node_mutex);
+
+       return found;
+}
+EXPORT_SYMBOL(target_tpg_has_node_acl);
+
 struct se_node_acl *core_tpg_check_initiator_node_acl(
        struct se_portal_group *tpg,
        unsigned char *initiatorname)
@@ -248,6 +271,15 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
        acl = target_alloc_node_acl(tpg, initiatorname);
        if (!acl)
                return NULL;
+       /*
+        * When allocating a dynamically generated node_acl, go ahead
+        * and take the extra kref now before returning to the fabric
+        * driver caller.
+        *
+        * Note this reference will be released at session shutdown
+        * time within transport_free_session() code.
+        */
+       kref_get(&acl->acl_kref);
        acl->dynamic_node_acl = 1;
 
        /*
@@ -318,7 +350,6 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
                acl->dynamic_node_acl = 0;
        }
        list_del(&acl->acl_list);
-       tpg->num_node_acls--;
        mutex_unlock(&tpg->acl_node_mutex);
 
        spin_lock_irqsave(&acl->nacl_sess_lock, flags);
@@ -329,7 +360,8 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
                if (sess->sess_tearing_down != 0)
                        continue;
 
-               target_get_session(sess);
+               if (!target_get_session(sess))
+                       continue;
                list_move(&sess->sess_acl_list, &sess_list);
        }
        spin_unlock_irqrestore(&acl->nacl_sess_lock, flags);
@@ -366,108 +398,52 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
  *
  */
 int core_tpg_set_initiator_node_queue_depth(
-       struct se_portal_group *tpg,
-       unsigned char *initiatorname,
-       u32 queue_depth,
-       int force)
+       struct se_node_acl *acl,
+       u32 queue_depth)
 {
-       struct se_session *sess, *init_sess = NULL;
-       struct se_node_acl *acl;
+       LIST_HEAD(sess_list);
+       struct se_portal_group *tpg = acl->se_tpg;
+       struct se_session *sess, *sess_tmp;
        unsigned long flags;
-       int dynamic_acl = 0;
-
-       mutex_lock(&tpg->acl_node_mutex);
-       acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname);
-       if (!acl) {
-               pr_err("Access Control List entry for %s Initiator"
-                       " Node %s does not exists for TPG %hu, ignoring"
-                       " request.\n", tpg->se_tpg_tfo->get_fabric_name(),
-                       initiatorname, tpg->se_tpg_tfo->tpg_get_tag(tpg));
-               mutex_unlock(&tpg->acl_node_mutex);
-               return -ENODEV;
-       }
-       if (acl->dynamic_node_acl) {
-               acl->dynamic_node_acl = 0;
-               dynamic_acl = 1;
-       }
-       mutex_unlock(&tpg->acl_node_mutex);
-
-       spin_lock_irqsave(&tpg->session_lock, flags);
-       list_for_each_entry(sess, &tpg->tpg_sess_list, sess_list) {
-               if (sess->se_node_acl != acl)
-                       continue;
-
-               if (!force) {
-                       pr_err("Unable to change queue depth for %s"
-                               " Initiator Node: %s while session is"
-                               " operational.  To forcefully change the queue"
-                               " depth and force session reinstatement"
-                               " use the \"force=1\" parameter.\n",
-                               tpg->se_tpg_tfo->get_fabric_name(), initiatorname);
-                       spin_unlock_irqrestore(&tpg->session_lock, flags);
-
-                       mutex_lock(&tpg->acl_node_mutex);
-                       if (dynamic_acl)
-                               acl->dynamic_node_acl = 1;
-                       mutex_unlock(&tpg->acl_node_mutex);
-                       return -EEXIST;
-               }
-               /*
-                * Determine if the session needs to be closed by our context.
-                */
-               if (!tpg->se_tpg_tfo->shutdown_session(sess))
-                       continue;
-
-               init_sess = sess;
-               break;
-       }
+       int rc;
 
        /*
         * User has requested to change the queue depth for a Initiator Node.
         * Change the value in the Node's struct se_node_acl, and call
-        * core_set_queue_depth_for_node() to add the requested queue depth.
-        *
-        * Finally call  tpg->se_tpg_tfo->close_session() to force session
-        * reinstatement to occur if there is an active session for the
-        * $FABRIC_MOD Initiator Node in question.
+        * target_set_nacl_queue_depth() to set the new queue depth.
         */
-       acl->queue_depth = queue_depth;
+       target_set_nacl_queue_depth(tpg, acl, queue_depth);
+
+       spin_lock_irqsave(&acl->nacl_sess_lock, flags);
+       list_for_each_entry_safe(sess, sess_tmp, &acl->acl_sess_list,
+                                sess_acl_list) {
+               if (sess->sess_tearing_down != 0)
+                       continue;
+               if (!target_get_session(sess))
+                       continue;
+               spin_unlock_irqrestore(&acl->nacl_sess_lock, flags);
 
-       if (core_set_queue_depth_for_node(tpg, acl) < 0) {
-               spin_unlock_irqrestore(&tpg->session_lock, flags);
                /*
-                * Force session reinstatement if
-                * core_set_queue_depth_for_node() failed, because we assume
-                * the $FABRIC_MOD has already the set session reinstatement
-                * bit from tpg->se_tpg_tfo->shutdown_session() called above.
+                * Finally call tpg->se_tpg_tfo->close_session() to force session
+                * reinstatement to occur if there is an active session for the
+                * $FABRIC_MOD Initiator Node in question.
                 */
-               if (init_sess)
-                       tpg->se_tpg_tfo->close_session(init_sess);
-
-               mutex_lock(&tpg->acl_node_mutex);
-               if (dynamic_acl)
-                       acl->dynamic_node_acl = 1;
-               mutex_unlock(&tpg->acl_node_mutex);
-               return -EINVAL;
+               rc = tpg->se_tpg_tfo->shutdown_session(sess);
+               target_put_session(sess);
+               if (!rc) {
+                       spin_lock_irqsave(&acl->nacl_sess_lock, flags);
+                       continue;
+               }
+               target_put_session(sess);
+               spin_lock_irqsave(&acl->nacl_sess_lock, flags);
        }
-       spin_unlock_irqrestore(&tpg->session_lock, flags);
-       /*
-        * If the $FABRIC_MOD session for the Initiator Node ACL exists,
-        * forcefully shutdown the $FABRIC_MOD session/nexus.
-        */
-       if (init_sess)
-               tpg->se_tpg_tfo->close_session(init_sess);
+       spin_unlock_irqrestore(&acl->nacl_sess_lock, flags);
 
        pr_debug("Successfully changed queue depth to: %d for Initiator"
-               " Node: %s on %s Target Portal Group: %u\n", queue_depth,
-               initiatorname, tpg->se_tpg_tfo->get_fabric_name(),
+               " Node: %s on %s Target Portal Group: %u\n", acl->queue_depth,
+               acl->initiatorname, tpg->se_tpg_tfo->get_fabric_name(),
                tpg->se_tpg_tfo->tpg_get_tag(tpg));
 
-       mutex_lock(&tpg->acl_node_mutex);
-       if (dynamic_acl)
-               acl->dynamic_node_acl = 1;
-       mutex_unlock(&tpg->acl_node_mutex);
-
        return 0;
 }
 EXPORT_SYMBOL(core_tpg_set_initiator_node_queue_depth);
@@ -595,7 +571,6 @@ int core_tpg_deregister(struct se_portal_group *se_tpg)
         */
        list_for_each_entry_safe(nacl, nacl_tmp, &node_list, acl_list) {
                list_del(&nacl->acl_list);
-               se_tpg->num_node_acls--;
 
                core_tpg_wait_for_nacl_pr_ref(nacl);
                core_free_device_list_for_node(nacl, se_tpg);
index 4fdcee2..9f3608e 100644 (file)
@@ -341,7 +341,6 @@ void __transport_register_session(
                                        &buf[0], PR_REG_ISID_LEN);
                        se_sess->sess_bin_isid = get_unaligned_be64(&buf[0]);
                }
-               kref_get(&se_nacl->acl_kref);
 
                spin_lock_irq(&se_nacl->nacl_sess_lock);
                /*
@@ -384,9 +383,9 @@ static void target_release_session(struct kref *kref)
        se_tpg->se_tpg_tfo->close_session(se_sess);
 }
 
-void target_get_session(struct se_session *se_sess)
+int target_get_session(struct se_session *se_sess)
 {
-       kref_get(&se_sess->sess_kref);
+       return kref_get_unless_zero(&se_sess->sess_kref);
 }
 EXPORT_SYMBOL(target_get_session);
 
@@ -432,6 +431,7 @@ void target_put_nacl(struct se_node_acl *nacl)
 {
        kref_put(&nacl->acl_kref, target_complete_nacl);
 }
+EXPORT_SYMBOL(target_put_nacl);
 
 void transport_deregister_session_configfs(struct se_session *se_sess)
 {
@@ -464,6 +464,15 @@ EXPORT_SYMBOL(transport_deregister_session_configfs);
 
 void transport_free_session(struct se_session *se_sess)
 {
+       struct se_node_acl *se_nacl = se_sess->se_node_acl;
+       /*
+        * Drop the se_node_acl->nacl_kref obtained from within
+        * core_tpg_get_initiator_node_acl().
+        */
+       if (se_nacl) {
+               se_sess->se_node_acl = NULL;
+               target_put_nacl(se_nacl);
+       }
        if (se_sess->sess_cmd_map) {
                percpu_ida_destroy(&se_sess->sess_tag_pool);
                kvfree(se_sess->sess_cmd_map);
@@ -478,7 +487,7 @@ void transport_deregister_session(struct se_session *se_sess)
        const struct target_core_fabric_ops *se_tfo;
        struct se_node_acl *se_nacl;
        unsigned long flags;
-       bool comp_nacl = true, drop_nacl = false;
+       bool drop_nacl = false;
 
        if (!se_tpg) {
                transport_free_session(se_sess);
@@ -502,7 +511,6 @@ void transport_deregister_session(struct se_session *se_sess)
        if (se_nacl && se_nacl->dynamic_node_acl) {
                if (!se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
                        list_del(&se_nacl->acl_list);
-                       se_tpg->num_node_acls--;
                        drop_nacl = true;
                }
        }
@@ -511,18 +519,16 @@ void transport_deregister_session(struct se_session *se_sess)
        if (drop_nacl) {
                core_tpg_wait_for_nacl_pr_ref(se_nacl);
                core_free_device_list_for_node(se_nacl, se_tpg);
+               se_sess->se_node_acl = NULL;
                kfree(se_nacl);
-               comp_nacl = false;
        }
        pr_debug("TARGET_CORE[%s]: Deregistered fabric_sess\n",
                se_tpg->se_tpg_tfo->get_fabric_name());
        /*
         * If last kref is dropping now for an explicit NodeACL, awake sleeping
         * ->acl_free_comp caller to wakeup configfs se_node_acl->acl_group
-        * removal context.
+        * removal context from within transport_free_session() code.
         */
-       if (se_nacl && comp_nacl)
-               target_put_nacl(se_nacl);
 
        transport_free_session(se_sess);
 }
@@ -715,7 +721,10 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
        cmd->transport_state |= (CMD_T_COMPLETE | CMD_T_ACTIVE);
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-       queue_work(target_completion_wq, &cmd->work);
+       if (cmd->cpuid == -1)
+               queue_work(target_completion_wq, &cmd->work);
+       else
+               queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work);
 }
 EXPORT_SYMBOL(target_complete_cmd);
 
@@ -1309,7 +1318,7 @@ EXPORT_SYMBOL(target_setup_cmd_from_cdb);
 
 /*
  * Used by fabric module frontends to queue tasks directly.
- * Many only be used from process context only
+ * May only be used from process context.
  */
 int transport_handle_cdb_direct(
        struct se_cmd *cmd)
@@ -1582,7 +1591,7 @@ static void target_complete_tmr_failure(struct work_struct *work)
 int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
                unsigned char *sense, u64 unpacked_lun,
                void *fabric_tmr_ptr, unsigned char tm_type,
-               gfp_t gfp, unsigned int tag, int flags)
+               gfp_t gfp, u64 tag, int flags)
 {
        struct se_portal_group *se_tpg;
        int ret;
index 5e6d6cb..dd600e5 100644 (file)
@@ -152,6 +152,7 @@ static struct genl_family tcmu_genl_family = {
        .maxattr = TCMU_ATTR_MAX,
        .mcgrps = tcmu_mcgrps,
        .n_mcgrps = ARRAY_SIZE(tcmu_mcgrps),
+       .netnsok = true,
 };
 
 static struct tcmu_cmd *tcmu_alloc_cmd(struct se_cmd *se_cmd)
@@ -194,7 +195,7 @@ static struct tcmu_cmd *tcmu_alloc_cmd(struct se_cmd *se_cmd)
 
 static inline void tcmu_flush_dcache_range(void *vaddr, size_t size)
 {
-       unsigned long offset = (unsigned long) vaddr & ~PAGE_MASK;
+       unsigned long offset = offset_in_page(vaddr);
 
        size = round_up(size+offset, PAGE_SIZE);
        vaddr -= offset;
@@ -840,7 +841,7 @@ static int tcmu_netlink_event(enum tcmu_genl_cmd cmd, const char *name, int mino
 
        genlmsg_end(skb, msg_header);
 
-       ret = genlmsg_multicast(&tcmu_genl_family, skb, 0,
+       ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0,
                                TCMU_MCGRP_CONFIG, GFP_KERNEL);
 
        /* We don't care if no one is listening */
@@ -917,8 +918,10 @@ static int tcmu_configure_device(struct se_device *dev)
        if (ret)
                goto err_register;
 
+       /* User can set hw_block_size before enable the device */
+       if (dev->dev_attrib.hw_block_size == 0)
+               dev->dev_attrib.hw_block_size = 512;
        /* Other attributes can be configured in userspace */
-       dev->dev_attrib.hw_block_size = 512;
        dev->dev_attrib.hw_max_sectors = 128;
        dev->dev_attrib.hw_queue_depth = 128;
 
index 39909da..c30003b 100644 (file)
@@ -166,7 +166,6 @@ void ft_aborted_task(struct se_cmd *);
  */
 void ft_recv_req(struct ft_sess *, struct fc_frame *);
 struct ft_tpg *ft_lport_find_tpg(struct fc_lport *);
-struct ft_node_acl *ft_acl_get(struct ft_tpg *, struct fc_rport_priv *);
 
 void ft_recv_write_data(struct ft_cmd *, struct fc_frame *);
 void ft_dump_cmd(struct ft_cmd *, const char *caller);
index 85aeaa0..4d375e9 100644 (file)
@@ -171,9 +171,31 @@ static ssize_t ft_nacl_node_name_store(struct config_item *item,
 CONFIGFS_ATTR(ft_nacl_, node_name);
 CONFIGFS_ATTR(ft_nacl_, port_name);
 
+static ssize_t ft_nacl_tag_show(struct config_item *item,
+               char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%s", acl_to_nacl(item)->acl_tag);
+}
+
+static ssize_t ft_nacl_tag_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct se_node_acl *se_nacl = acl_to_nacl(item);
+       int ret;
+
+       ret = core_tpg_set_initiator_node_tag(se_nacl->se_tpg, se_nacl, page);
+
+       if (ret < 0)
+               return ret;
+       return count;
+}
+
+CONFIGFS_ATTR(ft_nacl_, tag);
+
 static struct configfs_attribute *ft_nacl_base_attrs[] = {
        &ft_nacl_attr_port_name,
        &ft_nacl_attr_node_name,
+       &ft_nacl_attr_tag,
        NULL,
 };
 
@@ -198,31 +220,6 @@ static int ft_init_nodeacl(struct se_node_acl *nacl, const char *name)
        return 0;
 }
 
-struct ft_node_acl *ft_acl_get(struct ft_tpg *tpg, struct fc_rport_priv *rdata)
-{
-       struct ft_node_acl *found = NULL;
-       struct ft_node_acl *acl;
-       struct se_portal_group *se_tpg = &tpg->se_tpg;
-       struct se_node_acl *se_acl;
-
-       mutex_lock(&se_tpg->acl_node_mutex);
-       list_for_each_entry(se_acl, &se_tpg->acl_node_list, acl_list) {
-               acl = container_of(se_acl, struct ft_node_acl, se_node_acl);
-               pr_debug("acl %p port_name %llx\n",
-                       acl, (unsigned long long)acl->node_auth.port_name);
-               if (acl->node_auth.port_name == rdata->ids.port_name ||
-                   acl->node_auth.node_name == rdata->ids.node_name) {
-                       pr_debug("acl %p port_name %llx matched\n", acl,
-                                   (unsigned long long)rdata->ids.port_name);
-                       found = acl;
-                       /* XXX need to hold onto ACL */
-                       break;
-               }
-       }
-       mutex_unlock(&se_tpg->acl_node_mutex);
-       return found;
-}
-
 /*
  * local_port port_group (tpg) ops.
  */
index 847c1aa..6f7c65a 100644 (file)
@@ -154,9 +154,9 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
                        BUG_ON(!page);
                        from = kmap_atomic(page + (mem_off >> PAGE_SHIFT));
                        page_addr = from;
-                       from += mem_off & ~PAGE_MASK;
+                       from += offset_in_page(mem_off);
                        tlen = min(tlen, (size_t)(PAGE_SIZE -
-                                               (mem_off & ~PAGE_MASK)));
+                                               offset_in_page(mem_off)));
                        memcpy(to, from, tlen);
                        kunmap_atomic(page_addr);
                        to += tlen;
@@ -314,9 +314,9 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
 
                to = kmap_atomic(page + (mem_off >> PAGE_SHIFT));
                page_addr = to;
-               to += mem_off & ~PAGE_MASK;
+               to += offset_in_page(mem_off);
                tlen = min(tlen, (size_t)(PAGE_SIZE -
-                                         (mem_off & ~PAGE_MASK)));
+                                         offset_in_page(mem_off)));
                memcpy(to, from, tlen);
                kunmap_atomic(page_addr);
 
index 7b934ea..e19f4c5 100644 (file)
@@ -191,10 +191,15 @@ out:
  * Caller holds ft_lport_lock.
  */
 static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
-                                     struct ft_node_acl *acl)
+                                     struct fc_rport_priv *rdata)
 {
+       struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
+       struct se_node_acl *se_acl;
        struct ft_sess *sess;
        struct hlist_head *head;
+       unsigned char initiatorname[TRANSPORT_IQN_LEN];
+
+       ft_format_wwn(&initiatorname[0], TRANSPORT_IQN_LEN, rdata->ids.port_name);
 
        head = &tport->hash[ft_sess_hash(port_id)];
        hlist_for_each_entry_rcu(sess, head, hash)
@@ -212,7 +217,14 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
                kfree(sess);
                return NULL;
        }
-       sess->se_sess->se_node_acl = &acl->se_node_acl;
+
+       se_acl = core_tpg_get_initiator_node_acl(se_tpg, &initiatorname[0]);
+       if (!se_acl) {
+               transport_free_session(sess->se_sess);
+               kfree(sess);
+               return NULL;
+       }
+       sess->se_sess->se_node_acl = se_acl;
        sess->tport = tport;
        sess->port_id = port_id;
        kref_init(&sess->kref); /* ref for table entry */
@@ -221,7 +233,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 
        pr_debug("port_id %x sess %p\n", port_id, sess);
 
-       transport_register_session(&tport->tpg->se_tpg, &acl->se_node_acl,
+       transport_register_session(&tport->tpg->se_tpg, se_acl,
                                   sess->se_sess, sess);
        return sess;
 }
@@ -260,6 +272,14 @@ static struct ft_sess *ft_sess_delete(struct ft_tport *tport, u32 port_id)
        return NULL;
 }
 
+static void ft_close_sess(struct ft_sess *sess)
+{
+       transport_deregister_session_configfs(sess->se_sess);
+       target_sess_cmd_list_set_waiting(sess->se_sess);
+       target_wait_for_sess_cmds(sess->se_sess);
+       ft_sess_put(sess);
+}
+
 /*
  * Delete all sessions from tport.
  * Caller holds ft_lport_lock.
@@ -273,8 +293,7 @@ static void ft_sess_delete_all(struct ft_tport *tport)
             head < &tport->hash[FT_SESS_HASH_SIZE]; head++) {
                hlist_for_each_entry_rcu(sess, head, hash) {
                        ft_sess_unhash(sess);
-                       transport_deregister_session_configfs(sess->se_sess);
-                       ft_sess_put(sess);      /* release from table */
+                       ft_close_sess(sess);    /* release from table */
                }
        }
 }
@@ -313,8 +332,7 @@ void ft_sess_close(struct se_session *se_sess)
        pr_debug("port_id %x\n", port_id);
        ft_sess_unhash(sess);
        mutex_unlock(&ft_lport_lock);
-       transport_deregister_session_configfs(se_sess);
-       ft_sess_put(sess);
+       ft_close_sess(sess);
        /* XXX Send LOGO or PRLO */
        synchronize_rcu();              /* let transport deregister happen */
 }
@@ -343,17 +361,12 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len,
 {
        struct ft_tport *tport;
        struct ft_sess *sess;
-       struct ft_node_acl *acl;
        u32 fcp_parm;
 
        tport = ft_tport_get(rdata->local_port);
        if (!tport)
                goto not_target;        /* not a target for this local port */
 
-       acl = ft_acl_get(tport->tpg, rdata);
-       if (!acl)
-               goto not_target;        /* no target for this remote */
-
        if (!rspp)
                goto fill;
 
@@ -375,7 +388,7 @@ static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len,
                spp->spp_flags |= FC_SPP_EST_IMG_PAIR;
                if (!(fcp_parm & FCP_SPPF_INIT_FCN))
                        return FC_SPP_RESP_CONF;
-               sess = ft_sess_create(tport, rdata->ids.port_id, acl);
+               sess = ft_sess_create(tport, rdata->ids.port_id, rdata);
                if (!sess)
                        return FC_SPP_RESP_RES;
                if (!sess->params)
@@ -460,8 +473,7 @@ static void ft_prlo(struct fc_rport_priv *rdata)
                return;
        }
        mutex_unlock(&ft_lport_lock);
-       transport_deregister_session_configfs(sess->se_sess);
-       ft_sess_put(sess);              /* release from table */
+       ft_close_sess(sess);            /* release from table */
        rdata->prli_count--;
        /* XXX TBD - clearing actions.  unit attn, see 4.10 */
 }
index ccc0ad0..36fa724 100644 (file)
 /* Braswell thermal reporting device */
 #define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC
 
+/* Broxton thermal reporting device */
+#define PCI_DEVICE_ID_PROC_BXT0_THERMAL  0x0A8C
+#define PCI_DEVICE_ID_PROC_BXT1_THERMAL  0x1A8C
+#define PCI_DEVICE_ID_PROC_BXTX_THERMAL  0x4A8C
+#define PCI_DEVICE_ID_PROC_BXTP_THERMAL  0x5A8C
+
 struct power_config {
        u32     index;
        u32     min_uw;
@@ -404,6 +410,10 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_HSB_THERMAL)},
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_SKL_THERMAL)},
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BSW_THERMAL)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT0_THERMAL)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXT1_THERMAL)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTX_THERMAL)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BXTP_THERMAL)},
        { 0, },
 };
 
index 50c7da7..00d81af 100644 (file)
@@ -136,7 +136,7 @@ struct pch_dev_ops {
 
 
 /* dev ops for Wildcat Point */
-static struct pch_dev_ops pch_dev_ops_wpt = {
+static const struct pch_dev_ops pch_dev_ops_wpt = {
        .hw_init = pch_wpt_init,
        .get_temp = pch_wpt_get_temp,
 };
index 13d01ed..44b9c48 100644 (file)
@@ -75,11 +75,11 @@ struct rcar_thermal_priv {
 #define rcar_has_irq_support(priv)     ((priv)->common->base)
 #define rcar_id_to_shift(priv)         ((priv)->id * 8)
 
-#ifdef DEBUG
-# define rcar_force_update_temp(priv)  1
-#else
-# define rcar_force_update_temp(priv)  0
-#endif
+static const struct of_device_id rcar_thermal_dt_ids[] = {
+       { .compatible = "renesas,rcar-thermal", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
 
 /*
  *             basic functions
@@ -203,14 +203,26 @@ err_out_unlock:
 static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
 {
        struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
+       int tmp;
+       int ret;
 
-       if (!rcar_has_irq_support(priv) || rcar_force_update_temp(priv))
-               rcar_thermal_update_temp(priv);
+       ret = rcar_thermal_update_temp(priv);
+       if (ret < 0)
+               return ret;
 
        mutex_lock(&priv->lock);
-       *temp =  MCELSIUS((priv->ctemp * 5) - 65);
+       tmp =  MCELSIUS((priv->ctemp * 5) - 65);
        mutex_unlock(&priv->lock);
 
+       if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) {
+               struct device *dev = rcar_priv_to_dev(priv);
+
+               dev_err(dev, "it couldn't measure temperature correctly\n");
+               return -EIO;
+       }
+
+       *temp = tmp;
+
        return 0;
 }
 
@@ -288,6 +300,9 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable)
        unsigned long flags;
        u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */
 
+       if (!rcar_has_irq_support(priv))
+               return;
+
        spin_lock_irqsave(&common->lock, flags);
 
        rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask);
@@ -299,11 +314,15 @@ static void rcar_thermal_work(struct work_struct *work)
 {
        struct rcar_thermal_priv *priv;
        int cctemp, nctemp;
+       int ret;
 
        priv = container_of(work, struct rcar_thermal_priv, work.work);
 
        rcar_thermal_get_temp(priv->zone, &cctemp);
-       rcar_thermal_update_temp(priv);
+       ret = rcar_thermal_update_temp(priv);
+       if (ret < 0)
+               return;
+
        rcar_thermal_irq_enable(priv);
 
        rcar_thermal_get_temp(priv->zone, &nctemp);
@@ -368,8 +387,7 @@ static int rcar_thermal_remove(struct platform_device *pdev)
        struct rcar_thermal_priv *priv;
 
        rcar_thermal_for_each_priv(priv, common) {
-               if (rcar_has_irq_support(priv))
-                       rcar_thermal_irq_disable(priv);
+               rcar_thermal_irq_disable(priv);
                thermal_zone_device_unregister(priv->zone);
        }
 
@@ -441,7 +459,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
                mutex_init(&priv->lock);
                INIT_LIST_HEAD(&priv->list);
                INIT_DELAYED_WORK(&priv->work, rcar_thermal_work);
-               rcar_thermal_update_temp(priv);
+               ret = rcar_thermal_update_temp(priv);
+               if (ret < 0)
+                       goto error_unregister;
 
                priv->zone = thermal_zone_device_register("rcar_thermal",
                                                1, 0, priv,
@@ -453,8 +473,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
                        goto error_unregister;
                }
 
-               if (rcar_has_irq_support(priv))
-                       rcar_thermal_irq_enable(priv);
+               rcar_thermal_irq_enable(priv);
 
                list_move_tail(&priv->list, &common->head);
 
@@ -484,12 +503,6 @@ error_unregister:
        return ret;
 }
 
-static const struct of_device_id rcar_thermal_dt_ids[] = {
-       { .compatible = "renesas,rcar-thermal", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
-
 static struct platform_driver rcar_thermal_driver = {
        .driver = {
                .name   = "rcar_thermal",
index e845841..b58e3fb 100644 (file)
@@ -38,7 +38,7 @@ enum tshut_mode {
 };
 
 /**
- * the system Temperature Sensors tshut(tshut) polarity
+ * The system Temperature Sensors tshut(tshut) polarity
  * the bit 8 is tshut polarity.
  * 0: low active, 1: high active
  */
@@ -57,10 +57,10 @@ enum sensor_id {
 };
 
 /**
-* The conversion table has the adc value and temperature.
-* ADC_DECREMENT is the adc value decremnet.(e.g. v2_code_table)
-* ADC_INCREMNET is the adc value incremnet.(e.g. v3_code_table)
-*/
+ * The conversion table has the adc value and temperature.
+ * ADC_DECREMENT: the adc value is of diminishing.(e.g. v2_code_table)
+ * ADC_INCREMENT: the adc value is incremental.(e.g. v3_code_table)
+ */
 enum adc_sort_mode {
        ADC_DECREMENT = 0,
        ADC_INCREMENT,
@@ -72,16 +72,17 @@ enum adc_sort_mode {
  */
 #define SOC_MAX_SENSORS        2
 
+/**
+ * struct chip_tsadc_table: hold information about chip-specific differences
+ * @id: conversion table
+ * @length: size of conversion table
+ * @data_mask: mask to apply on data inputs
+ * @mode: sort mode of this adc variant (incrementing or decrementing)
+ */
 struct chip_tsadc_table {
        const struct tsadc_table *id;
-
-       /* the array table size*/
        unsigned int length;
-
-       /* that analogic mask data */
        u32 data_mask;
-
-       /* the sort mode is adc value that increment or decrement in table */
        enum adc_sort_mode mode;
 };
 
@@ -153,6 +154,7 @@ struct rockchip_thermal_data {
 #define TSADCV2_SHUT_2GPIO_SRC_EN(chn)         BIT(4 + (chn))
 #define TSADCV2_SHUT_2CRU_SRC_EN(chn)          BIT(8 + (chn))
 
+#define TSADCV1_INT_PD_CLEAR_MASK              ~BIT(16)
 #define TSADCV2_INT_PD_CLEAR_MASK              ~BIT(8)
 
 #define TSADCV2_DATA_MASK                      0xfff
@@ -168,6 +170,51 @@ struct tsadc_table {
        int temp;
 };
 
+/**
+ * Note:
+ * Code to Temperature mapping of the Temperature sensor is a piece wise linear
+ * curve.Any temperature, code faling between to 2 give temperatures can be
+ * linearly interpolated.
+ * Code to Temperature mapping should be updated based on sillcon results.
+ */
+static const struct tsadc_table v1_code_table[] = {
+       {TSADCV3_DATA_MASK, -40000},
+       {436, -40000},
+       {431, -35000},
+       {426, -30000},
+       {421, -25000},
+       {416, -20000},
+       {411, -15000},
+       {406, -10000},
+       {401, -5000},
+       {395, 0},
+       {390, 5000},
+       {385, 10000},
+       {380, 15000},
+       {375, 20000},
+       {370, 25000},
+       {364, 30000},
+       {359, 35000},
+       {354, 40000},
+       {349, 45000},
+       {343, 50000},
+       {338, 55000},
+       {333, 60000},
+       {328, 65000},
+       {322, 70000},
+       {317, 75000},
+       {312, 80000},
+       {307, 85000},
+       {301, 90000},
+       {296, 95000},
+       {291, 100000},
+       {286, 105000},
+       {280, 110000},
+       {275, 115000},
+       {270, 120000},
+       {264, 125000},
+};
+
 static const struct tsadc_table v2_code_table[] = {
        {TSADCV2_DATA_MASK, -40000},
        {3800, -40000},
@@ -245,6 +292,44 @@ static const struct tsadc_table v3_code_table[] = {
        {TSADCV3_DATA_MASK, 125000},
 };
 
+static const struct tsadc_table v4_code_table[] = {
+       {TSADCV3_DATA_MASK, -40000},
+       {431, -40000},
+       {426, -35000},
+       {421, -30000},
+       {415, -25000},
+       {410, -20000},
+       {405, -15000},
+       {399, -10000},
+       {394, -5000},
+       {389, 0},
+       {383, 5000},
+       {378, 10000},
+       {373, 15000},
+       {367, 20000},
+       {362, 25000},
+       {357, 30000},
+       {351, 35000},
+       {346, 40000},
+       {340, 45000},
+       {335, 50000},
+       {330, 55000},
+       {324, 60000},
+       {319, 65000},
+       {313, 70000},
+       {308, 75000},
+       {302, 80000},
+       {297, 85000},
+       {291, 90000},
+       {286, 95000},
+       {281, 100000},
+       {275, 105000},
+       {270, 110000},
+       {264, 115000},
+       {259, 120000},
+       {253, 125000},
+};
+
 static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table,
                                   int temp)
 {
@@ -368,6 +453,14 @@ static void rk_tsadcv2_initialize(void __iomem *regs,
                       regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
 }
 
+static void rk_tsadcv1_irq_ack(void __iomem *regs)
+{
+       u32 val;
+
+       val = readl_relaxed(regs + TSADCV2_INT_PD);
+       writel_relaxed(val & TSADCV1_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);
+}
+
 static void rk_tsadcv2_irq_ack(void __iomem *regs)
 {
        u32 val;
@@ -429,6 +522,29 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
        writel_relaxed(val, regs + TSADCV2_INT_EN);
 }
 
+static const struct rockchip_tsadc_chip rk3228_tsadc_data = {
+       .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
+       .chn_num = 1, /* one channel for tsadc */
+
+       .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
+       .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
+       .tshut_temp = 95000,
+
+       .initialize = rk_tsadcv2_initialize,
+       .irq_ack = rk_tsadcv1_irq_ack,
+       .control = rk_tsadcv2_control,
+       .get_temp = rk_tsadcv2_get_temp,
+       .set_tshut_temp = rk_tsadcv2_tshut_temp,
+       .set_tshut_mode = rk_tsadcv2_tshut_mode,
+
+       .table = {
+               .id = v1_code_table,
+               .length = ARRAY_SIZE(v1_code_table),
+               .data_mask = TSADCV3_DATA_MASK,
+               .mode = ADC_DECREMENT,
+       },
+};
+
 static const struct rockchip_tsadc_chip rk3288_tsadc_data = {
        .chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */
        .chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */
@@ -477,7 +593,35 @@ static const struct rockchip_tsadc_chip rk3368_tsadc_data = {
        },
 };
 
+static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
+       .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
+       .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */
+       .chn_num = 2, /* two channels for tsadc */
+
+       .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */
+       .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
+       .tshut_temp = 95000,
+
+       .initialize = rk_tsadcv2_initialize,
+       .irq_ack = rk_tsadcv1_irq_ack,
+       .control = rk_tsadcv2_control,
+       .get_temp = rk_tsadcv2_get_temp,
+       .set_tshut_temp = rk_tsadcv2_tshut_temp,
+       .set_tshut_mode = rk_tsadcv2_tshut_mode,
+
+       .table = {
+               .id = v4_code_table,
+               .length = ARRAY_SIZE(v4_code_table),
+               .data_mask = TSADCV3_DATA_MASK,
+               .mode = ADC_DECREMENT,
+       },
+};
+
 static const struct of_device_id of_rockchip_thermal_match[] = {
+       {
+               .compatible = "rockchip,rk3228-tsadc",
+               .data = (void *)&rk3228_tsadc_data,
+       },
        {
                .compatible = "rockchip,rk3288-tsadc",
                .data = (void *)&rk3288_tsadc_data,
@@ -486,6 +630,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = {
                .compatible = "rockchip,rk3368-tsadc",
                .data = (void *)&rk3368_tsadc_data,
        },
+       {
+               .compatible = "rockchip,rk3399-tsadc",
+               .data = (void *)&rk3399_tsadc_data,
+       },
        { /* end */ },
 };
 MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match);
@@ -617,7 +765,7 @@ rockchip_thermal_register_sensor(struct platform_device *pdev,
        return 0;
 }
 
-/*
+/**
  * Reset TSADC Controller, reset all tsadc registers.
  */
 static void rockchip_thermal_reset_controller(struct reset_control *reset)
index 2f9f708..ea9366a 100644 (file)
@@ -63,6 +63,19 @@ static unsigned long get_target_state(struct thermal_instance *instance,
        next_target = instance->target;
        dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
 
+       if (!instance->initialized) {
+               if (throttle) {
+                       next_target = (cur_state + 1) >= instance->upper ?
+                                       instance->upper :
+                                       ((cur_state + 1) < instance->lower ?
+                                       instance->lower : (cur_state + 1));
+               } else {
+                       next_target = THERMAL_NO_TARGET;
+               }
+
+               return next_target;
+       }
+
        switch (trend) {
        case THERMAL_TREND_RAISING:
                if (throttle) {
@@ -149,7 +162,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
                dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
                                        old_target, (int)instance->target);
 
-               if (old_target == instance->target)
+               if (instance->initialized && old_target == instance->target)
                        continue;
 
                /* Activate a passive thermal instance */
@@ -161,7 +174,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
                        instance->target == THERMAL_NO_TARGET)
                        update_passive_instance(tz, trip_type, -1);
 
-
+               instance->initialized = true;
                instance->cdev->updated = false; /* cdev needs update */
        }
 
index d9e525c..a0a8fd1 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/of.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
+#include <linux/suspend.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/thermal.h>
@@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list);
 static DEFINE_MUTEX(thermal_list_lock);
 static DEFINE_MUTEX(thermal_governor_lock);
 
+static atomic_t in_suspend;
+
 static struct thermal_governor *def_governor;
 
 static struct thermal_governor *__find_governor(const char *name)
@@ -532,14 +535,31 @@ static void update_temperature(struct thermal_zone_device *tz)
        mutex_unlock(&tz->lock);
 
        trace_thermal_temperature(tz);
-       dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
-                               tz->last_temperature, tz->temperature);
+       if (tz->last_temperature == THERMAL_TEMP_INVALID)
+               dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
+                       tz->temperature);
+       else
+               dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
+                       tz->last_temperature, tz->temperature);
+}
+
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
+{
+       struct thermal_instance *pos;
+
+       tz->temperature = THERMAL_TEMP_INVALID;
+       tz->passive = 0;
+       list_for_each_entry(pos, &tz->thermal_instances, tz_node)
+               pos->initialized = false;
 }
 
 void thermal_zone_device_update(struct thermal_zone_device *tz)
 {
        int count;
 
+       if (atomic_read(&in_suspend))
+               return;
+
        if (!tz->ops->get_temp)
                return;
 
@@ -676,8 +696,12 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        ret = tz->ops->set_trip_temp(tz, trip, temperature);
+       if (ret)
+               return ret;
 
-       return ret ? ret : count;
+       thermal_zone_device_update(tz);
+
+       return count;
 }
 
 static ssize_t
@@ -1321,6 +1345,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
        if (!result) {
                list_add_tail(&dev->tz_node, &tz->thermal_instances);
                list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
+               atomic_set(&tz->need_update, 1);
        }
        mutex_unlock(&cdev->lock);
        mutex_unlock(&tz->lock);
@@ -1430,6 +1455,7 @@ __thermal_cooling_device_register(struct device_node *np,
                                  const struct thermal_cooling_device_ops *ops)
 {
        struct thermal_cooling_device *cdev;
+       struct thermal_zone_device *pos = NULL;
        int result;
 
        if (type && strlen(type) >= THERMAL_NAME_LENGTH)
@@ -1474,6 +1500,12 @@ __thermal_cooling_device_register(struct device_node *np,
        /* Update binding information for 'this' new cdev */
        bind_cdev(cdev);
 
+       mutex_lock(&thermal_list_lock);
+       list_for_each_entry(pos, &thermal_tz_list, node)
+               if (atomic_cmpxchg(&pos->need_update, 1, 0))
+                       thermal_zone_device_update(pos);
+       mutex_unlock(&thermal_list_lock);
+
        return cdev;
 }
 
@@ -1806,6 +1838,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
        tz->trips = trips;
        tz->passive_delay = passive_delay;
        tz->polling_delay = polling_delay;
+       /* A new thermal zone needs to be updated anyway. */
+       atomic_set(&tz->need_update, 1);
 
        dev_set_name(&tz->device, "thermal_zone%d", tz->id);
        result = device_register(&tz->device);
@@ -1900,7 +1934,10 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
 
        INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
 
-       thermal_zone_device_update(tz);
+       thermal_zone_device_reset(tz);
+       /* Update the new thermal zone and mark it as already updated. */
+       if (atomic_cmpxchg(&tz->need_update, 1, 0))
+               thermal_zone_device_update(tz);
 
        return tz;
 
@@ -2140,6 +2177,36 @@ static void thermal_unregister_governors(void)
        thermal_gov_power_allocator_unregister();
 }
 
+static int thermal_pm_notify(struct notifier_block *nb,
+                               unsigned long mode, void *_unused)
+{
+       struct thermal_zone_device *tz;
+
+       switch (mode) {
+       case PM_HIBERNATION_PREPARE:
+       case PM_RESTORE_PREPARE:
+       case PM_SUSPEND_PREPARE:
+               atomic_set(&in_suspend, 1);
+               break;
+       case PM_POST_HIBERNATION:
+       case PM_POST_RESTORE:
+       case PM_POST_SUSPEND:
+               atomic_set(&in_suspend, 0);
+               list_for_each_entry(tz, &thermal_tz_list, node) {
+                       thermal_zone_device_reset(tz);
+                       thermal_zone_device_update(tz);
+               }
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+static struct notifier_block thermal_pm_nb = {
+       .notifier_call = thermal_pm_notify,
+};
+
 static int __init thermal_init(void)
 {
        int result;
@@ -2160,6 +2227,11 @@ static int __init thermal_init(void)
        if (result)
                goto exit_netlink;
 
+       result = register_pm_notifier(&thermal_pm_nb);
+       if (result)
+               pr_warn("Thermal: Can not register suspend notifier, return %d\n",
+                       result);
+
        return 0;
 
 exit_netlink:
@@ -2179,6 +2251,7 @@ error:
 
 static void __exit thermal_exit(void)
 {
+       unregister_pm_notifier(&thermal_pm_nb);
        of_thermal_destroy_zones();
        genetlink_exit();
        class_unregister(&thermal_class);
index d7ac1fc..749d41a 100644 (file)
@@ -41,6 +41,7 @@ struct thermal_instance {
        struct thermal_zone_device *tz;
        struct thermal_cooling_device *cdev;
        int trip;
+       bool initialized;
        unsigned long upper;    /* Highest cooling state for this trip point */
        unsigned long lower;    /* Lowest cooling state for this trip point */
        unsigned long target;   /* expected cooling state */
index d27a0c6..39721ec 100644 (file)
@@ -1047,7 +1047,7 @@ config SERIAL_SGI_IOC3
          say Y or M.  Otherwise, say N.
 
 config SERIAL_MSM
-       bool "MSM on-chip serial port support"
+       tristate "MSM on-chip serial port support"
        depends on ARCH_QCOM
        select SERIAL_CORE
 
index 460c855..14718a9 100644 (file)
@@ -249,12 +249,18 @@ static int usb_port_runtime_suspend(struct device *dev)
 
        return retval;
 }
+
+static int usb_port_prepare(struct device *dev)
+{
+       return 1;
+}
 #endif
 
 static const struct dev_pm_ops usb_port_pm_ops = {
 #ifdef CONFIG_PM
        .runtime_suspend =      usb_port_runtime_suspend,
        .runtime_resume =       usb_port_runtime_resume,
+       .prepare =              usb_port_prepare,
 #endif
 };
 
index 77e4c9b..ebb29ca 100644 (file)
@@ -311,7 +311,13 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
 
 static int usb_dev_prepare(struct device *dev)
 {
-       return 0;               /* Implement eventually? */
+       struct usb_device *udev = to_usb_device(dev);
+
+       /* Return 0 if the current wakeup setting is wrong, otherwise 1 */
+       if (udev->do_remote_wakeup != device_may_wakeup(dev))
+               return 0;
+
+       return 1;
 }
 
 static void usb_dev_complete(struct device *dev)
index be5aab9..af5d922 100644 (file)
@@ -205,6 +205,9 @@ config USB_F_HID
 config USB_F_PRINTER
        tristate
 
+config USB_F_TCM
+       tristate
+
 choice
        tristate "USB Gadget Drivers"
        default USB_ETH
@@ -457,6 +460,20 @@ config USB_CONFIGFS_F_PRINTER
          For more information, see Documentation/usb/gadget_printer.txt
          which includes sample code for accessing the device file.
 
+config USB_CONFIGFS_F_TCM
+       bool "USB Gadget Target Fabric"
+       depends on TARGET_CORE
+       depends on USB_CONFIGFS
+       select USB_LIBCOMPOSITE
+       select USB_F_TCM
+       help
+         This fabric is a USB gadget component. Two USB protocols are
+         supported that is BBB or BOT (Bulk Only Transport) and UAS
+         (USB Attached SCSI). BOT is advertised on alternative
+         interface 0 (primary) and UAS is on alternative interface 1.
+         Both protocols can work on USB2.0 and USB3.0.
+         UAS utilizes the USB 3.0 feature called streams support.
+
 source "drivers/usb/gadget/legacy/Kconfig"
 
 endchoice
index bd7def5..cb8c225 100644 (file)
@@ -44,3 +44,5 @@ usb_f_hid-y                   := f_hid.o
 obj-$(CONFIG_USB_F_HID)                += usb_f_hid.o
 usb_f_printer-y                        := f_printer.o
 obj-$(CONFIG_USB_F_PRINTER)    += usb_f_printer.o
+usb_f_tcm-y                    := f_tcm.o
+obj-$(CONFIG_USB_F_TCM)                += usb_f_tcm.o
index 0fbfb2b..26ccad5 100644 (file)
@@ -673,7 +673,7 @@ printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync)
        unsigned long           flags;
        int                     tx_list_empty;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        spin_lock_irqsave(&dev->lock, flags);
        tx_list_empty = (likely(list_empty(&dev->tx_reqs)));
        spin_unlock_irqrestore(&dev->lock, flags);
@@ -683,7 +683,7 @@ printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync)
                wait_event_interruptible(dev->tx_flush_wait,
                                (likely(list_empty(&dev->tx_reqs_active))));
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return 0;
 }
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
new file mode 100644 (file)
index 0000000..bad007b
--- /dev/null
@@ -0,0 +1,2381 @@
+/* Target based USB-Gadget
+ *
+ * UAS protocol handling, target callbacks, configfs handling,
+ * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling.
+ *
+ * Author: Sebastian Andrzej Siewior <bigeasy at linutronix dot de>
+ * License: GPLv2 as published by FSF.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/configfs.h>
+#include <linux/ctype.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/composite.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/storage.h>
+#include <scsi/scsi_tcq.h>
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+#include <asm/unaligned.h>
+
+#include "tcm.h"
+#include "u_tcm.h"
+#include "configfs.h"
+
+#define TPG_INSTANCES          1
+
+struct tpg_instance {
+       struct usb_function_instance    *func_inst;
+       struct usbg_tpg                 *tpg;
+};
+
+static struct tpg_instance tpg_instances[TPG_INSTANCES];
+
+static DEFINE_MUTEX(tpg_instances_lock);
+
+static inline struct f_uas *to_f_uas(struct usb_function *f)
+{
+       return container_of(f, struct f_uas, function);
+}
+
+static void usbg_cmd_release(struct kref *);
+
+static inline void usbg_cleanup_cmd(struct usbg_cmd *cmd)
+{
+       kref_put(&cmd->ref, usbg_cmd_release);
+}
+
+/* Start bot.c code */
+
+static int bot_enqueue_cmd_cbw(struct f_uas *fu)
+{
+       int ret;
+
+       if (fu->flags & USBG_BOT_CMD_PEND)
+               return 0;
+
+       ret = usb_ep_queue(fu->ep_out, fu->cmd.req, GFP_ATOMIC);
+       if (!ret)
+               fu->flags |= USBG_BOT_CMD_PEND;
+       return ret;
+}
+
+static void bot_status_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct usbg_cmd *cmd = req->context;
+       struct f_uas *fu = cmd->fu;
+
+       usbg_cleanup_cmd(cmd);
+       if (req->status < 0) {
+               pr_err("ERR %s(%d)\n", __func__, __LINE__);
+               return;
+       }
+
+       /* CSW completed, wait for next CBW */
+       bot_enqueue_cmd_cbw(fu);
+}
+
+static void bot_enqueue_sense_code(struct f_uas *fu, struct usbg_cmd *cmd)
+{
+       struct bulk_cs_wrap *csw = &fu->bot_status.csw;
+       int ret;
+       unsigned int csw_stat;
+
+       csw_stat = cmd->csw_code;
+       csw->Tag = cmd->bot_tag;
+       csw->Status = csw_stat;
+       fu->bot_status.req->context = cmd;
+       ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_ATOMIC);
+       if (ret)
+               pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret);
+}
+
+static void bot_err_compl(struct usb_ep *ep, struct usb_request *req)
+{
+       struct usbg_cmd *cmd = req->context;
+       struct f_uas *fu = cmd->fu;
+
+       if (req->status < 0)
+               pr_err("ERR %s(%d)\n", __func__, __LINE__);
+
+       if (cmd->data_len) {
+               if (cmd->data_len > ep->maxpacket) {
+                       req->length = ep->maxpacket;
+                       cmd->data_len -= ep->maxpacket;
+               } else {
+                       req->length = cmd->data_len;
+                       cmd->data_len = 0;
+               }
+
+               usb_ep_queue(ep, req, GFP_ATOMIC);
+               return;
+       }
+       bot_enqueue_sense_code(fu, cmd);
+}
+
+static void bot_send_bad_status(struct usbg_cmd *cmd)
+{
+       struct f_uas *fu = cmd->fu;
+       struct bulk_cs_wrap *csw = &fu->bot_status.csw;
+       struct usb_request *req;
+       struct usb_ep *ep;
+
+       csw->Residue = cpu_to_le32(cmd->data_len);
+
+       if (cmd->data_len) {
+               if (cmd->is_read) {
+                       ep = fu->ep_in;
+                       req = fu->bot_req_in;
+               } else {
+                       ep = fu->ep_out;
+                       req = fu->bot_req_out;
+               }
+
+               if (cmd->data_len > fu->ep_in->maxpacket) {
+                       req->length = ep->maxpacket;
+                       cmd->data_len -= ep->maxpacket;
+               } else {
+                       req->length = cmd->data_len;
+                       cmd->data_len = 0;
+               }
+               req->complete = bot_err_compl;
+               req->context = cmd;
+               req->buf = fu->cmd.buf;
+               usb_ep_queue(ep, req, GFP_KERNEL);
+       } else {
+               bot_enqueue_sense_code(fu, cmd);
+       }
+}
+
+static int bot_send_status(struct usbg_cmd *cmd, bool moved_data)
+{
+       struct f_uas *fu = cmd->fu;
+       struct bulk_cs_wrap *csw = &fu->bot_status.csw;
+       int ret;
+
+       if (cmd->se_cmd.scsi_status == SAM_STAT_GOOD) {
+               if (!moved_data && cmd->data_len) {
+                       /*
+                        * the host wants to move data, we don't. Fill / empty
+                        * the pipe and then send the csw with reside set.
+                        */
+                       cmd->csw_code = US_BULK_STAT_OK;
+                       bot_send_bad_status(cmd);
+                       return 0;
+               }
+
+               csw->Tag = cmd->bot_tag;
+               csw->Residue = cpu_to_le32(0);
+               csw->Status = US_BULK_STAT_OK;
+               fu->bot_status.req->context = cmd;
+
+               ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_KERNEL);
+               if (ret)
+                       pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret);
+       } else {
+               cmd->csw_code = US_BULK_STAT_FAIL;
+               bot_send_bad_status(cmd);
+       }
+       return 0;
+}
+
+/*
+ * Called after command (no data transfer) or after the write (to device)
+ * operation is completed
+ */
+static int bot_send_status_response(struct usbg_cmd *cmd)
+{
+       bool moved_data = false;
+
+       if (!cmd->is_read)
+               moved_data = true;
+       return bot_send_status(cmd, moved_data);
+}
+
+/* Read request completed, now we have to send the CSW */
+static void bot_read_compl(struct usb_ep *ep, struct usb_request *req)
+{
+       struct usbg_cmd *cmd = req->context;
+
+       if (req->status < 0)
+               pr_err("ERR %s(%d)\n", __func__, __LINE__);
+
+       bot_send_status(cmd, true);
+}
+
+static int bot_send_read_response(struct usbg_cmd *cmd)
+{
+       struct f_uas *fu = cmd->fu;
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct usb_gadget *gadget = fuas_to_gadget(fu);
+       int ret;
+
+       if (!cmd->data_len) {
+               cmd->csw_code = US_BULK_STAT_PHASE;
+               bot_send_bad_status(cmd);
+               return 0;
+       }
+
+       if (!gadget->sg_supported) {
+               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC);
+               if (!cmd->data_buf)
+                       return -ENOMEM;
+
+               sg_copy_to_buffer(se_cmd->t_data_sg,
+                               se_cmd->t_data_nents,
+                               cmd->data_buf,
+                               se_cmd->data_length);
+
+               fu->bot_req_in->buf = cmd->data_buf;
+       } else {
+               fu->bot_req_in->buf = NULL;
+               fu->bot_req_in->num_sgs = se_cmd->t_data_nents;
+               fu->bot_req_in->sg = se_cmd->t_data_sg;
+       }
+
+       fu->bot_req_in->complete = bot_read_compl;
+       fu->bot_req_in->length = se_cmd->data_length;
+       fu->bot_req_in->context = cmd;
+       ret = usb_ep_queue(fu->ep_in, fu->bot_req_in, GFP_ATOMIC);
+       if (ret)
+               pr_err("%s(%d)\n", __func__, __LINE__);
+       return 0;
+}
+
+static void usbg_data_write_cmpl(struct usb_ep *, struct usb_request *);
+static int usbg_prepare_w_request(struct usbg_cmd *, struct usb_request *);
+
+static int bot_send_write_request(struct usbg_cmd *cmd)
+{
+       struct f_uas *fu = cmd->fu;
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct usb_gadget *gadget = fuas_to_gadget(fu);
+       int ret;
+
+       init_completion(&cmd->write_complete);
+       cmd->fu = fu;
+
+       if (!cmd->data_len) {
+               cmd->csw_code = US_BULK_STAT_PHASE;
+               return -EINVAL;
+       }
+
+       if (!gadget->sg_supported) {
+               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL);
+               if (!cmd->data_buf)
+                       return -ENOMEM;
+
+               fu->bot_req_out->buf = cmd->data_buf;
+       } else {
+               fu->bot_req_out->buf = NULL;
+               fu->bot_req_out->num_sgs = se_cmd->t_data_nents;
+               fu->bot_req_out->sg = se_cmd->t_data_sg;
+       }
+
+       fu->bot_req_out->complete = usbg_data_write_cmpl;
+       fu->bot_req_out->length = se_cmd->data_length;
+       fu->bot_req_out->context = cmd;
+
+       ret = usbg_prepare_w_request(cmd, fu->bot_req_out);
+       if (ret)
+               goto cleanup;
+       ret = usb_ep_queue(fu->ep_out, fu->bot_req_out, GFP_KERNEL);
+       if (ret)
+               pr_err("%s(%d)\n", __func__, __LINE__);
+
+       wait_for_completion(&cmd->write_complete);
+       target_execute_cmd(se_cmd);
+cleanup:
+       return ret;
+}
+
+static int bot_submit_command(struct f_uas *, void *, unsigned int);
+
+static void bot_cmd_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_uas *fu = req->context;
+       int ret;
+
+       fu->flags &= ~USBG_BOT_CMD_PEND;
+
+       if (req->status < 0)
+               return;
+
+       ret = bot_submit_command(fu, req->buf, req->actual);
+       if (ret)
+               pr_err("%s(%d): %d\n", __func__, __LINE__, ret);
+}
+
+static int bot_prepare_reqs(struct f_uas *fu)
+{
+       int ret;
+
+       fu->bot_req_in = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL);
+       if (!fu->bot_req_in)
+               goto err;
+
+       fu->bot_req_out = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL);
+       if (!fu->bot_req_out)
+               goto err_out;
+
+       fu->cmd.req = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL);
+       if (!fu->cmd.req)
+               goto err_cmd;
+
+       fu->bot_status.req = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL);
+       if (!fu->bot_status.req)
+               goto err_sts;
+
+       fu->bot_status.req->buf = &fu->bot_status.csw;
+       fu->bot_status.req->length = US_BULK_CS_WRAP_LEN;
+       fu->bot_status.req->complete = bot_status_complete;
+       fu->bot_status.csw.Signature = cpu_to_le32(US_BULK_CS_SIGN);
+
+       fu->cmd.buf = kmalloc(fu->ep_out->maxpacket, GFP_KERNEL);
+       if (!fu->cmd.buf)
+               goto err_buf;
+
+       fu->cmd.req->complete = bot_cmd_complete;
+       fu->cmd.req->buf = fu->cmd.buf;
+       fu->cmd.req->length = fu->ep_out->maxpacket;
+       fu->cmd.req->context = fu;
+
+       ret = bot_enqueue_cmd_cbw(fu);
+       if (ret)
+               goto err_queue;
+       return 0;
+err_queue:
+       kfree(fu->cmd.buf);
+       fu->cmd.buf = NULL;
+err_buf:
+       usb_ep_free_request(fu->ep_in, fu->bot_status.req);
+err_sts:
+       usb_ep_free_request(fu->ep_out, fu->cmd.req);
+       fu->cmd.req = NULL;
+err_cmd:
+       usb_ep_free_request(fu->ep_out, fu->bot_req_out);
+       fu->bot_req_out = NULL;
+err_out:
+       usb_ep_free_request(fu->ep_in, fu->bot_req_in);
+       fu->bot_req_in = NULL;
+err:
+       pr_err("BOT: endpoint setup failed\n");
+       return -ENOMEM;
+}
+
+static void bot_cleanup_old_alt(struct f_uas *fu)
+{
+       if (!(fu->flags & USBG_ENABLED))
+               return;
+
+       usb_ep_disable(fu->ep_in);
+       usb_ep_disable(fu->ep_out);
+
+       if (!fu->bot_req_in)
+               return;
+
+       usb_ep_free_request(fu->ep_in, fu->bot_req_in);
+       usb_ep_free_request(fu->ep_out, fu->bot_req_out);
+       usb_ep_free_request(fu->ep_out, fu->cmd.req);
+       usb_ep_free_request(fu->ep_out, fu->bot_status.req);
+
+       kfree(fu->cmd.buf);
+
+       fu->bot_req_in = NULL;
+       fu->bot_req_out = NULL;
+       fu->cmd.req = NULL;
+       fu->bot_status.req = NULL;
+       fu->cmd.buf = NULL;
+}
+
+static void bot_set_alt(struct f_uas *fu)
+{
+       struct usb_function *f = &fu->function;
+       struct usb_gadget *gadget = f->config->cdev->gadget;
+       int ret;
+
+       fu->flags = USBG_IS_BOT;
+
+       config_ep_by_speed(gadget, f, fu->ep_in);
+       ret = usb_ep_enable(fu->ep_in);
+       if (ret)
+               goto err_b_in;
+
+       config_ep_by_speed(gadget, f, fu->ep_out);
+       ret = usb_ep_enable(fu->ep_out);
+       if (ret)
+               goto err_b_out;
+
+       ret = bot_prepare_reqs(fu);
+       if (ret)
+               goto err_wq;
+       fu->flags |= USBG_ENABLED;
+       pr_info("Using the BOT protocol\n");
+       return;
+err_wq:
+       usb_ep_disable(fu->ep_out);
+err_b_out:
+       usb_ep_disable(fu->ep_in);
+err_b_in:
+       fu->flags = USBG_IS_BOT;
+}
+
+static int usbg_bot_setup(struct usb_function *f,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct f_uas *fu = to_f_uas(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+       u16 w_value = le16_to_cpu(ctrl->wValue);
+       u16 w_length = le16_to_cpu(ctrl->wLength);
+       int luns;
+       u8 *ret_lun;
+
+       switch (ctrl->bRequest) {
+       case US_BULK_GET_MAX_LUN:
+               if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS |
+                                       USB_RECIP_INTERFACE))
+                       return -ENOTSUPP;
+
+               if (w_length < 1)
+                       return -EINVAL;
+               if (w_value != 0)
+                       return -EINVAL;
+               luns = atomic_read(&fu->tpg->tpg_port_count);
+               if (!luns) {
+                       pr_err("No LUNs configured?\n");
+                       return -EINVAL;
+               }
+               /*
+                * If 4 LUNs are present we return 3 i.e. LUN 0..3 can be
+                * accessed. The upper limit is 0xf
+                */
+               luns--;
+               if (luns > 0xf) {
+                       pr_info_once("Limiting the number of luns to 16\n");
+                       luns = 0xf;
+               }
+               ret_lun = cdev->req->buf;
+               *ret_lun = luns;
+               cdev->req->length = 1;
+               return usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
+
+       case US_BULK_RESET_REQUEST:
+               /* XXX maybe we should remove previous requests for IN + OUT */
+               bot_enqueue_cmd_cbw(fu);
+               return 0;
+       }
+       return -ENOTSUPP;
+}
+
+/* Start uas.c code */
+
+static void uasp_cleanup_one_stream(struct f_uas *fu, struct uas_stream *stream)
+{
+       /* We have either all three allocated or none */
+       if (!stream->req_in)
+               return;
+
+       usb_ep_free_request(fu->ep_in, stream->req_in);
+       usb_ep_free_request(fu->ep_out, stream->req_out);
+       usb_ep_free_request(fu->ep_status, stream->req_status);
+
+       stream->req_in = NULL;
+       stream->req_out = NULL;
+       stream->req_status = NULL;
+}
+
+static void uasp_free_cmdreq(struct f_uas *fu)
+{
+       usb_ep_free_request(fu->ep_cmd, fu->cmd.req);
+       kfree(fu->cmd.buf);
+       fu->cmd.req = NULL;
+       fu->cmd.buf = NULL;
+}
+
+static void uasp_cleanup_old_alt(struct f_uas *fu)
+{
+       int i;
+
+       if (!(fu->flags & USBG_ENABLED))
+               return;
+
+       usb_ep_disable(fu->ep_in);
+       usb_ep_disable(fu->ep_out);
+       usb_ep_disable(fu->ep_status);
+       usb_ep_disable(fu->ep_cmd);
+
+       for (i = 0; i < UASP_SS_EP_COMP_NUM_STREAMS; i++)
+               uasp_cleanup_one_stream(fu, &fu->stream[i]);
+       uasp_free_cmdreq(fu);
+}
+
+static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req);
+
+static int uasp_prepare_r_request(struct usbg_cmd *cmd)
+{
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct f_uas *fu = cmd->fu;
+       struct usb_gadget *gadget = fuas_to_gadget(fu);
+       struct uas_stream *stream = cmd->stream;
+
+       if (!gadget->sg_supported) {
+               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC);
+               if (!cmd->data_buf)
+                       return -ENOMEM;
+
+               sg_copy_to_buffer(se_cmd->t_data_sg,
+                               se_cmd->t_data_nents,
+                               cmd->data_buf,
+                               se_cmd->data_length);
+
+               stream->req_in->buf = cmd->data_buf;
+       } else {
+               stream->req_in->buf = NULL;
+               stream->req_in->num_sgs = se_cmd->t_data_nents;
+               stream->req_in->sg = se_cmd->t_data_sg;
+       }
+
+       stream->req_in->complete = uasp_status_data_cmpl;
+       stream->req_in->length = se_cmd->data_length;
+       stream->req_in->context = cmd;
+
+       cmd->state = UASP_SEND_STATUS;
+       return 0;
+}
+
+static void uasp_prepare_status(struct usbg_cmd *cmd)
+{
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct sense_iu *iu = &cmd->sense_iu;
+       struct uas_stream *stream = cmd->stream;
+
+       cmd->state = UASP_QUEUE_COMMAND;
+       iu->iu_id = IU_ID_STATUS;
+       iu->tag = cpu_to_be16(cmd->tag);
+
+       /*
+        * iu->status_qual = cpu_to_be16(STATUS QUALIFIER SAM-4. Where R U?);
+        */
+       iu->len = cpu_to_be16(se_cmd->scsi_sense_length);
+       iu->status = se_cmd->scsi_status;
+       stream->req_status->context = cmd;
+       stream->req_status->length = se_cmd->scsi_sense_length + 16;
+       stream->req_status->buf = iu;
+       stream->req_status->complete = uasp_status_data_cmpl;
+}
+
+static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req)
+{
+       struct usbg_cmd *cmd = req->context;
+       struct uas_stream *stream = cmd->stream;
+       struct f_uas *fu = cmd->fu;
+       int ret;
+
+       if (req->status < 0)
+               goto cleanup;
+
+       switch (cmd->state) {
+       case UASP_SEND_DATA:
+               ret = uasp_prepare_r_request(cmd);
+               if (ret)
+                       goto cleanup;
+               ret = usb_ep_queue(fu->ep_in, stream->req_in, GFP_ATOMIC);
+               if (ret)
+                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
+               break;
+
+       case UASP_RECEIVE_DATA:
+               ret = usbg_prepare_w_request(cmd, stream->req_out);
+               if (ret)
+                       goto cleanup;
+               ret = usb_ep_queue(fu->ep_out, stream->req_out, GFP_ATOMIC);
+               if (ret)
+                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
+               break;
+
+       case UASP_SEND_STATUS:
+               uasp_prepare_status(cmd);
+               ret = usb_ep_queue(fu->ep_status, stream->req_status,
+                               GFP_ATOMIC);
+               if (ret)
+                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
+               break;
+
+       case UASP_QUEUE_COMMAND:
+               usbg_cleanup_cmd(cmd);
+               usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
+               break;
+
+       default:
+               BUG();
+       }
+       return;
+
+cleanup:
+       usbg_cleanup_cmd(cmd);
+}
+
+static int uasp_send_status_response(struct usbg_cmd *cmd)
+{
+       struct f_uas *fu = cmd->fu;
+       struct uas_stream *stream = cmd->stream;
+       struct sense_iu *iu = &cmd->sense_iu;
+
+       iu->tag = cpu_to_be16(cmd->tag);
+       stream->req_status->complete = uasp_status_data_cmpl;
+       stream->req_status->context = cmd;
+       cmd->fu = fu;
+       uasp_prepare_status(cmd);
+       return usb_ep_queue(fu->ep_status, stream->req_status, GFP_ATOMIC);
+}
+
+static int uasp_send_read_response(struct usbg_cmd *cmd)
+{
+       struct f_uas *fu = cmd->fu;
+       struct uas_stream *stream = cmd->stream;
+       struct sense_iu *iu = &cmd->sense_iu;
+       int ret;
+
+       cmd->fu = fu;
+
+       iu->tag = cpu_to_be16(cmd->tag);
+       if (fu->flags & USBG_USE_STREAMS) {
+
+               ret = uasp_prepare_r_request(cmd);
+               if (ret)
+                       goto out;
+               ret = usb_ep_queue(fu->ep_in, stream->req_in, GFP_ATOMIC);
+               if (ret) {
+                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
+                       kfree(cmd->data_buf);
+                       cmd->data_buf = NULL;
+               }
+
+       } else {
+
+               iu->iu_id = IU_ID_READ_READY;
+               iu->tag = cpu_to_be16(cmd->tag);
+
+               stream->req_status->complete = uasp_status_data_cmpl;
+               stream->req_status->context = cmd;
+
+               cmd->state = UASP_SEND_DATA;
+               stream->req_status->buf = iu;
+               stream->req_status->length = sizeof(struct iu);
+
+               ret = usb_ep_queue(fu->ep_status, stream->req_status,
+                               GFP_ATOMIC);
+               if (ret)
+                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
+       }
+out:
+       return ret;
+}
+
+static int uasp_send_write_request(struct usbg_cmd *cmd)
+{
+       struct f_uas *fu = cmd->fu;
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct uas_stream *stream = cmd->stream;
+       struct sense_iu *iu = &cmd->sense_iu;
+       int ret;
+
+       init_completion(&cmd->write_complete);
+       cmd->fu = fu;
+
+       iu->tag = cpu_to_be16(cmd->tag);
+
+       if (fu->flags & USBG_USE_STREAMS) {
+
+               ret = usbg_prepare_w_request(cmd, stream->req_out);
+               if (ret)
+                       goto cleanup;
+               ret = usb_ep_queue(fu->ep_out, stream->req_out, GFP_ATOMIC);
+               if (ret)
+                       pr_err("%s(%d)\n", __func__, __LINE__);
+
+       } else {
+
+               iu->iu_id = IU_ID_WRITE_READY;
+               iu->tag = cpu_to_be16(cmd->tag);
+
+               stream->req_status->complete = uasp_status_data_cmpl;
+               stream->req_status->context = cmd;
+
+               cmd->state = UASP_RECEIVE_DATA;
+               stream->req_status->buf = iu;
+               stream->req_status->length = sizeof(struct iu);
+
+               ret = usb_ep_queue(fu->ep_status, stream->req_status,
+                               GFP_ATOMIC);
+               if (ret)
+                       pr_err("%s(%d)\n", __func__, __LINE__);
+       }
+
+       wait_for_completion(&cmd->write_complete);
+       target_execute_cmd(se_cmd);
+cleanup:
+       return ret;
+}
+
+static int usbg_submit_command(struct f_uas *, void *, unsigned int);
+
+static void uasp_cmd_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_uas *fu = req->context;
+       int ret;
+
+       if (req->status < 0)
+               return;
+
+       ret = usbg_submit_command(fu, req->buf, req->actual);
+       /*
+        * Once we tune for performance enqueue the command req here again so
+        * we can receive a second command while we processing this one. Pay
+        * attention to properly sync STAUS endpoint with DATA IN + OUT so you
+        * don't break HS.
+        */
+       if (!ret)
+               return;
+       usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
+}
+
+static int uasp_alloc_stream_res(struct f_uas *fu, struct uas_stream *stream)
+{
+       stream->req_in = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL);
+       if (!stream->req_in)
+               goto out;
+
+       stream->req_out = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL);
+       if (!stream->req_out)
+               goto err_out;
+
+       stream->req_status = usb_ep_alloc_request(fu->ep_status, GFP_KERNEL);
+       if (!stream->req_status)
+               goto err_sts;
+
+       return 0;
+err_sts:
+       usb_ep_free_request(fu->ep_status, stream->req_status);
+       stream->req_status = NULL;
+err_out:
+       usb_ep_free_request(fu->ep_out, stream->req_out);
+       stream->req_out = NULL;
+out:
+       return -ENOMEM;
+}
+
+static int uasp_alloc_cmd(struct f_uas *fu)
+{
+       fu->cmd.req = usb_ep_alloc_request(fu->ep_cmd, GFP_KERNEL);
+       if (!fu->cmd.req)
+               goto err;
+
+       fu->cmd.buf = kmalloc(fu->ep_cmd->maxpacket, GFP_KERNEL);
+       if (!fu->cmd.buf)
+               goto err_buf;
+
+       fu->cmd.req->complete = uasp_cmd_complete;
+       fu->cmd.req->buf = fu->cmd.buf;
+       fu->cmd.req->length = fu->ep_cmd->maxpacket;
+       fu->cmd.req->context = fu;
+       return 0;
+
+err_buf:
+       usb_ep_free_request(fu->ep_cmd, fu->cmd.req);
+err:
+       return -ENOMEM;
+}
+
+static void uasp_setup_stream_res(struct f_uas *fu, int max_streams)
+{
+       int i;
+
+       for (i = 0; i < max_streams; i++) {
+               struct uas_stream *s = &fu->stream[i];
+
+               s->req_in->stream_id = i + 1;
+               s->req_out->stream_id = i + 1;
+               s->req_status->stream_id = i + 1;
+       }
+}
+
+static int uasp_prepare_reqs(struct f_uas *fu)
+{
+       int ret;
+       int i;
+       int max_streams;
+
+       if (fu->flags & USBG_USE_STREAMS)
+               max_streams = UASP_SS_EP_COMP_NUM_STREAMS;
+       else
+               max_streams = 1;
+
+       for (i = 0; i < max_streams; i++) {
+               ret = uasp_alloc_stream_res(fu, &fu->stream[i]);
+               if (ret)
+                       goto err_cleanup;
+       }
+
+       ret = uasp_alloc_cmd(fu);
+       if (ret)
+               goto err_free_stream;
+       uasp_setup_stream_res(fu, max_streams);
+
+       ret = usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
+       if (ret)
+               goto err_free_stream;
+
+       return 0;
+
+err_free_stream:
+       uasp_free_cmdreq(fu);
+
+err_cleanup:
+       if (i) {
+               do {
+                       uasp_cleanup_one_stream(fu, &fu->stream[i - 1]);
+                       i--;
+               } while (i);
+       }
+       pr_err("UASP: endpoint setup failed\n");
+       return ret;
+}
+
+static void uasp_set_alt(struct f_uas *fu)
+{
+       struct usb_function *f = &fu->function;
+       struct usb_gadget *gadget = f->config->cdev->gadget;
+       int ret;
+
+       fu->flags = USBG_IS_UAS;
+
+       if (gadget->speed == USB_SPEED_SUPER)
+               fu->flags |= USBG_USE_STREAMS;
+
+       config_ep_by_speed(gadget, f, fu->ep_in);
+       ret = usb_ep_enable(fu->ep_in);
+       if (ret)
+               goto err_b_in;
+
+       config_ep_by_speed(gadget, f, fu->ep_out);
+       ret = usb_ep_enable(fu->ep_out);
+       if (ret)
+               goto err_b_out;
+
+       config_ep_by_speed(gadget, f, fu->ep_cmd);
+       ret = usb_ep_enable(fu->ep_cmd);
+       if (ret)
+               goto err_cmd;
+       config_ep_by_speed(gadget, f, fu->ep_status);
+       ret = usb_ep_enable(fu->ep_status);
+       if (ret)
+               goto err_status;
+
+       ret = uasp_prepare_reqs(fu);
+       if (ret)
+               goto err_wq;
+       fu->flags |= USBG_ENABLED;
+
+       pr_info("Using the UAS protocol\n");
+       return;
+err_wq:
+       usb_ep_disable(fu->ep_status);
+err_status:
+       usb_ep_disable(fu->ep_cmd);
+err_cmd:
+       usb_ep_disable(fu->ep_out);
+err_b_out:
+       usb_ep_disable(fu->ep_in);
+err_b_in:
+       fu->flags = 0;
+}
+
+static int get_cmd_dir(const unsigned char *cdb)
+{
+       int ret;
+
+       switch (cdb[0]) {
+       case READ_6:
+       case READ_10:
+       case READ_12:
+       case READ_16:
+       case INQUIRY:
+       case MODE_SENSE:
+       case MODE_SENSE_10:
+       case SERVICE_ACTION_IN_16:
+       case MAINTENANCE_IN:
+       case PERSISTENT_RESERVE_IN:
+       case SECURITY_PROTOCOL_IN:
+       case ACCESS_CONTROL_IN:
+       case REPORT_LUNS:
+       case READ_BLOCK_LIMITS:
+       case READ_POSITION:
+       case READ_CAPACITY:
+       case READ_TOC:
+       case READ_FORMAT_CAPACITIES:
+       case REQUEST_SENSE:
+               ret = DMA_FROM_DEVICE;
+               break;
+
+       case WRITE_6:
+       case WRITE_10:
+       case WRITE_12:
+       case WRITE_16:
+       case MODE_SELECT:
+       case MODE_SELECT_10:
+       case WRITE_VERIFY:
+       case WRITE_VERIFY_12:
+       case PERSISTENT_RESERVE_OUT:
+       case MAINTENANCE_OUT:
+       case SECURITY_PROTOCOL_OUT:
+       case ACCESS_CONTROL_OUT:
+               ret = DMA_TO_DEVICE;
+               break;
+       case ALLOW_MEDIUM_REMOVAL:
+       case TEST_UNIT_READY:
+       case SYNCHRONIZE_CACHE:
+       case START_STOP:
+       case ERASE:
+       case REZERO_UNIT:
+       case SEEK_10:
+       case SPACE:
+       case VERIFY:
+       case WRITE_FILEMARKS:
+               ret = DMA_NONE;
+               break;
+       default:
+#define CMD_DIR_MSG "target: Unknown data direction for SCSI Opcode 0x%02x\n"
+               pr_warn(CMD_DIR_MSG, cdb[0]);
+#undef CMD_DIR_MSG
+               ret = -EINVAL;
+       }
+       return ret;
+}
+
+static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req)
+{
+       struct usbg_cmd *cmd = req->context;
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+
+       if (req->status < 0) {
+               pr_err("%s() state %d transfer failed\n", __func__, cmd->state);
+               goto cleanup;
+       }
+
+       if (req->num_sgs == 0) {
+               sg_copy_from_buffer(se_cmd->t_data_sg,
+                               se_cmd->t_data_nents,
+                               cmd->data_buf,
+                               se_cmd->data_length);
+       }
+
+       complete(&cmd->write_complete);
+       return;
+
+cleanup:
+       usbg_cleanup_cmd(cmd);
+}
+
+static int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req)
+{
+       struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct f_uas *fu = cmd->fu;
+       struct usb_gadget *gadget = fuas_to_gadget(fu);
+
+       if (!gadget->sg_supported) {
+               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC);
+               if (!cmd->data_buf)
+                       return -ENOMEM;
+
+               req->buf = cmd->data_buf;
+       } else {
+               req->buf = NULL;
+               req->num_sgs = se_cmd->t_data_nents;
+               req->sg = se_cmd->t_data_sg;
+       }
+
+       req->complete = usbg_data_write_cmpl;
+       req->length = se_cmd->data_length;
+       req->context = cmd;
+       return 0;
+}
+
+static int usbg_send_status_response(struct se_cmd *se_cmd)
+{
+       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
+                       se_cmd);
+       struct f_uas *fu = cmd->fu;
+
+       if (fu->flags & USBG_IS_BOT)
+               return bot_send_status_response(cmd);
+       else
+               return uasp_send_status_response(cmd);
+}
+
+static int usbg_send_write_request(struct se_cmd *se_cmd)
+{
+       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
+                       se_cmd);
+       struct f_uas *fu = cmd->fu;
+
+       if (fu->flags & USBG_IS_BOT)
+               return bot_send_write_request(cmd);
+       else
+               return uasp_send_write_request(cmd);
+}
+
+static int usbg_send_read_response(struct se_cmd *se_cmd)
+{
+       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
+                       se_cmd);
+       struct f_uas *fu = cmd->fu;
+
+       if (fu->flags & USBG_IS_BOT)
+               return bot_send_read_response(cmd);
+       else
+               return uasp_send_read_response(cmd);
+}
+
+static void usbg_cmd_work(struct work_struct *work)
+{
+       struct usbg_cmd *cmd = container_of(work, struct usbg_cmd, work);
+       struct se_cmd *se_cmd;
+       struct tcm_usbg_nexus *tv_nexus;
+       struct usbg_tpg *tpg;
+       int dir;
+
+       se_cmd = &cmd->se_cmd;
+       tpg = cmd->fu->tpg;
+       tv_nexus = tpg->tpg_nexus;
+       dir = get_cmd_dir(cmd->cmd_buf);
+       if (dir < 0) {
+               transport_init_se_cmd(se_cmd,
+                               tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
+                               tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
+                               cmd->prio_attr, cmd->sense_iu.sense);
+               goto out;
+       }
+
+       if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
+                       cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
+                       0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE) < 0)
+               goto out;
+
+       return;
+
+out:
+       transport_send_check_condition_and_sense(se_cmd,
+                       TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+       usbg_cleanup_cmd(cmd);
+}
+
+static int usbg_submit_command(struct f_uas *fu,
+               void *cmdbuf, unsigned int len)
+{
+       struct command_iu *cmd_iu = cmdbuf;
+       struct usbg_cmd *cmd;
+       struct usbg_tpg *tpg;
+       struct tcm_usbg_nexus *tv_nexus;
+       u32 cmd_len;
+
+       if (cmd_iu->iu_id != IU_ID_COMMAND) {
+               pr_err("Unsupported type %d\n", cmd_iu->iu_id);
+               return -EINVAL;
+       }
+
+       cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->fu = fu;
+
+       /* XXX until I figure out why I can't free in on complete */
+       kref_init(&cmd->ref);
+       kref_get(&cmd->ref);
+
+       tpg = fu->tpg;
+       cmd_len = (cmd_iu->len & ~0x3) + 16;
+       if (cmd_len > USBG_MAX_CMD)
+               goto err;
+
+       memcpy(cmd->cmd_buf, cmd_iu->cdb, cmd_len);
+
+       cmd->tag = be16_to_cpup(&cmd_iu->tag);
+       cmd->se_cmd.tag = cmd->tag;
+       if (fu->flags & USBG_USE_STREAMS) {
+               if (cmd->tag > UASP_SS_EP_COMP_NUM_STREAMS)
+                       goto err;
+               if (!cmd->tag)
+                       cmd->stream = &fu->stream[0];
+               else
+                       cmd->stream = &fu->stream[cmd->tag - 1];
+       } else {
+               cmd->stream = &fu->stream[0];
+       }
+
+       tv_nexus = tpg->tpg_nexus;
+       if (!tv_nexus) {
+               pr_err("Missing nexus, ignoring command\n");
+               goto err;
+       }
+
+       switch (cmd_iu->prio_attr & 0x7) {
+       case UAS_HEAD_TAG:
+               cmd->prio_attr = TCM_HEAD_TAG;
+               break;
+       case UAS_ORDERED_TAG:
+               cmd->prio_attr = TCM_ORDERED_TAG;
+               break;
+       case UAS_ACA:
+               cmd->prio_attr = TCM_ACA_TAG;
+               break;
+       default:
+               pr_debug_once("Unsupported prio_attr: %02x.\n",
+                               cmd_iu->prio_attr);
+       case UAS_SIMPLE_TAG:
+               cmd->prio_attr = TCM_SIMPLE_TAG;
+               break;
+       }
+
+       cmd->unpacked_lun = scsilun_to_int(&cmd_iu->lun);
+
+       INIT_WORK(&cmd->work, usbg_cmd_work);
+       queue_work(tpg->workqueue, &cmd->work);
+
+       return 0;
+err:
+       kfree(cmd);
+       return -EINVAL;
+}
+
+static void bot_cmd_work(struct work_struct *work)
+{
+       struct usbg_cmd *cmd = container_of(work, struct usbg_cmd, work);
+       struct se_cmd *se_cmd;
+       struct tcm_usbg_nexus *tv_nexus;
+       struct usbg_tpg *tpg;
+       int dir;
+
+       se_cmd = &cmd->se_cmd;
+       tpg = cmd->fu->tpg;
+       tv_nexus = tpg->tpg_nexus;
+       dir = get_cmd_dir(cmd->cmd_buf);
+       if (dir < 0) {
+               transport_init_se_cmd(se_cmd,
+                               tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
+                               tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
+                               cmd->prio_attr, cmd->sense_iu.sense);
+               goto out;
+       }
+
+       if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
+                       cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
+                       cmd->data_len, cmd->prio_attr, dir, 0) < 0)
+               goto out;
+
+       return;
+
+out:
+       transport_send_check_condition_and_sense(se_cmd,
+                               TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+       usbg_cleanup_cmd(cmd);
+}
+
+static int bot_submit_command(struct f_uas *fu,
+               void *cmdbuf, unsigned int len)
+{
+       struct bulk_cb_wrap *cbw = cmdbuf;
+       struct usbg_cmd *cmd;
+       struct usbg_tpg *tpg;
+       struct tcm_usbg_nexus *tv_nexus;
+       u32 cmd_len;
+
+       if (cbw->Signature != cpu_to_le32(US_BULK_CB_SIGN)) {
+               pr_err("Wrong signature on CBW\n");
+               return -EINVAL;
+       }
+       if (len != 31) {
+               pr_err("Wrong length for CBW\n");
+               return -EINVAL;
+       }
+
+       cmd_len = cbw->Length;
+       if (cmd_len < 1 || cmd_len > 16)
+               return -EINVAL;
+
+       cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->fu = fu;
+
+       /* XXX until I figure out why I can't free in on complete */
+       kref_init(&cmd->ref);
+       kref_get(&cmd->ref);
+
+       tpg = fu->tpg;
+
+       memcpy(cmd->cmd_buf, cbw->CDB, cmd_len);
+
+       cmd->bot_tag = cbw->Tag;
+
+       tv_nexus = tpg->tpg_nexus;
+       if (!tv_nexus) {
+               pr_err("Missing nexus, ignoring command\n");
+               goto err;
+       }
+
+       cmd->prio_attr = TCM_SIMPLE_TAG;
+       cmd->unpacked_lun = cbw->Lun;
+       cmd->is_read = cbw->Flags & US_BULK_FLAG_IN ? 1 : 0;
+       cmd->data_len = le32_to_cpu(cbw->DataTransferLength);
+       cmd->se_cmd.tag = le32_to_cpu(cmd->bot_tag);
+
+       INIT_WORK(&cmd->work, bot_cmd_work);
+       queue_work(tpg->workqueue, &cmd->work);
+
+       return 0;
+err:
+       kfree(cmd);
+       return -EINVAL;
+}
+
+/* Start fabric.c code */
+
+static int usbg_check_true(struct se_portal_group *se_tpg)
+{
+       return 1;
+}
+
+static int usbg_check_false(struct se_portal_group *se_tpg)
+{
+       return 0;
+}
+
+static char *usbg_get_fabric_name(void)
+{
+       return "usb_gadget";
+}
+
+static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg)
+{
+       struct usbg_tpg *tpg = container_of(se_tpg,
+                               struct usbg_tpg, se_tpg);
+       struct usbg_tport *tport = tpg->tport;
+
+       return &tport->tport_name[0];
+}
+
+static u16 usbg_get_tag(struct se_portal_group *se_tpg)
+{
+       struct usbg_tpg *tpg = container_of(se_tpg,
+                               struct usbg_tpg, se_tpg);
+       return tpg->tport_tpgt;
+}
+
+static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg)
+{
+       return 1;
+}
+
+static void usbg_cmd_release(struct kref *ref)
+{
+       struct usbg_cmd *cmd = container_of(ref, struct usbg_cmd,
+                       ref);
+
+       transport_generic_free_cmd(&cmd->se_cmd, 0);
+}
+
+static void usbg_release_cmd(struct se_cmd *se_cmd)
+{
+       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
+                       se_cmd);
+       kfree(cmd->data_buf);
+       kfree(cmd);
+}
+
+static int usbg_shutdown_session(struct se_session *se_sess)
+{
+       return 0;
+}
+
+static void usbg_close_session(struct se_session *se_sess)
+{
+}
+
+static u32 usbg_sess_get_index(struct se_session *se_sess)
+{
+       return 0;
+}
+
+/*
+ * XXX Error recovery: return != 0 if we expect writes. Dunno when that could be
+ */
+static int usbg_write_pending_status(struct se_cmd *se_cmd)
+{
+       return 0;
+}
+
+static void usbg_set_default_node_attrs(struct se_node_acl *nacl)
+{
+}
+
+static int usbg_get_cmd_state(struct se_cmd *se_cmd)
+{
+       return 0;
+}
+
+static void usbg_queue_tm_rsp(struct se_cmd *se_cmd)
+{
+}
+
+static void usbg_aborted_task(struct se_cmd *se_cmd)
+{
+}
+
+static const char *usbg_check_wwn(const char *name)
+{
+       const char *n;
+       unsigned int len;
+
+       n = strstr(name, "naa.");
+       if (!n)
+               return NULL;
+       n += 4;
+       len = strlen(n);
+       if (len == 0 || len > USBG_NAMELEN - 1)
+               return NULL;
+       return n;
+}
+
+static int usbg_init_nodeacl(struct se_node_acl *se_nacl, const char *name)
+{
+       if (!usbg_check_wwn(name))
+               return -EINVAL;
+       return 0;
+}
+
+static struct se_portal_group *usbg_make_tpg(
+       struct se_wwn *wwn,
+       struct config_group *group,
+       const char *name)
+{
+       struct usbg_tport *tport = container_of(wwn, struct usbg_tport,
+                       tport_wwn);
+       struct usbg_tpg *tpg;
+       unsigned long tpgt;
+       int ret;
+       struct f_tcm_opts *opts;
+       unsigned i;
+
+       if (strstr(name, "tpgt_") != name)
+               return ERR_PTR(-EINVAL);
+       if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX)
+               return ERR_PTR(-EINVAL);
+       ret = -ENODEV;
+       mutex_lock(&tpg_instances_lock);
+       for (i = 0; i < TPG_INSTANCES; ++i)
+               if (tpg_instances[i].func_inst && !tpg_instances[i].tpg)
+                       break;
+       if (i == TPG_INSTANCES)
+               goto unlock_inst;
+
+       opts = container_of(tpg_instances[i].func_inst, struct f_tcm_opts,
+               func_inst);
+       mutex_lock(&opts->dep_lock);
+       if (!opts->ready)
+               goto unlock_dep;
+
+       if (opts->has_dep) {
+               if (!try_module_get(opts->dependent))
+                       goto unlock_dep;
+       } else {
+               ret = configfs_depend_item_unlocked(
+                       group->cg_subsys,
+                       &opts->func_inst.group.cg_item);
+               if (ret)
+                       goto unlock_dep;
+       }
+
+       tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL);
+       ret = -ENOMEM;
+       if (!tpg)
+               goto unref_dep;
+       mutex_init(&tpg->tpg_mutex);
+       atomic_set(&tpg->tpg_port_count, 0);
+       tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1);
+       if (!tpg->workqueue)
+               goto free_tpg;
+
+       tpg->tport = tport;
+       tpg->tport_tpgt = tpgt;
+
+       /*
+        * SPC doesn't assign a protocol identifier for USB-SCSI, so we
+        * pretend to be SAS..
+        */
+       ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SAS);
+       if (ret < 0)
+               goto free_workqueue;
+
+       tpg_instances[i].tpg = tpg;
+       tpg->fi = tpg_instances[i].func_inst;
+       mutex_unlock(&opts->dep_lock);
+       mutex_unlock(&tpg_instances_lock);
+       return &tpg->se_tpg;
+
+free_workqueue:
+       destroy_workqueue(tpg->workqueue);
+free_tpg:
+       kfree(tpg);
+unref_dep:
+       if (opts->has_dep)
+               module_put(opts->dependent);
+       else
+               configfs_undepend_item_unlocked(&opts->func_inst.group.cg_item);
+unlock_dep:
+       mutex_unlock(&opts->dep_lock);
+unlock_inst:
+       mutex_unlock(&tpg_instances_lock);
+
+       return ERR_PTR(ret);
+}
+
+static int tcm_usbg_drop_nexus(struct usbg_tpg *);
+
+static void usbg_drop_tpg(struct se_portal_group *se_tpg)
+{
+       struct usbg_tpg *tpg = container_of(se_tpg,
+                               struct usbg_tpg, se_tpg);
+       unsigned i;
+       struct f_tcm_opts *opts;
+
+       tcm_usbg_drop_nexus(tpg);
+       core_tpg_deregister(se_tpg);
+       destroy_workqueue(tpg->workqueue);
+
+       mutex_lock(&tpg_instances_lock);
+       for (i = 0; i < TPG_INSTANCES; ++i)
+               if (tpg_instances[i].tpg == tpg)
+                       break;
+       if (i < TPG_INSTANCES)
+               tpg_instances[i].tpg = NULL;
+       opts = container_of(tpg_instances[i].func_inst,
+               struct f_tcm_opts, func_inst);
+       mutex_lock(&opts->dep_lock);
+       if (opts->has_dep)
+               module_put(opts->dependent);
+       else
+               configfs_undepend_item_unlocked(&opts->func_inst.group.cg_item);
+       mutex_unlock(&opts->dep_lock);
+       mutex_unlock(&tpg_instances_lock);
+
+       kfree(tpg);
+}
+
+static struct se_wwn *usbg_make_tport(
+       struct target_fabric_configfs *tf,
+       struct config_group *group,
+       const char *name)
+{
+       struct usbg_tport *tport;
+       const char *wnn_name;
+       u64 wwpn = 0;
+
+       wnn_name = usbg_check_wwn(name);
+       if (!wnn_name)
+               return ERR_PTR(-EINVAL);
+
+       tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL);
+       if (!(tport))
+               return ERR_PTR(-ENOMEM);
+
+       tport->tport_wwpn = wwpn;
+       snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name);
+       return &tport->tport_wwn;
+}
+
+static void usbg_drop_tport(struct se_wwn *wwn)
+{
+       struct usbg_tport *tport = container_of(wwn,
+                               struct usbg_tport, tport_wwn);
+       kfree(tport);
+}
+
+/*
+ * If somebody feels like dropping the version property, go ahead.
+ */
+static ssize_t usbg_wwn_version_show(struct config_item *item,  char *page)
+{
+       return sprintf(page, "usb-gadget fabric module\n");
+}
+
+CONFIGFS_ATTR_RO(usbg_wwn_, version);
+
+static struct configfs_attribute *usbg_wwn_attrs[] = {
+       &usbg_wwn_attr_version,
+       NULL,
+};
+
+static ssize_t tcm_usbg_tpg_enable_show(struct config_item *item, char *page)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+       struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
+
+       return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect);
+}
+
+static int usbg_attach(struct usbg_tpg *);
+static void usbg_detach(struct usbg_tpg *);
+
+static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+       struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
+       bool op;
+       ssize_t ret;
+
+       ret = strtobool(page, &op);
+       if (ret)
+               return ret;
+
+       if ((op && tpg->gadget_connect) || (!op && !tpg->gadget_connect))
+               return -EINVAL;
+
+       if (op)
+               ret = usbg_attach(tpg);
+       else
+               usbg_detach(tpg);
+       if (ret)
+               return ret;
+
+       tpg->gadget_connect = op;
+
+       return count;
+}
+
+static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
+       struct tcm_usbg_nexus *tv_nexus;
+       ssize_t ret;
+
+       mutex_lock(&tpg->tpg_mutex);
+       tv_nexus = tpg->tpg_nexus;
+       if (!tv_nexus) {
+               ret = -ENODEV;
+               goto out;
+       }
+       ret = snprintf(page, PAGE_SIZE, "%s\n",
+                       tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
+out:
+       mutex_unlock(&tpg->tpg_mutex);
+       return ret;
+}
+
+static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
+{
+       struct se_portal_group *se_tpg;
+       struct tcm_usbg_nexus *tv_nexus;
+       int ret;
+
+       mutex_lock(&tpg->tpg_mutex);
+       if (tpg->tpg_nexus) {
+               ret = -EEXIST;
+               pr_debug("tpg->tpg_nexus already exists\n");
+               goto err_unlock;
+       }
+       se_tpg = &tpg->se_tpg;
+
+       ret = -ENOMEM;
+       tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
+       if (!tv_nexus)
+               goto err_unlock;
+       tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL);
+       if (IS_ERR(tv_nexus->tvn_se_sess))
+               goto err_free;
+
+       /*
+        * Since we are running in 'demo mode' this call with generate a
+        * struct se_node_acl for the tcm_vhost struct se_portal_group with
+        * the SCSI Initiator port name of the passed configfs group 'name'.
+        */
+       tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
+                       se_tpg, name);
+       if (!tv_nexus->tvn_se_sess->se_node_acl) {
+#define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
+               pr_debug(MAKE_NEXUS_MSG, name);
+#undef MAKE_NEXUS_MSG
+               goto err_session;
+       }
+       /*
+        * Now register the TCM vHost virtual I_T Nexus as active.
+        */
+       transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
+                       tv_nexus->tvn_se_sess, tv_nexus);
+       tpg->tpg_nexus = tv_nexus;
+       mutex_unlock(&tpg->tpg_mutex);
+       return 0;
+
+err_session:
+       transport_free_session(tv_nexus->tvn_se_sess);
+err_free:
+       kfree(tv_nexus);
+err_unlock:
+       mutex_unlock(&tpg->tpg_mutex);
+       return ret;
+}
+
+static int tcm_usbg_drop_nexus(struct usbg_tpg *tpg)
+{
+       struct se_session *se_sess;
+       struct tcm_usbg_nexus *tv_nexus;
+       int ret = -ENODEV;
+
+       mutex_lock(&tpg->tpg_mutex);
+       tv_nexus = tpg->tpg_nexus;
+       if (!tv_nexus)
+               goto out;
+
+       se_sess = tv_nexus->tvn_se_sess;
+       if (!se_sess)
+               goto out;
+
+       if (atomic_read(&tpg->tpg_port_count)) {
+               ret = -EPERM;
+#define MSG "Unable to remove Host I_T Nexus with active TPG port count: %d\n"
+               pr_err(MSG, atomic_read(&tpg->tpg_port_count));
+#undef MSG
+               goto out;
+       }
+
+       pr_debug("Removing I_T Nexus to Initiator Port: %s\n",
+                       tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
+       /*
+        * Release the SCSI I_T Nexus to the emulated vHost Target Port
+        */
+       transport_deregister_session(tv_nexus->tvn_se_sess);
+       tpg->tpg_nexus = NULL;
+
+       kfree(tv_nexus);
+       ret = 0;
+out:
+       mutex_unlock(&tpg->tpg_mutex);
+       return ret;
+}
+
+static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
+       unsigned char i_port[USBG_NAMELEN], *ptr;
+       int ret;
+
+       if (!strncmp(page, "NULL", 4)) {
+               ret = tcm_usbg_drop_nexus(tpg);
+               return (!ret) ? count : ret;
+       }
+       if (strlen(page) >= USBG_NAMELEN) {
+
+#define NEXUS_STORE_MSG "Emulated NAA Sas Address: %s, exceeds max: %d\n"
+               pr_err(NEXUS_STORE_MSG, page, USBG_NAMELEN);
+#undef NEXUS_STORE_MSG
+               return -EINVAL;
+       }
+       snprintf(i_port, USBG_NAMELEN, "%s", page);
+
+       ptr = strstr(i_port, "naa.");
+       if (!ptr) {
+               pr_err("Missing 'naa.' prefix\n");
+               return -EINVAL;
+       }
+
+       if (i_port[strlen(i_port) - 1] == '\n')
+               i_port[strlen(i_port) - 1] = '\0';
+
+       ret = tcm_usbg_make_nexus(tpg, &i_port[0]);
+       if (ret < 0)
+               return ret;
+       return count;
+}
+
+CONFIGFS_ATTR(tcm_usbg_tpg_, enable);
+CONFIGFS_ATTR(tcm_usbg_tpg_, nexus);
+
+static struct configfs_attribute *usbg_base_attrs[] = {
+       &tcm_usbg_tpg_attr_enable,
+       &tcm_usbg_tpg_attr_nexus,
+       NULL,
+};
+
+static int usbg_port_link(struct se_portal_group *se_tpg, struct se_lun *lun)
+{
+       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
+
+       atomic_inc(&tpg->tpg_port_count);
+       smp_mb__after_atomic();
+       return 0;
+}
+
+static void usbg_port_unlink(struct se_portal_group *se_tpg,
+               struct se_lun *se_lun)
+{
+       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
+
+       atomic_dec(&tpg->tpg_port_count);
+       smp_mb__after_atomic();
+}
+
+static int usbg_check_stop_free(struct se_cmd *se_cmd)
+{
+       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
+                       se_cmd);
+
+       kref_put(&cmd->ref, usbg_cmd_release);
+       return 1;
+}
+
+static const struct target_core_fabric_ops usbg_ops = {
+       .module                         = THIS_MODULE,
+       .name                           = "usb_gadget",
+       .get_fabric_name                = usbg_get_fabric_name,
+       .tpg_get_wwn                    = usbg_get_fabric_wwn,
+       .tpg_get_tag                    = usbg_get_tag,
+       .tpg_check_demo_mode            = usbg_check_true,
+       .tpg_check_demo_mode_cache      = usbg_check_false,
+       .tpg_check_demo_mode_write_protect = usbg_check_false,
+       .tpg_check_prod_mode_write_protect = usbg_check_false,
+       .tpg_get_inst_index             = usbg_tpg_get_inst_index,
+       .release_cmd                    = usbg_release_cmd,
+       .shutdown_session               = usbg_shutdown_session,
+       .close_session                  = usbg_close_session,
+       .sess_get_index                 = usbg_sess_get_index,
+       .sess_get_initiator_sid         = NULL,
+       .write_pending                  = usbg_send_write_request,
+       .write_pending_status           = usbg_write_pending_status,
+       .set_default_node_attributes    = usbg_set_default_node_attrs,
+       .get_cmd_state                  = usbg_get_cmd_state,
+       .queue_data_in                  = usbg_send_read_response,
+       .queue_status                   = usbg_send_status_response,
+       .queue_tm_rsp                   = usbg_queue_tm_rsp,
+       .aborted_task                   = usbg_aborted_task,
+       .check_stop_free                = usbg_check_stop_free,
+
+       .fabric_make_wwn                = usbg_make_tport,
+       .fabric_drop_wwn                = usbg_drop_tport,
+       .fabric_make_tpg                = usbg_make_tpg,
+       .fabric_drop_tpg                = usbg_drop_tpg,
+       .fabric_post_link               = usbg_port_link,
+       .fabric_pre_unlink              = usbg_port_unlink,
+       .fabric_init_nodeacl            = usbg_init_nodeacl,
+
+       .tfc_wwn_attrs                  = usbg_wwn_attrs,
+       .tfc_tpg_base_attrs             = usbg_base_attrs,
+};
+
+/* Start gadget.c code */
+
+static struct usb_interface_descriptor bot_intf_desc = {
+       .bLength =              sizeof(bot_intf_desc),
+       .bDescriptorType =      USB_DT_INTERFACE,
+       .bNumEndpoints =        2,
+       .bAlternateSetting =    USB_G_ALT_INT_BBB,
+       .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
+       .bInterfaceSubClass =   USB_SC_SCSI,
+       .bInterfaceProtocol =   USB_PR_BULK,
+};
+
+static struct usb_interface_descriptor uasp_intf_desc = {
+       .bLength =              sizeof(uasp_intf_desc),
+       .bDescriptorType =      USB_DT_INTERFACE,
+       .bNumEndpoints =        4,
+       .bAlternateSetting =    USB_G_ALT_INT_UAS,
+       .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
+       .bInterfaceSubClass =   USB_SC_SCSI,
+       .bInterfaceProtocol =   USB_PR_UAS,
+};
+
+static struct usb_endpoint_descriptor uasp_bi_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor uasp_fs_bi_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_pipe_usage_descriptor uasp_bi_pipe_desc = {
+       .bLength =              sizeof(uasp_bi_pipe_desc),
+       .bDescriptorType =      USB_DT_PIPE_USAGE,
+       .bPipeID =              DATA_IN_PIPE_ID,
+};
+
+static struct usb_endpoint_descriptor uasp_ss_bi_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+};
+
+static struct usb_ss_ep_comp_descriptor uasp_bi_ep_comp_desc = {
+       .bLength =              sizeof(uasp_bi_ep_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       .bMaxBurst =            0,
+       .bmAttributes =         UASP_SS_EP_COMP_LOG_STREAMS,
+       .wBytesPerInterval =    0,
+};
+
+static struct usb_ss_ep_comp_descriptor bot_bi_ep_comp_desc = {
+       .bLength =              sizeof(bot_bi_ep_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       .bMaxBurst =            0,
+};
+
+static struct usb_endpoint_descriptor uasp_bo_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor uasp_fs_bo_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_pipe_usage_descriptor uasp_bo_pipe_desc = {
+       .bLength =              sizeof(uasp_bo_pipe_desc),
+       .bDescriptorType =      USB_DT_PIPE_USAGE,
+       .bPipeID =              DATA_OUT_PIPE_ID,
+};
+
+static struct usb_endpoint_descriptor uasp_ss_bo_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(0x400),
+};
+
+static struct usb_ss_ep_comp_descriptor uasp_bo_ep_comp_desc = {
+       .bLength =              sizeof(uasp_bo_ep_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       .bmAttributes =         UASP_SS_EP_COMP_LOG_STREAMS,
+};
+
+static struct usb_ss_ep_comp_descriptor bot_bo_ep_comp_desc = {
+       .bLength =              sizeof(bot_bo_ep_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+};
+
+static struct usb_endpoint_descriptor uasp_status_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor uasp_fs_status_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_pipe_usage_descriptor uasp_status_pipe_desc = {
+       .bLength =              sizeof(uasp_status_pipe_desc),
+       .bDescriptorType =      USB_DT_PIPE_USAGE,
+       .bPipeID =              STATUS_PIPE_ID,
+};
+
+static struct usb_endpoint_descriptor uasp_ss_status_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+};
+
+static struct usb_ss_ep_comp_descriptor uasp_status_in_ep_comp_desc = {
+       .bLength =              sizeof(uasp_status_in_ep_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       .bmAttributes =         UASP_SS_EP_COMP_LOG_STREAMS,
+};
+
+static struct usb_endpoint_descriptor uasp_cmd_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor uasp_fs_cmd_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_pipe_usage_descriptor uasp_cmd_pipe_desc = {
+       .bLength =              sizeof(uasp_cmd_pipe_desc),
+       .bDescriptorType =      USB_DT_PIPE_USAGE,
+       .bPipeID =              CMD_PIPE_ID,
+};
+
+static struct usb_endpoint_descriptor uasp_ss_cmd_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+};
+
+static struct usb_ss_ep_comp_descriptor uasp_cmd_comp_desc = {
+       .bLength =              sizeof(uasp_cmd_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+};
+
+static struct usb_descriptor_header *uasp_fs_function_desc[] = {
+       (struct usb_descriptor_header *) &bot_intf_desc,
+       (struct usb_descriptor_header *) &uasp_fs_bi_desc,
+       (struct usb_descriptor_header *) &uasp_fs_bo_desc,
+
+       (struct usb_descriptor_header *) &uasp_intf_desc,
+       (struct usb_descriptor_header *) &uasp_fs_bi_desc,
+       (struct usb_descriptor_header *) &uasp_bi_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_fs_bo_desc,
+       (struct usb_descriptor_header *) &uasp_bo_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_fs_status_desc,
+       (struct usb_descriptor_header *) &uasp_status_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_fs_cmd_desc,
+       (struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
+       NULL,
+};
+
+static struct usb_descriptor_header *uasp_hs_function_desc[] = {
+       (struct usb_descriptor_header *) &bot_intf_desc,
+       (struct usb_descriptor_header *) &uasp_bi_desc,
+       (struct usb_descriptor_header *) &uasp_bo_desc,
+
+       (struct usb_descriptor_header *) &uasp_intf_desc,
+       (struct usb_descriptor_header *) &uasp_bi_desc,
+       (struct usb_descriptor_header *) &uasp_bi_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_bo_desc,
+       (struct usb_descriptor_header *) &uasp_bo_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_status_desc,
+       (struct usb_descriptor_header *) &uasp_status_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_cmd_desc,
+       (struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
+       NULL,
+};
+
+static struct usb_descriptor_header *uasp_ss_function_desc[] = {
+       (struct usb_descriptor_header *) &bot_intf_desc,
+       (struct usb_descriptor_header *) &uasp_ss_bi_desc,
+       (struct usb_descriptor_header *) &bot_bi_ep_comp_desc,
+       (struct usb_descriptor_header *) &uasp_ss_bo_desc,
+       (struct usb_descriptor_header *) &bot_bo_ep_comp_desc,
+
+       (struct usb_descriptor_header *) &uasp_intf_desc,
+       (struct usb_descriptor_header *) &uasp_ss_bi_desc,
+       (struct usb_descriptor_header *) &uasp_bi_ep_comp_desc,
+       (struct usb_descriptor_header *) &uasp_bi_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_ss_bo_desc,
+       (struct usb_descriptor_header *) &uasp_bo_ep_comp_desc,
+       (struct usb_descriptor_header *) &uasp_bo_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_ss_status_desc,
+       (struct usb_descriptor_header *) &uasp_status_in_ep_comp_desc,
+       (struct usb_descriptor_header *) &uasp_status_pipe_desc,
+       (struct usb_descriptor_header *) &uasp_ss_cmd_desc,
+       (struct usb_descriptor_header *) &uasp_cmd_comp_desc,
+       (struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
+       NULL,
+};
+
+static struct usb_string       tcm_us_strings[] = {
+       [USB_G_STR_INT_UAS].s           = "USB Attached SCSI",
+       [USB_G_STR_INT_BBB].s           = "Bulk Only Transport",
+       { },
+};
+
+static struct usb_gadget_strings tcm_stringtab = {
+       .language = 0x0409,
+       .strings = tcm_us_strings,
+};
+
+static struct usb_gadget_strings *tcm_strings[] = {
+       &tcm_stringtab,
+       NULL,
+};
+
+static int tcm_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct f_uas            *fu = to_f_uas(f);
+       struct usb_string       *us;
+       struct usb_gadget       *gadget = c->cdev->gadget;
+       struct usb_ep           *ep;
+       struct f_tcm_opts       *opts;
+       int                     iface;
+       int                     ret;
+
+       opts = container_of(f->fi, struct f_tcm_opts, func_inst);
+
+       mutex_lock(&opts->dep_lock);
+       if (!opts->can_attach) {
+               mutex_unlock(&opts->dep_lock);
+               return -ENODEV;
+       }
+       mutex_unlock(&opts->dep_lock);
+       us = usb_gstrings_attach(c->cdev, tcm_strings,
+               ARRAY_SIZE(tcm_us_strings));
+       if (IS_ERR(us))
+               return PTR_ERR(us);
+       bot_intf_desc.iInterface = us[USB_G_STR_INT_BBB].id;
+       uasp_intf_desc.iInterface = us[USB_G_STR_INT_UAS].id;
+
+       iface = usb_interface_id(c, f);
+       if (iface < 0)
+               return iface;
+
+       bot_intf_desc.bInterfaceNumber = iface;
+       uasp_intf_desc.bInterfaceNumber = iface;
+       fu->iface = iface;
+       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc,
+                       &uasp_bi_ep_comp_desc);
+       if (!ep)
+               goto ep_fail;
+
+       fu->ep_in = ep;
+
+       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
+                       &uasp_bo_ep_comp_desc);
+       if (!ep)
+               goto ep_fail;
+       fu->ep_out = ep;
+
+       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
+                       &uasp_status_in_ep_comp_desc);
+       if (!ep)
+               goto ep_fail;
+       fu->ep_status = ep;
+
+       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
+                       &uasp_cmd_comp_desc);
+       if (!ep)
+               goto ep_fail;
+       fu->ep_cmd = ep;
+
+       /* Assume endpoint addresses are the same for both speeds */
+       uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress;
+       uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress;
+       uasp_status_desc.bEndpointAddress =
+               uasp_ss_status_desc.bEndpointAddress;
+       uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
+
+       uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress;
+       uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress;
+       uasp_fs_status_desc.bEndpointAddress =
+               uasp_ss_status_desc.bEndpointAddress;
+       uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
+
+       ret = usb_assign_descriptors(f, uasp_fs_function_desc,
+                       uasp_hs_function_desc, uasp_ss_function_desc);
+       if (ret)
+               goto ep_fail;
+
+       return 0;
+ep_fail:
+       pr_err("Can't claim all required eps\n");
+
+       return -ENOTSUPP;
+}
+
+struct guas_setup_wq {
+       struct work_struct work;
+       struct f_uas *fu;
+       unsigned int alt;
+};
+
+static void tcm_delayed_set_alt(struct work_struct *wq)
+{
+       struct guas_setup_wq *work = container_of(wq, struct guas_setup_wq,
+                       work);
+       struct f_uas *fu = work->fu;
+       int alt = work->alt;
+
+       kfree(work);
+
+       if (fu->flags & USBG_IS_BOT)
+               bot_cleanup_old_alt(fu);
+       if (fu->flags & USBG_IS_UAS)
+               uasp_cleanup_old_alt(fu);
+
+       if (alt == USB_G_ALT_INT_BBB)
+               bot_set_alt(fu);
+       else if (alt == USB_G_ALT_INT_UAS)
+               uasp_set_alt(fu);
+       usb_composite_setup_continue(fu->function.config->cdev);
+}
+
+static int tcm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct f_uas *fu = to_f_uas(f);
+
+       if ((alt == USB_G_ALT_INT_BBB) || (alt == USB_G_ALT_INT_UAS)) {
+               struct guas_setup_wq *work;
+
+               work = kmalloc(sizeof(*work), GFP_ATOMIC);
+               if (!work)
+                       return -ENOMEM;
+               INIT_WORK(&work->work, tcm_delayed_set_alt);
+               work->fu = fu;
+               work->alt = alt;
+               schedule_work(&work->work);
+               return USB_GADGET_DELAYED_STATUS;
+       }
+       return -EOPNOTSUPP;
+}
+
+static void tcm_disable(struct usb_function *f)
+{
+       struct f_uas *fu = to_f_uas(f);
+
+       if (fu->flags & USBG_IS_UAS)
+               uasp_cleanup_old_alt(fu);
+       else if (fu->flags & USBG_IS_BOT)
+               bot_cleanup_old_alt(fu);
+       fu->flags = 0;
+}
+
+static int tcm_setup(struct usb_function *f,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct f_uas *fu = to_f_uas(f);
+
+       if (!(fu->flags & USBG_IS_BOT))
+               return -EOPNOTSUPP;
+
+       return usbg_bot_setup(f, ctrl);
+}
+
+static inline struct f_tcm_opts *to_f_tcm_opts(struct config_item *item)
+{
+       return container_of(to_config_group(item), struct f_tcm_opts,
+               func_inst.group);
+}
+
+static void tcm_attr_release(struct config_item *item)
+{
+       struct f_tcm_opts *opts = to_f_tcm_opts(item);
+
+       usb_put_function_instance(&opts->func_inst);
+}
+
+static struct configfs_item_operations tcm_item_ops = {
+       .release                = tcm_attr_release,
+};
+
+static struct config_item_type tcm_func_type = {
+       .ct_item_ops    = &tcm_item_ops,
+       .ct_owner       = THIS_MODULE,
+};
+
+static void tcm_free_inst(struct usb_function_instance *f)
+{
+       struct f_tcm_opts *opts;
+       unsigned i;
+
+       opts = container_of(f, struct f_tcm_opts, func_inst);
+
+       mutex_lock(&tpg_instances_lock);
+       for (i = 0; i < TPG_INSTANCES; ++i)
+               if (tpg_instances[i].func_inst == f)
+                       break;
+       if (i < TPG_INSTANCES)
+               tpg_instances[i].func_inst = NULL;
+       mutex_unlock(&tpg_instances_lock);
+
+       kfree(opts);
+}
+
+static int tcm_register_callback(struct usb_function_instance *f)
+{
+       struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
+
+       mutex_lock(&opts->dep_lock);
+       opts->can_attach = true;
+       mutex_unlock(&opts->dep_lock);
+
+       return 0;
+}
+
+static void tcm_unregister_callback(struct usb_function_instance *f)
+{
+       struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
+
+       mutex_lock(&opts->dep_lock);
+       unregister_gadget_item(opts->
+               func_inst.group.cg_item.ci_parent->ci_parent);
+       opts->can_attach = false;
+       mutex_unlock(&opts->dep_lock);
+}
+
+static int usbg_attach(struct usbg_tpg *tpg)
+{
+       struct usb_function_instance *f = tpg->fi;
+       struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
+
+       if (opts->tcm_register_callback)
+               return opts->tcm_register_callback(f);
+
+       return 0;
+}
+
+static void usbg_detach(struct usbg_tpg *tpg)
+{
+       struct usb_function_instance *f = tpg->fi;
+       struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
+
+       if (opts->tcm_unregister_callback)
+               opts->tcm_unregister_callback(f);
+}
+
+static int tcm_set_name(struct usb_function_instance *f, const char *name)
+{
+       struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst);
+
+       pr_debug("tcm: Activating %s\n", name);
+
+       mutex_lock(&opts->dep_lock);
+       opts->ready = true;
+       mutex_unlock(&opts->dep_lock);
+
+       return 0;
+}
+
+static struct usb_function_instance *tcm_alloc_inst(void)
+{
+       struct f_tcm_opts *opts;
+       int i;
+
+
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+
+       mutex_lock(&tpg_instances_lock);
+       for (i = 0; i < TPG_INSTANCES; ++i)
+               if (!tpg_instances[i].func_inst)
+                       break;
+
+       if (i == TPG_INSTANCES) {
+               mutex_unlock(&tpg_instances_lock);
+               kfree(opts);
+               return ERR_PTR(-EBUSY);
+       }
+       tpg_instances[i].func_inst = &opts->func_inst;
+       mutex_unlock(&tpg_instances_lock);
+
+       mutex_init(&opts->dep_lock);
+       opts->func_inst.set_inst_name = tcm_set_name;
+       opts->func_inst.free_func_inst = tcm_free_inst;
+       opts->tcm_register_callback = tcm_register_callback;
+       opts->tcm_unregister_callback = tcm_unregister_callback;
+
+       config_group_init_type_name(&opts->func_inst.group, "",
+                       &tcm_func_type);
+
+       return &opts->func_inst;
+}
+
+static void tcm_free(struct usb_function *f)
+{
+       struct f_uas *tcm = to_f_uas(f);
+
+       kfree(tcm);
+}
+
+static void tcm_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       usb_free_all_descriptors(f);
+}
+
+static struct usb_function *tcm_alloc(struct usb_function_instance *fi)
+{
+       struct f_uas *fu;
+       unsigned i;
+
+       mutex_lock(&tpg_instances_lock);
+       for (i = 0; i < TPG_INSTANCES; ++i)
+               if (tpg_instances[i].func_inst == fi)
+                       break;
+       if (i == TPG_INSTANCES) {
+               mutex_unlock(&tpg_instances_lock);
+               return ERR_PTR(-ENODEV);
+       }
+
+       fu = kzalloc(sizeof(*fu), GFP_KERNEL);
+       if (!fu) {
+               mutex_unlock(&tpg_instances_lock);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       fu->function.name = "Target Function";
+       fu->function.bind = tcm_bind;
+       fu->function.unbind = tcm_unbind;
+       fu->function.set_alt = tcm_set_alt;
+       fu->function.setup = tcm_setup;
+       fu->function.disable = tcm_disable;
+       fu->function.free_func = tcm_free;
+       fu->tpg = tpg_instances[i].tpg;
+       mutex_unlock(&tpg_instances_lock);
+
+       return &fu->function;
+}
+
+DECLARE_USB_FUNCTION(tcm, tcm_alloc_inst, tcm_alloc);
+
+static int tcm_init(void)
+{
+       int ret;
+
+       ret = usb_function_register(&tcmusb_func);
+       if (ret)
+               return ret;
+
+       ret = target_register_template(&usbg_ops);
+       if (ret)
+               usb_function_unregister(&tcmusb_func);
+
+       return ret;
+}
+module_init(tcm_init);
+
+static void tcm_exit(void)
+{
+       target_unregister_template(&usbg_ops);
+       usb_function_unregister(&tcmusb_func);
+}
+module_exit(tcm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sebastian Andrzej Siewior");
diff --git a/drivers/usb/gadget/function/tcm.h b/drivers/usb/gadget/function/tcm.h
new file mode 100644 (file)
index 0000000..b75c6f3
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef __TARGET_USB_GADGET_H__
+#define __TARGET_USB_GADGET_H__
+
+#include <linux/kref.h>
+/* #include <linux/usb/uas.h> */
+#include <linux/usb/composite.h>
+#include <linux/usb/uas.h>
+#include <linux/usb/storage.h>
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+
+#define USBG_NAMELEN 32
+
+#define fuas_to_gadget(f)      (f->function.config->cdev->gadget)
+#define UASP_SS_EP_COMP_LOG_STREAMS 4
+#define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS)
+
+enum {
+       USB_G_STR_INT_UAS = 0,
+       USB_G_STR_INT_BBB,
+};
+
+#define USB_G_ALT_INT_BBB       0
+#define USB_G_ALT_INT_UAS       1
+
+struct tcm_usbg_nexus {
+       struct se_session *tvn_se_sess;
+};
+
+struct usbg_tpg {
+       struct mutex tpg_mutex;
+       /* SAS port target portal group tag for TCM */
+       u16 tport_tpgt;
+       /* Pointer back to usbg_tport */
+       struct usbg_tport *tport;
+       struct workqueue_struct *workqueue;
+       /* Returned by usbg_make_tpg() */
+       struct se_portal_group se_tpg;
+       u32 gadget_connect;
+       struct tcm_usbg_nexus *tpg_nexus;
+       atomic_t tpg_port_count;
+
+       struct usb_function_instance *fi;
+};
+
+struct usbg_tport {
+       /* Binary World Wide unique Port Name for SAS Target port */
+       u64 tport_wwpn;
+       /* ASCII formatted WWPN for SAS Target port */
+       char tport_name[USBG_NAMELEN];
+       /* Returned by usbg_make_tport() */
+       struct se_wwn tport_wwn;
+};
+
+enum uas_state {
+       UASP_SEND_DATA,
+       UASP_RECEIVE_DATA,
+       UASP_SEND_STATUS,
+       UASP_QUEUE_COMMAND,
+};
+
+#define USBG_MAX_CMD    64
+struct usbg_cmd {
+       /* common */
+       u8 cmd_buf[USBG_MAX_CMD];
+       u32 data_len;
+       struct work_struct work;
+       int unpacked_lun;
+       struct se_cmd se_cmd;
+       void *data_buf; /* used if no sg support available */
+       struct f_uas *fu;
+       struct completion write_complete;
+       struct kref ref;
+
+       /* UAS only */
+       u16 tag;
+       u16 prio_attr;
+       struct sense_iu sense_iu;
+       enum uas_state state;
+       struct uas_stream *stream;
+
+       /* BOT only */
+       __le32 bot_tag;
+       unsigned int csw_code;
+       unsigned is_read:1;
+
+};
+
+struct uas_stream {
+       struct usb_request      *req_in;
+       struct usb_request      *req_out;
+       struct usb_request      *req_status;
+};
+
+struct usbg_cdb {
+       struct usb_request      *req;
+       void                    *buf;
+};
+
+struct bot_status {
+       struct usb_request      *req;
+       struct bulk_cs_wrap     csw;
+};
+
+struct f_uas {
+       struct usbg_tpg         *tpg;
+       struct usb_function     function;
+       u16                     iface;
+
+       u32                     flags;
+#define USBG_ENABLED           (1 << 0)
+#define USBG_IS_UAS            (1 << 1)
+#define USBG_USE_STREAMS       (1 << 2)
+#define USBG_IS_BOT            (1 << 3)
+#define USBG_BOT_CMD_PEND      (1 << 4)
+
+       struct usbg_cdb         cmd;
+       struct usb_ep           *ep_in;
+       struct usb_ep           *ep_out;
+
+       /* UAS */
+       struct usb_ep           *ep_status;
+       struct usb_ep           *ep_cmd;
+       struct uas_stream       stream[UASP_SS_EP_COMP_NUM_STREAMS];
+
+       /* BOT */
+       struct bot_status       bot_status;
+       struct usb_request      *bot_req_in;
+       struct usb_request      *bot_req_out;
+};
+
+#endif /* __TARGET_USB_GADGET_H__ */
diff --git a/drivers/usb/gadget/function/u_tcm.h b/drivers/usb/gadget/function/u_tcm.h
new file mode 100644 (file)
index 0000000..0bd751e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * u_tcm.h
+ *
+ * Utility definitions for the tcm function
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
+ *
+ * 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 U_TCM_H
+#define U_TCM_H
+
+#include <linux/usb/composite.h>
+
+/**
+ * @dependent: optional dependent module. Meant for legacy gadget.
+ * If non-null its refcount will be increased when a tpg is created and
+ * decreased when tpg is dropped.
+ * @dep_lock: lock for dependent module operations.
+ * @ready: true if the dependent module information is set.
+ * @can_attach: true a function can be bound to gadget
+ * @has_dep: true if there is a dependent module
+ *
+ */
+struct f_tcm_opts {
+       struct usb_function_instance    func_inst;
+       struct module                   *dependent;
+       struct mutex                    dep_lock;
+       bool                            ready;
+       bool                            can_attach;
+       bool                            has_dep;
+
+       /*
+        * Callbacks to be removed when legacy tcm gadget disappears.
+        *
+        * If you use the new function registration interface
+        * programmatically, you MUST set these callbacks to
+        * something sensible (e.g. probe/remove the composite).
+        */
+       int (*tcm_register_callback)(struct usb_function_instance *);
+       void (*tcm_unregister_callback)(struct usb_function_instance *);
+};
+
+#endif /* U_TCM_H */
index 4d682ad..a23d1b9 100644 (file)
@@ -250,6 +250,7 @@ config USB_GADGET_TARGET
        tristate "USB Gadget Target Fabric Module"
        depends on TARGET_CORE
        select USB_LIBCOMPOSITE
+       select USB_F_TCM
        help
          This fabric is an USB gadget. Two USB protocols are supported that is
          BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is
index 365afd7..7e179f8 100644 (file)
@@ -1521,10 +1521,10 @@ static void destroy_ep_files (struct dev_data *dev)
                spin_unlock_irq (&dev->lock);
 
                /* break link to dcache */
-               mutex_lock (&parent->i_mutex);
+               inode_lock(parent);
                d_delete (dentry);
                dput (dentry);
-               mutex_unlock (&parent->i_mutex);
+               inode_unlock(parent);
 
                spin_lock_irq (&dev->lock);
        }
index 7857fa4..0b0bb98 100644 (file)
 #include <target/target_core_fabric.h>
 #include <asm/unaligned.h>
 
-#include "tcm_usb_gadget.h"
+#include "u_tcm.h"
 
 USB_GADGET_COMPOSITE_OPTIONS();
 
-static inline struct f_uas *to_f_uas(struct usb_function *f)
-{
-       return container_of(f, struct f_uas, function);
-}
-
-static void usbg_cmd_release(struct kref *);
-
-static inline void usbg_cleanup_cmd(struct usbg_cmd *cmd)
-{
-       kref_put(&cmd->ref, usbg_cmd_release);
-}
-
-/* Start bot.c code */
-
-static int bot_enqueue_cmd_cbw(struct f_uas *fu)
-{
-       int ret;
-
-       if (fu->flags & USBG_BOT_CMD_PEND)
-               return 0;
-
-       ret = usb_ep_queue(fu->ep_out, fu->cmd.req, GFP_ATOMIC);
-       if (!ret)
-               fu->flags |= USBG_BOT_CMD_PEND;
-       return ret;
-}
-
-static void bot_status_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       struct usbg_cmd *cmd = req->context;
-       struct f_uas *fu = cmd->fu;
-
-       usbg_cleanup_cmd(cmd);
-       if (req->status < 0) {
-               pr_err("ERR %s(%d)\n", __func__, __LINE__);
-               return;
-       }
-
-       /* CSW completed, wait for next CBW */
-       bot_enqueue_cmd_cbw(fu);
-}
-
-static void bot_enqueue_sense_code(struct f_uas *fu, struct usbg_cmd *cmd)
-{
-       struct bulk_cs_wrap *csw = &fu->bot_status.csw;
-       int ret;
-       u8 *sense;
-       unsigned int csw_stat;
-
-       csw_stat = cmd->csw_code;
-
-       /*
-        * We can't send SENSE as a response. So we take ASC & ASCQ from our
-        * sense buffer and queue it and hope the host sends a REQUEST_SENSE
-        * command where it learns why we failed.
-        */
-       sense = cmd->sense_iu.sense;
-
-       csw->Tag = cmd->bot_tag;
-       csw->Status = csw_stat;
-       fu->bot_status.req->context = cmd;
-       ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_ATOMIC);
-       if (ret)
-               pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret);
-}
-
-static void bot_err_compl(struct usb_ep *ep, struct usb_request *req)
-{
-       struct usbg_cmd *cmd = req->context;
-       struct f_uas *fu = cmd->fu;
-
-       if (req->status < 0)
-               pr_err("ERR %s(%d)\n", __func__, __LINE__);
-
-       if (cmd->data_len) {
-               if (cmd->data_len > ep->maxpacket) {
-                       req->length = ep->maxpacket;
-                       cmd->data_len -= ep->maxpacket;
-               } else {
-                       req->length = cmd->data_len;
-                       cmd->data_len = 0;
-               }
-
-               usb_ep_queue(ep, req, GFP_ATOMIC);
-               return ;
-       }
-       bot_enqueue_sense_code(fu, cmd);
-}
-
-static void bot_send_bad_status(struct usbg_cmd *cmd)
-{
-       struct f_uas *fu = cmd->fu;
-       struct bulk_cs_wrap *csw = &fu->bot_status.csw;
-       struct usb_request *req;
-       struct usb_ep *ep;
-
-       csw->Residue = cpu_to_le32(cmd->data_len);
-
-       if (cmd->data_len) {
-               if (cmd->is_read) {
-                       ep = fu->ep_in;
-                       req = fu->bot_req_in;
-               } else {
-                       ep = fu->ep_out;
-                       req = fu->bot_req_out;
-               }
-
-               if (cmd->data_len > fu->ep_in->maxpacket) {
-                       req->length = ep->maxpacket;
-                       cmd->data_len -= ep->maxpacket;
-               } else {
-                       req->length = cmd->data_len;
-                       cmd->data_len = 0;
-               }
-               req->complete = bot_err_compl;
-               req->context = cmd;
-               req->buf = fu->cmd.buf;
-               usb_ep_queue(ep, req, GFP_KERNEL);
-       } else {
-               bot_enqueue_sense_code(fu, cmd);
-       }
-}
-
-static int bot_send_status(struct usbg_cmd *cmd, bool moved_data)
-{
-       struct f_uas *fu = cmd->fu;
-       struct bulk_cs_wrap *csw = &fu->bot_status.csw;
-       int ret;
-
-       if (cmd->se_cmd.scsi_status == SAM_STAT_GOOD) {
-               if (!moved_data && cmd->data_len) {
-                       /*
-                        * the host wants to move data, we don't. Fill / empty
-                        * the pipe and then send the csw with reside set.
-                        */
-                       cmd->csw_code = US_BULK_STAT_OK;
-                       bot_send_bad_status(cmd);
-                       return 0;
-               }
-
-               csw->Tag = cmd->bot_tag;
-               csw->Residue = cpu_to_le32(0);
-               csw->Status = US_BULK_STAT_OK;
-               fu->bot_status.req->context = cmd;
-
-               ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_KERNEL);
-               if (ret)
-                       pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret);
-       } else {
-               cmd->csw_code = US_BULK_STAT_FAIL;
-               bot_send_bad_status(cmd);
-       }
-       return 0;
-}
-
-/*
- * Called after command (no data transfer) or after the write (to device)
- * operation is completed
- */
-static int bot_send_status_response(struct usbg_cmd *cmd)
-{
-       bool moved_data = false;
-
-       if (!cmd->is_read)
-               moved_data = true;
-       return bot_send_status(cmd, moved_data);
-}
-
-/* Read request completed, now we have to send the CSW */
-static void bot_read_compl(struct usb_ep *ep, struct usb_request *req)
-{
-       struct usbg_cmd *cmd = req->context;
-
-       if (req->status < 0)
-               pr_err("ERR %s(%d)\n", __func__, __LINE__);
-
-       bot_send_status(cmd, true);
-}
-
-static int bot_send_read_response(struct usbg_cmd *cmd)
-{
-       struct f_uas *fu = cmd->fu;
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-       struct usb_gadget *gadget = fuas_to_gadget(fu);
-       int ret;
-
-       if (!cmd->data_len) {
-               cmd->csw_code = US_BULK_STAT_PHASE;
-               bot_send_bad_status(cmd);
-               return 0;
-       }
-
-       if (!gadget->sg_supported) {
-               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC);
-               if (!cmd->data_buf)
-                       return -ENOMEM;
-
-               sg_copy_to_buffer(se_cmd->t_data_sg,
-                               se_cmd->t_data_nents,
-                               cmd->data_buf,
-                               se_cmd->data_length);
-
-               fu->bot_req_in->buf = cmd->data_buf;
-       } else {
-               fu->bot_req_in->buf = NULL;
-               fu->bot_req_in->num_sgs = se_cmd->t_data_nents;
-               fu->bot_req_in->sg = se_cmd->t_data_sg;
-       }
-
-       fu->bot_req_in->complete = bot_read_compl;
-       fu->bot_req_in->length = se_cmd->data_length;
-       fu->bot_req_in->context = cmd;
-       ret = usb_ep_queue(fu->ep_in, fu->bot_req_in, GFP_ATOMIC);
-       if (ret)
-               pr_err("%s(%d)\n", __func__, __LINE__);
-       return 0;
-}
-
-static void usbg_data_write_cmpl(struct usb_ep *, struct usb_request *);
-static int usbg_prepare_w_request(struct usbg_cmd *, struct usb_request *);
-
-static int bot_send_write_request(struct usbg_cmd *cmd)
-{
-       struct f_uas *fu = cmd->fu;
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-       struct usb_gadget *gadget = fuas_to_gadget(fu);
-       int ret;
-
-       init_completion(&cmd->write_complete);
-       cmd->fu = fu;
-
-       if (!cmd->data_len) {
-               cmd->csw_code = US_BULK_STAT_PHASE;
-               return -EINVAL;
-       }
-
-       if (!gadget->sg_supported) {
-               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL);
-               if (!cmd->data_buf)
-                       return -ENOMEM;
-
-               fu->bot_req_out->buf = cmd->data_buf;
-       } else {
-               fu->bot_req_out->buf = NULL;
-               fu->bot_req_out->num_sgs = se_cmd->t_data_nents;
-               fu->bot_req_out->sg = se_cmd->t_data_sg;
-       }
-
-       fu->bot_req_out->complete = usbg_data_write_cmpl;
-       fu->bot_req_out->length = se_cmd->data_length;
-       fu->bot_req_out->context = cmd;
-
-       ret = usbg_prepare_w_request(cmd, fu->bot_req_out);
-       if (ret)
-               goto cleanup;
-       ret = usb_ep_queue(fu->ep_out, fu->bot_req_out, GFP_KERNEL);
-       if (ret)
-               pr_err("%s(%d)\n", __func__, __LINE__);
-
-       wait_for_completion(&cmd->write_complete);
-       target_execute_cmd(se_cmd);
-cleanup:
-       return ret;
-}
-
-static int bot_submit_command(struct f_uas *, void *, unsigned int);
-
-static void bot_cmd_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       struct f_uas *fu = req->context;
-       int ret;
-
-       fu->flags &= ~USBG_BOT_CMD_PEND;
-
-       if (req->status < 0)
-               return;
-
-       ret = bot_submit_command(fu, req->buf, req->actual);
-       if (ret)
-               pr_err("%s(%d): %d\n", __func__, __LINE__, ret);
-}
-
-static int bot_prepare_reqs(struct f_uas *fu)
-{
-       int ret;
-
-       fu->bot_req_in = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL);
-       if (!fu->bot_req_in)
-               goto err;
-
-       fu->bot_req_out = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL);
-       if (!fu->bot_req_out)
-               goto err_out;
-
-       fu->cmd.req = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL);
-       if (!fu->cmd.req)
-               goto err_cmd;
-
-       fu->bot_status.req = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL);
-       if (!fu->bot_status.req)
-               goto err_sts;
-
-       fu->bot_status.req->buf = &fu->bot_status.csw;
-       fu->bot_status.req->length = US_BULK_CS_WRAP_LEN;
-       fu->bot_status.req->complete = bot_status_complete;
-       fu->bot_status.csw.Signature = cpu_to_le32(US_BULK_CS_SIGN);
-
-       fu->cmd.buf = kmalloc(fu->ep_out->maxpacket, GFP_KERNEL);
-       if (!fu->cmd.buf)
-               goto err_buf;
-
-       fu->cmd.req->complete = bot_cmd_complete;
-       fu->cmd.req->buf = fu->cmd.buf;
-       fu->cmd.req->length = fu->ep_out->maxpacket;
-       fu->cmd.req->context = fu;
-
-       ret = bot_enqueue_cmd_cbw(fu);
-       if (ret)
-               goto err_queue;
-       return 0;
-err_queue:
-       kfree(fu->cmd.buf);
-       fu->cmd.buf = NULL;
-err_buf:
-       usb_ep_free_request(fu->ep_in, fu->bot_status.req);
-err_sts:
-       usb_ep_free_request(fu->ep_out, fu->cmd.req);
-       fu->cmd.req = NULL;
-err_cmd:
-       usb_ep_free_request(fu->ep_out, fu->bot_req_out);
-       fu->bot_req_out = NULL;
-err_out:
-       usb_ep_free_request(fu->ep_in, fu->bot_req_in);
-       fu->bot_req_in = NULL;
-err:
-       pr_err("BOT: endpoint setup failed\n");
-       return -ENOMEM;
-}
-
-static void bot_cleanup_old_alt(struct f_uas *fu)
-{
-       if (!(fu->flags & USBG_ENABLED))
-               return;
-
-       usb_ep_disable(fu->ep_in);
-       usb_ep_disable(fu->ep_out);
-
-       if (!fu->bot_req_in)
-               return;
-
-       usb_ep_free_request(fu->ep_in, fu->bot_req_in);
-       usb_ep_free_request(fu->ep_out, fu->bot_req_out);
-       usb_ep_free_request(fu->ep_out, fu->cmd.req);
-       usb_ep_free_request(fu->ep_out, fu->bot_status.req);
-
-       kfree(fu->cmd.buf);
-
-       fu->bot_req_in = NULL;
-       fu->bot_req_out = NULL;
-       fu->cmd.req = NULL;
-       fu->bot_status.req = NULL;
-       fu->cmd.buf = NULL;
-}
-
-static void bot_set_alt(struct f_uas *fu)
-{
-       struct usb_function *f = &fu->function;
-       struct usb_gadget *gadget = f->config->cdev->gadget;
-       int ret;
-
-       fu->flags = USBG_IS_BOT;
-
-       config_ep_by_speed(gadget, f, fu->ep_in);
-       ret = usb_ep_enable(fu->ep_in);
-       if (ret)
-               goto err_b_in;
-
-       config_ep_by_speed(gadget, f, fu->ep_out);
-       ret = usb_ep_enable(fu->ep_out);
-       if (ret)
-               goto err_b_out;
-
-       ret = bot_prepare_reqs(fu);
-       if (ret)
-               goto err_wq;
-       fu->flags |= USBG_ENABLED;
-       pr_info("Using the BOT protocol\n");
-       return;
-err_wq:
-       usb_ep_disable(fu->ep_out);
-err_b_out:
-       usb_ep_disable(fu->ep_in);
-err_b_in:
-       fu->flags = USBG_IS_BOT;
-}
-
-static int usbg_bot_setup(struct usb_function *f,
-               const struct usb_ctrlrequest *ctrl)
-{
-       struct f_uas *fu = to_f_uas(f);
-       struct usb_composite_dev *cdev = f->config->cdev;
-       u16 w_value = le16_to_cpu(ctrl->wValue);
-       u16 w_length = le16_to_cpu(ctrl->wLength);
-       int luns;
-       u8 *ret_lun;
-
-       switch (ctrl->bRequest) {
-       case US_BULK_GET_MAX_LUN:
-               if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS |
-                                       USB_RECIP_INTERFACE))
-                       return -ENOTSUPP;
-
-               if (w_length < 1)
-                       return -EINVAL;
-               if (w_value != 0)
-                       return -EINVAL;
-               luns = atomic_read(&fu->tpg->tpg_port_count);
-               if (!luns) {
-                       pr_err("No LUNs configured?\n");
-                       return -EINVAL;
-               }
-               /*
-                * If 4 LUNs are present we return 3 i.e. LUN 0..3 can be
-                * accessed. The upper limit is 0xf
-                */
-               luns--;
-               if (luns > 0xf) {
-                       pr_info_once("Limiting the number of luns to 16\n");
-                       luns = 0xf;
-               }
-               ret_lun = cdev->req->buf;
-               *ret_lun = luns;
-               cdev->req->length = 1;
-               return usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
-               break;
-
-       case US_BULK_RESET_REQUEST:
-               /* XXX maybe we should remove previous requests for IN + OUT */
-               bot_enqueue_cmd_cbw(fu);
-               return 0;
-               break;
-       }
-       return -ENOTSUPP;
-}
-
-/* Start uas.c code */
-
-static void uasp_cleanup_one_stream(struct f_uas *fu, struct uas_stream *stream)
-{
-       /* We have either all three allocated or none */
-       if (!stream->req_in)
-               return;
-
-       usb_ep_free_request(fu->ep_in, stream->req_in);
-       usb_ep_free_request(fu->ep_out, stream->req_out);
-       usb_ep_free_request(fu->ep_status, stream->req_status);
-
-       stream->req_in = NULL;
-       stream->req_out = NULL;
-       stream->req_status = NULL;
-}
-
-static void uasp_free_cmdreq(struct f_uas *fu)
-{
-       usb_ep_free_request(fu->ep_cmd, fu->cmd.req);
-       kfree(fu->cmd.buf);
-       fu->cmd.req = NULL;
-       fu->cmd.buf = NULL;
-}
-
-static void uasp_cleanup_old_alt(struct f_uas *fu)
-{
-       int i;
-
-       if (!(fu->flags & USBG_ENABLED))
-               return;
-
-       usb_ep_disable(fu->ep_in);
-       usb_ep_disable(fu->ep_out);
-       usb_ep_disable(fu->ep_status);
-       usb_ep_disable(fu->ep_cmd);
-
-       for (i = 0; i < UASP_SS_EP_COMP_NUM_STREAMS; i++)
-               uasp_cleanup_one_stream(fu, &fu->stream[i]);
-       uasp_free_cmdreq(fu);
-}
-
-static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req);
-
-static int uasp_prepare_r_request(struct usbg_cmd *cmd)
-{
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-       struct f_uas *fu = cmd->fu;
-       struct usb_gadget *gadget = fuas_to_gadget(fu);
-       struct uas_stream *stream = cmd->stream;
-
-       if (!gadget->sg_supported) {
-               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC);
-               if (!cmd->data_buf)
-                       return -ENOMEM;
-
-               sg_copy_to_buffer(se_cmd->t_data_sg,
-                               se_cmd->t_data_nents,
-                               cmd->data_buf,
-                               se_cmd->data_length);
-
-               stream->req_in->buf = cmd->data_buf;
-       } else {
-               stream->req_in->buf = NULL;
-               stream->req_in->num_sgs = se_cmd->t_data_nents;
-               stream->req_in->sg = se_cmd->t_data_sg;
-       }
-
-       stream->req_in->complete = uasp_status_data_cmpl;
-       stream->req_in->length = se_cmd->data_length;
-       stream->req_in->context = cmd;
-
-       cmd->state = UASP_SEND_STATUS;
-       return 0;
-}
-
-static void uasp_prepare_status(struct usbg_cmd *cmd)
-{
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-       struct sense_iu *iu = &cmd->sense_iu;
-       struct uas_stream *stream = cmd->stream;
-
-       cmd->state = UASP_QUEUE_COMMAND;
-       iu->iu_id = IU_ID_STATUS;
-       iu->tag = cpu_to_be16(cmd->tag);
-
-       /*
-        * iu->status_qual = cpu_to_be16(STATUS QUALIFIER SAM-4. Where R U?);
-        */
-       iu->len = cpu_to_be16(se_cmd->scsi_sense_length);
-       iu->status = se_cmd->scsi_status;
-       stream->req_status->context = cmd;
-       stream->req_status->length = se_cmd->scsi_sense_length + 16;
-       stream->req_status->buf = iu;
-       stream->req_status->complete = uasp_status_data_cmpl;
-}
-
-static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req)
-{
-       struct usbg_cmd *cmd = req->context;
-       struct uas_stream *stream = cmd->stream;
-       struct f_uas *fu = cmd->fu;
-       int ret;
-
-       if (req->status < 0)
-               goto cleanup;
-
-       switch (cmd->state) {
-       case UASP_SEND_DATA:
-               ret = uasp_prepare_r_request(cmd);
-               if (ret)
-                       goto cleanup;
-               ret = usb_ep_queue(fu->ep_in, stream->req_in, GFP_ATOMIC);
-               if (ret)
-                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
-               break;
-
-       case UASP_RECEIVE_DATA:
-               ret = usbg_prepare_w_request(cmd, stream->req_out);
-               if (ret)
-                       goto cleanup;
-               ret = usb_ep_queue(fu->ep_out, stream->req_out, GFP_ATOMIC);
-               if (ret)
-                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
-               break;
-
-       case UASP_SEND_STATUS:
-               uasp_prepare_status(cmd);
-               ret = usb_ep_queue(fu->ep_status, stream->req_status,
-                               GFP_ATOMIC);
-               if (ret)
-                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
-               break;
-
-       case UASP_QUEUE_COMMAND:
-               usbg_cleanup_cmd(cmd);
-               usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
-               break;
-
-       default:
-               BUG();
-       }
-       return;
-
-cleanup:
-       usbg_cleanup_cmd(cmd);
-}
-
-static int uasp_send_status_response(struct usbg_cmd *cmd)
-{
-       struct f_uas *fu = cmd->fu;
-       struct uas_stream *stream = cmd->stream;
-       struct sense_iu *iu = &cmd->sense_iu;
-
-       iu->tag = cpu_to_be16(cmd->tag);
-       stream->req_status->complete = uasp_status_data_cmpl;
-       stream->req_status->context = cmd;
-       cmd->fu = fu;
-       uasp_prepare_status(cmd);
-       return usb_ep_queue(fu->ep_status, stream->req_status, GFP_ATOMIC);
-}
-
-static int uasp_send_read_response(struct usbg_cmd *cmd)
-{
-       struct f_uas *fu = cmd->fu;
-       struct uas_stream *stream = cmd->stream;
-       struct sense_iu *iu = &cmd->sense_iu;
-       int ret;
-
-       cmd->fu = fu;
-
-       iu->tag = cpu_to_be16(cmd->tag);
-       if (fu->flags & USBG_USE_STREAMS) {
-
-               ret = uasp_prepare_r_request(cmd);
-               if (ret)
-                       goto out;
-               ret = usb_ep_queue(fu->ep_in, stream->req_in, GFP_ATOMIC);
-               if (ret) {
-                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
-                       kfree(cmd->data_buf);
-                       cmd->data_buf = NULL;
-               }
-
-       } else {
-
-               iu->iu_id = IU_ID_READ_READY;
-               iu->tag = cpu_to_be16(cmd->tag);
-
-               stream->req_status->complete = uasp_status_data_cmpl;
-               stream->req_status->context = cmd;
-
-               cmd->state = UASP_SEND_DATA;
-               stream->req_status->buf = iu;
-               stream->req_status->length = sizeof(struct iu);
-
-               ret = usb_ep_queue(fu->ep_status, stream->req_status,
-                               GFP_ATOMIC);
-               if (ret)
-                       pr_err("%s(%d) => %d\n", __func__, __LINE__, ret);
-       }
-out:
-       return ret;
-}
-
-static int uasp_send_write_request(struct usbg_cmd *cmd)
-{
-       struct f_uas *fu = cmd->fu;
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-       struct uas_stream *stream = cmd->stream;
-       struct sense_iu *iu = &cmd->sense_iu;
-       int ret;
-
-       init_completion(&cmd->write_complete);
-       cmd->fu = fu;
-
-       iu->tag = cpu_to_be16(cmd->tag);
-
-       if (fu->flags & USBG_USE_STREAMS) {
-
-               ret = usbg_prepare_w_request(cmd, stream->req_out);
-               if (ret)
-                       goto cleanup;
-               ret = usb_ep_queue(fu->ep_out, stream->req_out, GFP_ATOMIC);
-               if (ret)
-                       pr_err("%s(%d)\n", __func__, __LINE__);
-
-       } else {
-
-               iu->iu_id = IU_ID_WRITE_READY;
-               iu->tag = cpu_to_be16(cmd->tag);
-
-               stream->req_status->complete = uasp_status_data_cmpl;
-               stream->req_status->context = cmd;
-
-               cmd->state = UASP_RECEIVE_DATA;
-               stream->req_status->buf = iu;
-               stream->req_status->length = sizeof(struct iu);
-
-               ret = usb_ep_queue(fu->ep_status, stream->req_status,
-                               GFP_ATOMIC);
-               if (ret)
-                       pr_err("%s(%d)\n", __func__, __LINE__);
-       }
-
-       wait_for_completion(&cmd->write_complete);
-       target_execute_cmd(se_cmd);
-cleanup:
-       return ret;
-}
-
-static int usbg_submit_command(struct f_uas *, void *, unsigned int);
-
-static void uasp_cmd_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       struct f_uas *fu = req->context;
-       int ret;
-
-       if (req->status < 0)
-               return;
-
-       ret = usbg_submit_command(fu, req->buf, req->actual);
-       /*
-        * Once we tune for performance enqueue the command req here again so
-        * we can receive a second command while we processing this one. Pay
-        * attention to properly sync STAUS endpoint with DATA IN + OUT so you
-        * don't break HS.
-        */
-       if (!ret)
-               return;
-       usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
-}
-
-static int uasp_alloc_stream_res(struct f_uas *fu, struct uas_stream *stream)
-{
-       stream->req_in = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL);
-       if (!stream->req_in)
-               goto out;
-
-       stream->req_out = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL);
-       if (!stream->req_out)
-               goto err_out;
-
-       stream->req_status = usb_ep_alloc_request(fu->ep_status, GFP_KERNEL);
-       if (!stream->req_status)
-               goto err_sts;
-
-       return 0;
-err_sts:
-       usb_ep_free_request(fu->ep_status, stream->req_status);
-       stream->req_status = NULL;
-err_out:
-       usb_ep_free_request(fu->ep_out, stream->req_out);
-       stream->req_out = NULL;
-out:
-       return -ENOMEM;
-}
-
-static int uasp_alloc_cmd(struct f_uas *fu)
-{
-       fu->cmd.req = usb_ep_alloc_request(fu->ep_cmd, GFP_KERNEL);
-       if (!fu->cmd.req)
-               goto err;
-
-       fu->cmd.buf = kmalloc(fu->ep_cmd->maxpacket, GFP_KERNEL);
-       if (!fu->cmd.buf)
-               goto err_buf;
-
-       fu->cmd.req->complete = uasp_cmd_complete;
-       fu->cmd.req->buf = fu->cmd.buf;
-       fu->cmd.req->length = fu->ep_cmd->maxpacket;
-       fu->cmd.req->context = fu;
-       return 0;
-
-err_buf:
-       usb_ep_free_request(fu->ep_cmd, fu->cmd.req);
-err:
-       return -ENOMEM;
-}
-
-static void uasp_setup_stream_res(struct f_uas *fu, int max_streams)
-{
-       int i;
-
-       for (i = 0; i < max_streams; i++) {
-               struct uas_stream *s = &fu->stream[i];
-
-               s->req_in->stream_id = i + 1;
-               s->req_out->stream_id = i + 1;
-               s->req_status->stream_id = i + 1;
-       }
-}
-
-static int uasp_prepare_reqs(struct f_uas *fu)
-{
-       int ret;
-       int i;
-       int max_streams;
-
-       if (fu->flags & USBG_USE_STREAMS)
-               max_streams = UASP_SS_EP_COMP_NUM_STREAMS;
-       else
-               max_streams = 1;
-
-       for (i = 0; i < max_streams; i++) {
-               ret = uasp_alloc_stream_res(fu, &fu->stream[i]);
-               if (ret)
-                       goto err_cleanup;
-       }
-
-       ret = uasp_alloc_cmd(fu);
-       if (ret)
-               goto err_free_stream;
-       uasp_setup_stream_res(fu, max_streams);
-
-       ret = usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
-       if (ret)
-               goto err_free_stream;
-
-       return 0;
-
-err_free_stream:
-       uasp_free_cmdreq(fu);
-
-err_cleanup:
-       if (i) {
-               do {
-                       uasp_cleanup_one_stream(fu, &fu->stream[i - 1]);
-                       i--;
-               } while (i);
-       }
-       pr_err("UASP: endpoint setup failed\n");
-       return ret;
-}
-
-static void uasp_set_alt(struct f_uas *fu)
-{
-       struct usb_function *f = &fu->function;
-       struct usb_gadget *gadget = f->config->cdev->gadget;
-       int ret;
-
-       fu->flags = USBG_IS_UAS;
-
-       if (gadget->speed == USB_SPEED_SUPER)
-               fu->flags |= USBG_USE_STREAMS;
-
-       config_ep_by_speed(gadget, f, fu->ep_in);
-       ret = usb_ep_enable(fu->ep_in);
-       if (ret)
-               goto err_b_in;
-
-       config_ep_by_speed(gadget, f, fu->ep_out);
-       ret = usb_ep_enable(fu->ep_out);
-       if (ret)
-               goto err_b_out;
-
-       config_ep_by_speed(gadget, f, fu->ep_cmd);
-       ret = usb_ep_enable(fu->ep_cmd);
-       if (ret)
-               goto err_cmd;
-       config_ep_by_speed(gadget, f, fu->ep_status);
-       ret = usb_ep_enable(fu->ep_status);
-       if (ret)
-               goto err_status;
-
-       ret = uasp_prepare_reqs(fu);
-       if (ret)
-               goto err_wq;
-       fu->flags |= USBG_ENABLED;
-
-       pr_info("Using the UAS protocol\n");
-       return;
-err_wq:
-       usb_ep_disable(fu->ep_status);
-err_status:
-       usb_ep_disable(fu->ep_cmd);
-err_cmd:
-       usb_ep_disable(fu->ep_out);
-err_b_out:
-       usb_ep_disable(fu->ep_in);
-err_b_in:
-       fu->flags = 0;
-}
-
-static int get_cmd_dir(const unsigned char *cdb)
-{
-       int ret;
-
-       switch (cdb[0]) {
-       case READ_6:
-       case READ_10:
-       case READ_12:
-       case READ_16:
-       case INQUIRY:
-       case MODE_SENSE:
-       case MODE_SENSE_10:
-       case SERVICE_ACTION_IN_16:
-       case MAINTENANCE_IN:
-       case PERSISTENT_RESERVE_IN:
-       case SECURITY_PROTOCOL_IN:
-       case ACCESS_CONTROL_IN:
-       case REPORT_LUNS:
-       case READ_BLOCK_LIMITS:
-       case READ_POSITION:
-       case READ_CAPACITY:
-       case READ_TOC:
-       case READ_FORMAT_CAPACITIES:
-       case REQUEST_SENSE:
-               ret = DMA_FROM_DEVICE;
-               break;
-
-       case WRITE_6:
-       case WRITE_10:
-       case WRITE_12:
-       case WRITE_16:
-       case MODE_SELECT:
-       case MODE_SELECT_10:
-       case WRITE_VERIFY:
-       case WRITE_VERIFY_12:
-       case PERSISTENT_RESERVE_OUT:
-       case MAINTENANCE_OUT:
-       case SECURITY_PROTOCOL_OUT:
-       case ACCESS_CONTROL_OUT:
-               ret = DMA_TO_DEVICE;
-               break;
-       case ALLOW_MEDIUM_REMOVAL:
-       case TEST_UNIT_READY:
-       case SYNCHRONIZE_CACHE:
-       case START_STOP:
-       case ERASE:
-       case REZERO_UNIT:
-       case SEEK_10:
-       case SPACE:
-       case VERIFY:
-       case WRITE_FILEMARKS:
-               ret = DMA_NONE;
-               break;
-       default:
-               pr_warn("target: Unknown data direction for SCSI Opcode "
-                               "0x%02x\n", cdb[0]);
-               ret = -EINVAL;
-       }
-       return ret;
-}
-
-static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req)
-{
-       struct usbg_cmd *cmd = req->context;
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-
-       if (req->status < 0) {
-               pr_err("%s() state %d transfer failed\n", __func__, cmd->state);
-               goto cleanup;
-       }
-
-       if (req->num_sgs == 0) {
-               sg_copy_from_buffer(se_cmd->t_data_sg,
-                               se_cmd->t_data_nents,
-                               cmd->data_buf,
-                               se_cmd->data_length);
-       }
-
-       complete(&cmd->write_complete);
-       return;
-
-cleanup:
-       usbg_cleanup_cmd(cmd);
-}
-
-static int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req)
-{
-       struct se_cmd *se_cmd = &cmd->se_cmd;
-       struct f_uas *fu = cmd->fu;
-       struct usb_gadget *gadget = fuas_to_gadget(fu);
-
-       if (!gadget->sg_supported) {
-               cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC);
-               if (!cmd->data_buf)
-                       return -ENOMEM;
-
-               req->buf = cmd->data_buf;
-       } else {
-               req->buf = NULL;
-               req->num_sgs = se_cmd->t_data_nents;
-               req->sg = se_cmd->t_data_sg;
-       }
-
-       req->complete = usbg_data_write_cmpl;
-       req->length = se_cmd->data_length;
-       req->context = cmd;
-       return 0;
-}
-
-static int usbg_send_status_response(struct se_cmd *se_cmd)
-{
-       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
-                       se_cmd);
-       struct f_uas *fu = cmd->fu;
-
-       if (fu->flags & USBG_IS_BOT)
-               return bot_send_status_response(cmd);
-       else
-               return uasp_send_status_response(cmd);
-}
-
-static int usbg_send_write_request(struct se_cmd *se_cmd)
-{
-       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
-                       se_cmd);
-       struct f_uas *fu = cmd->fu;
-
-       if (fu->flags & USBG_IS_BOT)
-               return bot_send_write_request(cmd);
-       else
-               return uasp_send_write_request(cmd);
-}
-
-static int usbg_send_read_response(struct se_cmd *se_cmd)
-{
-       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
-                       se_cmd);
-       struct f_uas *fu = cmd->fu;
-
-       if (fu->flags & USBG_IS_BOT)
-               return bot_send_read_response(cmd);
-       else
-               return uasp_send_read_response(cmd);
-}
-
-static void usbg_cmd_work(struct work_struct *work)
-{
-       struct usbg_cmd *cmd = container_of(work, struct usbg_cmd, work);
-       struct se_cmd *se_cmd;
-       struct tcm_usbg_nexus *tv_nexus;
-       struct usbg_tpg *tpg;
-       int dir;
-
-       se_cmd = &cmd->se_cmd;
-       tpg = cmd->fu->tpg;
-       tv_nexus = tpg->tpg_nexus;
-       dir = get_cmd_dir(cmd->cmd_buf);
-       if (dir < 0) {
-               transport_init_se_cmd(se_cmd,
-                               tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
-                               tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
-                               cmd->prio_attr, cmd->sense_iu.sense);
-               goto out;
-       }
-
-       if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
-                       cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
-                       0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE) < 0)
-               goto out;
-
-       return;
-
-out:
-       transport_send_check_condition_and_sense(se_cmd,
-                       TCM_UNSUPPORTED_SCSI_OPCODE, 1);
-       usbg_cleanup_cmd(cmd);
-}
-
-static int usbg_submit_command(struct f_uas *fu,
-               void *cmdbuf, unsigned int len)
-{
-       struct command_iu *cmd_iu = cmdbuf;
-       struct usbg_cmd *cmd;
-       struct usbg_tpg *tpg;
-       struct se_cmd *se_cmd;
-       struct tcm_usbg_nexus *tv_nexus;
-       u32 cmd_len;
-       int ret;
-
-       if (cmd_iu->iu_id != IU_ID_COMMAND) {
-               pr_err("Unsupported type %d\n", cmd_iu->iu_id);
-               return -EINVAL;
-       }
-
-       cmd = kzalloc(sizeof *cmd, GFP_ATOMIC);
-       if (!cmd)
-               return -ENOMEM;
-
-       cmd->fu = fu;
-
-       /* XXX until I figure out why I can't free in on complete */
-       kref_init(&cmd->ref);
-       kref_get(&cmd->ref);
-
-       tpg = fu->tpg;
-       cmd_len = (cmd_iu->len & ~0x3) + 16;
-       if (cmd_len > USBG_MAX_CMD)
-               goto err;
-
-       memcpy(cmd->cmd_buf, cmd_iu->cdb, cmd_len);
-
-       cmd->tag = be16_to_cpup(&cmd_iu->tag);
-       cmd->se_cmd.tag = cmd->tag;
-       if (fu->flags & USBG_USE_STREAMS) {
-               if (cmd->tag > UASP_SS_EP_COMP_NUM_STREAMS)
-                       goto err;
-               if (!cmd->tag)
-                       cmd->stream = &fu->stream[0];
-               else
-                       cmd->stream = &fu->stream[cmd->tag - 1];
-       } else {
-               cmd->stream = &fu->stream[0];
-       }
-
-       tv_nexus = tpg->tpg_nexus;
-       if (!tv_nexus) {
-               pr_err("Missing nexus, ignoring command\n");
-               goto err;
-       }
-
-       switch (cmd_iu->prio_attr & 0x7) {
-       case UAS_HEAD_TAG:
-               cmd->prio_attr = TCM_HEAD_TAG;
-               break;
-       case UAS_ORDERED_TAG:
-               cmd->prio_attr = TCM_ORDERED_TAG;
-               break;
-       case UAS_ACA:
-               cmd->prio_attr = TCM_ACA_TAG;
-               break;
-       default:
-               pr_debug_once("Unsupported prio_attr: %02x.\n",
-                               cmd_iu->prio_attr);
-       case UAS_SIMPLE_TAG:
-               cmd->prio_attr = TCM_SIMPLE_TAG;
-               break;
-       }
-
-       se_cmd = &cmd->se_cmd;
-       cmd->unpacked_lun = scsilun_to_int(&cmd_iu->lun);
-
-       INIT_WORK(&cmd->work, usbg_cmd_work);
-       ret = queue_work(tpg->workqueue, &cmd->work);
-       if (ret < 0)
-               goto err;
-
-       return 0;
-err:
-       kfree(cmd);
-       return -EINVAL;
-}
-
-static void bot_cmd_work(struct work_struct *work)
-{
-       struct usbg_cmd *cmd = container_of(work, struct usbg_cmd, work);
-       struct se_cmd *se_cmd;
-       struct tcm_usbg_nexus *tv_nexus;
-       struct usbg_tpg *tpg;
-       int dir;
-
-       se_cmd = &cmd->se_cmd;
-       tpg = cmd->fu->tpg;
-       tv_nexus = tpg->tpg_nexus;
-       dir = get_cmd_dir(cmd->cmd_buf);
-       if (dir < 0) {
-               transport_init_se_cmd(se_cmd,
-                               tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
-                               tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
-                               cmd->prio_attr, cmd->sense_iu.sense);
-               goto out;
-       }
-
-       if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
-                       cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
-                       cmd->data_len, cmd->prio_attr, dir, 0) < 0)
-               goto out;
-
-       return;
-
-out:
-       transport_send_check_condition_and_sense(se_cmd,
-                               TCM_UNSUPPORTED_SCSI_OPCODE, 1);
-       usbg_cleanup_cmd(cmd);
-}
-
-static int bot_submit_command(struct f_uas *fu,
-               void *cmdbuf, unsigned int len)
-{
-       struct bulk_cb_wrap *cbw = cmdbuf;
-       struct usbg_cmd *cmd;
-       struct usbg_tpg *tpg;
-       struct se_cmd *se_cmd;
-       struct tcm_usbg_nexus *tv_nexus;
-       u32 cmd_len;
-       int ret;
-
-       if (cbw->Signature != cpu_to_le32(US_BULK_CB_SIGN)) {
-               pr_err("Wrong signature on CBW\n");
-               return -EINVAL;
-       }
-       if (len != 31) {
-               pr_err("Wrong length for CBW\n");
-               return -EINVAL;
-       }
-
-       cmd_len = cbw->Length;
-       if (cmd_len < 1 || cmd_len > 16)
-               return -EINVAL;
-
-       cmd = kzalloc(sizeof *cmd, GFP_ATOMIC);
-       if (!cmd)
-               return -ENOMEM;
-
-       cmd->fu = fu;
-
-       /* XXX until I figure out why I can't free in on complete */
-       kref_init(&cmd->ref);
-       kref_get(&cmd->ref);
-
-       tpg = fu->tpg;
-
-       memcpy(cmd->cmd_buf, cbw->CDB, cmd_len);
-
-       cmd->bot_tag = cbw->Tag;
-
-       tv_nexus = tpg->tpg_nexus;
-       if (!tv_nexus) {
-               pr_err("Missing nexus, ignoring command\n");
-               goto err;
-       }
-
-       cmd->prio_attr = TCM_SIMPLE_TAG;
-       se_cmd = &cmd->se_cmd;
-       cmd->unpacked_lun = cbw->Lun;
-       cmd->is_read = cbw->Flags & US_BULK_FLAG_IN ? 1 : 0;
-       cmd->data_len = le32_to_cpu(cbw->DataTransferLength);
-       cmd->se_cmd.tag = le32_to_cpu(cmd->bot_tag);
-
-       INIT_WORK(&cmd->work, bot_cmd_work);
-       ret = queue_work(tpg->workqueue, &cmd->work);
-       if (ret < 0)
-               goto err;
-
-       return 0;
-err:
-       kfree(cmd);
-       return -EINVAL;
-}
-
-/* Start fabric.c code */
-
-static int usbg_check_true(struct se_portal_group *se_tpg)
-{
-       return 1;
-}
-
-static int usbg_check_false(struct se_portal_group *se_tpg)
-{
-       return 0;
-}
-
-static char *usbg_get_fabric_name(void)
-{
-       return "usb_gadget";
-}
-
-static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg)
-{
-       struct usbg_tpg *tpg = container_of(se_tpg,
-                               struct usbg_tpg, se_tpg);
-       struct usbg_tport *tport = tpg->tport;
-
-       return &tport->tport_name[0];
-}
-
-static u16 usbg_get_tag(struct se_portal_group *se_tpg)
-{
-       struct usbg_tpg *tpg = container_of(se_tpg,
-                               struct usbg_tpg, se_tpg);
-       return tpg->tport_tpgt;
-}
-
-static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg)
-{
-       return 1;
-}
-
-static void usbg_cmd_release(struct kref *ref)
-{
-       struct usbg_cmd *cmd = container_of(ref, struct usbg_cmd,
-                       ref);
-
-       transport_generic_free_cmd(&cmd->se_cmd, 0);
-}
-
-static void usbg_release_cmd(struct se_cmd *se_cmd)
-{
-       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
-                       se_cmd);
-       kfree(cmd->data_buf);
-       kfree(cmd);
-       return;
-}
-
-static int usbg_shutdown_session(struct se_session *se_sess)
-{
-       return 0;
-}
-
-static void usbg_close_session(struct se_session *se_sess)
-{
-       return;
-}
-
-static u32 usbg_sess_get_index(struct se_session *se_sess)
-{
-       return 0;
-}
-
-/*
- * XXX Error recovery: return != 0 if we expect writes. Dunno when that could be
- */
-static int usbg_write_pending_status(struct se_cmd *se_cmd)
-{
-       return 0;
-}
-
-static void usbg_set_default_node_attrs(struct se_node_acl *nacl)
-{
-       return;
-}
-
-static int usbg_get_cmd_state(struct se_cmd *se_cmd)
-{
-       return 0;
-}
-
-static void usbg_queue_tm_rsp(struct se_cmd *se_cmd)
-{
-}
-
-static void usbg_aborted_task(struct se_cmd *se_cmd)
-{
-       return;
-}
-
-static const char *usbg_check_wwn(const char *name)
-{
-       const char *n;
-       unsigned int len;
-
-       n = strstr(name, "naa.");
-       if (!n)
-               return NULL;
-       n += 4;
-       len = strlen(n);
-       if (len == 0 || len > USBG_NAMELEN - 1)
-               return NULL;
-       return n;
-}
-
-static int usbg_init_nodeacl(struct se_node_acl *se_nacl, const char *name)
-{
-       if (!usbg_check_wwn(name))
-               return -EINVAL;
-       return 0;
-}
-
-struct usbg_tpg *the_only_tpg_I_currently_have;
-
-static struct se_portal_group *usbg_make_tpg(
-       struct se_wwn *wwn,
-       struct config_group *group,
-       const char *name)
-{
-       struct usbg_tport *tport = container_of(wwn, struct usbg_tport,
-                       tport_wwn);
-       struct usbg_tpg *tpg;
-       unsigned long tpgt;
-       int ret;
-
-       if (strstr(name, "tpgt_") != name)
-               return ERR_PTR(-EINVAL);
-       if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX)
-               return ERR_PTR(-EINVAL);
-       if (the_only_tpg_I_currently_have) {
-               pr_err("Until the gadget framework can't handle multiple\n");
-               pr_err("gadgets, you can't do this here.\n");
-               return ERR_PTR(-EBUSY);
-       }
-
-       tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL);
-       if (!tpg)
-               return ERR_PTR(-ENOMEM);
-       mutex_init(&tpg->tpg_mutex);
-       atomic_set(&tpg->tpg_port_count, 0);
-       tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1);
-       if (!tpg->workqueue) {
-               kfree(tpg);
-               return NULL;
-       }
-
-       tpg->tport = tport;
-       tpg->tport_tpgt = tpgt;
-
-       /*
-        * SPC doesn't assign a protocol identifier for USB-SCSI, so we
-        * pretend to be SAS..
-        */
-       ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SAS);
-       if (ret < 0) {
-               destroy_workqueue(tpg->workqueue);
-               kfree(tpg);
-               return NULL;
-       }
-       the_only_tpg_I_currently_have = tpg;
-       return &tpg->se_tpg;
-}
-
-static void usbg_drop_tpg(struct se_portal_group *se_tpg)
-{
-       struct usbg_tpg *tpg = container_of(se_tpg,
-                               struct usbg_tpg, se_tpg);
-
-       core_tpg_deregister(se_tpg);
-       destroy_workqueue(tpg->workqueue);
-       kfree(tpg);
-       the_only_tpg_I_currently_have = NULL;
-}
-
-static struct se_wwn *usbg_make_tport(
-       struct target_fabric_configfs *tf,
-       struct config_group *group,
-       const char *name)
-{
-       struct usbg_tport *tport;
-       const char *wnn_name;
-       u64 wwpn = 0;
-
-       wnn_name = usbg_check_wwn(name);
-       if (!wnn_name)
-               return ERR_PTR(-EINVAL);
-
-       tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL);
-       if (!(tport))
-               return ERR_PTR(-ENOMEM);
-       tport->tport_wwpn = wwpn;
-       snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name);
-       return &tport->tport_wwn;
-}
-
-static void usbg_drop_tport(struct se_wwn *wwn)
-{
-       struct usbg_tport *tport = container_of(wwn,
-                               struct usbg_tport, tport_wwn);
-       kfree(tport);
-}
-
-/*
- * If somebody feels like dropping the version property, go ahead.
- */
-static ssize_t usbg_wwn_version_show(struct config_item *item, char *page)
-{
-       return sprintf(page, "usb-gadget fabric module\n");
-}
-
-CONFIGFS_ATTR_RO(usbg_wwn_, version);
-
-static struct configfs_attribute *usbg_wwn_attrs[] = {
-       &usbg_wwn_attr_version,
-       NULL,
-};
-
-static ssize_t tcm_usbg_tpg_enable_show(struct config_item *item, char *page)
-{
-       struct se_portal_group *se_tpg = to_tpg(item);
-       struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
-
-       return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect);
-}
-
-static int usbg_attach(struct usbg_tpg *);
-static void usbg_detach(struct usbg_tpg *);
-
-static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item,
-               const char *page, size_t count)
-{
-       struct se_portal_group *se_tpg = to_tpg(item);
-       struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
-       unsigned long op;
-       ssize_t ret;
-
-       ret = kstrtoul(page, 0, &op);
-       if (ret < 0)
-               return -EINVAL;
-       if (op > 1)
-               return -EINVAL;
-
-       if (op && tpg->gadget_connect)
-               goto out;
-       if (!op && !tpg->gadget_connect)
-               goto out;
-
-       if (op) {
-               ret = usbg_attach(tpg);
-               if (ret)
-                       goto out;
-       } else {
-               usbg_detach(tpg);
-       }
-       tpg->gadget_connect = op;
-out:
-       return count;
-}
-
-static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page)
-{
-       struct se_portal_group *se_tpg = to_tpg(item);
-       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
-       struct tcm_usbg_nexus *tv_nexus;
-       ssize_t ret;
-
-       mutex_lock(&tpg->tpg_mutex);
-       tv_nexus = tpg->tpg_nexus;
-       if (!tv_nexus) {
-               ret = -ENODEV;
-               goto out;
-       }
-       ret = snprintf(page, PAGE_SIZE, "%s\n",
-                       tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
-out:
-       mutex_unlock(&tpg->tpg_mutex);
-       return ret;
-}
-
-static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
-{
-       struct se_portal_group *se_tpg;
-       struct tcm_usbg_nexus *tv_nexus;
-       int ret;
-
-       mutex_lock(&tpg->tpg_mutex);
-       if (tpg->tpg_nexus) {
-               ret = -EEXIST;
-               pr_debug("tpg->tpg_nexus already exists\n");
-               goto err_unlock;
-       }
-       se_tpg = &tpg->se_tpg;
-
-       ret = -ENOMEM;
-       tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
-       if (!tv_nexus)
-               goto err_unlock;
-       tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL);
-       if (IS_ERR(tv_nexus->tvn_se_sess))
-               goto err_free;
-
-       /*
-        * Since we are running in 'demo mode' this call with generate a
-        * struct se_node_acl for the tcm_vhost struct se_portal_group with
-        * the SCSI Initiator port name of the passed configfs group 'name'.
-        */
-       tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
-                       se_tpg, name);
-       if (!tv_nexus->tvn_se_sess->se_node_acl) {
-               pr_debug("core_tpg_check_initiator_node_acl() failed"
-                               " for %s\n", name);
-               goto err_session;
-       }
-       /*
-        * Now register the TCM vHost virtual I_T Nexus as active.
-        */
-       transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
-                       tv_nexus->tvn_se_sess, tv_nexus);
-       tpg->tpg_nexus = tv_nexus;
-       mutex_unlock(&tpg->tpg_mutex);
-       return 0;
-
-err_session:
-       transport_free_session(tv_nexus->tvn_se_sess);
-err_free:
-       kfree(tv_nexus);
-err_unlock:
-       mutex_unlock(&tpg->tpg_mutex);
-       return ret;
-}
-
-static int tcm_usbg_drop_nexus(struct usbg_tpg *tpg)
-{
-       struct se_session *se_sess;
-       struct tcm_usbg_nexus *tv_nexus;
-       int ret = -ENODEV;
-
-       mutex_lock(&tpg->tpg_mutex);
-       tv_nexus = tpg->tpg_nexus;
-       if (!tv_nexus)
-               goto out;
-
-       se_sess = tv_nexus->tvn_se_sess;
-       if (!se_sess)
-               goto out;
-
-       if (atomic_read(&tpg->tpg_port_count)) {
-               ret = -EPERM;
-               pr_err("Unable to remove Host I_T Nexus with"
-                               " active TPG port count: %d\n",
-                               atomic_read(&tpg->tpg_port_count));
-               goto out;
-       }
-
-       pr_debug("Removing I_T Nexus to Initiator Port: %s\n",
-                       tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
-       /*
-        * Release the SCSI I_T Nexus to the emulated vHost Target Port
-        */
-       transport_deregister_session(tv_nexus->tvn_se_sess);
-       tpg->tpg_nexus = NULL;
-
-       kfree(tv_nexus);
-       ret = 0;
-out:
-       mutex_unlock(&tpg->tpg_mutex);
-       return ret;
-}
-
-static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item,
-               const char *page, size_t count)
-{
-       struct se_portal_group *se_tpg = to_tpg(item);
-       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
-       unsigned char i_port[USBG_NAMELEN], *ptr;
-       int ret;
-
-       if (!strncmp(page, "NULL", 4)) {
-               ret = tcm_usbg_drop_nexus(tpg);
-               return (!ret) ? count : ret;
-       }
-       if (strlen(page) >= USBG_NAMELEN) {
-               pr_err("Emulated NAA Sas Address: %s, exceeds"
-                               " max: %d\n", page, USBG_NAMELEN);
-               return -EINVAL;
-       }
-       snprintf(i_port, USBG_NAMELEN, "%s", page);
-
-       ptr = strstr(i_port, "naa.");
-       if (!ptr) {
-               pr_err("Missing 'naa.' prefix\n");
-               return -EINVAL;
-       }
-
-       if (i_port[strlen(i_port) - 1] == '\n')
-               i_port[strlen(i_port) - 1] = '\0';
-
-       ret = tcm_usbg_make_nexus(tpg, &i_port[4]);
-       if (ret < 0)
-               return ret;
-       return count;
-}
-
-CONFIGFS_ATTR(tcm_usbg_tpg_, enable);
-CONFIGFS_ATTR(tcm_usbg_tpg_, nexus);
-
-static struct configfs_attribute *usbg_base_attrs[] = {
-       &tcm_usbg_tpg_attr_enable,
-       &tcm_usbg_tpg_attr_nexus,
-       NULL,
-};
-
-static int usbg_port_link(struct se_portal_group *se_tpg, struct se_lun *lun)
-{
-       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
-
-       atomic_inc(&tpg->tpg_port_count);
-       smp_mb__after_atomic();
-       return 0;
-}
-
-static void usbg_port_unlink(struct se_portal_group *se_tpg,
-               struct se_lun *se_lun)
-{
-       struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
-
-       atomic_dec(&tpg->tpg_port_count);
-       smp_mb__after_atomic();
-}
-
-static int usbg_check_stop_free(struct se_cmd *se_cmd)
-{
-       struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
-                       se_cmd);
-
-       kref_put(&cmd->ref, usbg_cmd_release);
-       return 1;
-}
-
-static const struct target_core_fabric_ops usbg_ops = {
-       .module                         = THIS_MODULE,
-       .name                           = "usb_gadget",
-       .get_fabric_name                = usbg_get_fabric_name,
-       .tpg_get_wwn                    = usbg_get_fabric_wwn,
-       .tpg_get_tag                    = usbg_get_tag,
-       .tpg_check_demo_mode            = usbg_check_true,
-       .tpg_check_demo_mode_cache      = usbg_check_false,
-       .tpg_check_demo_mode_write_protect = usbg_check_false,
-       .tpg_check_prod_mode_write_protect = usbg_check_false,
-       .tpg_get_inst_index             = usbg_tpg_get_inst_index,
-       .release_cmd                    = usbg_release_cmd,
-       .shutdown_session               = usbg_shutdown_session,
-       .close_session                  = usbg_close_session,
-       .sess_get_index                 = usbg_sess_get_index,
-       .sess_get_initiator_sid         = NULL,
-       .write_pending                  = usbg_send_write_request,
-       .write_pending_status           = usbg_write_pending_status,
-       .set_default_node_attributes    = usbg_set_default_node_attrs,
-       .get_cmd_state                  = usbg_get_cmd_state,
-       .queue_data_in                  = usbg_send_read_response,
-       .queue_status                   = usbg_send_status_response,
-       .queue_tm_rsp                   = usbg_queue_tm_rsp,
-       .aborted_task                   = usbg_aborted_task,
-       .check_stop_free                = usbg_check_stop_free,
-
-       .fabric_make_wwn                = usbg_make_tport,
-       .fabric_drop_wwn                = usbg_drop_tport,
-       .fabric_make_tpg                = usbg_make_tpg,
-       .fabric_drop_tpg                = usbg_drop_tpg,
-       .fabric_post_link               = usbg_port_link,
-       .fabric_pre_unlink              = usbg_port_unlink,
-       .fabric_init_nodeacl            = usbg_init_nodeacl,
-
-       .tfc_wwn_attrs                  = usbg_wwn_attrs,
-       .tfc_tpg_base_attrs             = usbg_base_attrs,
-};
-
-/* Start gadget.c code */
-
-static struct usb_interface_descriptor bot_intf_desc = {
-       .bLength =              sizeof(bot_intf_desc),
-       .bDescriptorType =      USB_DT_INTERFACE,
-       .bNumEndpoints =        2,
-       .bAlternateSetting =    USB_G_ALT_INT_BBB,
-       .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
-       .bInterfaceSubClass =   USB_SC_SCSI,
-       .bInterfaceProtocol =   USB_PR_BULK,
-};
-
-static struct usb_interface_descriptor uasp_intf_desc = {
-       .bLength =              sizeof(uasp_intf_desc),
-       .bDescriptorType =      USB_DT_INTERFACE,
-       .bNumEndpoints =        4,
-       .bAlternateSetting =    USB_G_ALT_INT_UAS,
-       .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
-       .bInterfaceSubClass =   USB_SC_SCSI,
-       .bInterfaceProtocol =   USB_PR_UAS,
-};
-
-static struct usb_endpoint_descriptor uasp_bi_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor uasp_fs_bi_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usb_pipe_usage_descriptor uasp_bi_pipe_desc = {
-       .bLength =              sizeof(uasp_bi_pipe_desc),
-       .bDescriptorType =      USB_DT_PIPE_USAGE,
-       .bPipeID =              DATA_IN_PIPE_ID,
-};
-
-static struct usb_endpoint_descriptor uasp_ss_bi_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor uasp_bi_ep_comp_desc = {
-       .bLength =              sizeof(uasp_bi_ep_comp_desc),
-       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-       .bMaxBurst =            0,
-       .bmAttributes =         UASP_SS_EP_COMP_LOG_STREAMS,
-       .wBytesPerInterval =    0,
-};
-
-static struct usb_ss_ep_comp_descriptor bot_bi_ep_comp_desc = {
-       .bLength =              sizeof(bot_bi_ep_comp_desc),
-       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-       .bMaxBurst =            0,
-};
-
-static struct usb_endpoint_descriptor uasp_bo_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor uasp_fs_bo_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usb_pipe_usage_descriptor uasp_bo_pipe_desc = {
-       .bLength =              sizeof(uasp_bo_pipe_desc),
-       .bDescriptorType =      USB_DT_PIPE_USAGE,
-       .bPipeID =              DATA_OUT_PIPE_ID,
-};
-
-static struct usb_endpoint_descriptor uasp_ss_bo_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(0x400),
-};
-
-static struct usb_ss_ep_comp_descriptor uasp_bo_ep_comp_desc = {
-       .bLength =              sizeof(uasp_bo_ep_comp_desc),
-       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-       .bmAttributes =         UASP_SS_EP_COMP_LOG_STREAMS,
-};
-
-static struct usb_ss_ep_comp_descriptor bot_bo_ep_comp_desc = {
-       .bLength =              sizeof(bot_bo_ep_comp_desc),
-       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-};
-
-static struct usb_endpoint_descriptor uasp_status_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor uasp_fs_status_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usb_pipe_usage_descriptor uasp_status_pipe_desc = {
-       .bLength =              sizeof(uasp_status_pipe_desc),
-       .bDescriptorType =      USB_DT_PIPE_USAGE,
-       .bPipeID =              STATUS_PIPE_ID,
-};
-
-static struct usb_endpoint_descriptor uasp_ss_status_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor uasp_status_in_ep_comp_desc = {
-       .bLength =              sizeof(uasp_status_in_ep_comp_desc),
-       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-       .bmAttributes =         UASP_SS_EP_COMP_LOG_STREAMS,
-};
-
-static struct usb_endpoint_descriptor uasp_cmd_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor uasp_fs_cmd_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usb_pipe_usage_descriptor uasp_cmd_pipe_desc = {
-       .bLength =              sizeof(uasp_cmd_pipe_desc),
-       .bDescriptorType =      USB_DT_PIPE_USAGE,
-       .bPipeID =              CMD_PIPE_ID,
-};
-
-static struct usb_endpoint_descriptor uasp_ss_cmd_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor uasp_cmd_comp_desc = {
-       .bLength =              sizeof(uasp_cmd_comp_desc),
-       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-};
-
-static struct usb_descriptor_header *uasp_fs_function_desc[] = {
-       (struct usb_descriptor_header *) &bot_intf_desc,
-       (struct usb_descriptor_header *) &uasp_fs_bi_desc,
-       (struct usb_descriptor_header *) &uasp_fs_bo_desc,
-
-       (struct usb_descriptor_header *) &uasp_intf_desc,
-       (struct usb_descriptor_header *) &uasp_fs_bi_desc,
-       (struct usb_descriptor_header *) &uasp_bi_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_fs_bo_desc,
-       (struct usb_descriptor_header *) &uasp_bo_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_fs_status_desc,
-       (struct usb_descriptor_header *) &uasp_status_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_fs_cmd_desc,
-       (struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
-       NULL,
-};
-
-static struct usb_descriptor_header *uasp_hs_function_desc[] = {
-       (struct usb_descriptor_header *) &bot_intf_desc,
-       (struct usb_descriptor_header *) &uasp_bi_desc,
-       (struct usb_descriptor_header *) &uasp_bo_desc,
-
-       (struct usb_descriptor_header *) &uasp_intf_desc,
-       (struct usb_descriptor_header *) &uasp_bi_desc,
-       (struct usb_descriptor_header *) &uasp_bi_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_bo_desc,
-       (struct usb_descriptor_header *) &uasp_bo_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_status_desc,
-       (struct usb_descriptor_header *) &uasp_status_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_cmd_desc,
-       (struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
-       NULL,
-};
-
-static struct usb_descriptor_header *uasp_ss_function_desc[] = {
-       (struct usb_descriptor_header *) &bot_intf_desc,
-       (struct usb_descriptor_header *) &uasp_ss_bi_desc,
-       (struct usb_descriptor_header *) &bot_bi_ep_comp_desc,
-       (struct usb_descriptor_header *) &uasp_ss_bo_desc,
-       (struct usb_descriptor_header *) &bot_bo_ep_comp_desc,
-
-       (struct usb_descriptor_header *) &uasp_intf_desc,
-       (struct usb_descriptor_header *) &uasp_ss_bi_desc,
-       (struct usb_descriptor_header *) &uasp_bi_ep_comp_desc,
-       (struct usb_descriptor_header *) &uasp_bi_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_ss_bo_desc,
-       (struct usb_descriptor_header *) &uasp_bo_ep_comp_desc,
-       (struct usb_descriptor_header *) &uasp_bo_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_ss_status_desc,
-       (struct usb_descriptor_header *) &uasp_status_in_ep_comp_desc,
-       (struct usb_descriptor_header *) &uasp_status_pipe_desc,
-       (struct usb_descriptor_header *) &uasp_ss_cmd_desc,
-       (struct usb_descriptor_header *) &uasp_cmd_comp_desc,
-       (struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
-       NULL,
-};
-
 #define UAS_VENDOR_ID  0x0525  /* NetChip */
 #define UAS_PRODUCT_ID 0xa4a5  /* Linux-USB File-backed Storage Gadget */
 
@@ -1981,13 +38,13 @@ static struct usb_device_descriptor usbg_device_desc = {
        .bNumConfigurations =   1,
 };
 
+#define USB_G_STR_CONFIG USB_GADGET_FIRST_AVAIL_IDX
+
 static struct usb_string       usbg_us_strings[] = {
        [USB_GADGET_MANUFACTURER_IDX].s = "Target Manufactor",
        [USB_GADGET_PRODUCT_IDX].s      = "Target Product",
        [USB_GADGET_SERIAL_IDX].s       = "000000000001",
        [USB_G_STR_CONFIG].s            = "default config",
-       [USB_G_STR_INT_UAS].s           = "USB Attached SCSI",
-       [USB_G_STR_INT_BBB].s           = "Bulk Only Transport",
        { },
 };
 
@@ -2001,184 +58,42 @@ static struct usb_gadget_strings *usbg_strings[] = {
        NULL,
 };
 
-static int guas_unbind(struct usb_composite_dev *cdev)
-{
-       return 0;
-}
-
-static struct usb_configuration usbg_config_driver = {
-       .label                  = "Linux Target",
-       .bConfigurationValue    = 1,
-       .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
-};
+static struct usb_function_instance *fi_tcm;
+static struct usb_function *f_tcm;
 
-static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
+static int guas_unbind(struct usb_composite_dev *cdev)
 {
-       struct f_uas            *fu = to_f_uas(f);
-       struct usb_gadget       *gadget = c->cdev->gadget;
-       struct usb_ep           *ep;
-       int                     iface;
-       int                     ret;
-
-       iface = usb_interface_id(c, f);
-       if (iface < 0)
-               return iface;
-
-       bot_intf_desc.bInterfaceNumber = iface;
-       uasp_intf_desc.bInterfaceNumber = iface;
-       fu->iface = iface;
-       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc,
-                       &uasp_bi_ep_comp_desc);
-       if (!ep)
-               goto ep_fail;
-       fu->ep_in = ep;
-
-       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
-                       &uasp_bo_ep_comp_desc);
-       if (!ep)
-               goto ep_fail;
-       fu->ep_out = ep;
-
-       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
-                       &uasp_status_in_ep_comp_desc);
-       if (!ep)
-               goto ep_fail;
-       fu->ep_status = ep;
-
-       ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
-                       &uasp_cmd_comp_desc);
-       if (!ep)
-               goto ep_fail;
-       fu->ep_cmd = ep;
-
-       /* Assume endpoint addresses are the same for both speeds */
-       uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress;
-       uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress;
-       uasp_status_desc.bEndpointAddress =
-               uasp_ss_status_desc.bEndpointAddress;
-       uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
-
-       uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress;
-       uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress;
-       uasp_fs_status_desc.bEndpointAddress =
-               uasp_ss_status_desc.bEndpointAddress;
-       uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
-
-       ret = usb_assign_descriptors(f, uasp_fs_function_desc,
-                       uasp_hs_function_desc, uasp_ss_function_desc);
-       if (ret)
-               goto ep_fail;
+       if (!IS_ERR_OR_NULL(f_tcm))
+               usb_put_function(f_tcm);
 
        return 0;
-ep_fail:
-       pr_err("Can't claim all required eps\n");
-       return -ENOTSUPP;
-}
-
-static void usbg_unbind(struct usb_configuration *c, struct usb_function *f)
-{
-       struct f_uas *fu = to_f_uas(f);
-
-       usb_free_all_descriptors(f);
-       kfree(fu);
-}
-
-struct guas_setup_wq {
-       struct work_struct work;
-       struct f_uas *fu;
-       unsigned int alt;
-};
-
-static void usbg_delayed_set_alt(struct work_struct *wq)
-{
-       struct guas_setup_wq *work = container_of(wq, struct guas_setup_wq,
-                       work);
-       struct f_uas *fu = work->fu;
-       int alt = work->alt;
-
-       kfree(work);
-
-       if (fu->flags & USBG_IS_BOT)
-               bot_cleanup_old_alt(fu);
-       if (fu->flags & USBG_IS_UAS)
-               uasp_cleanup_old_alt(fu);
-
-       if (alt == USB_G_ALT_INT_BBB)
-               bot_set_alt(fu);
-       else if (alt == USB_G_ALT_INT_UAS)
-               uasp_set_alt(fu);
-       usb_composite_setup_continue(fu->function.config->cdev);
 }
 
-static int usbg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+static int tcm_do_config(struct usb_configuration *c)
 {
-       struct f_uas *fu = to_f_uas(f);
+       int status;
 
-       if ((alt == USB_G_ALT_INT_BBB) || (alt == USB_G_ALT_INT_UAS)) {
-               struct guas_setup_wq *work;
+       f_tcm = usb_get_function(fi_tcm);
+       if (IS_ERR(f_tcm))
+               return PTR_ERR(f_tcm);
 
-               work = kmalloc(sizeof(*work), GFP_ATOMIC);
-               if (!work)
-                       return -ENOMEM;
-               INIT_WORK(&work->work, usbg_delayed_set_alt);
-               work->fu = fu;
-               work->alt = alt;
-               schedule_work(&work->work);
-               return USB_GADGET_DELAYED_STATUS;
+       status = usb_add_function(c, f_tcm);
+       if (status < 0) {
+               usb_put_function(f_tcm);
+               return status;
        }
-       return -EOPNOTSUPP;
-}
-
-static void usbg_disable(struct usb_function *f)
-{
-       struct f_uas *fu = to_f_uas(f);
-
-       if (fu->flags & USBG_IS_UAS)
-               uasp_cleanup_old_alt(fu);
-       else if (fu->flags & USBG_IS_BOT)
-               bot_cleanup_old_alt(fu);
-       fu->flags = 0;
-}
-
-static int usbg_setup(struct usb_function *f,
-               const struct usb_ctrlrequest *ctrl)
-{
-       struct f_uas *fu = to_f_uas(f);
-
-       if (!(fu->flags & USBG_IS_BOT))
-               return -EOPNOTSUPP;
 
-       return usbg_bot_setup(f, ctrl);
+       return 0;
 }
 
-static int usbg_cfg_bind(struct usb_configuration *c)
-{
-       struct f_uas *fu;
-       int ret;
-
-       fu = kzalloc(sizeof(*fu), GFP_KERNEL);
-       if (!fu)
-               return -ENOMEM;
-       fu->function.name = "Target Function";
-       fu->function.bind = usbg_bind;
-       fu->function.unbind = usbg_unbind;
-       fu->function.set_alt = usbg_set_alt;
-       fu->function.setup = usbg_setup;
-       fu->function.disable = usbg_disable;
-       fu->tpg = the_only_tpg_I_currently_have;
-
-       bot_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_BBB].id;
-       uasp_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_UAS].id;
-
-       ret = usb_add_function(c, &fu->function);
-       if (ret)
-               goto err;
+static struct usb_configuration usbg_config_driver = {
+       .label                  = "Linux Target",
+       .bConfigurationValue    = 1,
+       .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
+};
 
-       return 0;
-err:
-       kfree(fu);
-       return ret;
-}
+static int usbg_attach(struct usb_function_instance *f);
+static void usbg_detach(struct usb_function_instance *f);
 
 static int usb_target_bind(struct usb_composite_dev *cdev)
 {
@@ -2196,8 +111,7 @@ static int usb_target_bind(struct usb_composite_dev *cdev)
        usbg_config_driver.iConfiguration =
                usbg_us_strings[USB_G_STR_CONFIG].id;
 
-       ret = usb_add_config(cdev, &usbg_config_driver,
-                       usbg_cfg_bind);
+       ret = usb_add_config(cdev, &usbg_config_driver, tcm_do_config);
        if (ret)
                return ret;
        usb_composite_overwrite_options(cdev, &coverwrite);
@@ -2213,25 +127,44 @@ static struct usb_composite_driver usbg_driver = {
        .unbind         = guas_unbind,
 };
 
-static int usbg_attach(struct usbg_tpg *tpg)
+static int usbg_attach(struct usb_function_instance *f)
 {
        return usb_composite_probe(&usbg_driver);
 }
 
-static void usbg_detach(struct usbg_tpg *tpg)
+static void usbg_detach(struct usb_function_instance *f)
 {
        usb_composite_unregister(&usbg_driver);
 }
 
 static int __init usb_target_gadget_init(void)
 {
-       return target_register_template(&usbg_ops);
+       struct f_tcm_opts *tcm_opts;
+
+       fi_tcm = usb_get_function_instance("tcm");
+       if (IS_ERR(fi_tcm))
+               return PTR_ERR(fi_tcm);
+
+       tcm_opts = container_of(fi_tcm, struct f_tcm_opts, func_inst);
+       mutex_lock(&tcm_opts->dep_lock);
+       tcm_opts->tcm_register_callback = usbg_attach;
+       tcm_opts->tcm_unregister_callback = usbg_detach;
+       tcm_opts->dependent = THIS_MODULE;
+       tcm_opts->can_attach = true;
+       tcm_opts->has_dep = true;
+       mutex_unlock(&tcm_opts->dep_lock);
+
+       fi_tcm->set_inst_name(fi_tcm, "tcm-legacy");
+
+       return 0;
 }
 module_init(usb_target_gadget_init);
 
 static void __exit usb_target_gadget_exit(void)
 {
-       target_unregister_template(&usbg_ops);
+       if (!IS_ERR_OR_NULL(fi_tcm))
+               usb_put_function_instance(fi_tcm);
+
 }
 module_exit(usb_target_gadget_exit);
 
diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.h b/drivers/usb/gadget/legacy/tcm_usb_gadget.h
deleted file mode 100644 (file)
index 0b749e1..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-#ifndef __TARGET_USB_GADGET_H__
-#define __TARGET_USB_GADGET_H__
-
-#include <linux/kref.h>
-/* #include <linux/usb/uas.h> */
-#include <linux/usb/composite.h>
-#include <linux/usb/uas.h>
-#include <linux/usb/storage.h>
-#include <target/target_core_base.h>
-#include <target/target_core_fabric.h>
-
-#define USBG_NAMELEN 32
-
-#define fuas_to_gadget(f)      (f->function.config->cdev->gadget)
-#define UASP_SS_EP_COMP_LOG_STREAMS 4
-#define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS)
-
-enum {
-       USB_G_STR_CONFIG = USB_GADGET_FIRST_AVAIL_IDX,
-       USB_G_STR_INT_UAS,
-       USB_G_STR_INT_BBB,
-};
-
-#define USB_G_ALT_INT_BBB       0
-#define USB_G_ALT_INT_UAS       1
-
-struct tcm_usbg_nexus {
-       struct se_session *tvn_se_sess;
-};
-
-struct usbg_tpg {
-       struct mutex tpg_mutex;
-       /* SAS port target portal group tag for TCM */
-       u16 tport_tpgt;
-       /* Pointer back to usbg_tport */
-       struct usbg_tport *tport;
-       struct workqueue_struct *workqueue;
-       /* Returned by usbg_make_tpg() */
-       struct se_portal_group se_tpg;
-       u32 gadget_connect;
-       struct tcm_usbg_nexus *tpg_nexus;
-       atomic_t tpg_port_count;
-};
-
-struct usbg_tport {
-       /* Binary World Wide unique Port Name for SAS Target port */
-       u64 tport_wwpn;
-       /* ASCII formatted WWPN for SAS Target port */
-       char tport_name[USBG_NAMELEN];
-       /* Returned by usbg_make_tport() */
-       struct se_wwn tport_wwn;
-};
-
-enum uas_state {
-       UASP_SEND_DATA,
-       UASP_RECEIVE_DATA,
-       UASP_SEND_STATUS,
-       UASP_QUEUE_COMMAND,
-};
-
-#define USBG_MAX_CMD    64
-struct usbg_cmd {
-       /* common */
-       u8 cmd_buf[USBG_MAX_CMD];
-       u32 data_len;
-       struct work_struct work;
-       int unpacked_lun;
-       struct se_cmd se_cmd;
-       void *data_buf; /* used if no sg support available */
-       struct f_uas *fu;
-       struct completion write_complete;
-       struct kref ref;
-
-       /* UAS only */
-       u16 tag;
-       u16 prio_attr;
-       struct sense_iu sense_iu;
-       enum uas_state state;
-       struct uas_stream *stream;
-
-       /* BOT only */
-       __le32 bot_tag;
-       unsigned int csw_code;
-       unsigned is_read:1;
-
-};
-
-struct uas_stream {
-       struct usb_request      *req_in;
-       struct usb_request      *req_out;
-       struct usb_request      *req_status;
-};
-
-struct usbg_cdb {
-       struct usb_request      *req;
-       void                    *buf;
-};
-
-struct bot_status {
-       struct usb_request      *req;
-       struct bulk_cs_wrap     csw;
-};
-
-struct f_uas {
-       struct usbg_tpg         *tpg;
-       struct usb_function     function;
-       u16                     iface;
-
-       u32                     flags;
-#define USBG_ENABLED           (1 << 0)
-#define USBG_IS_UAS            (1 << 1)
-#define USBG_USE_STREAMS       (1 << 2)
-#define USBG_IS_BOT            (1 << 3)
-#define USBG_BOT_CMD_PEND      (1 << 4)
-
-       struct usbg_cdb         cmd;
-       struct usb_ep           *ep_in;
-       struct usb_ep           *ep_out;
-
-       /* UAS */
-       struct usb_ep           *ep_status;
-       struct usb_ep           *ep_cmd;
-       struct uas_stream       stream[UASP_SS_EP_COMP_NUM_STREAMS];
-
-       /* BOT */
-       struct bot_status       bot_status;
-       struct usb_request      *bot_req_in;
-       struct usb_request      *bot_req_out;
-};
-
-extern struct usbg_tpg *the_only_tpg_I_currently_have;
-
-#endif
index f92f5af..8755b2c 100644 (file)
@@ -91,7 +91,7 @@ static ssize_t queue_dbg_read(struct file *file, char __user *buf,
        if (!access_ok(VERIFY_WRITE, buf, nbytes))
                return -EFAULT;
 
-       mutex_lock(&file_inode(file)->i_mutex);
+       inode_lock(file_inode(file));
        list_for_each_entry_safe(req, tmp_req, queue, queue) {
                len = snprintf(tmpbuf, sizeof(tmpbuf),
                                "%8p %08x %c%c%c %5d %c%c%c\n",
@@ -118,7 +118,7 @@ static ssize_t queue_dbg_read(struct file *file, char __user *buf,
                nbytes -= len;
                buf += len;
        }
-       mutex_unlock(&file_inode(file)->i_mutex);
+       inode_unlock(file_inode(file));
 
        return actual;
 }
@@ -143,7 +143,7 @@ static int regs_dbg_open(struct inode *inode, struct file *file)
        u32 *data;
        int ret = -ENOMEM;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        udc = inode->i_private;
        data = kmalloc(inode->i_size, GFP_KERNEL);
        if (!data)
@@ -158,7 +158,7 @@ static int regs_dbg_open(struct inode *inode, struct file *file)
        ret = 0;
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
@@ -169,11 +169,11 @@ static ssize_t regs_dbg_read(struct file *file, char __user *buf,
        struct inode *inode = file_inode(file);
        int ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = simple_read_from_buffer(buf, nbytes, ppos,
                        file->private_data,
                        file_inode(file)->i_size);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
index daa563f..1f117c3 100644 (file)
@@ -229,6 +229,8 @@ config USB_EHCI_TEGRA
        depends on ARCH_TEGRA
        select USB_EHCI_ROOT_HUB_TT
        select USB_PHY
+       select USB_ULPI
+       select USB_ULPI_VIEWPORT
        help
          This driver enables support for the internal USB Host Controllers
          found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
index 3fc63c2..57721c7 100644 (file)
@@ -78,13 +78,13 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy
        if (!info->fbdefio)
                return 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        /* Kill off the delayed work */
        cancel_delayed_work_sync(&info->deferred_work);
 
        /* Run it immediately */
        schedule_delayed_work(&info->deferred_work, 0);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return 0;
 }
index 7bf835f..eadc894 100644 (file)
@@ -449,14 +449,14 @@ static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
        if (retval)
                return retval;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
 
        fid = filp->private_data;
        v9fs_blank_wstat(&wstat);
 
        retval = p9_client_wstat(fid, &wstat);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return retval;
 }
@@ -472,13 +472,13 @@ int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
        if (retval)
                return retval;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
 
        fid = filp->private_data;
 
        retval = p9_client_fsync(fid, datasync);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return retval;
 }
index ea4aba5..fadf408 100644 (file)
@@ -44,24 +44,24 @@ struct adfs_dir_ops;
  */
 struct adfs_sb_info {
        union { struct {
-               struct adfs_discmap *s_map;     /* bh list containing map        */
-               const struct adfs_dir_ops *s_dir; /* directory operations        */
+               struct adfs_discmap *s_map;     /* bh list containing map */
+               const struct adfs_dir_ops *s_dir; /* directory operations */
                };
-               struct rcu_head rcu;            /* used only at shutdown time    */
+               struct rcu_head rcu;    /* used only at shutdown time    */
        };
-       kuid_t          s_uid;          /* owner uid                             */
-       kgid_t          s_gid;          /* owner gid                             */
-       umode_t         s_owner_mask;   /* ADFS owner perm -> unix perm          */
-       umode_t         s_other_mask;   /* ADFS other perm -> unix perm          */
+       kuid_t          s_uid;          /* owner uid */
+       kgid_t          s_gid;          /* owner gid */
+       umode_t         s_owner_mask;   /* ADFS owner perm -> unix perm */
+       umode_t         s_other_mask;   /* ADFS other perm -> unix perm */
        int             s_ftsuffix;     /* ,xyz hex filetype suffix option */
 
-       __u32           s_ids_per_zone; /* max. no ids in one zone               */
-       __u32           s_idlen;        /* length of ID in map                   */
-       __u32           s_map_size;     /* sector size of a map                  */
-       unsigned long   s_size;         /* total size (in blocks) of this fs     */
-       signed int      s_map2blk;      /* shift left by this for map->sector    */
-       unsigned int    s_log2sharesize;/* log2 share size                       */
-       __le32          s_version;      /* disc format version                   */
+       __u32           s_ids_per_zone; /* max. no ids in one zone */
+       __u32           s_idlen;        /* length of ID in map */
+       __u32           s_map_size;     /* sector size of a map */
+       unsigned long   s_size;         /* total size (in blocks) of this fs */
+       signed int      s_map2blk;      /* shift left by this for map->sector*/
+       unsigned int    s_log2sharesize;/* log2 share size */
+       __le32          s_version;      /* disc format version */
        unsigned int    s_namelen;      /* maximum number of characters in name  */
 };
 
index 659c579..0548c53 100644 (file)
@@ -33,11 +33,11 @@ affs_file_release(struct inode *inode, struct file *filp)
                 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
 
        if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if (inode->i_size != AFFS_I(inode)->mmu_private)
                        affs_truncate(inode);
                affs_free_prealloc(inode);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
        return 0;
@@ -958,12 +958,12 @@ int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
        if (err)
                return err;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = write_inode_now(inode, 0);
        err = sync_blockdev(inode->i_sb->s_bdev);
        if (!ret)
                ret = err;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 const struct file_operations affs_file_operations = {
index 4baf1d2..d91a9c9 100644 (file)
@@ -483,7 +483,7 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
 
        fl->fl_type = F_UNLCK;
 
-       mutex_lock(&vnode->vfs_inode.i_mutex);
+       inode_lock(&vnode->vfs_inode);
 
        /* check local lock records first */
        ret = 0;
@@ -505,7 +505,7 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
        }
 
 error:
-       mutex_unlock(&vnode->vfs_inode.i_mutex);
+       inode_unlock(&vnode->vfs_inode);
        _leave(" = %d [%hd]", ret, fl->fl_type);
        return ret;
 }
index 0714abc..dfef94f 100644 (file)
@@ -693,7 +693,7 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (ret)
                return ret;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* use a writeback record as a marker in the queue - when this reaches
         * the front of the queue, all the outstanding writes are either
@@ -735,7 +735,7 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        afs_put_writeback(wb);
        _leave(" = %d", ret);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index 6530ced..25b24d0 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -195,7 +195,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
        struct timespec now;
        unsigned int ia_valid = attr->ia_valid;
 
-       WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
+       WARN_ON_ONCE(!inode_is_locked(inode));
 
        if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
                if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
index 3a93755..051ea48 100644 (file)
@@ -491,6 +491,7 @@ static inline int arch_elf_pt_proc(struct elfhdr *ehdr,
  * arch_check_elf() - check an ELF executable
  * @ehdr:      The main ELF header
  * @has_interp:        True if the ELF has an interpreter, else false.
+ * @interp_ehdr: The interpreter's ELF header
  * @state:     Architecture-specific state preserved throughout the process
  *             of loading the ELF.
  *
@@ -502,6 +503,7 @@ static inline int arch_elf_pt_proc(struct elfhdr *ehdr,
  *         with that return code.
  */
 static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp,
+                                struct elfhdr *interp_ehdr,
                                 struct arch_elf_state *state)
 {
        /* Dummy implementation, always proceed */
@@ -829,7 +831,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
         * still possible to return an error to the code that invoked
         * the exec syscall.
         */
-       retval = arch_check_elf(&loc->elf_ex, !!interpreter, &arch_state);
+       retval = arch_check_elf(&loc->elf_ex,
+                               !!interpreter, &loc->interp_elf_ex,
+                               &arch_state);
        if (retval)
                goto out_free_dentry;
 
index 78f005f..3a3ced7 100644 (file)
@@ -638,11 +638,11 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
        case 3:
                /* Delete this handler. */
                root = dget(file->f_path.dentry->d_sb->s_root);
-               mutex_lock(&d_inode(root)->i_mutex);
+               inode_lock(d_inode(root));
 
                kill_node(e);
 
-               mutex_unlock(&d_inode(root)->i_mutex);
+               inode_unlock(d_inode(root));
                dput(root);
                break;
        default:
@@ -675,7 +675,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
                return PTR_ERR(e);
 
        root = dget(sb->s_root);
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
        dentry = lookup_one_len(e->name, root, strlen(e->name));
        err = PTR_ERR(dentry);
        if (IS_ERR(dentry))
@@ -711,7 +711,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
 out2:
        dput(dentry);
 out:
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        dput(root);
 
        if (err) {
@@ -754,12 +754,12 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer,
        case 3:
                /* Delete all handlers. */
                root = dget(file->f_path.dentry->d_sb->s_root);
-               mutex_lock(&d_inode(root)->i_mutex);
+               inode_lock(d_inode(root));
 
                while (!list_empty(&entries))
                        kill_node(list_entry(entries.next, Node, list));
 
-               mutex_unlock(&d_inode(root)->i_mutex);
+               inode_unlock(d_inode(root));
                dput(root);
                break;
        default:
index ba762ea..7b9cd49 100644 (file)
@@ -75,7 +75,7 @@ void kill_bdev(struct block_device *bdev)
 {
        struct address_space *mapping = bdev->bd_inode->i_mapping;
 
-       if (mapping->nrpages == 0 && mapping->nrshadows == 0)
+       if (mapping->nrpages == 0 && mapping->nrexceptional == 0)
                return;
 
        invalidate_bh_lrus();
@@ -346,9 +346,9 @@ static loff_t block_llseek(struct file *file, loff_t offset, int whence)
        struct inode *bd_inode = bdev_file_inode(file);
        loff_t retval;
 
-       mutex_lock(&bd_inode->i_mutex);
+       inode_lock(bd_inode);
        retval = fixed_size_llseek(file, offset, whence, i_size_read(bd_inode));
-       mutex_unlock(&bd_inode->i_mutex);
+       inode_unlock(bd_inode);
        return retval;
 }
        
@@ -1142,9 +1142,9 @@ void bd_set_size(struct block_device *bdev, loff_t size)
 {
        unsigned bsize = bdev_logical_block_size(bdev);
 
-       mutex_lock(&bdev->bd_inode->i_mutex);
+       inode_lock(bdev->bd_inode);
        i_size_write(bdev->bd_inode, size);
-       mutex_unlock(&bdev->bd_inode->i_mutex);
+       inode_unlock(bdev->bd_inode);
        while (bsize < PAGE_CACHE_SIZE) {
                if (size & bsize)
                        break;
@@ -1741,9 +1741,9 @@ static void blkdev_vm_open(struct vm_area_struct *vma)
        struct inode *bd_inode = bdev_file_inode(vma->vm_file);
        struct block_device *bdev = I_BDEV(bd_inode);
 
-       mutex_lock(&bd_inode->i_mutex);
+       inode_lock(bd_inode);
        bdev->bd_map_count++;
-       mutex_unlock(&bd_inode->i_mutex);
+       inode_unlock(bd_inode);
 }
 
 static void blkdev_vm_close(struct vm_area_struct *vma)
@@ -1751,9 +1751,9 @@ static void blkdev_vm_close(struct vm_area_struct *vma)
        struct inode *bd_inode = bdev_file_inode(vma->vm_file);
        struct block_device *bdev = I_BDEV(bd_inode);
 
-       mutex_lock(&bd_inode->i_mutex);
+       inode_lock(bd_inode);
        bdev->bd_map_count--;
-       mutex_unlock(&bd_inode->i_mutex);
+       inode_unlock(bd_inode);
 }
 
 static const struct vm_operations_struct blkdev_dax_vm_ops = {
@@ -1777,7 +1777,7 @@ static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
        struct block_device *bdev = I_BDEV(bd_inode);
 
        file_accessed(file);
-       mutex_lock(&bd_inode->i_mutex);
+       inode_lock(bd_inode);
        bdev->bd_map_count++;
        if (IS_DAX(bd_inode)) {
                vma->vm_ops = &blkdev_dax_vm_ops;
@@ -1785,7 +1785,7 @@ static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
        } else {
                vma->vm_ops = &blkdev_default_vm_ops;
        }
-       mutex_unlock(&bd_inode->i_mutex);
+       inode_unlock(bd_inode);
 
        return 0;
 }
index 08405a3..b90cd37 100644 (file)
@@ -560,13 +560,13 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info,
  */
 static void __merge_refs(struct list_head *head, int mode)
 {
-       struct __prelim_ref *ref1;
+       struct __prelim_ref *pos1;
 
-       list_for_each_entry(ref1, head, list) {
-               struct __prelim_ref *ref2 = ref1, *tmp;
+       list_for_each_entry(pos1, head, list) {
+               struct __prelim_ref *pos2 = pos1, *tmp;
 
-               list_for_each_entry_safe_continue(ref2, tmp, head, list) {
-                       struct __prelim_ref *xchg;
+               list_for_each_entry_safe_continue(pos2, tmp, head, list) {
+                       struct __prelim_ref *xchg, *ref1 = pos1, *ref2 = pos2;
                        struct extent_inode_elem *eie;
 
                        if (!ref_for_same_block(ref1, ref2))
index 97ad9bb..bfe4a33 100644 (file)
@@ -1614,7 +1614,7 @@ struct btrfs_fs_info {
 
        spinlock_t delayed_iput_lock;
        struct list_head delayed_iputs;
-       struct rw_semaphore delayed_iput_sem;
+       struct mutex cleaner_delayed_iput_mutex;
 
        /* this protects tree_mod_seq_list */
        spinlock_t tree_mod_seq_lock;
@@ -3641,6 +3641,7 @@ int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans,
 int __get_raid_index(u64 flags);
 int btrfs_start_write_no_snapshoting(struct btrfs_root *root);
 void btrfs_end_write_no_snapshoting(struct btrfs_root *root);
+void btrfs_wait_for_snapshot_creation(struct btrfs_root *root);
 void check_system_chunk(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root,
                        const u64 type);
index 1e668fb..cbb7dbf 100644 (file)
@@ -614,7 +614,7 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
                em = lookup_extent_mapping(em_tree, start, (u64)-1);
                if (!em)
                        break;
-               map = (struct map_lookup *)em->bdev;
+               map = em->map_lookup;
                for (i = 0; i < map->num_stripes; i++)
                        if (srcdev == map->stripes[i].dev)
                                map->stripes[i].dev = tgtdev;
index e99ccd6..dd08e29 100644 (file)
 #include <asm/cpufeature.h>
 #endif
 
+#define BTRFS_SUPER_FLAG_SUPP  (BTRFS_HEADER_FLAG_WRITTEN |\
+                                BTRFS_HEADER_FLAG_RELOC |\
+                                BTRFS_SUPER_FLAG_ERROR |\
+                                BTRFS_SUPER_FLAG_SEEDING |\
+                                BTRFS_SUPER_FLAG_METADUMP)
+
 static const struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
@@ -1583,8 +1589,23 @@ int btrfs_init_fs_root(struct btrfs_root *root)
        ret = get_anon_bdev(&root->anon_dev);
        if (ret)
                goto free_writers;
+
+       mutex_lock(&root->objectid_mutex);
+       ret = btrfs_find_highest_objectid(root,
+                                       &root->highest_objectid);
+       if (ret) {
+               mutex_unlock(&root->objectid_mutex);
+               goto free_root_dev;
+       }
+
+       ASSERT(root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
+
+       mutex_unlock(&root->objectid_mutex);
+
        return 0;
 
+free_root_dev:
+       free_anon_bdev(root->anon_dev);
 free_writers:
        btrfs_free_subvolume_writers(root->subv_writers);
 fail:
@@ -1786,7 +1807,10 @@ static int cleaner_kthread(void *arg)
                        goto sleep;
                }
 
+               mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
                btrfs_run_delayed_iputs(root);
+               mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
+
                again = btrfs_clean_one_deleted_snapshot(root);
                mutex_unlock(&root->fs_info->cleaner_mutex);
 
@@ -2556,8 +2580,8 @@ int open_ctree(struct super_block *sb,
        mutex_init(&fs_info->delete_unused_bgs_mutex);
        mutex_init(&fs_info->reloc_mutex);
        mutex_init(&fs_info->delalloc_root_mutex);
+       mutex_init(&fs_info->cleaner_delayed_iput_mutex);
        seqlock_init(&fs_info->profiles_lock);
-       init_rwsem(&fs_info->delayed_iput_sem);
 
        INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
        INIT_LIST_HEAD(&fs_info->space_info);
@@ -2742,26 +2766,6 @@ int open_ctree(struct super_block *sb,
                goto fail_alloc;
        }
 
-       /*
-        * Leafsize and nodesize were always equal, this is only a sanity check.
-        */
-       if (le32_to_cpu(disk_super->__unused_leafsize) !=
-           btrfs_super_nodesize(disk_super)) {
-               printk(KERN_ERR "BTRFS: couldn't mount because metadata "
-                      "blocksizes don't match.  node %d leaf %d\n",
-                      btrfs_super_nodesize(disk_super),
-                      le32_to_cpu(disk_super->__unused_leafsize));
-               err = -EINVAL;
-               goto fail_alloc;
-       }
-       if (btrfs_super_nodesize(disk_super) > BTRFS_MAX_METADATA_BLOCKSIZE) {
-               printk(KERN_ERR "BTRFS: couldn't mount because metadata "
-                      "blocksize (%d) was too large\n",
-                      btrfs_super_nodesize(disk_super));
-               err = -EINVAL;
-               goto fail_alloc;
-       }
-
        features = btrfs_super_incompat_flags(disk_super);
        features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
        if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
@@ -2833,17 +2837,6 @@ int open_ctree(struct super_block *sb,
        sb->s_blocksize = sectorsize;
        sb->s_blocksize_bits = blksize_bits(sectorsize);
 
-       if (btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
-               printk(KERN_ERR "BTRFS: valid FS not found on %s\n", sb->s_id);
-               goto fail_sb_buffer;
-       }
-
-       if (sectorsize != PAGE_SIZE) {
-               printk(KERN_ERR "BTRFS: incompatible sector size (%lu) "
-                      "found on %s\n", (unsigned long)sectorsize, sb->s_id);
-               goto fail_sb_buffer;
-       }
-
        mutex_lock(&fs_info->chunk_mutex);
        ret = btrfs_read_sys_array(tree_root);
        mutex_unlock(&fs_info->chunk_mutex);
@@ -2915,6 +2908,18 @@ retry_root_backup:
        tree_root->commit_root = btrfs_root_node(tree_root);
        btrfs_set_root_refs(&tree_root->root_item, 1);
 
+       mutex_lock(&tree_root->objectid_mutex);
+       ret = btrfs_find_highest_objectid(tree_root,
+                                       &tree_root->highest_objectid);
+       if (ret) {
+               mutex_unlock(&tree_root->objectid_mutex);
+               goto recovery_tree_root;
+       }
+
+       ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
+
+       mutex_unlock(&tree_root->objectid_mutex);
+
        ret = btrfs_read_roots(fs_info, tree_root);
        if (ret)
                goto recovery_tree_root;
@@ -4018,8 +4023,17 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
                              int read_only)
 {
        struct btrfs_super_block *sb = fs_info->super_copy;
+       u64 nodesize = btrfs_super_nodesize(sb);
+       u64 sectorsize = btrfs_super_sectorsize(sb);
        int ret = 0;
 
+       if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
+               printk(KERN_ERR "BTRFS: no valid FS found\n");
+               ret = -EINVAL;
+       }
+       if (btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)
+               printk(KERN_WARNING "BTRFS: unrecognized super flag: %llu\n",
+                               btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
        if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) {
                printk(KERN_ERR "BTRFS: tree_root level too big: %d >= %d\n",
                                btrfs_super_root_level(sb), BTRFS_MAX_LEVEL);
@@ -4037,31 +4051,46 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
        }
 
        /*
-        * The common minimum, we don't know if we can trust the nodesize/sectorsize
-        * items yet, they'll be verified later. Issue just a warning.
+        * Check sectorsize and nodesize first, other check will need it.
+        * Check all possible sectorsize(4K, 8K, 16K, 32K, 64K) here.
         */
-       if (!IS_ALIGNED(btrfs_super_root(sb), 4096))
+       if (!is_power_of_2(sectorsize) || sectorsize < 4096 ||
+           sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE) {
+               printk(KERN_ERR "BTRFS: invalid sectorsize %llu\n", sectorsize);
+               ret = -EINVAL;
+       }
+       /* Only PAGE SIZE is supported yet */
+       if (sectorsize != PAGE_CACHE_SIZE) {
+               printk(KERN_ERR "BTRFS: sectorsize %llu not supported yet, only support %lu\n",
+                               sectorsize, PAGE_CACHE_SIZE);
+               ret = -EINVAL;
+       }
+       if (!is_power_of_2(nodesize) || nodesize < sectorsize ||
+           nodesize > BTRFS_MAX_METADATA_BLOCKSIZE) {
+               printk(KERN_ERR "BTRFS: invalid nodesize %llu\n", nodesize);
+               ret = -EINVAL;
+       }
+       if (nodesize != le32_to_cpu(sb->__unused_leafsize)) {
+               printk(KERN_ERR "BTRFS: invalid leafsize %u, should be %llu\n",
+                               le32_to_cpu(sb->__unused_leafsize),
+                               nodesize);
+               ret = -EINVAL;
+       }
+
+       /* Root alignment check */
+       if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) {
                printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n",
                                btrfs_super_root(sb));
-       if (!IS_ALIGNED(btrfs_super_chunk_root(sb), 4096))
+               ret = -EINVAL;
+       }
+       if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) {
                printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n",
                                btrfs_super_chunk_root(sb));
-       if (!IS_ALIGNED(btrfs_super_log_root(sb), 4096))
-               printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n",
-                               btrfs_super_log_root(sb));
-
-       /*
-        * Check the lower bound, the alignment and other constraints are
-        * checked later.
-        */
-       if (btrfs_super_nodesize(sb) < 4096) {
-               printk(KERN_ERR "BTRFS: nodesize too small: %u < 4096\n",
-                               btrfs_super_nodesize(sb));
                ret = -EINVAL;
        }
-       if (btrfs_super_sectorsize(sb) < 4096) {
-               printk(KERN_ERR "BTRFS: sectorsize too small: %u < 4096\n",
-                               btrfs_super_sectorsize(sb));
+       if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) {
+               printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n",
+                               btrfs_super_log_root(sb));
                ret = -EINVAL;
        }
 
index 60cc139..e2287c7 100644 (file)
@@ -4139,8 +4139,10 @@ commit_trans:
                    !atomic_read(&root->fs_info->open_ioctl_trans)) {
                        need_commit--;
 
-                       if (need_commit > 0)
+                       if (need_commit > 0) {
+                               btrfs_start_delalloc_roots(fs_info, 0, -1);
                                btrfs_wait_ordered_roots(fs_info, -1);
+                       }
 
                        trans = btrfs_join_transaction(root);
                        if (IS_ERR(trans))
@@ -4153,11 +4155,12 @@ commit_trans:
                                if (ret)
                                        return ret;
                                /*
-                                * make sure that all running delayed iput are
-                                * done
+                                * The cleaner kthread might still be doing iput
+                                * operations. Wait for it to finish so that
+                                * more space is released.
                                 */
-                               down_write(&root->fs_info->delayed_iput_sem);
-                               up_write(&root->fs_info->delayed_iput_sem);
+                               mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
+                               mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
                                goto again;
                        } else {
                                btrfs_end_transaction(trans, root);
@@ -10399,7 +10402,7 @@ btrfs_start_trans_remove_block_group(struct btrfs_fs_info *fs_info,
         * more device items and remove one chunk item), but this is done at
         * btrfs_remove_chunk() through a call to check_system_chunk().
         */
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        num_items = 3 + map->num_stripes;
        free_extent_map(em);
 
@@ -10586,7 +10589,7 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
 
        disk_super = fs_info->super_copy;
        if (!btrfs_super_root(disk_super))
-               return 1;
+               return -EINVAL;
 
        features = btrfs_super_incompat_flags(disk_super);
        if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
@@ -10816,3 +10819,23 @@ int btrfs_start_write_no_snapshoting(struct btrfs_root *root)
        }
        return 1;
 }
+
+static int wait_snapshoting_atomic_t(atomic_t *a)
+{
+       schedule();
+       return 0;
+}
+
+void btrfs_wait_for_snapshot_creation(struct btrfs_root *root)
+{
+       while (true) {
+               int ret;
+
+               ret = btrfs_start_write_no_snapshoting(root);
+               if (ret)
+                       break;
+               wait_on_atomic_t(&root->will_be_snapshoted,
+                                wait_snapshoting_atomic_t,
+                                TASK_UNINTERRUPTIBLE);
+       }
+}
index 6a98bdd..84fb56d 100644 (file)
@@ -76,7 +76,7 @@ void free_extent_map(struct extent_map *em)
                WARN_ON(extent_map_in_tree(em));
                WARN_ON(!list_empty(&em->list));
                if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags))
-                       kfree(em->bdev);
+                       kfree(em->map_lookup);
                kmem_cache_free(extent_map_cache, em);
        }
 }
index b2991fd..eb8b8fa 100644 (file)
@@ -32,7 +32,15 @@ struct extent_map {
        u64 block_len;
        u64 generation;
        unsigned long flags;
-       struct block_device *bdev;
+       union {
+               struct block_device *bdev;
+
+               /*
+                * used for chunk mappings
+                * flags & EXTENT_FLAG_FS_MAPPING must be set
+                */
+               struct map_lookup *map_lookup;
+       };
        atomic_t refs;
        unsigned int compress_type;
        struct list_head list;
index 83d7859..098bb8f 100644 (file)
@@ -406,8 +406,7 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info)
 /* simple helper to fault in pages and copy.  This should go away
  * and be replaced with calls into generic code.
  */
-static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
-                                        size_t write_bytes,
+static noinline int btrfs_copy_from_user(loff_t pos, size_t write_bytes,
                                         struct page **prepared_pages,
                                         struct iov_iter *i)
 {
@@ -1588,8 +1587,7 @@ again:
                        ret = 0;
                }
 
-               copied = btrfs_copy_from_user(pos, num_pages,
-                                          write_bytes, pages, i);
+               copied = btrfs_copy_from_user(pos, write_bytes, pages, i);
 
                /*
                 * if we have trouble faulting in the pages, fall
@@ -1764,17 +1762,17 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
        loff_t pos;
        size_t count;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        err = generic_write_checks(iocb, from);
        if (err <= 0) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                return err;
        }
 
        current->backing_dev_info = inode_to_bdi(inode);
        err = file_remove_privs(file);
        if (err) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                goto out;
        }
 
@@ -1785,7 +1783,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
         * to stop this write operation to ensure FS consistency.
         */
        if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                err = -EROFS;
                goto out;
        }
@@ -1806,7 +1804,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
                end_pos = round_up(pos + count, root->sectorsize);
                err = btrfs_cont_expand(inode, i_size_read(inode), end_pos);
                if (err) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        goto out;
                }
        }
@@ -1822,7 +1820,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
                        iocb->ki_pos = pos + num_written;
        }
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        /*
         * We also have to set last_sub_trans to the current log transid,
@@ -1911,7 +1909,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        atomic_inc(&root->log_batch);
        full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
                             &BTRFS_I(inode)->runtime_flags);
@@ -1963,7 +1961,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                ret = start_ordered_ops(inode, start, end);
        }
        if (ret) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                goto out;
        }
        atomic_inc(&root->log_batch);
@@ -2009,7 +2007,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                 */
                clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
                          &BTRFS_I(inode)->runtime_flags);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                goto out;
        }
 
@@ -2033,7 +2031,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                goto out;
        }
        trans->sync = true;
@@ -2056,7 +2054,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
         * file again, but that will end up using the synchronization
         * inside btrfs_sync_log to keep things safe.
         */
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        /*
         * If any of the ordered extents had an error, just return it to user
@@ -2305,7 +2303,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ino_size = round_up(inode->i_size, PAGE_CACHE_SIZE);
        ret = find_first_non_hole(inode, &offset, &len);
        if (ret < 0)
@@ -2345,7 +2343,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
                truncated_page = true;
                ret = btrfs_truncate_page(inode, offset, 0, 0);
                if (ret) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        return ret;
                }
        }
@@ -2421,7 +2419,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
                ret = btrfs_wait_ordered_range(inode, lockstart,
                                               lockend - lockstart + 1);
                if (ret) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        return ret;
                }
        }
@@ -2576,7 +2574,7 @@ out_only_mutex:
                        ret = btrfs_end_transaction(trans, root);
                }
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (ret && !err)
                err = ret;
        return err;
@@ -2660,7 +2658,7 @@ static long btrfs_fallocate(struct file *file, int mode,
        if (ret < 0)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = inode_newsize_ok(inode, alloc_end);
        if (ret)
                goto out;
@@ -2818,7 +2816,7 @@ out:
         * So this is completely used as cleanup.
         */
        btrfs_qgroup_free_data(inode, alloc_start, alloc_end - alloc_start);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        /* Let go of our reservation. */
        btrfs_free_reserved_data_space(inode, alloc_start,
                                       alloc_end - alloc_start);
@@ -2894,7 +2892,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)
        struct inode *inode = file->f_mapping->host;
        int ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        switch (whence) {
        case SEEK_END:
        case SEEK_CUR:
@@ -2903,20 +2901,20 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)
        case SEEK_DATA:
        case SEEK_HOLE:
                if (offset >= i_size_read(inode)) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        return -ENXIO;
                }
 
                ret = find_desired_extent(inode, &offset, whence);
                if (ret) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        return ret;
                }
        }
 
        offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return offset;
 }
 
index 8b57c17..e50316c 100644 (file)
@@ -515,7 +515,7 @@ out:
        return ret;
 }
 
-static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
 {
        struct btrfs_path *path;
        int ret;
@@ -555,13 +555,6 @@ int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid)
        int ret;
        mutex_lock(&root->objectid_mutex);
 
-       if (unlikely(root->highest_objectid < BTRFS_FIRST_FREE_OBJECTID)) {
-               ret = btrfs_find_highest_objectid(root,
-                                                 &root->highest_objectid);
-               if (ret)
-                       goto out;
-       }
-
        if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
                ret = -ENOSPC;
                goto out;
index ddb347b..c8e864b 100644 (file)
@@ -9,5 +9,6 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
                         struct btrfs_trans_handle *trans);
 
 int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid);
+int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid);
 
 #endif
index 2478301..e28f3d4 100644 (file)
@@ -3134,7 +3134,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
 
-       down_read(&fs_info->delayed_iput_sem);
        spin_lock(&fs_info->delayed_iput_lock);
        while (!list_empty(&fs_info->delayed_iputs)) {
                struct btrfs_inode *inode;
@@ -3153,7 +3152,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
                spin_lock(&fs_info->delayed_iput_lock);
        }
        spin_unlock(&fs_info->delayed_iput_lock);
-       up_read(&root->fs_info->delayed_iput_sem);
 }
 
 /*
@@ -4874,26 +4872,6 @@ next:
        return err;
 }
 
-static int wait_snapshoting_atomic_t(atomic_t *a)
-{
-       schedule();
-       return 0;
-}
-
-static void wait_for_snapshot_creation(struct btrfs_root *root)
-{
-       while (true) {
-               int ret;
-
-               ret = btrfs_start_write_no_snapshoting(root);
-               if (ret)
-                       break;
-               wait_on_atomic_t(&root->will_be_snapshoted,
-                                wait_snapshoting_atomic_t,
-                                TASK_UNINTERRUPTIBLE);
-       }
-}
-
 static int btrfs_setsize(struct inode *inode, struct iattr *attr)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -4925,7 +4903,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)
                 * truncation, it must capture all writes that happened before
                 * this truncation.
                 */
-               wait_for_snapshot_creation(root);
+               btrfs_wait_for_snapshot_creation(root);
                ret = btrfs_cont_expand(inode, oldsize, newsize);
                if (ret) {
                        btrfs_end_write_no_snapshoting(root);
@@ -8469,7 +8447,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                 * not unlock the i_mutex at this case.
                 */
                if (offset + count <= inode->i_size) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        relock = true;
                }
                ret = btrfs_delalloc_reserve_space(inode, offset, count);
@@ -8526,7 +8504,7 @@ out:
        if (wakeup)
                inode_dio_end(inode);
        if (relock)
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
 
        return ret;
 }
index 2a47a31..952172c 100644 (file)
@@ -240,7 +240,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        ip_oldflags = ip->flags;
        i_oldflags = inode->i_flags;
@@ -358,7 +358,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
        }
 
  out_unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        mnt_drop_write_file(file);
        return ret;
 }
@@ -568,6 +568,10 @@ static noinline int create_subvol(struct inode *dir,
                goto fail;
        }
 
+       mutex_lock(&new_root->objectid_mutex);
+       new_root->highest_objectid = new_dirid;
+       mutex_unlock(&new_root->objectid_mutex);
+
        /*
         * insert the directory item
         */
@@ -877,7 +881,7 @@ out_up_read:
 out_dput:
        dput(dentry);
 out_unlock:
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        return error;
 }
 
@@ -1389,18 +1393,18 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                        ra_index += cluster;
                }
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
                        BTRFS_I(inode)->force_compress = compress_type;
                ret = cluster_pages_for_defrag(inode, pages, i, cluster);
                if (ret < 0) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        goto out_ra;
                }
 
                defrag_count += ret;
                balance_dirty_pages_ratelimited(inode->i_mapping);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
                if (newer_than) {
                        if (newer_off == (u64)-1)
@@ -1461,9 +1465,9 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 
 out_ra:
        if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        if (!file)
                kfree(ra);
@@ -2426,7 +2430,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                goto out_dput;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * Don't allow to delete a subvolume with send in progress. This is
@@ -2539,7 +2543,7 @@ out_up_write:
                spin_unlock(&dest->root_item_lock);
        }
 out_unlock_inode:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (!err) {
                d_invalidate(dentry);
                btrfs_invalidate_inodes(dest);
@@ -2555,7 +2559,7 @@ out_unlock_inode:
 out_dput:
        dput(dentry);
 out_unlock_dir:
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
 out_drop_write:
        mnt_drop_write_file(file);
 out:
@@ -2853,8 +2857,8 @@ static inline void lock_extent_range(struct inode *inode, u64 off, u64 len)
 
 static void btrfs_double_inode_unlock(struct inode *inode1, struct inode *inode2)
 {
-       mutex_unlock(&inode1->i_mutex);
-       mutex_unlock(&inode2->i_mutex);
+       inode_unlock(inode1);
+       inode_unlock(inode2);
 }
 
 static void btrfs_double_inode_lock(struct inode *inode1, struct inode *inode2)
@@ -2862,8 +2866,8 @@ static void btrfs_double_inode_lock(struct inode *inode1, struct inode *inode2)
        if (inode1 < inode2)
                swap(inode1, inode2);
 
-       mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
-       mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(inode1, I_MUTEX_PARENT);
+       inode_lock_nested(inode2, I_MUTEX_CHILD);
 }
 
 static void btrfs_double_extent_unlock(struct inode *inode1, u64 loff1,
@@ -3022,7 +3026,7 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
                return 0;
 
        if (same_inode) {
-               mutex_lock(&src->i_mutex);
+               inode_lock(src);
 
                ret = extent_same_check_offsets(src, loff, &len, olen);
                if (ret)
@@ -3097,7 +3101,7 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
        btrfs_cmp_data_free(&cmp);
 out_unlock:
        if (same_inode)
-               mutex_unlock(&src->i_mutex);
+               inode_unlock(src);
        else
                btrfs_double_inode_unlock(src, dst);
 
@@ -3745,7 +3749,7 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src,
        if (!same_inode) {
                btrfs_double_inode_lock(src, inode);
        } else {
-               mutex_lock(&src->i_mutex);
+               inode_lock(src);
        }
 
        /* determine range to clone */
@@ -3816,7 +3820,7 @@ out_unlock:
        if (!same_inode)
                btrfs_double_inode_unlock(src, inode);
        else
-               mutex_unlock(&src->i_mutex);
+               inode_unlock(src);
        return ret;
 }
 
index 6d70754..5516136 100644 (file)
@@ -609,13 +609,28 @@ static int rbio_can_merge(struct btrfs_raid_bio *last,
        return 1;
 }
 
+static int rbio_stripe_page_index(struct btrfs_raid_bio *rbio, int stripe,
+                                 int index)
+{
+       return stripe * rbio->stripe_npages + index;
+}
+
+/*
+ * these are just the pages from the rbio array, not from anything
+ * the FS sent down to us
+ */
+static struct page *rbio_stripe_page(struct btrfs_raid_bio *rbio, int stripe,
+                                    int index)
+{
+       return rbio->stripe_pages[rbio_stripe_page_index(rbio, stripe, index)];
+}
+
 /*
  * helper to index into the pstripe
  */
 static struct page *rbio_pstripe_page(struct btrfs_raid_bio *rbio, int index)
 {
-       index += (rbio->nr_data * rbio->stripe_len) >> PAGE_CACHE_SHIFT;
-       return rbio->stripe_pages[index];
+       return rbio_stripe_page(rbio, rbio->nr_data, index);
 }
 
 /*
@@ -626,10 +641,7 @@ static struct page *rbio_qstripe_page(struct btrfs_raid_bio *rbio, int index)
 {
        if (rbio->nr_data + 1 == rbio->real_stripes)
                return NULL;
-
-       index += ((rbio->nr_data + 1) * rbio->stripe_len) >>
-               PAGE_CACHE_SHIFT;
-       return rbio->stripe_pages[index];
+       return rbio_stripe_page(rbio, rbio->nr_data + 1, index);
 }
 
 /*
@@ -889,6 +901,7 @@ static void raid_write_end_io(struct bio *bio)
 {
        struct btrfs_raid_bio *rbio = bio->bi_private;
        int err = bio->bi_error;
+       int max_errors;
 
        if (err)
                fail_bio_stripe(rbio, bio);
@@ -901,7 +914,9 @@ static void raid_write_end_io(struct bio *bio)
        err = 0;
 
        /* OK, we have read all the stripes we need to. */
-       if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
+       max_errors = (rbio->operation == BTRFS_RBIO_PARITY_SCRUB) ?
+                    0 : rbio->bbio->max_errors;
+       if (atomic_read(&rbio->error) > max_errors)
                err = -EIO;
 
        rbio_orig_end_io(rbio, err);
@@ -947,8 +962,7 @@ static struct page *page_in_rbio(struct btrfs_raid_bio *rbio,
  */
 static unsigned long rbio_nr_pages(unsigned long stripe_len, int nr_stripes)
 {
-       unsigned long nr = stripe_len * nr_stripes;
-       return DIV_ROUND_UP(nr, PAGE_CACHE_SIZE);
+       return DIV_ROUND_UP(stripe_len, PAGE_CACHE_SIZE) * nr_stripes;
 }
 
 /*
@@ -966,8 +980,8 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_root *root,
        void *p;
 
        rbio = kzalloc(sizeof(*rbio) + num_pages * sizeof(struct page *) * 2 +
-                      DIV_ROUND_UP(stripe_npages, BITS_PER_LONG / 8),
-                       GFP_NOFS);
+                      DIV_ROUND_UP(stripe_npages, BITS_PER_LONG) *
+                      sizeof(long), GFP_NOFS);
        if (!rbio)
                return ERR_PTR(-ENOMEM);
 
@@ -1021,18 +1035,17 @@ static int alloc_rbio_pages(struct btrfs_raid_bio *rbio)
                if (!page)
                        return -ENOMEM;
                rbio->stripe_pages[i] = page;
-               ClearPageUptodate(page);
        }
        return 0;
 }
 
-/* allocate pages for just the p/q stripes */
+/* only allocate pages for p/q stripes */
 static int alloc_rbio_parity_pages(struct btrfs_raid_bio *rbio)
 {
        int i;
        struct page *page;
 
-       i = (rbio->nr_data * rbio->stripe_len) >> PAGE_CACHE_SHIFT;
+       i = rbio_stripe_page_index(rbio, rbio->nr_data, 0);
 
        for (; i < rbio->nr_pages; i++) {
                if (rbio->stripe_pages[i])
@@ -1120,18 +1133,6 @@ static void validate_rbio_for_rmw(struct btrfs_raid_bio *rbio)
        }
 }
 
-/*
- * these are just the pages from the rbio array, not from anything
- * the FS sent down to us
- */
-static struct page *rbio_stripe_page(struct btrfs_raid_bio *rbio, int stripe, int page)
-{
-       int index;
-       index = stripe * (rbio->stripe_len >> PAGE_CACHE_SHIFT);
-       index += page;
-       return rbio->stripe_pages[index];
-}
-
 /*
  * helper function to walk our bio list and populate the bio_pages array with
  * the result.  This seems expensive, but it is faster than constantly
@@ -1175,7 +1176,6 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
 {
        struct btrfs_bio *bbio = rbio->bbio;
        void *pointers[rbio->real_stripes];
-       int stripe_len = rbio->stripe_len;
        int nr_data = rbio->nr_data;
        int stripe;
        int pagenr;
@@ -1183,7 +1183,6 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
        int q_stripe = -1;
        struct bio_list bio_list;
        struct bio *bio;
-       int pages_per_stripe = stripe_len >> PAGE_CACHE_SHIFT;
        int ret;
 
        bio_list_init(&bio_list);
@@ -1226,7 +1225,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
        else
                clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
 
-       for (pagenr = 0; pagenr < pages_per_stripe; pagenr++) {
+       for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) {
                struct page *p;
                /* first collect one page from each data stripe */
                for (stripe = 0; stripe < nr_data; stripe++) {
@@ -1268,7 +1267,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
         * everything else.
         */
        for (stripe = 0; stripe < rbio->real_stripes; stripe++) {
-               for (pagenr = 0; pagenr < pages_per_stripe; pagenr++) {
+               for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) {
                        struct page *page;
                        if (stripe < rbio->nr_data) {
                                page = page_in_rbio(rbio, stripe, pagenr, 1);
@@ -1292,7 +1291,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
                if (!bbio->tgtdev_map[stripe])
                        continue;
 
-               for (pagenr = 0; pagenr < pages_per_stripe; pagenr++) {
+               for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) {
                        struct page *page;
                        if (stripe < rbio->nr_data) {
                                page = page_in_rbio(rbio, stripe, pagenr, 1);
@@ -1506,7 +1505,6 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
        int bios_to_read = 0;
        struct bio_list bio_list;
        int ret;
-       int nr_pages = DIV_ROUND_UP(rbio->stripe_len, PAGE_CACHE_SIZE);
        int pagenr;
        int stripe;
        struct bio *bio;
@@ -1525,7 +1523,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
         * stripe
         */
        for (stripe = 0; stripe < rbio->nr_data; stripe++) {
-               for (pagenr = 0; pagenr < nr_pages; pagenr++) {
+               for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) {
                        struct page *page;
                        /*
                         * we want to find all the pages missing from
@@ -1801,7 +1799,6 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
        int pagenr, stripe;
        void **pointers;
        int faila = -1, failb = -1;
-       int nr_pages = DIV_ROUND_UP(rbio->stripe_len, PAGE_CACHE_SIZE);
        struct page *page;
        int err;
        int i;
@@ -1824,7 +1821,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
 
        index_rbio_pages(rbio);
 
-       for (pagenr = 0; pagenr < nr_pages; pagenr++) {
+       for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) {
                /*
                 * Now we just use bitmap to mark the horizontal stripes in
                 * which we have data when doing parity scrub.
@@ -1935,7 +1932,7 @@ pstripe:
                 * other endio functions will fiddle the uptodate bits
                 */
                if (rbio->operation == BTRFS_RBIO_WRITE) {
-                       for (i = 0;  i < nr_pages; i++) {
+                       for (i = 0;  i < rbio->stripe_npages; i++) {
                                if (faila != -1) {
                                        page = rbio_stripe_page(rbio, faila, i);
                                        SetPageUptodate(page);
@@ -2031,7 +2028,6 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
        int bios_to_read = 0;
        struct bio_list bio_list;
        int ret;
-       int nr_pages = DIV_ROUND_UP(rbio->stripe_len, PAGE_CACHE_SIZE);
        int pagenr;
        int stripe;
        struct bio *bio;
@@ -2055,7 +2051,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
                        continue;
                }
 
-               for (pagenr = 0; pagenr < nr_pages; pagenr++) {
+               for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) {
                        struct page *p;
 
                        /*
@@ -2279,37 +2275,11 @@ static int alloc_rbio_essential_pages(struct btrfs_raid_bio *rbio)
                        if (!page)
                                return -ENOMEM;
                        rbio->stripe_pages[index] = page;
-                       ClearPageUptodate(page);
                }
        }
        return 0;
 }
 
-/*
- * end io function used by finish_rmw.  When we finally
- * get here, we've written a full stripe
- */
-static void raid_write_parity_end_io(struct bio *bio)
-{
-       struct btrfs_raid_bio *rbio = bio->bi_private;
-       int err = bio->bi_error;
-
-       if (bio->bi_error)
-               fail_bio_stripe(rbio, bio);
-
-       bio_put(bio);
-
-       if (!atomic_dec_and_test(&rbio->stripes_pending))
-               return;
-
-       err = 0;
-
-       if (atomic_read(&rbio->error))
-               err = -EIO;
-
-       rbio_orig_end_io(rbio, err);
-}
-
 static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
                                         int need_check)
 {
@@ -2462,7 +2432,7 @@ submit_write:
                        break;
 
                bio->bi_private = rbio;
-               bio->bi_end_io = raid_write_parity_end_io;
+               bio->bi_end_io = raid_write_end_io;
                submit_bio(WRITE, bio);
        }
        return;
index ef6d8fc..fd1c4d9 100644 (file)
@@ -3030,7 +3030,7 @@ int prealloc_file_extent_cluster(struct inode *inode,
        int ret = 0;
 
        BUG_ON(cluster->start != cluster->boundary[0]);
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        ret = btrfs_check_data_free_space(inode, cluster->start,
                                          cluster->end + 1 - cluster->start);
@@ -3057,7 +3057,7 @@ int prealloc_file_extent_cluster(struct inode *inode,
        btrfs_free_reserved_data_space(inode, cluster->start,
                                       cluster->end + 1 - cluster->start);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index 0c981eb..92bf5ee 100644 (file)
@@ -2813,7 +2813,7 @@ out:
 
 static inline int scrub_calc_parity_bitmap_len(int nsectors)
 {
-       return DIV_ROUND_UP(nsectors, BITS_PER_LONG) * (BITS_PER_LONG / 8);
+       return DIV_ROUND_UP(nsectors, BITS_PER_LONG) * sizeof(long);
 }
 
 static void scrub_parity_get(struct scrub_parity *sparity)
@@ -3458,7 +3458,7 @@ static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx,
                return ret;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (em->start != chunk_offset)
                goto out;
 
@@ -4279,7 +4279,7 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root,
                return PTR_ERR(inode);
 
        /* Avoid truncate/dio/punch hole.. */
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        inode_dio_wait(inode);
 
        physical_for_dev_replace = nocow_ctx->physical_for_dev_replace;
@@ -4358,7 +4358,7 @@ next_page:
        }
        ret = COPY_COMPLETE;
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        iput(inode);
        return ret;
 }
index 9b9eab6..d41e09f 100644 (file)
@@ -383,6 +383,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
        int ret = 0;
        char *compress_type;
        bool compress_force = false;
+       enum btrfs_compression_type saved_compress_type;
+       bool saved_compress_force;
+       int no_compress = 0;
 
        cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
        if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE))
@@ -462,6 +465,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        /* Fallthrough */
                case Opt_compress:
                case Opt_compress_type:
+                       saved_compress_type = btrfs_test_opt(root, COMPRESS) ?
+                               info->compress_type : BTRFS_COMPRESS_NONE;
+                       saved_compress_force =
+                               btrfs_test_opt(root, FORCE_COMPRESS);
                        if (token == Opt_compress ||
                            token == Opt_compress_force ||
                            strcmp(args[0].from, "zlib") == 0) {
@@ -470,6 +477,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                btrfs_set_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, NODATACOW);
                                btrfs_clear_opt(info->mount_opt, NODATASUM);
+                               no_compress = 0;
                        } else if (strcmp(args[0].from, "lzo") == 0) {
                                compress_type = "lzo";
                                info->compress_type = BTRFS_COMPRESS_LZO;
@@ -477,25 +485,21 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                btrfs_clear_opt(info->mount_opt, NODATACOW);
                                btrfs_clear_opt(info->mount_opt, NODATASUM);
                                btrfs_set_fs_incompat(info, COMPRESS_LZO);
+                               no_compress = 0;
                        } else if (strncmp(args[0].from, "no", 2) == 0) {
                                compress_type = "no";
                                btrfs_clear_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                                compress_force = false;
+                               no_compress++;
                        } else {
                                ret = -EINVAL;
                                goto out;
                        }
 
                        if (compress_force) {
-                               btrfs_set_and_info(root, FORCE_COMPRESS,
-                                                  "force %s compression",
-                                                  compress_type);
+                               btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
                        } else {
-                               if (!btrfs_test_opt(root, COMPRESS))
-                                       btrfs_info(root->fs_info,
-                                                  "btrfs: use %s compression",
-                                                  compress_type);
                                /*
                                 * If we remount from compress-force=xxx to
                                 * compress=xxx, we need clear FORCE_COMPRESS
@@ -504,6 +508,17 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                 */
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                        }
+                       if ((btrfs_test_opt(root, COMPRESS) &&
+                            (info->compress_type != saved_compress_type ||
+                             compress_force != saved_compress_force)) ||
+                           (!btrfs_test_opt(root, COMPRESS) &&
+                            no_compress == 1)) {
+                               btrfs_info(root->fs_info,
+                                          "%s %s compression",
+                                          (compress_force) ? "force" : "use",
+                                          compress_type);
+                       }
+                       compress_force = false;
                        break;
                case Opt_ssd:
                        btrfs_set_and_info(root, SSD,
index c32abbc..366b335 100644 (file)
@@ -108,7 +108,7 @@ const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
        },
 };
 
-const u64 const btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
+const u64 btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
        [BTRFS_RAID_RAID10] = BTRFS_BLOCK_GROUP_RAID10,
        [BTRFS_RAID_RAID1]  = BTRFS_BLOCK_GROUP_RAID1,
        [BTRFS_RAID_DUP]    = BTRFS_BLOCK_GROUP_DUP,
@@ -233,6 +233,7 @@ static struct btrfs_device *__alloc_device(void)
        spin_lock_init(&dev->reada_lock);
        atomic_set(&dev->reada_in_flight, 0);
        atomic_set(&dev->dev_stats_ccnt, 0);
+       btrfs_device_data_ordered_init(dev);
        INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
        INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
 
@@ -1183,7 +1184,7 @@ again:
                struct map_lookup *map;
                int i;
 
-               map = (struct map_lookup *)em->bdev;
+               map = em->map_lookup;
                for (i = 0; i < map->num_stripes; i++) {
                        u64 end;
 
@@ -2755,7 +2756,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                        free_extent_map(em);
                return -EINVAL;
        }
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        lock_chunks(root->fs_info->chunk_root);
        check_system_chunk(trans, extent_root, map->type);
        unlock_chunks(root->fs_info->chunk_root);
@@ -3751,7 +3752,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
        if (btrfs_get_num_tolerated_disk_barrier_failures(bctl->meta.target) <
                btrfs_get_num_tolerated_disk_barrier_failures(bctl->data.target)) {
                btrfs_warn(fs_info,
-       "metatdata profile 0x%llx has lower redundancy than data profile 0x%llx",
+       "metadata profile 0x%llx has lower redundancy than data profile 0x%llx",
                        bctl->meta.target, bctl->data.target);
        }
 
@@ -4718,7 +4719,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                goto error;
        }
        set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
-       em->bdev = (struct block_device *)map;
+       em->map_lookup = map;
        em->start = start;
        em->len = num_bytes;
        em->block_start = 0;
@@ -4813,7 +4814,7 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                return -EINVAL;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        item_size = btrfs_chunk_item_size(map->num_stripes);
        stripe_size = em->orig_block_len;
 
@@ -4968,7 +4969,7 @@ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset)
        if (!em)
                return 1;
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        for (i = 0; i < map->num_stripes; i++) {
                if (map->stripes[i].dev->missing) {
                        miss_ndevs++;
@@ -5048,7 +5049,7 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
                return 1;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (map->type & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1))
                ret = map->num_stripes;
        else if (map->type & BTRFS_BLOCK_GROUP_RAID10)
@@ -5084,7 +5085,7 @@ unsigned long btrfs_full_stripe_len(struct btrfs_root *root,
        BUG_ON(!em);
 
        BUG_ON(em->start > logical || em->start + em->len < logical);
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
                len = map->stripe_len * nr_data_stripes(map);
        free_extent_map(em);
@@ -5105,7 +5106,7 @@ int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree,
        BUG_ON(!em);
 
        BUG_ON(em->start > logical || em->start + em->len < logical);
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
                ret = 1;
        free_extent_map(em);
@@ -5264,7 +5265,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                return -EINVAL;
        }
 
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
        offset = logical - em->start;
 
        stripe_len = map->stripe_len;
@@ -5378,35 +5379,33 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
                 * target drive.
                 */
                for (i = 0; i < tmp_num_stripes; i++) {
-                       if (tmp_bbio->stripes[i].dev->devid == srcdev_devid) {
-                               /*
-                                * In case of DUP, in order to keep it
-                                * simple, only add the mirror with the
-                                * lowest physical address
-                                */
-                               if (found &&
-                                   physical_of_found <=
-                                    tmp_bbio->stripes[i].physical)
-                                       continue;
-                               index_srcdev = i;
-                               found = 1;
-                               physical_of_found =
-                                       tmp_bbio->stripes[i].physical;
-                       }
+                       if (tmp_bbio->stripes[i].dev->devid != srcdev_devid)
+                               continue;
+
+                       /*
+                        * In case of DUP, in order to keep it simple, only add
+                        * the mirror with the lowest physical address
+                        */
+                       if (found &&
+                           physical_of_found <= tmp_bbio->stripes[i].physical)
+                               continue;
+
+                       index_srcdev = i;
+                       found = 1;
+                       physical_of_found = tmp_bbio->stripes[i].physical;
                }
 
-               if (found) {
-                       mirror_num = index_srcdev + 1;
-                       patch_the_first_stripe_for_dev_replace = 1;
-                       physical_to_patch_in_first_stripe = physical_of_found;
-               } else {
+               btrfs_put_bbio(tmp_bbio);
+
+               if (!found) {
                        WARN_ON(1);
                        ret = -EIO;
-                       btrfs_put_bbio(tmp_bbio);
                        goto out;
                }
 
-               btrfs_put_bbio(tmp_bbio);
+               mirror_num = index_srcdev + 1;
+               patch_the_first_stripe_for_dev_replace = 1;
+               physical_to_patch_in_first_stripe = physical_of_found;
        } else if (mirror_num > map->num_stripes) {
                mirror_num = 0;
        }
@@ -5806,7 +5805,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
                free_extent_map(em);
                return -EIO;
        }
-       map = (struct map_lookup *)em->bdev;
+       map = em->map_lookup;
 
        length = em->len;
        rmap_len = map->stripe_len;
@@ -6069,7 +6068,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        bbio->fs_info = root->fs_info;
        atomic_set(&bbio->stripes_pending, bbio->num_stripes);
 
-       if (bbio->raid_map) {
+       if ((bbio->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK) &&
+           ((rw & WRITE) || (mirror_num > 1))) {
                /* In this case, map_length has been set to the length of
                   a single stripe; not the whole write */
                if (rw & WRITE) {
@@ -6210,6 +6210,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
        struct extent_map *em;
        u64 logical;
        u64 length;
+       u64 stripe_len;
        u64 devid;
        u8 uuid[BTRFS_UUID_SIZE];
        int num_stripes;
@@ -6218,6 +6219,37 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
 
        logical = key->offset;
        length = btrfs_chunk_length(leaf, chunk);
+       stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
+       num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+       /* Validation check */
+       if (!num_stripes) {
+               btrfs_err(root->fs_info, "invalid chunk num_stripes: %u",
+                         num_stripes);
+               return -EIO;
+       }
+       if (!IS_ALIGNED(logical, root->sectorsize)) {
+               btrfs_err(root->fs_info,
+                         "invalid chunk logical %llu", logical);
+               return -EIO;
+       }
+       if (!length || !IS_ALIGNED(length, root->sectorsize)) {
+               btrfs_err(root->fs_info,
+                       "invalid chunk length %llu", length);
+               return -EIO;
+       }
+       if (!is_power_of_2(stripe_len)) {
+               btrfs_err(root->fs_info, "invalid chunk stripe length: %llu",
+                         stripe_len);
+               return -EIO;
+       }
+       if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) &
+           btrfs_chunk_type(leaf, chunk)) {
+               btrfs_err(root->fs_info, "unrecognized chunk type: %llu",
+                         ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
+                           BTRFS_BLOCK_GROUP_PROFILE_MASK) &
+                         btrfs_chunk_type(leaf, chunk));
+               return -EIO;
+       }
 
        read_lock(&map_tree->map_tree.lock);
        em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
@@ -6234,7 +6266,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
        em = alloc_extent_map();
        if (!em)
                return -ENOMEM;
-       num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
        map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS);
        if (!map) {
                free_extent_map(em);
@@ -6242,7 +6273,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
        }
 
        set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
-       em->bdev = (struct block_device *)map;
+       em->map_lookup = map;
        em->start = logical;
        em->len = length;
        em->orig_start = 0;
@@ -6944,7 +6975,7 @@ void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
        /* In order to kick the device replace finish process */
        lock_chunks(root);
        list_for_each_entry(em, &transaction->pending_chunks, list) {
-               map = (struct map_lookup *)em->bdev;
+               map = em->map_lookup;
 
                for (i = 0; i < map->num_stripes; i++) {
                        dev = map->stripes[i].dev;
index fd953c3..6c68d63 100644 (file)
@@ -126,7 +126,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
         * locks the inode's i_mutex before calling setxattr or removexattr.
         */
        if (flags & XATTR_REPLACE) {
-               ASSERT(mutex_is_locked(&inode->i_mutex));
+               ASSERT(inode_is_locked(inode));
                di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode),
                                        name, name_len, 0);
                if (!di)
index afa023d..675a333 100644 (file)
@@ -446,7 +446,7 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
                return 0;
 
        cachefiles_begin_secure(cache, &saved_cred);
-       mutex_lock(&d_inode(object->backer)->i_mutex);
+       inode_lock(d_inode(object->backer));
 
        /* if there's an extension to a partial page at the end of the backing
         * file, we need to discard the partial page so that we pick up new
@@ -465,7 +465,7 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
        ret = notify_change(object->backer, &newattrs, NULL);
 
 truncate_failed:
-       mutex_unlock(&d_inode(object->backer)->i_mutex);
+       inode_unlock(d_inode(object->backer));
        cachefiles_end_secure(cache, saved_cred);
 
        if (ret == -EIO) {
index c4b8934..1c2334c 100644 (file)
@@ -295,7 +295,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
                                cachefiles_mark_object_buried(cache, rep, why);
                }
 
-               mutex_unlock(&d_inode(dir)->i_mutex);
+               inode_unlock(d_inode(dir));
 
                if (ret == -EIO)
                        cachefiles_io_error(cache, "Unlink failed");
@@ -306,7 +306,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
 
        /* directories have to be moved to the graveyard */
        _debug("move stale object to graveyard");
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 
 try_again:
        /* first step is to make up a grave dentry in the graveyard */
@@ -423,13 +423,13 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
 
        dir = dget_parent(object->dentry);
 
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
        if (test_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->fscache.flags)) {
                /* object allocation for the same key preemptively deleted this
                 * object's file so that it could create its own file */
                _debug("object preemptively buried");
-               mutex_unlock(&d_inode(dir)->i_mutex);
+               inode_unlock(d_inode(dir));
                ret = 0;
        } else {
                /* we need to check that our parent is _still_ our parent - it
@@ -442,7 +442,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
                        /* it got moved, presumably by cachefilesd culling it,
                         * so it's no longer in the key path and we can ignore
                         * it */
-                       mutex_unlock(&d_inode(dir)->i_mutex);
+                       inode_unlock(d_inode(dir));
                        ret = 0;
                }
        }
@@ -501,7 +501,7 @@ lookup_again:
        /* search the current directory for the element name */
        _debug("lookup '%s'", name);
 
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
        start = jiffies;
        next = lookup_one_len(name, dir, nlen);
@@ -585,7 +585,7 @@ lookup_again:
        /* process the next component */
        if (key) {
                _debug("advance");
-               mutex_unlock(&d_inode(dir)->i_mutex);
+               inode_unlock(d_inode(dir));
                dput(dir);
                dir = next;
                next = NULL;
@@ -623,7 +623,7 @@ lookup_again:
        /* note that we're now using this object */
        ret = cachefiles_mark_object_active(cache, object);
 
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        dput(dir);
        dir = NULL;
 
@@ -705,7 +705,7 @@ lookup_error:
                cachefiles_io_error(cache, "Lookup failed");
        next = NULL;
 error:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        dput(next);
 error_out2:
        dput(dir);
@@ -729,7 +729,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
        _enter(",,%s", dirname);
 
        /* search the current directory for the element name */
-       mutex_lock(&d_inode(dir)->i_mutex);
+       inode_lock(d_inode(dir));
 
        start = jiffies;
        subdir = lookup_one_len(dirname, dir, strlen(dirname));
@@ -768,7 +768,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
                       d_backing_inode(subdir)->i_ino);
        }
 
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 
        /* we need to make sure the subdir is a directory */
        ASSERT(d_backing_inode(subdir));
@@ -800,19 +800,19 @@ check_error:
        return ERR_PTR(ret);
 
 mkdir_error:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        dput(subdir);
        pr_err("mkdir %s failed with error %d\n", dirname, ret);
        return ERR_PTR(ret);
 
 lookup_error:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        ret = PTR_ERR(subdir);
        pr_err("Lookup %s failed with error %d\n", dirname, ret);
        return ERR_PTR(ret);
 
 nomem_d_alloc:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        _leave(" = -ENOMEM");
        return ERR_PTR(-ENOMEM);
 }
@@ -837,7 +837,7 @@ static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
        //       dir, filename);
 
        /* look up the victim */
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
        start = jiffies;
        victim = lookup_one_len(filename, dir, strlen(filename));
@@ -852,7 +852,7 @@ static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
         * at the netfs's request whilst the cull was in progress
         */
        if (d_is_negative(victim)) {
-               mutex_unlock(&d_inode(dir)->i_mutex);
+               inode_unlock(d_inode(dir));
                dput(victim);
                _leave(" = -ENOENT [absent]");
                return ERR_PTR(-ENOENT);
@@ -881,13 +881,13 @@ static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
 
 object_in_use:
        read_unlock(&cache->active_lock);
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        dput(victim);
        //_leave(" = -EBUSY [in use]");
        return ERR_PTR(-EBUSY);
 
 lookup_error:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        ret = PTR_ERR(victim);
        if (ret == -ENOENT) {
                /* file or dir now absent - probably retired by netfs */
@@ -947,7 +947,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
        return 0;
 
 error_unlock:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 error:
        dput(victim);
        if (ret == -ENOENT) {
@@ -982,7 +982,7 @@ int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir,
        if (IS_ERR(victim))
                return PTR_ERR(victim);
 
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        dput(victim);
        //_leave(" = 0");
        return 0;
index b7d218a..c222137 100644 (file)
@@ -1108,7 +1108,7 @@ retry_locked:
                return 0;
 
        /* past end of file? */
-       i_size = inode->i_size;   /* caller holds i_mutex */
+       i_size = i_size_read(inode);
 
        if (page_off >= i_size ||
            (pos_in_page == 0 && (pos+len) >= i_size &&
@@ -1149,7 +1149,6 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
                page = grab_cache_page_write_begin(mapping, index, 0);
                if (!page)
                        return -ENOMEM;
-               *pagep = page;
 
                dout("write_begin file %p inode %p page %p %d~%d\n", file,
                     inode, page, (int)pos, (int)len);
@@ -1184,8 +1183,7 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
                zero_user_segment(page, from+copied, len);
 
        /* did file size increase? */
-       /* (no need for i_size_read(); we caller holds i_mutex */
-       if (pos+copied > inode->i_size)
+       if (pos+copied > i_size_read(inode))
                check_cap = ceph_inode_set_size(inode, pos+copied);
 
        if (!PageUptodate(page))
@@ -1378,11 +1376,13 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
        ret = VM_FAULT_NOPAGE;
        if ((off > size) ||
-           (page->mapping != inode->i_mapping))
+           (page->mapping != inode->i_mapping)) {
+               unlock_page(page);
                goto out;
+       }
 
        ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
-       if (ret == 0) {
+       if (ret >= 0) {
                /* success.  we'll keep the page locked. */
                set_page_dirty(page);
                ret = VM_FAULT_LOCKED;
@@ -1393,8 +1393,6 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
                        ret = VM_FAULT_SIGBUS;
        }
 out:
-       if (ret != VM_FAULT_LOCKED)
-               unlock_page(page);
        if (ret == VM_FAULT_LOCKED ||
            ci->i_inline_version != CEPH_INLINE_NONE) {
                int dirty;
index a4766de..a351480 100644 (file)
@@ -106,7 +106,7 @@ static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
 
        memset(&aux, 0, sizeof(aux));
        aux.mtime = inode->i_mtime;
-       aux.size = inode->i_size;
+       aux.size = i_size_read(inode);
 
        memcpy(buffer, &aux, sizeof(aux));
 
@@ -117,9 +117,7 @@ static void ceph_fscache_inode_get_attr(const void *cookie_netfs_data,
                                        uint64_t *size)
 {
        const struct ceph_inode_info* ci = cookie_netfs_data;
-       const struct inode* inode = &ci->vfs_inode;
-
-       *size = inode->i_size;
+       *size = i_size_read(&ci->vfs_inode);
 }
 
 static enum fscache_checkaux ceph_fscache_inode_check_aux(
@@ -134,7 +132,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
 
        memset(&aux, 0, sizeof(aux));
        aux.mtime = inode->i_mtime;
-       aux.size = inode->i_size;
+       aux.size = i_size_read(inode);
 
        if (memcmp(data, &aux, sizeof(aux)) != 0)
                return FSCACHE_CHECKAUX_OBSOLETE;
@@ -197,7 +195,7 @@ void ceph_fscache_register_inode_cookie(struct ceph_fs_client* fsc,
                return;
 
        /* Avoid multiple racing open requests */
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (ci->fscache)
                goto done;
@@ -207,7 +205,7 @@ void ceph_fscache_register_inode_cookie(struct ceph_fs_client* fsc,
                                             ci, true);
        fscache_check_consistency(ci->fscache);
 done:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
 }
 
index c69e125..cdbf8cf 100644 (file)
@@ -2030,7 +2030,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        if (datasync)
                goto out;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        dirty = try_flush_caps(inode, &flush_tid);
        dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
@@ -2046,7 +2046,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                ret = wait_event_interruptible(ci->i_cap_wq,
                                        caps_are_flushed(inode, flush_tid));
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 out:
        dout("fsync %p%s result=%d\n", inode, datasync ? " datasync" : "", ret);
        return ret;
index 9314b4e..fd11fb2 100644 (file)
@@ -507,7 +507,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
        loff_t old_offset = ceph_make_fpos(fi->frag, fi->next_offset);
        loff_t retval;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        retval = -EINVAL;
        switch (whence) {
        case SEEK_CUR:
@@ -542,7 +542,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
                }
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return retval;
 }
 
index fe02ae7..3b31723 100644 (file)
@@ -215,7 +215,7 @@ static int ceph_get_name(struct dentry *parent, char *name,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
 
        req->r_inode = d_inode(child);
        ihold(d_inode(child));
@@ -224,7 +224,7 @@ static int ceph_get_name(struct dentry *parent, char *name,
        req->r_num_caps = 2;
        err = ceph_mdsc_do_request(mdsc, NULL, req);
 
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
 
        if (!err) {
                struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
index 3c68e6a..86a9c38 100644 (file)
@@ -397,8 +397,9 @@ int ceph_release(struct inode *inode, struct file *file)
 }
 
 enum {
-       CHECK_EOF = 1,
-       READ_INLINE = 2,
+       HAVE_RETRIED = 1,
+       CHECK_EOF =    2,
+       READ_INLINE =  3,
 };
 
 /*
@@ -411,17 +412,15 @@ enum {
 static int striped_read(struct inode *inode,
                        u64 off, u64 len,
                        struct page **pages, int num_pages,
-                       int *checkeof, bool o_direct,
-                       unsigned long buf_align)
+                       int *checkeof)
 {
        struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_inode_info *ci = ceph_inode(inode);
        u64 pos, this_len, left;
-       int io_align, page_align;
-       int pages_left;
-       int read;
+       loff_t i_size;
+       int page_align, pages_left;
+       int read, ret;
        struct page **page_pos;
-       int ret;
        bool hit_stripe, was_short;
 
        /*
@@ -432,13 +431,9 @@ static int striped_read(struct inode *inode,
        page_pos = pages;
        pages_left = num_pages;
        read = 0;
-       io_align = off & ~PAGE_MASK;
 
 more:
-       if (o_direct)
-               page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
-       else
-               page_align = pos & ~PAGE_MASK;
+       page_align = pos & ~PAGE_MASK;
        this_len = left;
        ret = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode),
                                  &ci->i_layout, pos, &this_len,
@@ -452,13 +447,12 @@ more:
        dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read,
             ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
 
+       i_size = i_size_read(inode);
        if (ret >= 0) {
                int didpages;
-               if (was_short && (pos + ret < inode->i_size)) {
-                       int zlen = min(this_len - ret,
-                                      inode->i_size - pos - ret);
-                       int zoff = (o_direct ? buf_align : io_align) +
-                                   read + ret;
+               if (was_short && (pos + ret < i_size)) {
+                       int zlen = min(this_len - ret, i_size - pos - ret);
+                       int zoff = (off & ~PAGE_MASK) + read + ret;
                        dout(" zero gap %llu to %llu\n",
                                pos + ret, pos + ret + zlen);
                        ceph_zero_page_vector_range(zoff, zlen, pages);
@@ -473,14 +467,14 @@ more:
                pages_left -= didpages;
 
                /* hit stripe and need continue*/
-               if (left && hit_stripe && pos < inode->i_size)
+               if (left && hit_stripe && pos < i_size)
                        goto more;
        }
 
        if (read > 0) {
                ret = read;
                /* did we bounce off eof? */
-               if (pos + left > inode->i_size)
+               if (pos + left > i_size)
                        *checkeof = CHECK_EOF;
        }
 
@@ -521,54 +515,28 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i,
        if (ret < 0)
                return ret;
 
-       if (iocb->ki_flags & IOCB_DIRECT) {
-               while (iov_iter_count(i)) {
-                       size_t start;
-                       ssize_t n;
-
-                       n = dio_get_pagev_size(i);
-                       pages = dio_get_pages_alloc(i, n, &start, &num_pages);
-                       if (IS_ERR(pages))
-                               return PTR_ERR(pages);
-
-                       ret = striped_read(inode, off, n,
-                                          pages, num_pages, checkeof,
-                                          1, start);
-
-                       ceph_put_page_vector(pages, num_pages, true);
-
-                       if (ret <= 0)
-                               break;
-                       off += ret;
-                       iov_iter_advance(i, ret);
-                       if (ret < n)
+       num_pages = calc_pages_for(off, len);
+       pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
+       if (IS_ERR(pages))
+               return PTR_ERR(pages);
+       ret = striped_read(inode, off, len, pages,
+                               num_pages, checkeof);
+       if (ret > 0) {
+               int l, k = 0;
+               size_t left = ret;
+
+               while (left) {
+                       size_t page_off = off & ~PAGE_MASK;
+                       size_t copy = min_t(size_t, left,
+                                           PAGE_SIZE - page_off);
+                       l = copy_page_to_iter(pages[k++], page_off, copy, i);
+                       off += l;
+                       left -= l;
+                       if (l < copy)
                                break;
                }
-       } else {
-               num_pages = calc_pages_for(off, len);
-               pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
-               if (IS_ERR(pages))
-                       return PTR_ERR(pages);
-               ret = striped_read(inode, off, len, pages,
-                                       num_pages, checkeof, 0, 0);
-               if (ret > 0) {
-                       int l, k = 0;
-                       size_t left = ret;
-
-                       while (left) {
-                               size_t page_off = off & ~PAGE_MASK;
-                               size_t copy = min_t(size_t,
-                                                   PAGE_SIZE - page_off, left);
-                               l = copy_page_to_iter(pages[k++], page_off,
-                                                     copy, i);
-                               off += l;
-                               left -= l;
-                               if (l < copy)
-                                       break;
-                       }
-               }
-               ceph_release_page_vector(pages, num_pages);
        }
+       ceph_release_page_vector(pages, num_pages);
 
        if (off > iocb->ki_pos) {
                ret = off - iocb->ki_pos;
@@ -579,6 +547,193 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i,
        return ret;
 }
 
+struct ceph_aio_request {
+       struct kiocb *iocb;
+       size_t total_len;
+       int write;
+       int error;
+       struct list_head osd_reqs;
+       unsigned num_reqs;
+       atomic_t pending_reqs;
+       struct timespec mtime;
+       struct ceph_cap_flush *prealloc_cf;
+};
+
+struct ceph_aio_work {
+       struct work_struct work;
+       struct ceph_osd_request *req;
+};
+
+static void ceph_aio_retry_work(struct work_struct *work);
+
+static void ceph_aio_complete(struct inode *inode,
+                             struct ceph_aio_request *aio_req)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int ret;
+
+       if (!atomic_dec_and_test(&aio_req->pending_reqs))
+               return;
+
+       ret = aio_req->error;
+       if (!ret)
+               ret = aio_req->total_len;
+
+       dout("ceph_aio_complete %p rc %d\n", inode, ret);
+
+       if (ret >= 0 && aio_req->write) {
+               int dirty;
+
+               loff_t endoff = aio_req->iocb->ki_pos + aio_req->total_len;
+               if (endoff > i_size_read(inode)) {
+                       if (ceph_inode_set_size(inode, endoff))
+                               ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+               }
+
+               spin_lock(&ci->i_ceph_lock);
+               ci->i_inline_version = CEPH_INLINE_NONE;
+               dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR,
+                                              &aio_req->prealloc_cf);
+               spin_unlock(&ci->i_ceph_lock);
+               if (dirty)
+                       __mark_inode_dirty(inode, dirty);
+
+       }
+
+       ceph_put_cap_refs(ci, (aio_req->write ? CEPH_CAP_FILE_WR :
+                                               CEPH_CAP_FILE_RD));
+
+       aio_req->iocb->ki_complete(aio_req->iocb, ret, 0);
+
+       ceph_free_cap_flush(aio_req->prealloc_cf);
+       kfree(aio_req);
+}
+
+static void ceph_aio_complete_req(struct ceph_osd_request *req,
+                                 struct ceph_msg *msg)
+{
+       int rc = req->r_result;
+       struct inode *inode = req->r_inode;
+       struct ceph_aio_request *aio_req = req->r_priv;
+       struct ceph_osd_data *osd_data = osd_req_op_extent_osd_data(req, 0);
+       int num_pages = calc_pages_for((u64)osd_data->alignment,
+                                      osd_data->length);
+
+       dout("ceph_aio_complete_req %p rc %d bytes %llu\n",
+            inode, rc, osd_data->length);
+
+       if (rc == -EOLDSNAPC) {
+               struct ceph_aio_work *aio_work;
+               BUG_ON(!aio_req->write);
+
+               aio_work = kmalloc(sizeof(*aio_work), GFP_NOFS);
+               if (aio_work) {
+                       INIT_WORK(&aio_work->work, ceph_aio_retry_work);
+                       aio_work->req = req;
+                       queue_work(ceph_inode_to_client(inode)->wb_wq,
+                                  &aio_work->work);
+                       return;
+               }
+               rc = -ENOMEM;
+       } else if (!aio_req->write) {
+               if (rc == -ENOENT)
+                       rc = 0;
+               if (rc >= 0 && osd_data->length > rc) {
+                       int zoff = osd_data->alignment + rc;
+                       int zlen = osd_data->length - rc;
+                       /*
+                        * If read is satisfied by single OSD request,
+                        * it can pass EOF. Otherwise read is within
+                        * i_size.
+                        */
+                       if (aio_req->num_reqs == 1) {
+                               loff_t i_size = i_size_read(inode);
+                               loff_t endoff = aio_req->iocb->ki_pos + rc;
+                               if (endoff < i_size)
+                                       zlen = min_t(size_t, zlen,
+                                                    i_size - endoff);
+                               aio_req->total_len = rc + zlen;
+                       }
+
+                       if (zlen > 0)
+                               ceph_zero_page_vector_range(zoff, zlen,
+                                                           osd_data->pages);
+               }
+       }
+
+       ceph_put_page_vector(osd_data->pages, num_pages, false);
+       ceph_osdc_put_request(req);
+
+       if (rc < 0)
+               cmpxchg(&aio_req->error, 0, rc);
+
+       ceph_aio_complete(inode, aio_req);
+       return;
+}
+
+static void ceph_aio_retry_work(struct work_struct *work)
+{
+       struct ceph_aio_work *aio_work =
+               container_of(work, struct ceph_aio_work, work);
+       struct ceph_osd_request *orig_req = aio_work->req;
+       struct ceph_aio_request *aio_req = orig_req->r_priv;
+       struct inode *inode = orig_req->r_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_snap_context *snapc;
+       struct ceph_osd_request *req;
+       int ret;
+
+       spin_lock(&ci->i_ceph_lock);
+       if (__ceph_have_pending_cap_snap(ci)) {
+               struct ceph_cap_snap *capsnap =
+                       list_last_entry(&ci->i_cap_snaps,
+                                       struct ceph_cap_snap,
+                                       ci_item);
+               snapc = ceph_get_snap_context(capsnap->context);
+       } else {
+               BUG_ON(!ci->i_head_snapc);
+               snapc = ceph_get_snap_context(ci->i_head_snapc);
+       }
+       spin_unlock(&ci->i_ceph_lock);
+
+       req = ceph_osdc_alloc_request(orig_req->r_osdc, snapc, 2,
+                       false, GFP_NOFS);
+       if (IS_ERR(req)) {
+               ret = PTR_ERR(req);
+               req = orig_req;
+               goto out;
+       }
+
+       req->r_flags =  CEPH_OSD_FLAG_ORDERSNAP |
+                       CEPH_OSD_FLAG_ONDISK |
+                       CEPH_OSD_FLAG_WRITE;
+       req->r_base_oloc = orig_req->r_base_oloc;
+       req->r_base_oid = orig_req->r_base_oid;
+
+       req->r_ops[0] = orig_req->r_ops[0];
+       osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0);
+
+       ceph_osdc_build_request(req, req->r_ops[0].extent.offset,
+                               snapc, CEPH_NOSNAP, &aio_req->mtime);
+
+       ceph_put_snap_context(snapc);
+       ceph_osdc_put_request(orig_req);
+
+       req->r_callback = ceph_aio_complete_req;
+       req->r_inode = inode;
+       req->r_priv = aio_req;
+
+       ret = ceph_osdc_start_request(req->r_osdc, req, false);
+out:
+       if (ret < 0) {
+               BUG_ON(ret == -EOLDSNAPC);
+               req->r_result = ret;
+               ceph_aio_complete_req(req, NULL);
+       }
+
+       kfree(aio_work);
+}
+
 /*
  * Write commit request unsafe callback, called to tell us when a
  * request is unsafe (that is, in flight--has been handed to the
@@ -612,16 +767,10 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe)
 }
 
 
-/*
- * Synchronous write, straight from __user pointer or user pages.
- *
- * If write spans object boundary, just do multiple writes.  (For a
- * correct atomic write, we should e.g. take write locks on all
- * objects, rollback on failure, etc.)
- */
 static ssize_t
-ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
-                      struct ceph_snap_context *snapc)
+ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
+                      struct ceph_snap_context *snapc,
+                      struct ceph_cap_flush **pcf)
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
@@ -630,44 +779,52 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
        struct ceph_vino vino;
        struct ceph_osd_request *req;
        struct page **pages;
-       int num_pages;
-       int written = 0;
+       struct ceph_aio_request *aio_req = NULL;
+       int num_pages = 0;
        int flags;
-       int check_caps = 0;
        int ret;
        struct timespec mtime = CURRENT_TIME;
-       size_t count = iov_iter_count(from);
+       size_t count = iov_iter_count(iter);
+       loff_t pos = iocb->ki_pos;
+       bool write = iov_iter_rw(iter) == WRITE;
 
-       if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
+       if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
                return -EROFS;
 
-       dout("sync_direct_write on file %p %lld~%u\n", file, pos,
-            (unsigned)count);
+       dout("sync_direct_read_write (%s) on file %p %lld~%u\n",
+            (write ? "write" : "read"), file, pos, (unsigned)count);
 
        ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + count);
        if (ret < 0)
                return ret;
 
-       ret = invalidate_inode_pages2_range(inode->i_mapping,
-                                           pos >> PAGE_CACHE_SHIFT,
-                                           (pos + count) >> PAGE_CACHE_SHIFT);
-       if (ret < 0)
-               dout("invalidate_inode_pages2_range returned %d\n", ret);
+       if (write) {
+               ret = invalidate_inode_pages2_range(inode->i_mapping,
+                                       pos >> PAGE_CACHE_SHIFT,
+                                       (pos + count) >> PAGE_CACHE_SHIFT);
+               if (ret < 0)
+                       dout("invalidate_inode_pages2_range returned %d\n", ret);
 
-       flags = CEPH_OSD_FLAG_ORDERSNAP |
-               CEPH_OSD_FLAG_ONDISK |
-               CEPH_OSD_FLAG_WRITE;
+               flags = CEPH_OSD_FLAG_ORDERSNAP |
+                       CEPH_OSD_FLAG_ONDISK |
+                       CEPH_OSD_FLAG_WRITE;
+       } else {
+               flags = CEPH_OSD_FLAG_READ;
+       }
 
-       while (iov_iter_count(from) > 0) {
-               u64 len = dio_get_pagev_size(from);
-               size_t start;
-               ssize_t n;
+       while (iov_iter_count(iter) > 0) {
+               u64 size = dio_get_pagev_size(iter);
+               size_t start = 0;
+               ssize_t len;
 
                vino = ceph_vino(inode);
                req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
-                                           vino, pos, &len, 0,
-                                           2,/*include a 'startsync' command*/
-                                           CEPH_OSD_OP_WRITE, flags, snapc,
+                                           vino, pos, &size, 0,
+                                           /*include a 'startsync' command*/
+                                           write ? 2 : 1,
+                                           write ? CEPH_OSD_OP_WRITE :
+                                                   CEPH_OSD_OP_READ,
+                                           flags, snapc,
                                            ci->i_truncate_seq,
                                            ci->i_truncate_size,
                                            false);
@@ -676,10 +833,8 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
                        break;
                }
 
-               osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0);
-
-               n = len;
-               pages = dio_get_pages_alloc(from, len, &start, &num_pages);
+               len = size;
+               pages = dio_get_pages_alloc(iter, len, &start, &num_pages);
                if (IS_ERR(pages)) {
                        ceph_osdc_put_request(req);
                        ret = PTR_ERR(pages);
@@ -687,47 +842,128 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
                }
 
                /*
-                * throw out any page cache pages in this range. this
-                * may block.
+                * To simplify error handling, allow AIO when IO within i_size
+                * or IO can be satisfied by single OSD request.
                 */
-               truncate_inode_pages_range(inode->i_mapping, pos,
-                                  (pos+n) | (PAGE_CACHE_SIZE-1));
-               osd_req_op_extent_osd_data_pages(req, 0, pages, n, start,
-                                               false, false);
+               if (pos == iocb->ki_pos && !is_sync_kiocb(iocb) &&
+                   (len == count || pos + count <= i_size_read(inode))) {
+                       aio_req = kzalloc(sizeof(*aio_req), GFP_KERNEL);
+                       if (aio_req) {
+                               aio_req->iocb = iocb;
+                               aio_req->write = write;
+                               INIT_LIST_HEAD(&aio_req->osd_reqs);
+                               if (write) {
+                                       aio_req->mtime = mtime;
+                                       swap(aio_req->prealloc_cf, *pcf);
+                               }
+                       }
+                       /* ignore error */
+               }
+
+               if (write) {
+                       /*
+                        * throw out any page cache pages in this range. this
+                        * may block.
+                        */
+                       truncate_inode_pages_range(inode->i_mapping, pos,
+                                       (pos+len) | (PAGE_CACHE_SIZE - 1));
+
+                       osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0);
+               }
+
+
+               osd_req_op_extent_osd_data_pages(req, 0, pages, len, start,
+                                                false, false);
 
-               /* BUG_ON(vino.snap != CEPH_NOSNAP); */
                ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
 
-               ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
+               if (aio_req) {
+                       aio_req->total_len += len;
+                       aio_req->num_reqs++;
+                       atomic_inc(&aio_req->pending_reqs);
+
+                       req->r_callback = ceph_aio_complete_req;
+                       req->r_inode = inode;
+                       req->r_priv = aio_req;
+                       list_add_tail(&req->r_unsafe_item, &aio_req->osd_reqs);
+
+                       pos += len;
+                       iov_iter_advance(iter, len);
+                       continue;
+               }
+
+               ret = ceph_osdc_start_request(req->r_osdc, req, false);
                if (!ret)
                        ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
 
+               size = i_size_read(inode);
+               if (!write) {
+                       if (ret == -ENOENT)
+                               ret = 0;
+                       if (ret >= 0 && ret < len && pos + ret < size) {
+                               int zlen = min_t(size_t, len - ret,
+                                                size - pos - ret);
+                               ceph_zero_page_vector_range(start + ret, zlen,
+                                                           pages);
+                               ret += zlen;
+                       }
+                       if (ret >= 0)
+                               len = ret;
+               }
+
                ceph_put_page_vector(pages, num_pages, false);
 
                ceph_osdc_put_request(req);
-               if (ret)
+               if (ret < 0)
                        break;
-               pos += n;
-               written += n;
-               iov_iter_advance(from, n);
 
-               if (pos > i_size_read(inode)) {
-                       check_caps = ceph_inode_set_size(inode, pos);
-                       if (check_caps)
+               pos += len;
+               iov_iter_advance(iter, len);
+
+               if (!write && pos >= size)
+                       break;
+
+               if (write && pos > size) {
+                       if (ceph_inode_set_size(inode, pos))
                                ceph_check_caps(ceph_inode(inode),
                                                CHECK_CAPS_AUTHONLY,
                                                NULL);
                }
        }
 
-       if (ret != -EOLDSNAPC && written > 0) {
+       if (aio_req) {
+               if (aio_req->num_reqs == 0) {
+                       kfree(aio_req);
+                       return ret;
+               }
+
+               ceph_get_cap_refs(ci, write ? CEPH_CAP_FILE_WR :
+                                             CEPH_CAP_FILE_RD);
+
+               while (!list_empty(&aio_req->osd_reqs)) {
+                       req = list_first_entry(&aio_req->osd_reqs,
+                                              struct ceph_osd_request,
+                                              r_unsafe_item);
+                       list_del_init(&req->r_unsafe_item);
+                       if (ret >= 0)
+                               ret = ceph_osdc_start_request(req->r_osdc,
+                                                             req, false);
+                       if (ret < 0) {
+                               BUG_ON(ret == -EOLDSNAPC);
+                               req->r_result = ret;
+                               ceph_aio_complete_req(req, NULL);
+                       }
+               }
+               return -EIOCBQUEUED;
+       }
+
+       if (ret != -EOLDSNAPC && pos > iocb->ki_pos) {
+               ret = pos - iocb->ki_pos;
                iocb->ki_pos = pos;
-               ret = written;
        }
        return ret;
 }
 
-
 /*
  * Synchronous write, straight from __user pointer or user pages.
  *
@@ -897,8 +1133,14 @@ again:
                     ceph_cap_string(got));
 
                if (ci->i_inline_version == CEPH_INLINE_NONE) {
-                       /* hmm, this isn't really async... */
-                       ret = ceph_sync_read(iocb, to, &retry_op);
+                       if (!retry_op && (iocb->ki_flags & IOCB_DIRECT)) {
+                               ret = ceph_direct_read_write(iocb, to,
+                                                            NULL, NULL);
+                               if (ret >= 0 && ret < len)
+                                       retry_op = CHECK_EOF;
+                       } else {
+                               ret = ceph_sync_read(iocb, to, &retry_op);
+                       }
                } else {
                        retry_op = READ_INLINE;
                }
@@ -916,7 +1158,7 @@ again:
                pinned_page = NULL;
        }
        ceph_put_cap_refs(ci, got);
-       if (retry_op && ret >= 0) {
+       if (retry_op > HAVE_RETRIED && ret >= 0) {
                int statret;
                struct page *page = NULL;
                loff_t i_size;
@@ -968,12 +1210,11 @@ again:
                if (retry_op == CHECK_EOF && iocb->ki_pos < i_size &&
                    ret < len) {
                        dout("sync_read hit hole, ppos %lld < size %lld"
-                            ", reading more\n", iocb->ki_pos,
-                            inode->i_size);
+                            ", reading more\n", iocb->ki_pos, i_size);
 
                        read += ret;
                        len -= ret;
-                       retry_op = 0;
+                       retry_op = HAVE_RETRIED;
                        goto again;
                }
        }
@@ -1014,7 +1255,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (!prealloc_cf)
                return -ENOMEM;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* We can write back this queue in page reclaim */
        current->backing_dev_info = inode_to_bdi(inode);
@@ -1052,7 +1293,7 @@ retry_snap:
        }
 
        dout("aio_write %p %llx.%llx %llu~%zd getting caps. i_size %llu\n",
-            inode, ceph_vinop(inode), pos, count, inode->i_size);
+            inode, ceph_vinop(inode), pos, count, i_size_read(inode));
        if (fi->fmode & CEPH_FILE_MODE_LAZY)
                want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
        else
@@ -1070,7 +1311,7 @@ retry_snap:
            (iocb->ki_flags & IOCB_DIRECT) || (fi->flags & CEPH_F_SYNC)) {
                struct ceph_snap_context *snapc;
                struct iov_iter data;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
                spin_lock(&ci->i_ceph_lock);
                if (__ceph_have_pending_cap_snap(ci)) {
@@ -1088,8 +1329,8 @@ retry_snap:
                /* we might need to revert back to that point */
                data = *from;
                if (iocb->ki_flags & IOCB_DIRECT)
-                       written = ceph_sync_direct_write(iocb, &data, pos,
-                                                        snapc);
+                       written = ceph_direct_read_write(iocb, &data, snapc,
+                                                        &prealloc_cf);
                else
                        written = ceph_sync_write(iocb, &data, pos, snapc);
                if (written == -EOLDSNAPC) {
@@ -1097,14 +1338,14 @@ retry_snap:
                                "got EOLDSNAPC, retrying\n",
                                inode, ceph_vinop(inode),
                                pos, (unsigned)count);
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
                        goto retry_snap;
                }
                if (written > 0)
                        iov_iter_advance(from, written);
                ceph_put_snap_context(snapc);
        } else {
-               loff_t old_size = inode->i_size;
+               loff_t old_size = i_size_read(inode);
                /*
                 * No need to acquire the i_truncate_mutex. Because
                 * the MDS revokes Fwb caps before sending truncate
@@ -1115,9 +1356,9 @@ retry_snap:
                written = generic_perform_write(file, from, pos);
                if (likely(written >= 0))
                        iocb->ki_pos = pos + written;
-               if (inode->i_size > old_size)
+               if (i_size_read(inode) > old_size)
                        ceph_fscache_update_objectsize(inode);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
        if (written >= 0) {
@@ -1147,7 +1388,7 @@ retry_snap:
        goto out_unlocked;
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 out_unlocked:
        ceph_free_cap_flush(prealloc_cf);
        current->backing_dev_info = NULL;
@@ -1160,9 +1401,10 @@ out_unlocked:
 static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
 {
        struct inode *inode = file->f_mapping->host;
+       loff_t i_size;
        int ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (whence == SEEK_END || whence == SEEK_DATA || whence == SEEK_HOLE) {
                ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
@@ -1172,9 +1414,10 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
                }
        }
 
+       i_size = i_size_read(inode);
        switch (whence) {
        case SEEK_END:
-               offset += inode->i_size;
+               offset += i_size;
                break;
        case SEEK_CUR:
                /*
@@ -1190,24 +1433,24 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
                offset += file->f_pos;
                break;
        case SEEK_DATA:
-               if (offset >= inode->i_size) {
+               if (offset >= i_size) {
                        ret = -ENXIO;
                        goto out;
                }
                break;
        case SEEK_HOLE:
-               if (offset >= inode->i_size) {
+               if (offset >= i_size) {
                        ret = -ENXIO;
                        goto out;
                }
-               offset = inode->i_size;
+               offset = i_size;
                break;
        }
 
        offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return offset;
 }
 
@@ -1363,7 +1606,7 @@ static long ceph_fallocate(struct file *file, int mode,
        if (!prealloc_cf)
                return -ENOMEM;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (ceph_snap(inode) != CEPH_NOSNAP) {
                ret = -EROFS;
@@ -1418,7 +1661,7 @@ static long ceph_fallocate(struct file *file, int mode,
 
        ceph_put_cap_refs(ci, got);
 unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        ceph_free_cap_flush(prealloc_cf);
        return ret;
 }
index da55eb8..fb4ba2e 100644 (file)
@@ -548,7 +548,7 @@ int ceph_fill_file_size(struct inode *inode, int issued,
        if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
            (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
                dout("size %lld -> %llu\n", inode->i_size, size);
-               inode->i_size = size;
+               i_size_write(inode, size);
                inode->i_blocks = (size + (1<<9) - 1) >> 9;
                ci->i_reported_size = size;
                if (truncate_seq != ci->i_truncate_seq) {
@@ -808,7 +808,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
                        spin_unlock(&ci->i_ceph_lock);
 
                        err = -EINVAL;
-                       if (WARN_ON(symlen != inode->i_size))
+                       if (WARN_ON(symlen != i_size_read(inode)))
                                goto out;
 
                        err = -ENOMEM;
@@ -1549,7 +1549,7 @@ int ceph_inode_set_size(struct inode *inode, loff_t size)
 
        spin_lock(&ci->i_ceph_lock);
        dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size);
-       inode->i_size = size;
+       i_size_write(inode, size);
        inode->i_blocks = (size + (1 << 9) - 1) >> 9;
 
        /* tell the MDS if we are approaching max_size */
@@ -1911,7 +1911,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
                     inode->i_size, attr->ia_size);
                if ((issued & CEPH_CAP_FILE_EXCL) &&
                    attr->ia_size > inode->i_size) {
-                       inode->i_size = attr->ia_size;
+                       i_size_write(inode, attr->ia_size);
                        inode->i_blocks =
                                (attr->ia_size + (1 << 9) - 1) >> 9;
                        inode->i_ctime = attr->ia_ctime;
index 7febcf2..50b2684 100644 (file)
@@ -50,7 +50,7 @@ void cifs_vfs_err(const char *fmt, ...)
        vaf.fmt = fmt;
        vaf.va = &args;
 
-       pr_err("CIFS VFS: %pV", &vaf);
+       pr_err_ratelimited("CIFS VFS: %pV", &vaf);
 
        va_end(args);
 }
index f40fbac..66cf0f9 100644 (file)
@@ -51,14 +51,13 @@ __printf(1, 2) void cifs_vfs_err(const char *fmt, ...);
 /* information message: e.g., configuration, major event */
 #define cifs_dbg(type, fmt, ...)                                       \
 do {                                                                   \
-       if (type == FYI) {                                              \
-               if (cifsFYI & CIFS_INFO) {                              \
-                       pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__);  \
-               }                                                       \
+       if (type == FYI && cifsFYI & CIFS_INFO) {                       \
+               pr_debug_ratelimited("%s: "                             \
+                           fmt, __FILE__, ##__VA_ARGS__);              \
        } else if (type == VFS) {                                       \
                cifs_vfs_err(fmt, ##__VA_ARGS__);                       \
        } else if (type == NOISY && type != 0) {                        \
-               pr_debug(fmt, ##__VA_ARGS__);                           \
+               pr_debug_ratelimited(fmt, ##__VA_ARGS__);               \
        }                                                               \
 } while (0)
 
index c4c1169..c48ca13 100644 (file)
@@ -507,6 +507,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 
        seq_printf(s, ",rsize=%u", cifs_sb->rsize);
        seq_printf(s, ",wsize=%u", cifs_sb->wsize);
+       seq_printf(s, ",echo_interval=%lu",
+                       tcon->ses->server->echo_interval / HZ);
        /* convert actimeo and display it in seconds */
        seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
 
@@ -640,9 +642,9 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
                while (*s && *s != sep)
                        s++;
 
-               mutex_lock(&dir->i_mutex);
+               inode_lock(dir);
                child = lookup_one_len(p, dentry, s - p);
-               mutex_unlock(&dir->i_mutex);
+               inode_unlock(dir);
                dput(dentry);
                dentry = child;
        } while (!IS_ERR(dentry));
@@ -752,6 +754,9 @@ cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
        ssize_t rc;
        struct inode *inode = file_inode(iocb->ki_filp);
 
+       if (iocb->ki_filp->f_flags & O_DIRECT)
+               return cifs_user_readv(iocb, iter);
+
        rc = cifs_revalidate_mapping(inode);
        if (rc)
                return rc;
@@ -766,6 +771,18 @@ static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        ssize_t written;
        int rc;
 
+       if (iocb->ki_filp->f_flags & O_DIRECT) {
+               written = cifs_user_writev(iocb, from);
+               if (written > 0 && CIFS_CACHE_READ(cinode)) {
+                       cifs_zap_mapping(inode);
+                       cifs_dbg(FYI,
+                                "Set no oplock for inode=%p after a write operation\n",
+                                inode);
+                       cinode->oplock = 0;
+               }
+               return written;
+       }
+
        written = cifs_get_writer(cinode);
        if (written)
                return written;
index 2b510c5..a25b251 100644 (file)
 #define SERVER_NAME_LENGTH 40
 #define SERVER_NAME_LEN_WITH_NULL     (SERVER_NAME_LENGTH + 1)
 
-/* SMB echo "timeout" -- FIXME: tunable? */
-#define SMB_ECHO_INTERVAL (60 * HZ)
+/* echo interval in seconds */
+#define SMB_ECHO_INTERVAL_MIN 1
+#define SMB_ECHO_INTERVAL_MAX 600
+#define SMB_ECHO_INTERVAL_DEFAULT 60
 
 #include "cifspdu.h"
 
@@ -225,7 +227,7 @@ struct smb_version_operations {
        void (*print_stats)(struct seq_file *m, struct cifs_tcon *);
        void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *);
        /* verify the message */
-       int (*check_message)(char *, unsigned int);
+       int (*check_message)(char *, unsigned int, struct TCP_Server_Info *);
        bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
        void (*downgrade_oplock)(struct TCP_Server_Info *,
                                        struct cifsInodeInfo *, bool);
@@ -507,6 +509,7 @@ struct smb_vol {
        struct sockaddr_storage dstaddr; /* destination address */
        struct sockaddr_storage srcaddr; /* allow binding to a local IP */
        struct nls_table *local_nls;
+       unsigned int echo_interval; /* echo interval in secs */
 };
 
 #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
@@ -627,7 +630,9 @@ struct TCP_Server_Info {
 #ifdef CONFIG_CIFS_SMB2
        unsigned int    max_read;
        unsigned int    max_write;
+       __u8            preauth_hash[512];
 #endif /* CONFIG_CIFS_SMB2 */
+       unsigned long echo_interval;
 };
 
 static inline unsigned int
@@ -809,7 +814,10 @@ struct cifs_ses {
        bool need_reconnect:1; /* connection reset, uid now invalid */
 #ifdef CONFIG_CIFS_SMB2
        __u16 session_flags;
-       char smb3signingkey[SMB3_SIGN_KEY_SIZE]; /* for signing smb3 packets */
+       __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
+       __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
+       __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
+       __u8 preauth_hash[512];
 #endif /* CONFIG_CIFS_SMB2 */
 };
 
index c63fd1d..eed7ff5 100644 (file)
@@ -102,7 +102,7 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
                        struct smb_hdr *out_buf,
                        int *bytes_returned);
 extern int cifs_reconnect(struct TCP_Server_Info *server);
-extern int checkSMB(char *buf, unsigned int length);
+extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr);
 extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
 extern bool backup_cred(struct cifs_sb_info *);
 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
@@ -439,7 +439,8 @@ extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
 extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
 extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
 extern int calc_seckey(struct cifs_ses *);
-extern int generate_smb3signingkey(struct cifs_ses *);
+extern int generate_smb30signingkey(struct cifs_ses *);
+extern int generate_smb311signingkey(struct cifs_ses *);
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern int calc_lanman_hash(const char *password, const char *cryptkey,
index ecb0803..4fbd92d 100644 (file)
@@ -95,6 +95,7 @@ enum {
        Opt_cruid, Opt_gid, Opt_file_mode,
        Opt_dirmode, Opt_port,
        Opt_rsize, Opt_wsize, Opt_actimeo,
+       Opt_echo_interval,
 
        /* Mount options which take string value */
        Opt_user, Opt_pass, Opt_ip,
@@ -188,6 +189,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_rsize, "rsize=%s" },
        { Opt_wsize, "wsize=%s" },
        { Opt_actimeo, "actimeo=%s" },
+       { Opt_echo_interval, "echo_interval=%s" },
 
        { Opt_blank_user, "user=" },
        { Opt_blank_user, "username=" },
@@ -368,7 +370,6 @@ cifs_reconnect(struct TCP_Server_Info *server)
        server->session_key.response = NULL;
        server->session_key.len = 0;
        server->lstrp = jiffies;
-       mutex_unlock(&server->srv_mutex);
 
        /* mark submitted MIDs for retry and issue callback */
        INIT_LIST_HEAD(&retry_list);
@@ -381,6 +382,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                list_move(&mid_entry->qhead, &retry_list);
        }
        spin_unlock(&GlobalMid_Lock);
+       mutex_unlock(&server->srv_mutex);
 
        cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
        list_for_each_safe(tmp, tmp2, &retry_list) {
@@ -418,6 +420,7 @@ cifs_echo_request(struct work_struct *work)
        int rc;
        struct TCP_Server_Info *server = container_of(work,
                                        struct TCP_Server_Info, echo.work);
+       unsigned long echo_interval = server->echo_interval;
 
        /*
         * We cannot send an echo if it is disabled or until the
@@ -427,7 +430,7 @@ cifs_echo_request(struct work_struct *work)
         */
        if (!server->ops->need_neg || server->ops->need_neg(server) ||
            (server->ops->can_echo && !server->ops->can_echo(server)) ||
-           time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
+           time_before(jiffies, server->lstrp + echo_interval - HZ))
                goto requeue_echo;
 
        rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
@@ -436,7 +439,7 @@ cifs_echo_request(struct work_struct *work)
                         server->hostname);
 
 requeue_echo:
-       queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL);
+       queue_delayed_work(cifsiod_wq, &server->echo, echo_interval);
 }
 
 static bool
@@ -487,9 +490,9 @@ server_unresponsive(struct TCP_Server_Info *server)
         *     a response in >60s.
         */
        if (server->tcpStatus == CifsGood &&
-           time_after(jiffies, server->lstrp + 2 * SMB_ECHO_INTERVAL)) {
-               cifs_dbg(VFS, "Server %s has not responded in %d seconds. Reconnecting...\n",
-                        server->hostname, (2 * SMB_ECHO_INTERVAL) / HZ);
+           time_after(jiffies, server->lstrp + 2 * server->echo_interval)) {
+               cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n",
+                        server->hostname, (2 * server->echo_interval) / HZ);
                cifs_reconnect(server);
                wake_up(&server->response_q);
                return true;
@@ -828,7 +831,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
         * 48 bytes is enough to display the header and a little bit
         * into the payload for debugging purposes.
         */
-       length = server->ops->check_message(buf, server->total_read);
+       length = server->ops->check_message(buf, server->total_read, server);
        if (length != 0)
                cifs_dump_mem("Bad SMB: ", buf,
                        min_t(unsigned int, server->total_read, 48));
@@ -1624,6 +1627,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                                goto cifs_parse_mount_err;
                        }
                        break;
+               case Opt_echo_interval:
+                       if (get_option_ul(args, &option)) {
+                               cifs_dbg(VFS, "%s: Invalid echo interval value\n",
+                                        __func__);
+                               goto cifs_parse_mount_err;
+                       }
+                       vol->echo_interval = option;
+                       break;
 
                /* String Arguments */
 
@@ -2089,6 +2100,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
        if (!match_security(server, vol))
                return 0;
 
+       if (server->echo_interval != vol->echo_interval)
+               return 0;
+
        return 1;
 }
 
@@ -2208,6 +2222,12 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        tcp_ses->tcpStatus = CifsNew;
        ++tcp_ses->srv_count;
 
+       if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN &&
+               volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX)
+               tcp_ses->echo_interval = volume_info->echo_interval * HZ;
+       else
+               tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
+
        rc = ip_connect(tcp_ses);
        if (rc < 0) {
                cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
@@ -2237,7 +2257,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        cifs_fscache_get_client_cookie(tcp_ses);
 
        /* queue echo request delayed work */
-       queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL);
+       queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
 
        return tcp_ses;
 
index 0a2752b..ff882ae 100644 (file)
@@ -2267,7 +2267,7 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
        rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (rc)
                return rc;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        xid = get_xid();
 
@@ -2292,7 +2292,7 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
        }
 
        free_xid(xid);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return rc;
 }
 
@@ -2309,7 +2309,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (rc)
                return rc;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        xid = get_xid();
 
@@ -2326,7 +2326,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        }
 
        free_xid(xid);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return rc;
 }
 
@@ -2672,7 +2672,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
         * with a brlock that prevents writing.
         */
        down_read(&cinode->lock_sem);
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        rc = generic_write_checks(iocb, from);
        if (rc <= 0)
@@ -2685,7 +2685,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
        else
                rc = -EACCES;
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (rc > 0) {
                ssize_t err = generic_write_sync(file, iocb->ki_pos - rc, rc);
index a329f5b..aeb26db 100644 (file)
@@ -814,8 +814,21 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
                        }
                } else
                        fattr.cf_uniqueid = iunique(sb, ROOT_I);
-       } else
-               fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
+       } else {
+               if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+                   validinum == false && server->ops->get_srv_inum) {
+                       /*
+                        * Pass a NULL tcon to ensure we don't make a round
+                        * trip to the server. This only works for SMB2+.
+                        */
+                       tmprc = server->ops->get_srv_inum(xid,
+                               NULL, cifs_sb, full_path,
+                               &fattr.cf_uniqueid, data);
+                       if (tmprc)
+                               fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
+               } else
+                       fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
+       }
 
        /* query for SFU type info if supported and needed */
        if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
@@ -856,6 +869,13 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
        } else {
                /* we already have inode, update it */
 
+               /* if uniqueid is different, return error */
+               if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
+                   CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) {
+                       rc = -ESTALE;
+                       goto cgii_exit;
+               }
+
                /* if filetype is different, return error */
                if (unlikely(((*inode)->i_mode & S_IFMT) !=
                    (fattr.cf_mode & S_IFMT))) {
index 8442b8b..813fe13 100644 (file)
@@ -310,7 +310,7 @@ check_smb_hdr(struct smb_hdr *smb)
 }
 
 int
-checkSMB(char *buf, unsigned int total_read)
+checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
 {
        struct smb_hdr *smb = (struct smb_hdr *)buf;
        __u32 rfclen = be32_to_cpu(smb->smb_buf_length);
index 0557c45..b30a4a6 100644 (file)
@@ -847,6 +847,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
                 * if buggy server returns . and .. late do we want to
                 * check for that here?
                 */
+               *tmp_buf = 0;
                rc = cifs_filldir(current_entry, file, ctx,
                                  tmp_buf, max_len);
                if (rc) {
index 1c59070..389fb9f 100644 (file)
@@ -38,7 +38,7 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
         * Make sure that this really is an SMB, that it is a response,
         * and that the message ids match.
         */
-       if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
+       if ((hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
            (mid == wire_mid)) {
                if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
                        return 0;
@@ -50,9 +50,9 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
                                cifs_dbg(VFS, "Received Request not response\n");
                }
        } else { /* bad signature or mid */
-               if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER)
+               if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
                        cifs_dbg(VFS, "Bad protocol string signature header %x\n",
-                                *(unsigned int *) hdr->ProtocolId);
+                                le32_to_cpu(hdr->ProtocolId));
                if (mid != wire_mid)
                        cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
                                 mid, wire_mid);
@@ -93,11 +93,11 @@ static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
 };
 
 int
-smb2_check_message(char *buf, unsigned int length)
+smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
 {
        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
        struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
-       __u64 mid = le64_to_cpu(hdr->MessageId);
+       __u64 mid;
        __u32 len = get_rfc1002_length(buf);
        __u32 clc_len;  /* calculated length */
        int command;
@@ -111,6 +111,30 @@ smb2_check_message(char *buf, unsigned int length)
         * ie Validate the wct via smb2_struct_sizes table above
         */
 
+       if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+               struct smb2_transform_hdr *thdr =
+                       (struct smb2_transform_hdr *)buf;
+               struct cifs_ses *ses = NULL;
+               struct list_head *tmp;
+
+               /* decrypt frame now that it is completely read in */
+               spin_lock(&cifs_tcp_ses_lock);
+               list_for_each(tmp, &srvr->smb_ses_list) {
+                       ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+                       if (ses->Suid == thdr->SessionId)
+                               break;
+
+                       ses = NULL;
+               }
+               spin_unlock(&cifs_tcp_ses_lock);
+               if (ses == NULL) {
+                       cifs_dbg(VFS, "no decryption - session id not found\n");
+                       return 1;
+               }
+       }
+
+
+       mid = le64_to_cpu(hdr->MessageId);
        if (length < sizeof(struct smb2_pdu)) {
                if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
                        pdu->StructureSize2 = 0;
@@ -322,7 +346,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
 
        /* return pointer to beginning of data area, ie offset from SMB start */
        if ((*off != 0) && (*len != 0))
-               return (char *)(&hdr->ProtocolId[0]) + *off;
+               return (char *)(&hdr->ProtocolId) + *off;
        else
                return NULL;
 }
index 53ccdde..3525ed7 100644 (file)
@@ -182,6 +182,11 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
        __u64 wire_mid = le64_to_cpu(hdr->MessageId);
 
+       if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+               cifs_dbg(VFS, "encrypted frame parsing not supported yet");
+               return NULL;
+       }
+
        spin_lock(&GlobalMid_Lock);
        list_for_each_entry(mid, &server->pending_mid_q, qhead) {
                if ((mid->mid == wire_mid) &&
@@ -1692,7 +1697,7 @@ struct smb_version_operations smb30_operations = {
        .get_lease_key = smb2_get_lease_key,
        .set_lease_key = smb2_set_lease_key,
        .new_lease_key = smb2_new_lease_key,
-       .generate_signingkey = generate_smb3signingkey,
+       .generate_signingkey = generate_smb30signingkey,
        .calc_signature = smb3_calc_signature,
        .set_integrity  = smb3_set_integrity,
        .is_read_op = smb21_is_read_op,
@@ -1779,7 +1784,7 @@ struct smb_version_operations smb311_operations = {
        .get_lease_key = smb2_get_lease_key,
        .set_lease_key = smb2_set_lease_key,
        .new_lease_key = smb2_new_lease_key,
-       .generate_signingkey = generate_smb3signingkey,
+       .generate_signingkey = generate_smb311signingkey,
        .calc_signature = smb3_calc_signature,
        .set_integrity  = smb3_set_integrity,
        .is_read_op = smb21_is_read_op,
@@ -1838,7 +1843,7 @@ struct smb_version_values smb21_values = {
 struct smb_version_values smb30_values = {
        .version_string = SMB30_VERSION_STRING,
        .protocol_id = SMB30_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1858,7 +1863,7 @@ struct smb_version_values smb30_values = {
 struct smb_version_values smb302_values = {
        .version_string = SMB302_VERSION_STRING,
        .protocol_id = SMB302_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
index 7675555..10f8d5c 100644 (file)
@@ -97,10 +97,7 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
        hdr->smb2_buf_length = cpu_to_be32(parmsize + sizeof(struct smb2_hdr)
                        - 4 /*  RFC 1001 length field itself not counted */);
 
-       hdr->ProtocolId[0] = 0xFE;
-       hdr->ProtocolId[1] = 'S';
-       hdr->ProtocolId[2] = 'M';
-       hdr->ProtocolId[3] = 'B';
+       hdr->ProtocolId = SMB2_PROTO_NUMBER;
        hdr->StructureSize = cpu_to_le16(64);
        hdr->Command = smb2_cmd;
        hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
@@ -1573,7 +1570,8 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
                goto ioctl_exit;
        }
 
-       memcpy(*out_data, rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset),
+       memcpy(*out_data,
+              (char *)&rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset),
               *plen);
 ioctl_exit:
        free_rsp_buf(resp_buftype, rsp);
@@ -2093,7 +2091,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
        }
 
        if (*buf) {
-               memcpy(*buf, (char *)rsp->hdr.ProtocolId + rsp->DataOffset,
+               memcpy(*buf, (char *)&rsp->hdr.ProtocolId + rsp->DataOffset,
                       *nbytes);
                free_rsp_buf(resp_buftype, iov[0].iov_base);
        } else if (resp_buftype != CIFS_NO_BUFFER) {
index 4af5278..ff88d9f 100644 (file)
@@ -86,6 +86,7 @@
 #define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */
 
 #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
+#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
 
 /*
  * SMB2 Header Definition
@@ -102,7 +103,7 @@ struct smb2_hdr {
        __be32 smb2_buf_length; /* big endian on wire */
                                /* length is only two or three bytes - with
                                 one or two byte type preceding it that MBZ */
-       __u8   ProtocolId[4];   /* 0xFE 'S' 'M' 'B' */
+       __le32 ProtocolId;      /* 0xFE 'S' 'M' 'B' */
        __le16 StructureSize;   /* 64 */
        __le16 CreditCharge;    /* MBZ */
        __le32 Status;          /* Error from server */
@@ -128,11 +129,10 @@ struct smb2_transform_hdr {
                                 one or two byte type preceding it that MBZ */
        __u8   ProtocolId[4];   /* 0xFD 'S' 'M' 'B' */
        __u8   Signature[16];
-       __u8   Nonce[11];
-       __u8   Reserved[5];
+       __u8   Nonce[16];
        __le32 OriginalMessageSize;
        __u16  Reserved1;
-       __le16 EncryptionAlgorithm;
+       __le16 Flags; /* EncryptionAlgorithm */
        __u64  SessionId;
 } __packed;
 
index 79dc650..4f07dc9 100644 (file)
@@ -34,7 +34,8 @@ struct smb_rqst;
  *****************************************************************
  */
 extern int map_smb2_to_linux_error(char *buf, bool log_err);
-extern int smb2_check_message(char *buf, unsigned int length);
+extern int smb2_check_message(char *buf, unsigned int length,
+                             struct TCP_Server_Info *server);
 extern unsigned int smb2_calc_size(void *buf);
 extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr);
 extern __le16 *cifs_convert_path_to_utf16(const char *from,
index d4c5b6f..8732a43 100644 (file)
@@ -222,8 +222,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
        return rc;
 }
 
-int
-generate_smb3signingkey(struct cifs_ses *ses)
+static int generate_key(struct cifs_ses *ses, struct kvec label,
+                       struct kvec context, __u8 *key, unsigned int key_size)
 {
        unsigned char zero = 0x0;
        __u8 i[4] = {0, 0, 0, 1};
@@ -233,7 +233,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
        unsigned char *hashptr = prfhash;
 
        memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
-       memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
+       memset(key, 0x0, key_size);
 
        rc = smb3_crypto_shash_allocate(ses->server);
        if (rc) {
@@ -262,7 +262,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
        }
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
-                               "SMB2AESCMAC", 12);
+                               label.iov_base, label.iov_len);
        if (rc) {
                cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
                goto smb3signkey_ret;
@@ -276,7 +276,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
        }
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
-                               "SmbSign", 8);
+                               context.iov_base, context.iov_len);
        if (rc) {
                cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
                goto smb3signkey_ret;
@@ -296,12 +296,102 @@ generate_smb3signingkey(struct cifs_ses *ses)
                goto smb3signkey_ret;
        }
 
-       memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
+       memcpy(key, hashptr, key_size);
 
 smb3signkey_ret:
        return rc;
 }
 
+struct derivation {
+       struct kvec label;
+       struct kvec context;
+};
+
+struct derivation_triplet {
+       struct derivation signing;
+       struct derivation encryption;
+       struct derivation decryption;
+};
+
+static int
+generate_smb3signingkey(struct cifs_ses *ses,
+                       const struct derivation_triplet *ptriplet)
+{
+       int rc;
+
+       rc = generate_key(ses, ptriplet->signing.label,
+                         ptriplet->signing.context, ses->smb3signingkey,
+                         SMB3_SIGN_KEY_SIZE);
+       if (rc)
+               return rc;
+
+       rc = generate_key(ses, ptriplet->encryption.label,
+                         ptriplet->encryption.context, ses->smb3encryptionkey,
+                         SMB3_SIGN_KEY_SIZE);
+       if (rc)
+               return rc;
+
+       return generate_key(ses, ptriplet->decryption.label,
+                           ptriplet->decryption.context,
+                           ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
+}
+
+int
+generate_smb30signingkey(struct cifs_ses *ses)
+
+{
+       struct derivation_triplet triplet;
+       struct derivation *d;
+
+       d = &triplet.signing;
+       d->label.iov_base = "SMB2AESCMAC";
+       d->label.iov_len = 12;
+       d->context.iov_base = "SmbSign";
+       d->context.iov_len = 8;
+
+       d = &triplet.encryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerIn ";
+       d->context.iov_len = 10;
+
+       d = &triplet.decryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerOut";
+       d->context.iov_len = 10;
+
+       return generate_smb3signingkey(ses, &triplet);
+}
+
+int
+generate_smb311signingkey(struct cifs_ses *ses)
+
+{
+       struct derivation_triplet triplet;
+       struct derivation *d;
+
+       d = &triplet.signing;
+       d->label.iov_base = "SMB2AESCMAC";
+       d->label.iov_len = 12;
+       d->context.iov_base = "SmbSign";
+       d->context.iov_len = 8;
+
+       d = &triplet.encryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerIn ";
+       d->context.iov_len = 10;
+
+       d = &triplet.decryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerOut";
+       d->context.iov_len = 10;
+
+       return generate_smb3signingkey(ses, &triplet);
+}
+
 int
 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 {
index 2a24c52..87abe8e 100644 (file)
@@ -576,14 +576,16 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
        cifs_in_send_dec(server);
        cifs_save_when_sent(mid);
 
-       if (rc < 0)
+       if (rc < 0) {
                server->sequence_number -= 2;
+               cifs_delete_mid(mid);
+       }
+
        mutex_unlock(&server->srv_mutex);
 
        if (rc == 0)
                return 0;
 
-       cifs_delete_mid(mid);
        add_credits_and_wake_if(server, credits, optype);
        return rc;
 }
index f829fe9..5104d84 100644 (file)
@@ -72,8 +72,7 @@ void coda_sysctl_clean(void);
 } while (0)
 
 
-#define CODA_FREE(ptr,size) \
-    do { if (size < PAGE_SIZE) kfree((ptr)); else vfree((ptr)); } while (0)
+#define CODA_FREE(ptr, size) kvfree((ptr))
 
 /* inode to cnode access functions */
 
index fda9f43..42e731b 100644 (file)
@@ -427,13 +427,13 @@ static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
        if (host_file->f_op->iterate) {
                struct inode *host_inode = file_inode(host_file);
 
-               mutex_lock(&host_inode->i_mutex);
+               inode_lock(host_inode);
                ret = -ENOENT;
                if (!IS_DEADDIR(host_inode)) {
                        ret = host_file->f_op->iterate(host_file, ctx);
                        file_accessed(host_file);
                }
-               mutex_unlock(&host_inode->i_mutex);
+               inode_unlock(host_inode);
                return ret;
        }
        /* Venus: we must read Venus dirents from a file */
index 1da3805..f47c748 100644 (file)
@@ -71,12 +71,12 @@ coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
 
        host_file = cfi->cfi_container;
        file_start_write(host_file);
-       mutex_lock(&coda_inode->i_mutex);
+       inode_lock(coda_inode);
        ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos);
        coda_inode->i_size = file_inode(host_file)->i_size;
        coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
        coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
-       mutex_unlock(&coda_inode->i_mutex);
+       inode_unlock(coda_inode);
        file_end_write(host_file);
        return ret;
 }
@@ -203,7 +203,7 @@ int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
        err = filemap_write_and_wait_range(coda_inode->i_mapping, start, end);
        if (err)
                return err;
-       mutex_lock(&coda_inode->i_mutex);
+       inode_lock(coda_inode);
 
        cfi = CODA_FTOC(coda_file);
        BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
@@ -212,7 +212,7 @@ int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
        err = vfs_fsync(host_file, datasync);
        if (!err && !datasync)
                err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));
-       mutex_unlock(&coda_inode->i_mutex);
+       inode_unlock(coda_inode);
 
        return err;
 }
index 7ae97e8..f419519 100644 (file)
@@ -640,13 +640,13 @@ static void detach_groups(struct config_group *group)
 
                child = sd->s_dentry;
 
-               mutex_lock(&d_inode(child)->i_mutex);
+               inode_lock(d_inode(child));
 
                configfs_detach_group(sd->s_element);
                d_inode(child)->i_flags |= S_DEAD;
                dont_mount(child);
 
-               mutex_unlock(&d_inode(child)->i_mutex);
+               inode_unlock(d_inode(child));
 
                d_delete(child);
                dput(child);
@@ -834,11 +834,11 @@ static int configfs_attach_item(struct config_item *parent_item,
                         * the VFS may already have hit and used them. Thus,
                         * we must lock them as rmdir() would.
                         */
-                       mutex_lock(&d_inode(dentry)->i_mutex);
+                       inode_lock(d_inode(dentry));
                        configfs_remove_dir(item);
                        d_inode(dentry)->i_flags |= S_DEAD;
                        dont_mount(dentry);
-                       mutex_unlock(&d_inode(dentry)->i_mutex);
+                       inode_unlock(d_inode(dentry));
                        d_delete(dentry);
                }
        }
@@ -874,7 +874,7 @@ static int configfs_attach_group(struct config_item *parent_item,
                 * We must also lock the inode to remove it safely in case of
                 * error, as rmdir() would.
                 */
-               mutex_lock_nested(&d_inode(dentry)->i_mutex, I_MUTEX_CHILD);
+               inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
                configfs_adjust_dir_dirent_depth_before_populate(sd);
                ret = populate_groups(to_config_group(item));
                if (ret) {
@@ -883,7 +883,7 @@ static int configfs_attach_group(struct config_item *parent_item,
                        dont_mount(dentry);
                }
                configfs_adjust_dir_dirent_depth_after_populate(sd);
-               mutex_unlock(&d_inode(dentry)->i_mutex);
+               inode_unlock(d_inode(dentry));
                if (ret)
                        d_delete(dentry);
        }
@@ -1070,11 +1070,55 @@ out:
        return ret;
 }
 
+static int configfs_do_depend_item(struct dentry *subsys_dentry,
+                                  struct config_item *target)
+{
+       struct configfs_dirent *p;
+       int ret;
+
+       spin_lock(&configfs_dirent_lock);
+       /* Scan the tree, return 0 if found */
+       ret = configfs_depend_prep(subsys_dentry, target);
+       if (ret)
+               goto out_unlock_dirent_lock;
+
+       /*
+        * We are sure that the item is not about to be removed by rmdir(), and
+        * not in the middle of attachment by mkdir().
+        */
+       p = target->ci_dentry->d_fsdata;
+       p->s_dependent_count += 1;
+
+out_unlock_dirent_lock:
+       spin_unlock(&configfs_dirent_lock);
+
+       return ret;
+}
+
+static inline struct configfs_dirent *
+configfs_find_subsys_dentry(struct configfs_dirent *root_sd,
+                           struct config_item *subsys_item)
+{
+       struct configfs_dirent *p;
+       struct configfs_dirent *ret = NULL;
+
+       list_for_each_entry(p, &root_sd->s_children, s_sibling) {
+               if (p->s_type & CONFIGFS_DIR &&
+                   p->s_element == subsys_item) {
+                       ret = p;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+
 int configfs_depend_item(struct configfs_subsystem *subsys,
                         struct config_item *target)
 {
        int ret;
-       struct configfs_dirent *p, *root_sd, *subsys_sd = NULL;
+       struct configfs_dirent *subsys_sd;
        struct config_item *s_item = &subsys->su_group.cg_item;
        struct dentry *root;
 
@@ -1091,43 +1135,19 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
         * subsystem is really registered, and so we need to lock out
         * configfs_[un]register_subsystem().
         */
-       mutex_lock(&d_inode(root)->i_mutex);
-
-       root_sd = root->d_fsdata;
-
-       list_for_each_entry(p, &root_sd->s_children, s_sibling) {
-               if (p->s_type & CONFIGFS_DIR) {
-                       if (p->s_element == s_item) {
-                               subsys_sd = p;
-                               break;
-                       }
-               }
-       }
+       inode_lock(d_inode(root));
 
+       subsys_sd = configfs_find_subsys_dentry(root->d_fsdata, s_item);
        if (!subsys_sd) {
                ret = -ENOENT;
                goto out_unlock_fs;
        }
 
        /* Ok, now we can trust subsys/s_item */
+       ret = configfs_do_depend_item(subsys_sd->s_dentry, target);
 
-       spin_lock(&configfs_dirent_lock);
-       /* Scan the tree, return 0 if found */
-       ret = configfs_depend_prep(subsys_sd->s_dentry, target);
-       if (ret)
-               goto out_unlock_dirent_lock;
-
-       /*
-        * We are sure that the item is not about to be removed by rmdir(), and
-        * not in the middle of attachment by mkdir().
-        */
-       p = target->ci_dentry->d_fsdata;
-       p->s_dependent_count += 1;
-
-out_unlock_dirent_lock:
-       spin_unlock(&configfs_dirent_lock);
 out_unlock_fs:
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
 
        /*
         * If we succeeded, the fs is pinned via other methods.  If not,
@@ -1144,8 +1164,7 @@ EXPORT_SYMBOL(configfs_depend_item);
  * configfs_depend_item() because we know that that the client driver is
  * pinned, thus the subsystem is pinned, and therefore configfs is pinned.
  */
-void configfs_undepend_item(struct configfs_subsystem *subsys,
-                           struct config_item *target)
+void configfs_undepend_item(struct config_item *target)
 {
        struct configfs_dirent *sd;
 
@@ -1168,6 +1187,79 @@ void configfs_undepend_item(struct configfs_subsystem *subsys,
 }
 EXPORT_SYMBOL(configfs_undepend_item);
 
+/*
+ * caller_subsys is a caller's subsystem not target's. This is used to
+ * determine if we should lock root and check subsys or not. When we are
+ * in the same subsystem as our target there is no need to do locking as
+ * we know that subsys is valid and is not unregistered during this function
+ * as we are called from callback of one of his children and VFS holds a lock
+ * on some inode. Otherwise we have to lock our root to  ensure that target's
+ * subsystem it is not unregistered during this function.
+ */
+int configfs_depend_item_unlocked(struct configfs_subsystem *caller_subsys,
+                                 struct config_item *target)
+{
+       struct configfs_subsystem *target_subsys;
+       struct config_group *root, *parent;
+       struct configfs_dirent *subsys_sd;
+       int ret = -ENOENT;
+
+       /* Disallow this function for configfs root */
+       if (configfs_is_root(target))
+               return -EINVAL;
+
+       parent = target->ci_group;
+       /*
+        * This may happen when someone is trying to depend root
+        * directory of some subsystem
+        */
+       if (configfs_is_root(&parent->cg_item)) {
+               target_subsys = to_configfs_subsystem(to_config_group(target));
+               root = parent;
+       } else {
+               target_subsys = parent->cg_subsys;
+               /* Find a cofnigfs root as we may need it for locking */
+               for (root = parent; !configfs_is_root(&root->cg_item);
+                    root = root->cg_item.ci_group)
+                       ;
+       }
+
+       if (target_subsys != caller_subsys) {
+               /*
+                * We are in other configfs subsystem, so we have to do
+                * additional locking to prevent other subsystem from being
+                * unregistered
+                */
+               inode_lock(d_inode(root->cg_item.ci_dentry));
+
+               /*
+                * As we are trying to depend item from other subsystem
+                * we have to check if this subsystem is still registered
+                */
+               subsys_sd = configfs_find_subsys_dentry(
+                               root->cg_item.ci_dentry->d_fsdata,
+                               &target_subsys->su_group.cg_item);
+               if (!subsys_sd)
+                       goto out_root_unlock;
+       } else {
+               subsys_sd = target_subsys->su_group.cg_item.ci_dentry->d_fsdata;
+       }
+
+       /* Now we can execute core of depend item */
+       ret = configfs_do_depend_item(subsys_sd->s_dentry, target);
+
+       if (target_subsys != caller_subsys)
+out_root_unlock:
+               /*
+                * We were called from subsystem other than our target so we
+                * took some locks so now it's time to release them
+                */
+               inode_unlock(d_inode(root->cg_item.ci_dentry));
+
+       return ret;
+}
+EXPORT_SYMBOL(configfs_depend_item_unlocked);
+
 static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
        int ret = 0;
@@ -1469,7 +1561,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name)
        down_write(&configfs_rename_sem);
        parent = item->parent->dentry;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
 
        new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
        if (!IS_ERR(new_dentry)) {
@@ -1485,7 +1577,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name)
                        error = -EEXIST;
                dput(new_dentry);
        }
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        up_write(&configfs_rename_sem);
 
        return error;
@@ -1498,7 +1590,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
        struct configfs_dirent * parent_sd = dentry->d_fsdata;
        int err;
 
-       mutex_lock(&d_inode(dentry)->i_mutex);
+       inode_lock(d_inode(dentry));
        /*
         * Fake invisibility if dir belongs to a group/default groups hierarchy
         * being attached
@@ -1511,7 +1603,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
                else
                        err = 0;
        }
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
 
        return err;
 }
@@ -1521,11 +1613,11 @@ static int configfs_dir_close(struct inode *inode, struct file *file)
        struct dentry * dentry = file->f_path.dentry;
        struct configfs_dirent * cursor = file->private_data;
 
-       mutex_lock(&d_inode(dentry)->i_mutex);
+       inode_lock(d_inode(dentry));
        spin_lock(&configfs_dirent_lock);
        list_del_init(&cursor->s_sibling);
        spin_unlock(&configfs_dirent_lock);
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
 
        release_configfs_dirent(cursor);
 
@@ -1606,7 +1698,7 @@ static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
 {
        struct dentry * dentry = file->f_path.dentry;
 
-       mutex_lock(&d_inode(dentry)->i_mutex);
+       inode_lock(d_inode(dentry));
        switch (whence) {
                case 1:
                        offset += file->f_pos;
@@ -1614,7 +1706,7 @@ static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
                        if (offset >= 0)
                                break;
                default:
-                       mutex_unlock(&d_inode(dentry)->i_mutex);
+                       inode_unlock(d_inode(dentry));
                        return -EINVAL;
        }
        if (offset != file->f_pos) {
@@ -1640,7 +1732,7 @@ static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
                        spin_unlock(&configfs_dirent_lock);
                }
        }
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
        return offset;
 }
 
@@ -1675,14 +1767,14 @@ int configfs_register_group(struct config_group *parent_group,
 
        parent = parent_group->cg_item.ci_dentry;
 
-       mutex_lock_nested(&d_inode(parent)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
        ret = create_default_group(parent_group, group);
        if (!ret) {
                spin_lock(&configfs_dirent_lock);
                configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata);
                spin_unlock(&configfs_dirent_lock);
        }
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        return ret;
 }
 EXPORT_SYMBOL(configfs_register_group);
@@ -1699,7 +1791,7 @@ void configfs_unregister_group(struct config_group *group)
        struct dentry *dentry = group->cg_item.ci_dentry;
        struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
 
-       mutex_lock_nested(&d_inode(parent)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
        spin_lock(&configfs_dirent_lock);
        configfs_detach_prep(dentry, NULL);
        spin_unlock(&configfs_dirent_lock);
@@ -1708,7 +1800,7 @@ void configfs_unregister_group(struct config_group *group)
        d_inode(dentry)->i_flags |= S_DEAD;
        dont_mount(dentry);
        d_delete(dentry);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
 
        dput(dentry);
 
@@ -1780,7 +1872,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
        sd = root->d_fsdata;
        link_group(to_config_group(sd->s_element), group);
 
-       mutex_lock_nested(&d_inode(root)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(root), I_MUTEX_PARENT);
 
        err = -ENOMEM;
        dentry = d_alloc_name(root, group->cg_item.ci_name);
@@ -1800,7 +1892,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
                }
        }
 
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
 
        if (err) {
                unlink_group(group);
@@ -1821,9 +1913,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
                return;
        }
 
-       mutex_lock_nested(&d_inode(root)->i_mutex,
+       inode_lock_nested(d_inode(root),
                          I_MUTEX_PARENT);
-       mutex_lock_nested(&d_inode(dentry)->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
        mutex_lock(&configfs_symlink_mutex);
        spin_lock(&configfs_dirent_lock);
        if (configfs_detach_prep(dentry, NULL)) {
@@ -1834,11 +1926,11 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
        configfs_detach_group(&group->cg_item);
        d_inode(dentry)->i_flags |= S_DEAD;
        dont_mount(dentry);
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
 
        d_delete(dentry);
 
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
 
        dput(dentry);
 
index 3687187..33b7ee3 100644 (file)
@@ -540,10 +540,10 @@ int configfs_create_file(struct config_item * item, const struct configfs_attrib
        umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
        int error = 0;
 
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_NORMAL);
+       inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL);
        error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode,
                                     CONFIGFS_ITEM_ATTR);
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 
        return error;
 }
@@ -562,10 +562,10 @@ int configfs_create_bin_file(struct config_item *item,
        umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG;
        int error = 0;
 
-       mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL);
+       inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL);
        error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode,
                                     CONFIGFS_ITEM_BIN_ATTR);
-       mutex_unlock(&dir->d_inode->i_mutex);
+       inode_unlock(dir->d_inode);
 
        return error;
 }
index 0cc810e..cee087d 100644 (file)
@@ -255,7 +255,7 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
                /* no inode means this hasn't been made visible yet */
                return;
 
-       mutex_lock(&d_inode(dir)->i_mutex);
+       inode_lock(d_inode(dir));
        list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
                if (!sd->s_element)
                        continue;
@@ -268,5 +268,5 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
                        break;
                }
        }
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 }
index b3c153c..9ea87e9 100644 (file)
@@ -118,6 +118,26 @@ int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
        ret = cn_vprintf(cn, fmt, arg);
        va_end(arg);
 
+       if (ret == 0) {
+               /*
+                * Ensure that this coredump name component can't cause the
+                * resulting corefile path to consist of a ".." or ".".
+                */
+               if ((cn->used - cur == 1 && cn->corename[cur] == '.') ||
+                               (cn->used - cur == 2 && cn->corename[cur] == '.'
+                               && cn->corename[cur+1] == '.'))
+                       cn->corename[cur] = '!';
+
+               /*
+                * Empty names are fishy and could be used to create a "//" in a
+                * corefile name, causing the coredump to happen one directory
+                * level too high. Enforce that all components of the core
+                * pattern are at least one character long.
+                */
+               if (cn->used == cur)
+                       ret = cn_printf(cn, "!");
+       }
+
        for (; cur < cn->used; ++cur) {
                if (cn->corename[cur] == '/')
                        cn->corename[cur] = '!';
index 7af8797..4fd6b0c 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -24,6 +24,7 @@
 #include <linux/memcontrol.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/pagevec.h>
 #include <linux/pmem.h>
 #include <linux/sched.h>
 #include <linux/uio.h>
@@ -245,13 +246,14 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode,
        loff_t end = pos + iov_iter_count(iter);
 
        memset(&bh, 0, sizeof(bh));
+       bh.b_bdev = inode->i_sb->s_bdev;
 
        if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ) {
                struct address_space *mapping = inode->i_mapping;
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                retval = filemap_write_and_wait_range(mapping, pos, end - 1);
                if (retval) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        goto out;
                }
        }
@@ -263,7 +265,7 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode,
        retval = dax_io(inode, iter, pos, end, get_block, &bh);
 
        if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ)
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
        if ((retval > 0) && end_io)
                end_io(iocb, pos, retval, bh.b_private);
@@ -324,6 +326,199 @@ static int copy_user_bh(struct page *to, struct inode *inode,
        return 0;
 }
 
+#define NO_SECTOR -1
+#define DAX_PMD_INDEX(page_index) (page_index & (PMD_MASK >> PAGE_CACHE_SHIFT))
+
+static int dax_radix_entry(struct address_space *mapping, pgoff_t index,
+               sector_t sector, bool pmd_entry, bool dirty)
+{
+       struct radix_tree_root *page_tree = &mapping->page_tree;
+       pgoff_t pmd_index = DAX_PMD_INDEX(index);
+       int type, error = 0;
+       void *entry;
+
+       WARN_ON_ONCE(pmd_entry && !dirty);
+       __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+
+       spin_lock_irq(&mapping->tree_lock);
+
+       entry = radix_tree_lookup(page_tree, pmd_index);
+       if (entry && RADIX_DAX_TYPE(entry) == RADIX_DAX_PMD) {
+               index = pmd_index;
+               goto dirty;
+       }
+
+       entry = radix_tree_lookup(page_tree, index);
+       if (entry) {
+               type = RADIX_DAX_TYPE(entry);
+               if (WARN_ON_ONCE(type != RADIX_DAX_PTE &&
+                                       type != RADIX_DAX_PMD)) {
+                       error = -EIO;
+                       goto unlock;
+               }
+
+               if (!pmd_entry || type == RADIX_DAX_PMD)
+                       goto dirty;
+
+               /*
+                * We only insert dirty PMD entries into the radix tree.  This
+                * means we don't need to worry about removing a dirty PTE
+                * entry and inserting a clean PMD entry, thus reducing the
+                * range we would flush with a follow-up fsync/msync call.
+                */
+               radix_tree_delete(&mapping->page_tree, index);
+               mapping->nrexceptional--;
+       }
+
+       if (sector == NO_SECTOR) {
+               /*
+                * This can happen during correct operation if our pfn_mkwrite
+                * fault raced against a hole punch operation.  If this
+                * happens the pte that was hole punched will have been
+                * unmapped and the radix tree entry will have been removed by
+                * the time we are called, but the call will still happen.  We
+                * will return all the way up to wp_pfn_shared(), where the
+                * pte_same() check will fail, eventually causing page fault
+                * to be retried by the CPU.
+                */
+               goto unlock;
+       }
+
+       error = radix_tree_insert(page_tree, index,
+                       RADIX_DAX_ENTRY(sector, pmd_entry));
+       if (error)
+               goto unlock;
+
+       mapping->nrexceptional++;
+ dirty:
+       if (dirty)
+               radix_tree_tag_set(page_tree, index, PAGECACHE_TAG_DIRTY);
+ unlock:
+       spin_unlock_irq(&mapping->tree_lock);
+       return error;
+}
+
+static int dax_writeback_one(struct block_device *bdev,
+               struct address_space *mapping, pgoff_t index, void *entry)
+{
+       struct radix_tree_root *page_tree = &mapping->page_tree;
+       int type = RADIX_DAX_TYPE(entry);
+       struct radix_tree_node *node;
+       struct blk_dax_ctl dax;
+       void **slot;
+       int ret = 0;
+
+       spin_lock_irq(&mapping->tree_lock);
+       /*
+        * Regular page slots are stabilized by the page lock even
+        * without the tree itself locked.  These unlocked entries
+        * need verification under the tree lock.
+        */
+       if (!__radix_tree_lookup(page_tree, index, &node, &slot))
+               goto unlock;
+       if (*slot != entry)
+               goto unlock;
+
+       /* another fsync thread may have already written back this entry */
+       if (!radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE))
+               goto unlock;
+
+       if (WARN_ON_ONCE(type != RADIX_DAX_PTE && type != RADIX_DAX_PMD)) {
+               ret = -EIO;
+               goto unlock;
+       }
+
+       dax.sector = RADIX_DAX_SECTOR(entry);
+       dax.size = (type == RADIX_DAX_PMD ? PMD_SIZE : PAGE_SIZE);
+       spin_unlock_irq(&mapping->tree_lock);
+
+       /*
+        * We cannot hold tree_lock while calling dax_map_atomic() because it
+        * eventually calls cond_resched().
+        */
+       ret = dax_map_atomic(bdev, &dax);
+       if (ret < 0)
+               return ret;
+
+       if (WARN_ON_ONCE(ret < dax.size)) {
+               ret = -EIO;
+               goto unmap;
+       }
+
+       wb_cache_pmem(dax.addr, dax.size);
+
+       spin_lock_irq(&mapping->tree_lock);
+       radix_tree_tag_clear(page_tree, index, PAGECACHE_TAG_TOWRITE);
+       spin_unlock_irq(&mapping->tree_lock);
+ unmap:
+       dax_unmap_atomic(bdev, &dax);
+       return ret;
+
+ unlock:
+       spin_unlock_irq(&mapping->tree_lock);
+       return ret;
+}
+
+/*
+ * Flush the mapping to the persistent domain within the byte range of [start,
+ * end]. This is required by data integrity operations to ensure file data is
+ * on persistent storage prior to completion of the operation.
+ */
+int dax_writeback_mapping_range(struct address_space *mapping, loff_t start,
+               loff_t end)
+{
+       struct inode *inode = mapping->host;
+       struct block_device *bdev = inode->i_sb->s_bdev;
+       pgoff_t start_index, end_index, pmd_index;
+       pgoff_t indices[PAGEVEC_SIZE];
+       struct pagevec pvec;
+       bool done = false;
+       int i, ret = 0;
+       void *entry;
+
+       if (WARN_ON_ONCE(inode->i_blkbits != PAGE_SHIFT))
+               return -EIO;
+
+       start_index = start >> PAGE_CACHE_SHIFT;
+       end_index = end >> PAGE_CACHE_SHIFT;
+       pmd_index = DAX_PMD_INDEX(start_index);
+
+       rcu_read_lock();
+       entry = radix_tree_lookup(&mapping->page_tree, pmd_index);
+       rcu_read_unlock();
+
+       /* see if the start of our range is covered by a PMD entry */
+       if (entry && RADIX_DAX_TYPE(entry) == RADIX_DAX_PMD)
+               start_index = pmd_index;
+
+       tag_pages_for_writeback(mapping, start_index, end_index);
+
+       pagevec_init(&pvec, 0);
+       while (!done) {
+               pvec.nr = find_get_entries_tag(mapping, start_index,
+                               PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE,
+                               pvec.pages, indices);
+
+               if (pvec.nr == 0)
+                       break;
+
+               for (i = 0; i < pvec.nr; i++) {
+                       if (indices[i] > end_index) {
+                               done = true;
+                               break;
+                       }
+
+                       ret = dax_writeback_one(bdev, mapping, indices[i],
+                                       pvec.pages[i]);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+       wmb_pmem();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dax_writeback_mapping_range);
+
 static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
                        struct vm_area_struct *vma, struct vm_fault *vmf)
 {
@@ -363,6 +558,11 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
        }
        dax_unmap_atomic(bdev, &dax);
 
+       error = dax_radix_entry(mapping, vmf->pgoff, dax.sector, false,
+                       vmf->flags & FAULT_FLAG_WRITE);
+       if (error)
+               goto out;
+
        error = vm_insert_mixed(vma, vaddr, dax.pfn);
 
  out:
@@ -408,6 +608,7 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
 
        memset(&bh, 0, sizeof(bh));
        block = (sector_t)vmf->pgoff << (PAGE_SHIFT - blkbits);
+       bh.b_bdev = inode->i_sb->s_bdev;
        bh.b_size = PAGE_SIZE;
 
  repeat:
@@ -487,6 +688,7 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                delete_from_page_cache(page);
                unlock_page(page);
                page_cache_release(page);
+               page = NULL;
        }
 
        /*
@@ -590,7 +792,8 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        struct block_device *bdev;
        pgoff_t size, pgoff;
        sector_t block;
-       int result = 0;
+       int error, result = 0;
+       bool alloc = false;
 
        /* dax pmd mappings require pfn_t_devmap() */
        if (!IS_ENABLED(CONFIG_FS_DAX_PMD))
@@ -624,13 +827,21 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        }
 
        memset(&bh, 0, sizeof(bh));
+       bh.b_bdev = inode->i_sb->s_bdev;
        block = (sector_t)pgoff << (PAGE_SHIFT - blkbits);
 
        bh.b_size = PMD_SIZE;
-       if (get_block(inode, block, &bh, write) != 0)
+
+       if (get_block(inode, block, &bh, 0) != 0)
                return VM_FAULT_SIGBUS;
+
+       if (!buffer_mapped(&bh) && write) {
+               if (get_block(inode, block, &bh, 1) != 0)
+                       return VM_FAULT_SIGBUS;
+               alloc = true;
+       }
+
        bdev = bh.b_bdev;
-       i_mmap_lock_read(mapping);
 
        /*
         * If the filesystem isn't willing to tell us the length of a hole,
@@ -639,19 +850,22 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
         */
        if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE) {
                dax_pmd_dbg(&bh, address, "allocated block too small");
-               goto fallback;
+               return VM_FAULT_FALLBACK;
        }
 
        /*
         * If we allocated new storage, make sure no process has any
         * zero pages covering this hole
         */
-       if (buffer_new(&bh)) {
-               i_mmap_unlock_read(mapping);
-               unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
-               i_mmap_lock_read(mapping);
+       if (alloc) {
+               loff_t lstart = pgoff << PAGE_SHIFT;
+               loff_t lend = lstart + PMD_SIZE - 1; /* inclusive */
+
+               truncate_pagecache_range(inode, lstart, lend);
        }
 
+       i_mmap_lock_read(mapping);
+
        /*
         * If a truncate happened while we were allocating blocks, we may
         * leave blocks allocated to the file that are beyond EOF.  We can't
@@ -664,7 +878,8 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                goto out;
        }
        if ((pgoff | PG_PMD_COLOUR) >= size) {
-               dax_pmd_dbg(&bh, address, "pgoff unaligned");
+               dax_pmd_dbg(&bh, address,
+                               "offset + huge page size > file size");
                goto fallback;
        }
 
@@ -732,6 +947,31 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                }
                dax_unmap_atomic(bdev, &dax);
 
+               /*
+                * For PTE faults we insert a radix tree entry for reads, and
+                * leave it clean.  Then on the first write we dirty the radix
+                * tree entry via the dax_pfn_mkwrite() path.  This sequence
+                * allows the dax_pfn_mkwrite() call to be simpler and avoid a
+                * call into get_block() to translate the pgoff to a sector in
+                * order to be able to create a new radix tree entry.
+                *
+                * The PMD path doesn't have an equivalent to
+                * dax_pfn_mkwrite(), though, so for a read followed by a
+                * write we traverse all the way through __dax_pmd_fault()
+                * twice.  This means we can just skip inserting a radix tree
+                * entry completely on the initial read and just wait until
+                * the write to insert a dirty entry.
+                */
+               if (write) {
+                       error = dax_radix_entry(mapping, pgoff, dax.sector,
+                                       true, true);
+                       if (error) {
+                               dax_pmd_dbg(&bh, address,
+                                               "PMD radix insertion failed");
+                               goto fallback;
+                       }
+               }
+
                dev_dbg(part_to_dev(bdev->bd_part),
                                "%s: %s addr: %lx pfn: %lx sect: %llx\n",
                                __func__, current->comm, address,
@@ -790,15 +1030,20 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault);
  * dax_pfn_mkwrite - handle first write to DAX page
  * @vma: The virtual memory area where the fault occurred
  * @vmf: The description of the fault
- *
  */
 int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
-       struct super_block *sb = file_inode(vma->vm_file)->i_sb;
+       struct file *file = vma->vm_file;
 
-       sb_start_pagefault(sb);
-       file_update_time(vma->vm_file);
-       sb_end_pagefault(sb);
+       /*
+        * We pass NO_SECTOR to dax_radix_entry() because we expect that a
+        * RADIX_DAX_PTE entry already exists in the radix tree from a
+        * previous call to __dax_fault().  We just want to look up that PTE
+        * entry using vmf->pgoff and make sure the dirty tag is set.  This
+        * saves us from having to make a call to get_block() here to look
+        * up the sector.
+        */
+       dax_radix_entry(file->f_mapping, vmf->pgoff, NO_SECTOR, false, true);
        return VM_FAULT_NOPAGE;
 }
 EXPORT_SYMBOL_GPL(dax_pfn_mkwrite);
@@ -835,6 +1080,7 @@ int dax_zero_page_range(struct inode *inode, loff_t from, unsigned length,
        BUG_ON((offset + length) > PAGE_CACHE_SIZE);
 
        memset(&bh, 0, sizeof(bh));
+       bh.b_bdev = inode->i_sb->s_bdev;
        bh.b_size = PAGE_CACHE_SIZE;
        err = get_block(inode, index, &bh, 0);
        if (err < 0)
index b4539e8..92d5140 100644 (file)
@@ -2462,7 +2462,7 @@ EXPORT_SYMBOL(d_rehash);
  */
 void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
 {
-       BUG_ON(!mutex_is_locked(&dentry->d_parent->d_inode->i_mutex));
+       BUG_ON(!inode_is_locked(dentry->d_parent->d_inode));
        BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */
 
        spin_lock(&dentry->d_lock);
@@ -2738,7 +2738,7 @@ static int __d_unalias(struct inode *inode,
        if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
                goto out_err;
        m1 = &dentry->d_sb->s_vfs_rename_mutex;
-       if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
+       if (!inode_trylock(alias->d_parent->d_inode))
                goto out_err;
        m2 = &alias->d_parent->d_inode->i_mutex;
 out_unalias:
index b7fcc0d..bece948 100644 (file)
@@ -265,7 +265,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
        if (!parent)
                parent = debugfs_mount->mnt_root;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(dentry) && d_really_is_positive(dentry)) {
                dput(dentry);
@@ -273,7 +273,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
        }
 
        if (IS_ERR(dentry)) {
-               mutex_unlock(&d_inode(parent)->i_mutex);
+               inode_unlock(d_inode(parent));
                simple_release_fs(&debugfs_mount, &debugfs_mount_count);
        }
 
@@ -282,7 +282,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
 
 static struct dentry *failed_creating(struct dentry *dentry)
 {
-       mutex_unlock(&d_inode(dentry->d_parent)->i_mutex);
+       inode_unlock(d_inode(dentry->d_parent));
        dput(dentry);
        simple_release_fs(&debugfs_mount, &debugfs_mount_count);
        return NULL;
@@ -290,7 +290,7 @@ static struct dentry *failed_creating(struct dentry *dentry)
 
 static struct dentry *end_creating(struct dentry *dentry)
 {
-       mutex_unlock(&d_inode(dentry->d_parent)->i_mutex);
+       inode_unlock(d_inode(dentry->d_parent));
        return dentry;
 }
 
@@ -560,9 +560,9 @@ void debugfs_remove(struct dentry *dentry)
        if (!parent || d_really_is_negative(parent))
                return;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        ret = __debugfs_remove(dentry, parent);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        if (!ret)
                simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
@@ -594,7 +594,7 @@ void debugfs_remove_recursive(struct dentry *dentry)
 
        parent = dentry;
  down:
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
  loop:
        /*
         * The parent->d_subdirs is protected by the d_lock. Outside that
@@ -609,7 +609,7 @@ void debugfs_remove_recursive(struct dentry *dentry)
                /* perhaps simple_empty(child) makes more sense */
                if (!list_empty(&child->d_subdirs)) {
                        spin_unlock(&parent->d_lock);
-                       mutex_unlock(&d_inode(parent)->i_mutex);
+                       inode_unlock(d_inode(parent));
                        parent = child;
                        goto down;
                }
@@ -630,10 +630,10 @@ void debugfs_remove_recursive(struct dentry *dentry)
        }
        spin_unlock(&parent->d_lock);
 
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        child = parent;
        parent = parent->d_parent;
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
 
        if (child != dentry)
                /* go up */
@@ -641,7 +641,7 @@ void debugfs_remove_recursive(struct dentry *dentry)
 
        if (!__debugfs_remove(child, parent))
                simple_release_fs(&debugfs_mount, &debugfs_mount_count);
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
 }
 EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
 
index c35ffdc..1f107fd 100644 (file)
@@ -255,7 +255,7 @@ static int mknod_ptmx(struct super_block *sb)
        if (!uid_valid(root_uid) || !gid_valid(root_gid))
                return -EINVAL;
 
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
 
        /* If we have already created ptmx node, return */
        if (fsi->ptmx_dentry) {
@@ -292,7 +292,7 @@ static int mknod_ptmx(struct super_block *sb)
        fsi->ptmx_dentry = dentry;
        rc = 0;
 out:
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        return rc;
 }
 
@@ -615,7 +615,7 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
 
        sprintf(s, "%d", index);
 
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
 
        dentry = d_alloc_name(root, s);
        if (dentry) {
@@ -626,7 +626,7 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
                inode = ERR_PTR(-ENOMEM);
        }
 
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
 
        return inode;
 }
@@ -671,7 +671,7 @@ void devpts_pty_kill(struct inode *inode)
 
        BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
 
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
 
        dentry = d_find_alias(inode);
 
@@ -680,7 +680,7 @@ void devpts_pty_kill(struct inode *inode)
        dput(dentry);   /* d_alloc_name() in devpts_pty_new() */
        dput(dentry);           /* d_find_alias above */
 
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
 }
 
 static int __init init_devpts_fs(void)
index 602e844..1b2f7ff 100644 (file)
@@ -1157,12 +1157,12 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
                                        iocb->ki_filp->f_mapping;
 
                        /* will be released by direct_io_worker */
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
 
                        retval = filemap_write_and_wait_range(mapping, offset,
                                                              end - 1);
                        if (retval) {
-                               mutex_unlock(&inode->i_mutex);
+                               inode_unlock(inode);
                                kmem_cache_free(dio_cache, dio);
                                goto out;
                        }
@@ -1173,7 +1173,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
        dio->i_size = i_size_read(inode);
        if (iov_iter_rw(iter) == READ && offset >= dio->i_size) {
                if (dio->flags & DIO_LOCKING)
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                kmem_cache_free(dio_cache, dio);
                retval = 0;
                goto out;
@@ -1295,7 +1295,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
         * of protecting us from looking up uninitialized blocks.
         */
        if (iov_iter_rw(iter) == READ && (dio->flags & DIO_LOCKING))
-               mutex_unlock(&dio->inode->i_mutex);
+               inode_unlock(dio->inode);
 
        /*
         * The only time we want to leave bios in flight is when a successful
index 1925d6d..58c2f4a 100644 (file)
@@ -516,7 +516,7 @@ static ssize_t device_write(struct file *file, const char __user *buf,
                return -EINVAL;
 
        kbuf = memdup_user_nul(buf, count);
-       if (!IS_ERR(kbuf))
+       if (IS_ERR(kbuf))
                return PTR_ERR(kbuf);
 
        if (check_version(kbuf)) {
index 040aa87..4e685ac 100644 (file)
@@ -41,13 +41,13 @@ static struct dentry *lock_parent(struct dentry *dentry)
        struct dentry *dir;
 
        dir = dget_parent(dentry);
-       mutex_lock_nested(&(d_inode(dir)->i_mutex), I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
        return dir;
 }
 
 static void unlock_dir(struct dentry *dir)
 {
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        dput(dir);
 }
 
@@ -397,11 +397,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        int rc = 0;
 
        lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent);
-       mutex_lock(&d_inode(lower_dir_dentry)->i_mutex);
+       inode_lock(d_inode(lower_dir_dentry));
        lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name,
                                      lower_dir_dentry,
                                      ecryptfs_dentry->d_name.len);
-       mutex_unlock(&d_inode(lower_dir_dentry)->i_mutex);
+       inode_unlock(d_inode(lower_dir_dentry));
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
                ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
@@ -426,11 +426,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
                       "filename; rc = [%d]\n", __func__, rc);
                goto out;
        }
-       mutex_lock(&d_inode(lower_dir_dentry)->i_mutex);
+       inode_lock(d_inode(lower_dir_dentry));
        lower_dentry = lookup_one_len(encrypted_and_encoded_name,
                                      lower_dir_dentry,
                                      encrypted_and_encoded_name_size);
-       mutex_unlock(&d_inode(lower_dir_dentry)->i_mutex);
+       inode_unlock(d_inode(lower_dir_dentry));
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
                ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
@@ -869,9 +869,9 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
        if (!rc && lower_ia.ia_valid & ATTR_SIZE) {
                struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
 
-               mutex_lock(&d_inode(lower_dentry)->i_mutex);
+               inode_lock(d_inode(lower_dentry));
                rc = notify_change(lower_dentry, &lower_ia, NULL);
-               mutex_unlock(&d_inode(lower_dentry)->i_mutex);
+               inode_unlock(d_inode(lower_dentry));
        }
        return rc;
 }
@@ -970,9 +970,9 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
        if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
                lower_ia.ia_valid &= ~ATTR_MODE;
 
-       mutex_lock(&d_inode(lower_dentry)->i_mutex);
+       inode_lock(d_inode(lower_dentry));
        rc = notify_change(lower_dentry, &lower_ia, NULL);
-       mutex_unlock(&d_inode(lower_dentry)->i_mutex);
+       inode_unlock(d_inode(lower_dentry));
 out:
        fsstack_copy_attr_all(inode, lower_inode);
        return rc;
@@ -1048,10 +1048,10 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
                rc = -EOPNOTSUPP;
                goto out;
        }
-       mutex_lock(&d_inode(lower_dentry)->i_mutex);
+       inode_lock(d_inode(lower_dentry));
        rc = d_inode(lower_dentry)->i_op->getxattr(lower_dentry, name, value,
                                                   size);
-       mutex_unlock(&d_inode(lower_dentry)->i_mutex);
+       inode_unlock(d_inode(lower_dentry));
 out:
        return rc;
 }
@@ -1075,9 +1075,9 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
                rc = -EOPNOTSUPP;
                goto out;
        }
-       mutex_lock(&d_inode(lower_dentry)->i_mutex);
+       inode_lock(d_inode(lower_dentry));
        rc = d_inode(lower_dentry)->i_op->listxattr(lower_dentry, list, size);
-       mutex_unlock(&d_inode(lower_dentry)->i_mutex);
+       inode_unlock(d_inode(lower_dentry));
 out:
        return rc;
 }
@@ -1092,9 +1092,9 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
                rc = -EOPNOTSUPP;
                goto out;
        }
-       mutex_lock(&d_inode(lower_dentry)->i_mutex);
+       inode_lock(d_inode(lower_dentry));
        rc = d_inode(lower_dentry)->i_op->removexattr(lower_dentry, name);
-       mutex_unlock(&d_inode(lower_dentry)->i_mutex);
+       inode_unlock(d_inode(lower_dentry));
 out:
        return rc;
 }
index caba848..c6ced4c 100644 (file)
@@ -436,7 +436,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
                rc = -ENOMEM;
                goto out;
        }
-       mutex_lock(&lower_inode->i_mutex);
+       inode_lock(lower_inode);
        size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
                                           xattr_virt, PAGE_CACHE_SIZE);
        if (size < 0)
@@ -444,7 +444,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
        put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
        rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
                                         xattr_virt, size, 0);
-       mutex_unlock(&lower_inode->i_mutex);
+       inode_unlock(lower_inode);
        if (rc)
                printk(KERN_ERR "Error whilst attempting to write inode size "
                       "to lower file xattr; rc = [%d]\n", rc);
index 90001da..c424e48 100644 (file)
@@ -50,9 +50,9 @@ static ssize_t efivarfs_file_write(struct file *file,
                d_delete(file->f_path.dentry);
                dput(file->f_path.dentry);
        } else {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                i_size_write(inode, datasize + sizeof(attributes));
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
        bytes = count;
index 86a2121..b8a564f 100644 (file)
@@ -160,10 +160,10 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
        efivar_entry_size(entry, &size);
        efivar_entry_add(entry, &efivarfs_list);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        inode->i_private = entry;
        i_size_write(inode, size + sizeof(entry->var.Attributes));
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        d_add(dentry, inode);
 
        return 0;
index 1e009ca..ae1dbcf 100644 (file)
@@ -92,7 +92,7 @@
  */
 
 /* Epoll private bits inside the event mask */
-#define EP_PRIVATE_BITS (EPOLLWAKEUP | EPOLLONESHOT | EPOLLET)
+#define EP_PRIVATE_BITS (EPOLLWAKEUP | EPOLLONESHOT | EPOLLET | EPOLLEXCLUSIVE)
 
 /* Maximum number of nesting allowed inside epoll sets */
 #define EP_MAX_NESTS 4
@@ -1002,6 +1002,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
        unsigned long flags;
        struct epitem *epi = ep_item_from_wait(wait);
        struct eventpoll *ep = epi->ep;
+       int ewake = 0;
 
        if ((unsigned long)key & POLLFREE) {
                ep_pwq_from_wait(wait)->whead = NULL;
@@ -1066,8 +1067,10 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
         * Wake up ( if active ) both the eventpoll wait list and the ->poll()
         * wait list.
         */
-       if (waitqueue_active(&ep->wq))
+       if (waitqueue_active(&ep->wq)) {
+               ewake = 1;
                wake_up_locked(&ep->wq);
+       }
        if (waitqueue_active(&ep->poll_wait))
                pwake++;
 
@@ -1078,6 +1081,9 @@ out_unlock:
        if (pwake)
                ep_poll_safewake(&ep->poll_wait);
 
+       if (epi->event.events & EPOLLEXCLUSIVE)
+               return ewake;
+
        return 1;
 }
 
@@ -1095,7 +1101,10 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
                init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
                pwq->whead = whead;
                pwq->base = epi;
-               add_wait_queue(whead, &pwq->wait);
+               if (epi->event.events & EPOLLEXCLUSIVE)
+                       add_wait_queue_exclusive(whead, &pwq->wait);
+               else
+                       add_wait_queue(whead, &pwq->wait);
                list_add_tail(&pwq->llink, &epi->pwqlist);
                epi->nwait++;
        } else {
@@ -1861,6 +1870,15 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
        if (f.file == tf.file || !is_file_epoll(f.file))
                goto error_tgt_fput;
 
+       /*
+        * epoll adds to the wakeup queue at EPOLL_CTL_ADD time only,
+        * so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation.
+        * Also, we do not currently supported nested exclusive wakeups.
+        */
+       if ((epds.events & EPOLLEXCLUSIVE) && (op == EPOLL_CTL_MOD ||
+               (op == EPOLL_CTL_ADD && is_file_epoll(tf.file))))
+               goto error_tgt_fput;
+
        /*
         * At this point it is safe to assume that the "private_data" contains
         * our own data structure.
index 828ec5f..dcd4ac7 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1307,13 +1307,13 @@ static void bprm_fill_uid(struct linux_binprm *bprm)
                return;
 
        /* Be careful if suid/sgid is set */
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* reload atomically mode/uid/gid now that lock held */
        mode = inode->i_mode;
        uid = inode->i_uid;
        gid = inode->i_gid;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        /* We ignore suid/sgid if there are no mappings for them in the ns */
        if (!kuid_has_mapping(bprm->cred->user_ns, uid) ||
index 906de66..28645f0 100644 (file)
@@ -52,9 +52,9 @@ static int exofs_file_fsync(struct file *filp, loff_t start, loff_t end,
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = sync_inode_metadata(filp->f_mapping->host, 1);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index 714cd37..c46f1a1 100644 (file)
@@ -124,10 +124,10 @@ static struct dentry *reconnect_one(struct vfsmount *mnt,
        int err;
 
        parent = ERR_PTR(-EACCES);
-       mutex_lock(&dentry->d_inode->i_mutex);
+       inode_lock(dentry->d_inode);
        if (mnt->mnt_sb->s_export_op->get_parent)
                parent = mnt->mnt_sb->s_export_op->get_parent(dentry);
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       inode_unlock(dentry->d_inode);
 
        if (IS_ERR(parent)) {
                dprintk("%s: get_parent of %ld failed, err %d\n",
@@ -143,9 +143,9 @@ static struct dentry *reconnect_one(struct vfsmount *mnt,
        if (err)
                goto out_err;
        dprintk("%s: found name: %s\n", __func__, nbuf);
-       mutex_lock(&parent->d_inode->i_mutex);
+       inode_lock(parent->d_inode);
        tmp = lookup_one_len(nbuf, parent, strlen(nbuf));
-       mutex_unlock(&parent->d_inode->i_mutex);
+       inode_unlock(parent->d_inode);
        if (IS_ERR(tmp)) {
                dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp));
                goto out_err;
@@ -503,10 +503,10 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 */
                err = exportfs_get_name(mnt, target_dir, nbuf, result);
                if (!err) {
-                       mutex_lock(&target_dir->d_inode->i_mutex);
+                       inode_lock(target_dir->d_inode);
                        nresult = lookup_one_len(nbuf, target_dir,
                                                 strlen(nbuf));
-                       mutex_unlock(&target_dir->d_inode->i_mutex);
+                       inode_unlock(target_dir->d_inode);
                        if (!IS_ERR(nresult)) {
                                if (nresult->d_inode) {
                                        dput(result);
index 11a42c5..2c88d68 100644 (file)
@@ -102,8 +102,8 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma,
 {
        struct inode *inode = file_inode(vma->vm_file);
        struct ext2_inode_info *ei = EXT2_I(inode);
-       int ret = VM_FAULT_NOPAGE;
        loff_t size;
+       int ret;
 
        sb_start_pagefault(inode->i_sb);
        file_update_time(vma->vm_file);
@@ -113,6 +113,8 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma,
        size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
        if (vmf->pgoff >= size)
                ret = VM_FAULT_SIGBUS;
+       else
+               ret = dax_pfn_mkwrite(vma, vmf);
 
        up_read(&ei->dax_sem);
        sb_end_pagefault(inode->i_sb);
index 5d46c09..b386af2 100644 (file)
@@ -51,10 +51,10 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
                flags = ext2_mask_flags(inode->i_mode, flags);
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                /* Is it quota file? Do not allow user to mess with it */
                if (IS_NOQUOTA(inode)) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        ret = -EPERM;
                        goto setflags_out;
                }
@@ -68,7 +68,7 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                 */
                if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
                        if (!capable(CAP_LINUX_IMMUTABLE)) {
-                               mutex_unlock(&inode->i_mutex);
+                               inode_unlock(inode);
                                ret = -EPERM;
                                goto setflags_out;
                        }
@@ -80,7 +80,7 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
                ext2_set_inode_flags(inode);
                inode->i_ctime = CURRENT_TIME_SEC;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
                mark_inode_dirty(inode);
 setflags_out:
@@ -102,10 +102,10 @@ setflags_out:
                        goto setversion_out;
                }
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                inode->i_ctime = CURRENT_TIME_SEC;
                inode->i_generation = generation;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
                mark_inode_dirty(inode);
 setversion_out:
index 1a08350..c802120 100644 (file)
@@ -384,14 +384,12 @@ int ext4_decrypt(struct page *page)
                                EXT4_DECRYPT, page->index, page, page);
 }
 
-int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
+int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
+                          ext4_fsblk_t pblk, ext4_lblk_t len)
 {
        struct ext4_crypto_ctx  *ctx;
        struct page             *ciphertext_page = NULL;
        struct bio              *bio;
-       ext4_lblk_t             lblk = le32_to_cpu(ex->ee_block);
-       ext4_fsblk_t            pblk = ext4_ext_pblock(ex);
-       unsigned int            len = ext4_ext_get_actual_len(ex);
        int                     ret, err = 0;
 
 #if 0
index c5882b3..9a16d1e 100644 (file)
@@ -213,9 +213,11 @@ retry:
                res = -ENOKEY;
                goto out;
        }
+       down_read(&keyring_key->sem);
        ukp = user_key_payload(keyring_key);
        if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
                res = -EINVAL;
+               up_read(&keyring_key->sem);
                goto out;
        }
        master_key = (struct ext4_encryption_key *)ukp->data;
@@ -226,10 +228,12 @@ retry:
                            "ext4: key size incorrect: %d\n",
                            master_key->size);
                res = -ENOKEY;
+               up_read(&keyring_key->sem);
                goto out;
        }
        res = ext4_derive_key_aes(ctx.nonce, master_key->raw,
                                  raw_key);
+       up_read(&keyring_key->sem);
        if (res)
                goto out;
 got_key:
index cc7ca4e..0662b28 100644 (file)
@@ -378,14 +378,22 @@ struct flex_groups {
 #define EXT4_PROJINHERIT_FL            0x20000000 /* Create with parents projid */
 #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
 
-#define EXT4_FL_USER_VISIBLE           0x004BDFFF /* User visible flags */
-#define EXT4_FL_USER_MODIFIABLE                0x004380FF /* User modifiable flags */
+#define EXT4_FL_USER_VISIBLE           0x304BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE                0x204380FF /* User modifiable flags */
+
+#define EXT4_FL_XFLAG_VISIBLE          (EXT4_SYNC_FL | \
+                                        EXT4_IMMUTABLE_FL | \
+                                        EXT4_APPEND_FL | \
+                                        EXT4_NODUMP_FL | \
+                                        EXT4_NOATIME_FL | \
+                                        EXT4_PROJINHERIT_FL)
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
                           EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
                           EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
-                          EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL)
+                          EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\
+                          EXT4_PROJINHERIT_FL)
 
 /* Flags that are appropriate for regular files (all but dir-specific ones). */
 #define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))
@@ -555,10 +563,12 @@ enum {
 #define EXT4_GET_BLOCKS_NO_NORMALIZE           0x0040
        /* Request will not result in inode size update (user for fallocate) */
 #define EXT4_GET_BLOCKS_KEEP_SIZE              0x0080
-       /* Do not take i_data_sem locking in ext4_map_blocks */
-#define EXT4_GET_BLOCKS_NO_LOCK                        0x0100
        /* Convert written extents to unwritten */
-#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN      0x0200
+#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN      0x0100
+       /* Write zeros to newly created written extents */
+#define EXT4_GET_BLOCKS_ZERO                   0x0200
+#define EXT4_GET_BLOCKS_CREATE_ZERO            (EXT4_GET_BLOCKS_CREATE |\
+                                       EXT4_GET_BLOCKS_ZERO)
 
 /*
  * The bit position of these flags must not overlap with any of the
@@ -616,6 +626,46 @@ enum {
 #define EXT4_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
 #define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy)
 
+#ifndef FS_IOC_FSGETXATTR
+/* Until the uapi changes get merged for project quota... */
+
+#define FS_IOC_FSGETXATTR              _IOR('X', 31, struct fsxattr)
+#define FS_IOC_FSSETXATTR              _IOW('X', 32, struct fsxattr)
+
+/*
+ * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
+ */
+struct fsxattr {
+       __u32           fsx_xflags;     /* xflags field value (get/set) */
+       __u32           fsx_extsize;    /* extsize field value (get/set)*/
+       __u32           fsx_nextents;   /* nextents field value (get)   */
+       __u32           fsx_projid;     /* project identifier (get/set) */
+       unsigned char   fsx_pad[12];
+};
+
+/*
+ * Flags for the fsx_xflags field
+ */
+#define FS_XFLAG_REALTIME      0x00000001      /* data in realtime volume */
+#define FS_XFLAG_PREALLOC      0x00000002      /* preallocated file extents */
+#define FS_XFLAG_IMMUTABLE     0x00000008      /* file cannot be modified */
+#define FS_XFLAG_APPEND                0x00000010      /* all writes append */
+#define FS_XFLAG_SYNC          0x00000020      /* all writes synchronous */
+#define FS_XFLAG_NOATIME       0x00000040      /* do not update access time */
+#define FS_XFLAG_NODUMP                0x00000080      /* do not include in backups */
+#define FS_XFLAG_RTINHERIT     0x00000100      /* create with rt bit set */
+#define FS_XFLAG_PROJINHERIT   0x00000200      /* create with parents projid */
+#define FS_XFLAG_NOSYMLINKS    0x00000400      /* disallow symlink creation */
+#define FS_XFLAG_EXTSIZE       0x00000800      /* extent size allocator hint */
+#define FS_XFLAG_EXTSZINHERIT  0x00001000      /* inherit inode extent size */
+#define FS_XFLAG_NODEFRAG      0x00002000      /* do not defragment */
+#define FS_XFLAG_FILESTREAM    0x00004000      /* use filestream allocator */
+#define FS_XFLAG_HASATTR       0x80000000      /* no DIFLAG for this */
+#endif /* !defined(FS_IOC_FSGETXATTR) */
+
+#define EXT4_IOC_FSGETXATTR            FS_IOC_FSGETXATTR
+#define EXT4_IOC_FSSETXATTR            FS_IOC_FSSETXATTR
+
 #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 /*
  * ioctl commands in 32 bit emulation
@@ -910,6 +960,15 @@ struct ext4_inode_info {
         * by other means, so we have i_data_sem.
         */
        struct rw_semaphore i_data_sem;
+       /*
+        * i_mmap_sem is for serializing page faults with truncate / punch hole
+        * operations. We have to make sure that new page cannot be faulted in
+        * a section of the inode that is being punched. We cannot easily use
+        * i_data_sem for this since we need protection for the whole punch
+        * operation and i_data_sem ranks below transaction start so we have
+        * to occasionally drop it.
+        */
+       struct rw_semaphore i_mmap_sem;
        struct inode vfs_inode;
        struct jbd2_inode *jinode;
 
@@ -993,6 +1052,7 @@ struct ext4_inode_info {
        /* Encryption params */
        struct ext4_crypt_info *i_crypt_info;
 #endif
+       kprojid_t i_projid;
 };
 
 /*
@@ -1248,7 +1308,7 @@ struct ext4_super_block {
 #endif
 
 /* Number of quota types we support */
-#define EXT4_MAXQUOTAS 2
+#define EXT4_MAXQUOTAS 3
 
 /*
  * fourth extended-fs super-block data in memory
@@ -1754,7 +1814,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,              ENCRYPT)
                                         EXT4_FEATURE_RO_COMPAT_HUGE_FILE |\
                                         EXT4_FEATURE_RO_COMPAT_BIGALLOC |\
                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
-                                        EXT4_FEATURE_RO_COMPAT_QUOTA)
+                                        EXT4_FEATURE_RO_COMPAT_QUOTA |\
+                                        EXT4_FEATURE_RO_COMPAT_PROJECT)
 
 #define EXTN_FEATURE_FUNCS(ver) \
 static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \
@@ -1796,6 +1857,11 @@ static inline bool ext4_has_incompat_features(struct super_block *sb)
 #define        EXT4_DEF_RESUID         0
 #define        EXT4_DEF_RESGID         0
 
+/*
+ * Default project ID
+ */
+#define        EXT4_DEF_PROJID         0
+
 #define EXT4_DEF_INODE_READAHEAD_BLKS  32
 
 /*
@@ -2234,7 +2300,8 @@ void ext4_restore_control_page(struct page *data_page);
 struct page *ext4_encrypt(struct inode *inode,
                          struct page *plaintext_page);
 int ext4_decrypt(struct page *page);
-int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex);
+int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
+                          ext4_fsblk_t pblk, ext4_lblk_t len);
 
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
 int ext4_init_crypto(void);
@@ -2440,8 +2507,8 @@ struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int);
 struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int);
 int ext4_get_block_write(struct inode *inode, sector_t iblock,
                         struct buffer_head *bh_result, int create);
-int ext4_get_block_dax(struct inode *inode, sector_t iblock,
-                        struct buffer_head *bh_result, int create);
+int ext4_dax_mmap_get_block(struct inode *inode, sector_t iblock,
+                           struct buffer_head *bh_result, int create);
 int ext4_get_block(struct inode *inode, sector_t iblock,
                                struct buffer_head *bh_result, int create);
 int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
@@ -2484,9 +2551,13 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
 extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
                             loff_t lstart, loff_t lend);
 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
+extern int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 extern qsize_t *ext4_get_reserved_space(struct inode *inode);
+extern int ext4_get_projid(struct inode *inode, kprojid_t *projid);
 extern void ext4_da_update_reserve_space(struct inode *inode,
                                        int used, int quota_claim);
+extern int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk,
+                             ext4_fsblk_t pblk, ext4_lblk_t len);
 
 /* indirect.c */
 extern int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
@@ -2825,7 +2896,7 @@ do {                                                              \
 static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize)
 {
        WARN_ON_ONCE(S_ISREG(inode->i_mode) &&
-                    !mutex_is_locked(&inode->i_mutex));
+                    !inode_is_locked(inode));
        down_write(&EXT4_I(inode)->i_data_sem);
        if (newsize > EXT4_I(inode)->i_disksize)
                EXT4_I(inode)->i_disksize = newsize;
@@ -2848,6 +2919,9 @@ static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize)
        return changed;
 }
 
+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+                                     loff_t len);
+
 struct ext4_group_info {
        unsigned long   bb_state;
        struct rb_root  bb_free_root;
@@ -2986,8 +3060,7 @@ extern int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
                                         struct page *page);
 extern int ext4_try_add_inline_entry(handle_t *handle,
                                     struct ext4_filename *fname,
-                                    struct dentry *dentry,
-                                    struct inode *inode);
+                                    struct inode *dir, struct inode *inode);
 extern int ext4_try_create_inline_dir(handle_t *handle,
                                      struct inode *parent,
                                      struct inode *inode);
index 551353b..0ffabaf 100644 (file)
@@ -3119,19 +3119,11 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
 {
        ext4_fsblk_t ee_pblock;
        unsigned int ee_len;
-       int ret;
 
        ee_len    = ext4_ext_get_actual_len(ex);
        ee_pblock = ext4_ext_pblock(ex);
-
-       if (ext4_encrypted_inode(inode))
-               return ext4_encrypted_zeroout(inode, ex);
-
-       ret = sb_issue_zeroout(inode->i_sb, ee_pblock, ee_len, GFP_NOFS);
-       if (ret > 0)
-               ret = 0;
-
-       return ret;
+       return ext4_issue_zeroout(inode, le32_to_cpu(ex->ee_block), ee_pblock,
+                                 ee_len);
 }
 
 /*
@@ -4052,6 +4044,14 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
        }
        /* IO end_io complete, convert the filled extent to written */
        if (flags & EXT4_GET_BLOCKS_CONVERT) {
+               if (flags & EXT4_GET_BLOCKS_ZERO) {
+                       if (allocated > map->m_len)
+                               allocated = map->m_len;
+                       err = ext4_issue_zeroout(inode, map->m_lblk, newblock,
+                                                allocated);
+                       if (err < 0)
+                               goto out2;
+               }
                ret = ext4_convert_unwritten_extents_endio(handle, inode, map,
                                                           ppath);
                if (ret >= 0) {
@@ -4685,10 +4685,6 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
        if (len <= EXT_UNWRITTEN_MAX_LEN)
                flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
 
-       /* Wait all existing dio workers, newcomers will block on i_mutex */
-       ext4_inode_block_unlocked_dio(inode);
-       inode_dio_wait(inode);
-
        /*
         * credits to insert 1 extent into extent tree
         */
@@ -4752,8 +4748,6 @@ retry:
                goto retry;
        }
 
-       ext4_inode_resume_unlocked_dio(inode);
-
        return ret > 0 ? ret2 : ret;
 }
 
@@ -4770,7 +4764,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
        int partial_begin, partial_end;
        loff_t start, end;
        ext4_lblk_t lblk;
-       struct address_space *mapping = inode->i_mapping;
        unsigned int blkbits = inode->i_blkbits;
 
        trace_ext4_zero_range(inode, offset, len, mode);
@@ -4785,17 +4778,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
                        return ret;
        }
 
-       /*
-        * Write out all dirty pages to avoid race conditions
-        * Then release them.
-        */
-       if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
-               ret = filemap_write_and_wait_range(mapping, offset,
-                                                  offset + len - 1);
-               if (ret)
-                       return ret;
-       }
-
        /*
         * Round up offset. This is not fallocate, we neet to zero out
         * blocks, so convert interior block aligned part of the range to
@@ -4817,7 +4799,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
        else
                max_blocks -= lblk;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * Indirect files do not support unwritten extnets
@@ -4839,6 +4821,10 @@ static long ext4_zero_range(struct file *file, loff_t offset,
        if (mode & FALLOC_FL_KEEP_SIZE)
                flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
 
+       /* Wait all existing dio workers, newcomers will block on i_mutex */
+       ext4_inode_block_unlocked_dio(inode);
+       inode_dio_wait(inode);
+
        /* Preallocate the range including the unaligned edges */
        if (partial_begin || partial_end) {
                ret = ext4_alloc_file_blocks(file,
@@ -4847,7 +4833,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
                                 round_down(offset, 1 << blkbits)) >> blkbits,
                                new_size, flags, mode);
                if (ret)
-                       goto out_mutex;
+                       goto out_dio;
 
        }
 
@@ -4856,16 +4842,23 @@ static long ext4_zero_range(struct file *file, loff_t offset,
                flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
                          EXT4_EX_NOCACHE);
 
-               /* Now release the pages and zero block aligned part of pages*/
+               /*
+                * Prevent page faults from reinstantiating pages we have
+                * released from page cache.
+                */
+               down_write(&EXT4_I(inode)->i_mmap_sem);
+               ret = ext4_update_disksize_before_punch(inode, offset, len);
+               if (ret) {
+                       up_write(&EXT4_I(inode)->i_mmap_sem);
+                       goto out_dio;
+               }
+               /* Now release the pages and zero block aligned part of pages */
                truncate_pagecache_range(inode, start, end - 1);
                inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
 
-               /* Wait all existing dio workers, newcomers will block on i_mutex */
-               ext4_inode_block_unlocked_dio(inode);
-               inode_dio_wait(inode);
-
                ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
                                             flags, mode);
+               up_write(&EXT4_I(inode)->i_mmap_sem);
                if (ret)
                        goto out_dio;
        }
@@ -4909,7 +4902,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
 out_dio:
        ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
@@ -4980,7 +4973,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        if (mode & FALLOC_FL_KEEP_SIZE)
                flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * We only support preallocation for extent-based files only
@@ -4998,8 +4991,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
                        goto out;
        }
 
+       /* Wait all existing dio workers, newcomers will block on i_mutex */
+       ext4_inode_block_unlocked_dio(inode);
+       inode_dio_wait(inode);
+
        ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
                                     flags, mode);
+       ext4_inode_resume_unlocked_dio(inode);
        if (ret)
                goto out;
 
@@ -5008,7 +5006,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
                                                EXT4_I(inode)->i_sync_tid);
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
        return ret;
 }
@@ -5494,21 +5492,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
                        return ret;
        }
 
-       /*
-        * Need to round down offset to be aligned with page size boundary
-        * for page size > block size.
-        */
-       ioffset = round_down(offset, PAGE_SIZE);
-
-       /* Write out all dirty pages */
-       ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
-                                          LLONG_MAX);
-       if (ret)
-               return ret;
-
-       /* Take mutex lock */
-       mutex_lock(&inode->i_mutex);
-
+       inode_lock(inode);
        /*
         * There is no need to overlap collapse range with EOF, in which case
         * it is effectively a truncate operation
@@ -5524,17 +5508,43 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
                goto out_mutex;
        }
 
-       truncate_pagecache(inode, ioffset);
-
        /* Wait for existing dio to complete */
        ext4_inode_block_unlocked_dio(inode);
        inode_dio_wait(inode);
 
+       /*
+        * Prevent page faults from reinstantiating pages we have released from
+        * page cache.
+        */
+       down_write(&EXT4_I(inode)->i_mmap_sem);
+       /*
+        * Need to round down offset to be aligned with page size boundary
+        * for page size > block size.
+        */
+       ioffset = round_down(offset, PAGE_SIZE);
+       /*
+        * Write tail of the last page before removed range since it will get
+        * removed from the page cache below.
+        */
+       ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset);
+       if (ret)
+               goto out_mmap;
+       /*
+        * Write data that will be shifted to preserve them when discarding
+        * page cache below. We are also protected from pages becoming dirty
+        * by i_mmap_sem.
+        */
+       ret = filemap_write_and_wait_range(inode->i_mapping, offset + len,
+                                          LLONG_MAX);
+       if (ret)
+               goto out_mmap;
+       truncate_pagecache(inode, ioffset);
+
        credits = ext4_writepage_trans_blocks(inode);
        handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
        if (IS_ERR(handle)) {
                ret = PTR_ERR(handle);
-               goto out_dio;
+               goto out_mmap;
        }
 
        down_write(&EXT4_I(inode)->i_data_sem);
@@ -5573,10 +5583,11 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
 
 out_stop:
        ext4_journal_stop(handle);
-out_dio:
+out_mmap:
+       up_write(&EXT4_I(inode)->i_mmap_sem);
        ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
@@ -5627,21 +5638,7 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
                        return ret;
        }
 
-       /*
-        * Need to round down to align start offset to page size boundary
-        * for page size > block size.
-        */
-       ioffset = round_down(offset, PAGE_SIZE);
-
-       /* Write out all dirty pages */
-       ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
-                       LLONG_MAX);
-       if (ret)
-               return ret;
-
-       /* Take mutex lock */
-       mutex_lock(&inode->i_mutex);
-
+       inode_lock(inode);
        /* Currently just for extent based files */
        if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
                ret = -EOPNOTSUPP;
@@ -5660,17 +5657,32 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
                goto out_mutex;
        }
 
-       truncate_pagecache(inode, ioffset);
-
        /* Wait for existing dio to complete */
        ext4_inode_block_unlocked_dio(inode);
        inode_dio_wait(inode);
 
+       /*
+        * Prevent page faults from reinstantiating pages we have released from
+        * page cache.
+        */
+       down_write(&EXT4_I(inode)->i_mmap_sem);
+       /*
+        * Need to round down to align start offset to page size boundary
+        * for page size > block size.
+        */
+       ioffset = round_down(offset, PAGE_SIZE);
+       /* Write out all dirty pages */
+       ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
+                       LLONG_MAX);
+       if (ret)
+               goto out_mmap;
+       truncate_pagecache(inode, ioffset);
+
        credits = ext4_writepage_trans_blocks(inode);
        handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
        if (IS_ERR(handle)) {
                ret = PTR_ERR(handle);
-               goto out_dio;
+               goto out_mmap;
        }
 
        /* Expand file to avoid data loss if there is error while shifting */
@@ -5741,10 +5753,11 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
 
 out_stop:
        ext4_journal_stop(handle);
-out_dio:
+out_mmap:
+       up_write(&EXT4_I(inode)->i_mmap_sem);
        ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
@@ -5779,8 +5792,8 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
 
        BUG_ON(!rwsem_is_locked(&EXT4_I(inode1)->i_data_sem));
        BUG_ON(!rwsem_is_locked(&EXT4_I(inode2)->i_data_sem));
-       BUG_ON(!mutex_is_locked(&inode1->i_mutex));
-       BUG_ON(!mutex_is_locked(&inode2->i_mutex));
+       BUG_ON(!inode_is_locked(inode1));
+       BUG_ON(!inode_is_locked(inode2));
 
        *erp = ext4_es_remove_extent(inode1, lblk1, count);
        if (unlikely(*erp))
index 113837e..1126436 100644 (file)
@@ -113,7 +113,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
                ext4_unwritten_wait(inode);
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = generic_write_checks(iocb, from);
        if (ret <= 0)
                goto out;
@@ -169,7 +169,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        }
 
        ret = __generic_file_write_iter(iocb, from);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (ret > 0) {
                ssize_t err;
@@ -186,50 +186,42 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        return ret;
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (aio_mutex)
                mutex_unlock(aio_mutex);
        return ret;
 }
 
 #ifdef CONFIG_FS_DAX
-static void ext4_end_io_unwritten(struct buffer_head *bh, int uptodate)
-{
-       struct inode *inode = bh->b_assoc_map->host;
-       /* XXX: breaks on 32-bit > 16TB. Is that even supported? */
-       loff_t offset = (loff_t)(uintptr_t)bh->b_private << inode->i_blkbits;
-       int err;
-       if (!uptodate)
-               return;
-       WARN_ON(!buffer_unwritten(bh));
-       err = ext4_convert_unwritten_extents(NULL, inode, offset, bh->b_size);
-}
-
 static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        int result;
        handle_t *handle = NULL;
-       struct super_block *sb = file_inode(vma->vm_file)->i_sb;
+       struct inode *inode = file_inode(vma->vm_file);
+       struct super_block *sb = inode->i_sb;
        bool write = vmf->flags & FAULT_FLAG_WRITE;
 
        if (write) {
                sb_start_pagefault(sb);
                file_update_time(vma->vm_file);
+               down_read(&EXT4_I(inode)->i_mmap_sem);
                handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
                                                EXT4_DATA_TRANS_BLOCKS(sb));
-       }
+       } else
+               down_read(&EXT4_I(inode)->i_mmap_sem);
 
        if (IS_ERR(handle))
                result = VM_FAULT_SIGBUS;
        else
-               result = __dax_fault(vma, vmf, ext4_get_block_dax,
-                                               ext4_end_io_unwritten);
+               result = __dax_fault(vma, vmf, ext4_dax_mmap_get_block, NULL);
 
        if (write) {
                if (!IS_ERR(handle))
                        ext4_journal_stop(handle);
+               up_read(&EXT4_I(inode)->i_mmap_sem);
                sb_end_pagefault(sb);
-       }
+       } else
+               up_read(&EXT4_I(inode)->i_mmap_sem);
 
        return result;
 }
@@ -246,44 +238,88 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
        if (write) {
                sb_start_pagefault(sb);
                file_update_time(vma->vm_file);
+               down_read(&EXT4_I(inode)->i_mmap_sem);
                handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
                                ext4_chunk_trans_blocks(inode,
                                                        PMD_SIZE / PAGE_SIZE));
-       }
+       } else
+               down_read(&EXT4_I(inode)->i_mmap_sem);
 
        if (IS_ERR(handle))
                result = VM_FAULT_SIGBUS;
        else
                result = __dax_pmd_fault(vma, addr, pmd, flags,
-                               ext4_get_block_dax, ext4_end_io_unwritten);
+                               ext4_dax_mmap_get_block, NULL);
 
        if (write) {
                if (!IS_ERR(handle))
                        ext4_journal_stop(handle);
+               up_read(&EXT4_I(inode)->i_mmap_sem);
                sb_end_pagefault(sb);
-       }
+       } else
+               up_read(&EXT4_I(inode)->i_mmap_sem);
 
        return result;
 }
 
 static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
-       return dax_mkwrite(vma, vmf, ext4_get_block_dax,
-                               ext4_end_io_unwritten);
+       int err;
+       struct inode *inode = file_inode(vma->vm_file);
+
+       sb_start_pagefault(inode->i_sb);
+       file_update_time(vma->vm_file);
+       down_read(&EXT4_I(inode)->i_mmap_sem);
+       err = __dax_mkwrite(vma, vmf, ext4_dax_mmap_get_block, NULL);
+       up_read(&EXT4_I(inode)->i_mmap_sem);
+       sb_end_pagefault(inode->i_sb);
+
+       return err;
+}
+
+/*
+ * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_mkwrite()
+ * handler we check for races agaist truncate. Note that since we cycle through
+ * i_mmap_sem, we are sure that also any hole punching that began before we
+ * were called is finished by now and so if it included part of the file we
+ * are working on, our pte will get unmapped and the check for pte_same() in
+ * wp_pfn_shared() fails. Thus fault gets retried and things work out as
+ * desired.
+ */
+static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma,
+                               struct vm_fault *vmf)
+{
+       struct inode *inode = file_inode(vma->vm_file);
+       struct super_block *sb = inode->i_sb;
+       loff_t size;
+       int ret;
+
+       sb_start_pagefault(sb);
+       file_update_time(vma->vm_file);
+       down_read(&EXT4_I(inode)->i_mmap_sem);
+       size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       if (vmf->pgoff >= size)
+               ret = VM_FAULT_SIGBUS;
+       else
+               ret = dax_pfn_mkwrite(vma, vmf);
+       up_read(&EXT4_I(inode)->i_mmap_sem);
+       sb_end_pagefault(sb);
+
+       return ret;
 }
 
 static const struct vm_operations_struct ext4_dax_vm_ops = {
        .fault          = ext4_dax_fault,
        .pmd_fault      = ext4_dax_pmd_fault,
        .page_mkwrite   = ext4_dax_mkwrite,
-       .pfn_mkwrite    = dax_pfn_mkwrite,
+       .pfn_mkwrite    = ext4_dax_pfn_mkwrite,
 };
 #else
 #define ext4_dax_vm_ops        ext4_file_vm_ops
 #endif
 
 static const struct vm_operations_struct ext4_file_vm_ops = {
-       .fault          = filemap_fault,
+       .fault          = ext4_filemap_fault,
        .map_pages      = filemap_map_pages,
        .page_mkwrite   = ext4_page_mkwrite,
 };
@@ -527,11 +563,11 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
        int blkbits;
        int ret = 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        isize = i_size_read(inode);
        if (offset >= isize) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                return -ENXIO;
        }
 
@@ -579,7 +615,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
                dataoff = (loff_t)last << blkbits;
        } while (last <= end);
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (dataoff > isize)
                return -ENXIO;
@@ -600,11 +636,11 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
        int blkbits;
        int ret = 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        isize = i_size_read(inode);
        if (offset >= isize) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                return -ENXIO;
        }
 
@@ -655,7 +691,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
                break;
        } while (last <= end);
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (holeoff > isize)
                holeoff = isize;
index 1b8024d..3fcfd50 100644 (file)
@@ -799,6 +799,13 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
                inode->i_gid = dir->i_gid;
        } else
                inode_init_owner(inode, dir, mode);
+
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
+           ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT))
+               ei->i_projid = EXT4_I(dir)->i_projid;
+       else
+               ei->i_projid = make_kprojid(&init_user_ns, EXT4_DEF_PROJID);
+
        err = dquot_initialize(inode);
        if (err)
                goto out;
index d884989..dfe3b9b 100644 (file)
@@ -995,12 +995,11 @@ void ext4_show_inline_dir(struct inode *dir, struct buffer_head *bh,
  */
 static int ext4_add_dirent_to_inline(handle_t *handle,
                                     struct ext4_filename *fname,
-                                    struct dentry *dentry,
+                                    struct inode *dir,
                                     struct inode *inode,
                                     struct ext4_iloc *iloc,
                                     void *inline_start, int inline_size)
 {
-       struct inode    *dir = d_inode(dentry->d_parent);
        int             err;
        struct ext4_dir_entry_2 *de;
 
@@ -1245,12 +1244,11 @@ out:
  * the new created block.
  */
 int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
-                             struct dentry *dentry, struct inode *inode)
+                             struct inode *dir, struct inode *inode)
 {
        int ret, inline_size;
        void *inline_start;
        struct ext4_iloc iloc;
-       struct inode *dir = d_inode(dentry->d_parent);
 
        ret = ext4_get_inode_loc(dir, &iloc);
        if (ret)
@@ -1264,7 +1262,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
                                                 EXT4_INLINE_DOTDOT_SIZE;
        inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
 
-       ret = ext4_add_dirent_to_inline(handle, fname, dentry, inode, &iloc,
+       ret = ext4_add_dirent_to_inline(handle, fname, dir, inode, &iloc,
                                        inline_start, inline_size);
        if (ret != -ENOSPC)
                goto out;
@@ -1285,7 +1283,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
        if (inline_size) {
                inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
 
-               ret = ext4_add_dirent_to_inline(handle, fname, dentry,
+               ret = ext4_add_dirent_to_inline(handle, fname, dir,
                                                inode, &iloc, inline_start,
                                                inline_size);
 
index b3bd912..83bc8bf 100644 (file)
@@ -383,6 +383,21 @@ static int __check_block_validity(struct inode *inode, const char *func,
        return 0;
 }
 
+int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
+                      ext4_lblk_t len)
+{
+       int ret;
+
+       if (ext4_encrypted_inode(inode))
+               return ext4_encrypted_zeroout(inode, lblk, pblk, len);
+
+       ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
+       if (ret > 0)
+               ret = 0;
+
+       return ret;
+}
+
 #define check_block_validity(inode, map)       \
        __check_block_validity((inode), __func__, __LINE__, (map))
 
@@ -403,8 +418,7 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
         * out taking i_data_sem.  So at the time the unwritten extent
         * could be converted.
         */
-       if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
-               down_read(&EXT4_I(inode)->i_data_sem);
+       down_read(&EXT4_I(inode)->i_data_sem);
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
                retval = ext4_ext_map_blocks(handle, inode, map, flags &
                                             EXT4_GET_BLOCKS_KEEP_SIZE);
@@ -412,8 +426,7 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
                retval = ext4_ind_map_blocks(handle, inode, map, flags &
                                             EXT4_GET_BLOCKS_KEEP_SIZE);
        }
-       if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
-               up_read((&EXT4_I(inode)->i_data_sem));
+       up_read((&EXT4_I(inode)->i_data_sem));
 
        /*
         * We don't check m_len because extent will be collpased in status
@@ -509,8 +522,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
         * Try to see if we can get the block without requesting a new
         * file system block.
         */
-       if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
-               down_read(&EXT4_I(inode)->i_data_sem);
+       down_read(&EXT4_I(inode)->i_data_sem);
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
                retval = ext4_ext_map_blocks(handle, inode, map, flags &
                                             EXT4_GET_BLOCKS_KEEP_SIZE);
@@ -541,8 +553,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                if (ret < 0)
                        retval = ret;
        }
-       if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
-               up_read((&EXT4_I(inode)->i_data_sem));
+       up_read((&EXT4_I(inode)->i_data_sem));
 
 found:
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
@@ -625,6 +636,22 @@ found:
                        WARN_ON(1);
                }
 
+               /*
+                * We have to zeroout blocks before inserting them into extent
+                * status tree. Otherwise someone could look them up there and
+                * use them before they are really zeroed.
+                */
+               if (flags & EXT4_GET_BLOCKS_ZERO &&
+                   map->m_flags & EXT4_MAP_MAPPED &&
+                   map->m_flags & EXT4_MAP_NEW) {
+                       ret = ext4_issue_zeroout(inode, map->m_lblk,
+                                                map->m_pblk, map->m_len);
+                       if (ret) {
+                               retval = ret;
+                               goto out_sem;
+                       }
+               }
+
                /*
                 * If the extent has been zeroed out, we don't need to update
                 * extent status tree.
@@ -632,7 +659,7 @@ found:
                if ((flags & EXT4_GET_BLOCKS_PRE_IO) &&
                    ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
                        if (ext4_es_is_written(&es))
-                               goto has_zeroout;
+                               goto out_sem;
                }
                status = map->m_flags & EXT4_MAP_UNWRITTEN ?
                                EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
@@ -643,11 +670,13 @@ found:
                        status |= EXTENT_STATUS_DELAYED;
                ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
                                            map->m_pblk, status);
-               if (ret < 0)
+               if (ret < 0) {
                        retval = ret;
+                       goto out_sem;
+               }
        }
 
-has_zeroout:
+out_sem:
        up_write((&EXT4_I(inode)->i_data_sem));
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
                ret = check_block_validity(inode, map);
@@ -674,7 +703,7 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
        map.m_lblk = iblock;
        map.m_len = bh->b_size >> inode->i_blkbits;
 
-       if (flags && !(flags & EXT4_GET_BLOCKS_NO_LOCK) && !handle) {
+       if (flags && !handle) {
                /* Direct IO write... */
                if (map.m_len > DIO_MAX_BLOCKS)
                        map.m_len = DIO_MAX_BLOCKS;
@@ -694,16 +723,6 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
 
                map_bh(bh, inode->i_sb, map.m_pblk);
                bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
-               if (IS_DAX(inode) && buffer_unwritten(bh)) {
-                       /*
-                        * dgc: I suspect unwritten conversion on ext4+DAX is
-                        * fundamentally broken here when there are concurrent
-                        * read/write in progress on this inode.
-                        */
-                       WARN_ON_ONCE(io_end);
-                       bh->b_assoc_map = inode->i_mapping;
-                       bh->b_private = (void *)(unsigned long)iblock;
-               }
                if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
                        set_buffer_defer_completion(bh);
                bh->b_size = inode->i_sb->s_blocksize * map.m_len;
@@ -879,9 +898,6 @@ int do_journal_get_write_access(handle_t *handle,
        return ret;
 }
 
-static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock,
-                  struct buffer_head *bh_result, int create);
-
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
 static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
                                  get_block_t *get_block)
@@ -3054,25 +3070,96 @@ int ext4_get_block_write(struct inode *inode, sector_t iblock,
                               EXT4_GET_BLOCKS_IO_CREATE_EXT);
 }
 
-static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock,
+static int ext4_get_block_overwrite(struct inode *inode, sector_t iblock,
                   struct buffer_head *bh_result, int create)
 {
-       ext4_debug("ext4_get_block_write_nolock: inode %lu, create flag %d\n",
+       int ret;
+
+       ext4_debug("ext4_get_block_overwrite: inode %lu, create flag %d\n",
                   inode->i_ino, create);
-       return _ext4_get_block(inode, iblock, bh_result,
-                              EXT4_GET_BLOCKS_NO_LOCK);
+       ret = _ext4_get_block(inode, iblock, bh_result, 0);
+       /*
+        * Blocks should have been preallocated! ext4_file_write_iter() checks
+        * that.
+        */
+       WARN_ON_ONCE(!buffer_mapped(bh_result));
+
+       return ret;
 }
 
-int ext4_get_block_dax(struct inode *inode, sector_t iblock,
-                  struct buffer_head *bh_result, int create)
+#ifdef CONFIG_FS_DAX
+int ext4_dax_mmap_get_block(struct inode *inode, sector_t iblock,
+                           struct buffer_head *bh_result, int create)
 {
-       int flags = EXT4_GET_BLOCKS_PRE_IO | EXT4_GET_BLOCKS_UNWRIT_EXT;
-       if (create)
-               flags |= EXT4_GET_BLOCKS_CREATE;
-       ext4_debug("ext4_get_block_dax: inode %lu, create flag %d\n",
+       int ret, err;
+       int credits;
+       struct ext4_map_blocks map;
+       handle_t *handle = NULL;
+       int flags = 0;
+
+       ext4_debug("ext4_dax_mmap_get_block: inode %lu, create flag %d\n",
                   inode->i_ino, create);
-       return _ext4_get_block(inode, iblock, bh_result, flags);
+       map.m_lblk = iblock;
+       map.m_len = bh_result->b_size >> inode->i_blkbits;
+       credits = ext4_chunk_trans_blocks(inode, map.m_len);
+       if (create) {
+               flags |= EXT4_GET_BLOCKS_PRE_IO | EXT4_GET_BLOCKS_CREATE_ZERO;
+               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits);
+               if (IS_ERR(handle)) {
+                       ret = PTR_ERR(handle);
+                       return ret;
+               }
+       }
+
+       ret = ext4_map_blocks(handle, inode, &map, flags);
+       if (create) {
+               err = ext4_journal_stop(handle);
+               if (ret >= 0 && err < 0)
+                       ret = err;
+       }
+       if (ret <= 0)
+               goto out;
+       if (map.m_flags & EXT4_MAP_UNWRITTEN) {
+               int err2;
+
+               /*
+                * We are protected by i_mmap_sem so we know block cannot go
+                * away from under us even though we dropped i_data_sem.
+                * Convert extent to written and write zeros there.
+                *
+                * Note: We may get here even when create == 0.
+                */
+               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits);
+               if (IS_ERR(handle)) {
+                       ret = PTR_ERR(handle);
+                       goto out;
+               }
+
+               err = ext4_map_blocks(handle, inode, &map,
+                     EXT4_GET_BLOCKS_CONVERT | EXT4_GET_BLOCKS_CREATE_ZERO);
+               if (err < 0)
+                       ret = err;
+               err2 = ext4_journal_stop(handle);
+               if (err2 < 0 && ret > 0)
+                       ret = err2;
+       }
+out:
+       WARN_ON_ONCE(ret == 0 && create);
+       if (ret > 0) {
+               map_bh(bh_result, inode->i_sb, map.m_pblk);
+               bh_result->b_state = (bh_result->b_state & ~EXT4_MAP_FLAGS) |
+                                       map.m_flags;
+               /*
+                * At least for now we have to clear BH_New so that DAX code
+                * doesn't attempt to zero blocks again in a racy way.
+                */
+               bh_result->b_state &= ~(1 << BH_New);
+               bh_result->b_size = map.m_len << inode->i_blkbits;
+               ret = 0;
+       }
+       return ret;
 }
+#endif
 
 static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
                            ssize_t size, void *private)
@@ -3143,10 +3230,8 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
        /* If we do a overwrite dio, i_mutex locking can be released */
        overwrite = *((int *)iocb->private);
 
-       if (overwrite) {
-               down_read(&EXT4_I(inode)->i_data_sem);
-               mutex_unlock(&inode->i_mutex);
-       }
+       if (overwrite)
+               inode_unlock(inode);
 
        /*
         * We could direct write to holes and fallocate.
@@ -3189,7 +3274,7 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
        }
 
        if (overwrite) {
-               get_block_func = ext4_get_block_write_nolock;
+               get_block_func = ext4_get_block_overwrite;
        } else {
                get_block_func = ext4_get_block_write;
                dio_flags = DIO_LOCKING;
@@ -3245,10 +3330,8 @@ retake_lock:
        if (iov_iter_rw(iter) == WRITE)
                inode_dio_end(inode);
        /* take i_mutex locking again if we do a ovewrite dio */
-       if (overwrite) {
-               up_read(&EXT4_I(inode)->i_data_sem);
-               mutex_lock(&inode->i_mutex);
-       }
+       if (overwrite)
+               inode_lock(inode);
 
        return ret;
 }
@@ -3558,6 +3641,35 @@ int ext4_can_truncate(struct inode *inode)
        return 0;
 }
 
+/*
+ * We have to make sure i_disksize gets properly updated before we truncate
+ * page cache due to hole punching or zero range. Otherwise i_disksize update
+ * can get lost as it may have been postponed to submission of writeback but
+ * that will never happen after we truncate page cache.
+ */
+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+                                     loff_t len)
+{
+       handle_t *handle;
+       loff_t size = i_size_read(inode);
+
+       WARN_ON(!inode_is_locked(inode));
+       if (offset > size || offset + len < size)
+               return 0;
+
+       if (EXT4_I(inode)->i_disksize >= size)
+               return 0;
+
+       handle = ext4_journal_start(inode, EXT4_HT_MISC, 1);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ext4_update_i_disksize(inode, size);
+       ext4_mark_inode_dirty(handle, inode);
+       ext4_journal_stop(handle);
+
+       return 0;
+}
+
 /*
  * ext4_punch_hole: punches a hole in a file by releaseing the blocks
  * associated with the given offset and length
@@ -3595,7 +3707,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
                        return ret;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* No need to punch hole beyond i_size */
        if (offset >= inode->i_size)
@@ -3623,17 +3735,26 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
 
        }
 
+       /* Wait all existing dio workers, newcomers will block on i_mutex */
+       ext4_inode_block_unlocked_dio(inode);
+       inode_dio_wait(inode);
+
+       /*
+        * Prevent page faults from reinstantiating pages we have released from
+        * page cache.
+        */
+       down_write(&EXT4_I(inode)->i_mmap_sem);
        first_block_offset = round_up(offset, sb->s_blocksize);
        last_block_offset = round_down((offset + length), sb->s_blocksize) - 1;
 
        /* Now release the pages and zero block aligned part of pages*/
-       if (last_block_offset > first_block_offset)
+       if (last_block_offset > first_block_offset) {
+               ret = ext4_update_disksize_before_punch(inode, offset, length);
+               if (ret)
+                       goto out_dio;
                truncate_pagecache_range(inode, first_block_offset,
                                         last_block_offset);
-
-       /* Wait all existing dio workers, newcomers will block on i_mutex */
-       ext4_inode_block_unlocked_dio(inode);
-       inode_dio_wait(inode);
+       }
 
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
                credits = ext4_writepage_trans_blocks(inode);
@@ -3680,19 +3801,15 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
        if (IS_SYNC(inode))
                ext4_handle_sync(handle);
 
-       /* Now release the pages again to reduce race window */
-       if (last_block_offset > first_block_offset)
-               truncate_pagecache_range(inode, first_block_offset,
-                                        last_block_offset);
-
        inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
        ext4_mark_inode_dirty(handle, inode);
 out_stop:
        ext4_journal_stop(handle);
 out_dio:
+       up_write(&EXT4_I(inode)->i_mmap_sem);
        ext4_inode_resume_unlocked_dio(inode);
 out_mutex:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
@@ -3762,7 +3879,7 @@ void ext4_truncate(struct inode *inode)
         * have i_mutex locked because it's not necessary.
         */
        if (!(inode->i_state & (I_NEW|I_FREEING)))
-               WARN_ON(!mutex_is_locked(&inode->i_mutex));
+               WARN_ON(!inode_is_locked(inode));
        trace_ext4_truncate_enter(inode);
 
        if (!ext4_can_truncate(inode))
@@ -4076,6 +4193,14 @@ static inline void ext4_iget_extra_inode(struct inode *inode,
                EXT4_I(inode)->i_inline_off = 0;
 }
 
+int ext4_get_projid(struct inode *inode, kprojid_t *projid)
+{
+       if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT))
+               return -EOPNOTSUPP;
+       *projid = EXT4_I(inode)->i_projid;
+       return 0;
+}
+
 struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 {
        struct ext4_iloc iloc;
@@ -4087,6 +4212,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        int block;
        uid_t i_uid;
        gid_t i_gid;
+       projid_t i_projid;
 
        inode = iget_locked(sb, ino);
        if (!inode)
@@ -4136,12 +4262,20 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        inode->i_mode = le16_to_cpu(raw_inode->i_mode);
        i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
        i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_PROJECT) &&
+           EXT4_INODE_SIZE(sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+           EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))
+               i_projid = (projid_t)le32_to_cpu(raw_inode->i_projid);
+       else
+               i_projid = EXT4_DEF_PROJID;
+
        if (!(test_opt(inode->i_sb, NO_UID32))) {
                i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
                i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
        }
        i_uid_write(inode, i_uid);
        i_gid_write(inode, i_gid);
+       ei->i_projid = make_kprojid(&init_user_ns, i_projid);
        set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
 
        ext4_clear_state_flags(ei);     /* Only relevant on 32-bit archs */
@@ -4440,6 +4574,7 @@ static int ext4_do_update_inode(handle_t *handle,
        int need_datasync = 0, set_large_file = 0;
        uid_t i_uid;
        gid_t i_gid;
+       projid_t i_projid;
 
        spin_lock(&ei->i_raw_lock);
 
@@ -4452,6 +4587,7 @@ static int ext4_do_update_inode(handle_t *handle,
        raw_inode->i_mode = cpu_to_le16(inode->i_mode);
        i_uid = i_uid_read(inode);
        i_gid = i_gid_read(inode);
+       i_projid = from_kprojid(&init_user_ns, ei->i_projid);
        if (!(test_opt(inode->i_sb, NO_UID32))) {
                raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
                raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
@@ -4529,6 +4665,15 @@ static int ext4_do_update_inode(handle_t *handle,
                                cpu_to_le16(ei->i_extra_isize);
                }
        }
+
+       BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
+                       EXT4_FEATURE_RO_COMPAT_PROJECT) &&
+              i_projid != EXT4_DEF_PROJID);
+
+       if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+           EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))
+               raw_inode->i_projid = cpu_to_le32(i_projid);
+
        ext4_inode_csum_set(inode, raw_inode, ei);
        spin_unlock(&ei->i_raw_lock);
        if (inode->i_sb->s_flags & MS_LAZYTIME)
@@ -4824,6 +4969,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        } else
                                ext4_wait_for_tail_page_commit(inode);
                }
+               down_write(&EXT4_I(inode)->i_mmap_sem);
                /*
                 * Truncate pagecache after we've waited for commit
                 * in data=journal mode to make pages freeable.
@@ -4831,6 +4977,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                truncate_pagecache(inode, inode->i_size);
                if (shrink)
                        ext4_truncate(inode);
+               up_write(&EXT4_I(inode)->i_mmap_sem);
        }
 
        if (!rc) {
@@ -5279,6 +5426,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
        sb_start_pagefault(inode->i_sb);
        file_update_time(vma->vm_file);
+
+       down_read(&EXT4_I(inode)->i_mmap_sem);
        /* Delalloc case is easy... */
        if (test_opt(inode->i_sb, DELALLOC) &&
            !ext4_should_journal_data(inode) &&
@@ -5348,6 +5497,19 @@ retry_alloc:
 out_ret:
        ret = block_page_mkwrite_return(ret);
 out:
+       up_read(&EXT4_I(inode)->i_mmap_sem);
        sb_end_pagefault(inode->i_sb);
        return ret;
 }
+
+int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+       struct inode *inode = file_inode(vma->vm_file);
+       int err;
+
+       down_read(&EXT4_I(inode)->i_mmap_sem);
+       err = filemap_fault(vma, vmf);
+       up_read(&EXT4_I(inode)->i_mmap_sem);
+
+       return err;
+}
index 5e872fd..0f6c369 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mount.h>
 #include <linux/file.h>
 #include <linux/random.h>
+#include <linux/quotaops.h>
 #include <asm/uaccess.h>
 #include "ext4_jbd2.h"
 #include "ext4.h"
@@ -202,6 +203,238 @@ static int uuid_is_zero(__u8 u[16])
        return 1;
 }
 
+static int ext4_ioctl_setflags(struct inode *inode,
+                              unsigned int flags)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       handle_t *handle = NULL;
+       int err = EPERM, migrate = 0;
+       struct ext4_iloc iloc;
+       unsigned int oldflags, mask, i;
+       unsigned int jflag;
+
+       /* Is it quota file? Do not allow user to mess with it */
+       if (IS_NOQUOTA(inode))
+               goto flags_out;
+
+       oldflags = ei->i_flags;
+
+       /* The JOURNAL_DATA flag is modifiable only by root */
+       jflag = flags & EXT4_JOURNAL_DATA_FL;
+
+       /*
+        * The IMMUTABLE and APPEND_ONLY flags can only be changed by
+        * the relevant capability.
+        *
+        * This test looks nicer. Thanks to Pauline Middelink
+        */
+       if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
+               if (!capable(CAP_LINUX_IMMUTABLE))
+                       goto flags_out;
+       }
+
+       /*
+        * The JOURNAL_DATA flag can only be changed by
+        * the relevant capability.
+        */
+       if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
+               if (!capable(CAP_SYS_RESOURCE))
+                       goto flags_out;
+       }
+       if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
+               migrate = 1;
+
+       if (flags & EXT4_EOFBLOCKS_FL) {
+               /* we don't support adding EOFBLOCKS flag */
+               if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
+                       err = -EOPNOTSUPP;
+                       goto flags_out;
+               }
+       } else if (oldflags & EXT4_EOFBLOCKS_FL)
+               ext4_truncate(inode);
+
+       handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
+       if (IS_ERR(handle)) {
+               err = PTR_ERR(handle);
+               goto flags_out;
+       }
+       if (IS_SYNC(inode))
+               ext4_handle_sync(handle);
+       err = ext4_reserve_inode_write(handle, inode, &iloc);
+       if (err)
+               goto flags_err;
+
+       for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
+               if (!(mask & EXT4_FL_USER_MODIFIABLE))
+                       continue;
+               if (mask & flags)
+                       ext4_set_inode_flag(inode, i);
+               else
+                       ext4_clear_inode_flag(inode, i);
+       }
+
+       ext4_set_inode_flags(inode);
+       inode->i_ctime = ext4_current_time(inode);
+
+       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+flags_err:
+       ext4_journal_stop(handle);
+       if (err)
+               goto flags_out;
+
+       if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
+               err = ext4_change_inode_journal_flag(inode, jflag);
+       if (err)
+               goto flags_out;
+       if (migrate) {
+               if (flags & EXT4_EXTENTS_FL)
+                       err = ext4_ext_migrate(inode);
+               else
+                       err = ext4_ind_migrate(inode);
+       }
+
+flags_out:
+       return err;
+}
+
+#ifdef CONFIG_QUOTA
+static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
+{
+       struct inode *inode = file_inode(filp);
+       struct super_block *sb = inode->i_sb;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       int err, rc;
+       handle_t *handle;
+       kprojid_t kprojid;
+       struct ext4_iloc iloc;
+       struct ext4_inode *raw_inode;
+
+       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                       EXT4_FEATURE_RO_COMPAT_PROJECT)) {
+               if (projid != EXT4_DEF_PROJID)
+                       return -EOPNOTSUPP;
+               else
+                       return 0;
+       }
+
+       if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE)
+               return -EOPNOTSUPP;
+
+       kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
+
+       if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
+               return 0;
+
+       err = mnt_want_write_file(filp);
+       if (err)
+               return err;
+
+       err = -EPERM;
+       inode_lock(inode);
+       /* Is it quota file? Do not allow user to mess with it */
+       if (IS_NOQUOTA(inode))
+               goto out_unlock;
+
+       err = ext4_get_inode_loc(inode, &iloc);
+       if (err)
+               goto out_unlock;
+
+       raw_inode = ext4_raw_inode(&iloc);
+       if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
+               err = -EOVERFLOW;
+               brelse(iloc.bh);
+               goto out_unlock;
+       }
+       brelse(iloc.bh);
+
+       dquot_initialize(inode);
+
+       handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+               EXT4_QUOTA_INIT_BLOCKS(sb) +
+               EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+       if (IS_ERR(handle)) {
+               err = PTR_ERR(handle);
+               goto out_unlock;
+       }
+
+       err = ext4_reserve_inode_write(handle, inode, &iloc);
+       if (err)
+               goto out_stop;
+
+       if (sb_has_quota_limits_enabled(sb, PRJQUOTA)) {
+               struct dquot *transfer_to[MAXQUOTAS] = { };
+
+               transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
+               if (transfer_to[PRJQUOTA]) {
+                       err = __dquot_transfer(inode, transfer_to);
+                       dqput(transfer_to[PRJQUOTA]);
+                       if (err)
+                               goto out_dirty;
+               }
+       }
+       EXT4_I(inode)->i_projid = kprojid;
+       inode->i_ctime = ext4_current_time(inode);
+out_dirty:
+       rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
+       if (!err)
+               err = rc;
+out_stop:
+       ext4_journal_stop(handle);
+out_unlock:
+       inode_unlock(inode);
+       mnt_drop_write_file(filp);
+       return err;
+}
+#else
+static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
+{
+       if (projid != EXT4_DEF_PROJID)
+               return -EOPNOTSUPP;
+       return 0;
+}
+#endif
+
+/* Transfer internal flags to xflags */
+static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
+{
+       __u32 xflags = 0;
+
+       if (iflags & EXT4_SYNC_FL)
+               xflags |= FS_XFLAG_SYNC;
+       if (iflags & EXT4_IMMUTABLE_FL)
+               xflags |= FS_XFLAG_IMMUTABLE;
+       if (iflags & EXT4_APPEND_FL)
+               xflags |= FS_XFLAG_APPEND;
+       if (iflags & EXT4_NODUMP_FL)
+               xflags |= FS_XFLAG_NODUMP;
+       if (iflags & EXT4_NOATIME_FL)
+               xflags |= FS_XFLAG_NOATIME;
+       if (iflags & EXT4_PROJINHERIT_FL)
+               xflags |= FS_XFLAG_PROJINHERIT;
+       return xflags;
+}
+
+/* Transfer xflags flags to internal */
+static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
+{
+       unsigned long iflags = 0;
+
+       if (xflags & FS_XFLAG_SYNC)
+               iflags |= EXT4_SYNC_FL;
+       if (xflags & FS_XFLAG_IMMUTABLE)
+               iflags |= EXT4_IMMUTABLE_FL;
+       if (xflags & FS_XFLAG_APPEND)
+               iflags |= EXT4_APPEND_FL;
+       if (xflags & FS_XFLAG_NODUMP)
+               iflags |= EXT4_NODUMP_FL;
+       if (xflags & FS_XFLAG_NOATIME)
+               iflags |= EXT4_NOATIME_FL;
+       if (xflags & FS_XFLAG_PROJINHERIT)
+               iflags |= EXT4_PROJINHERIT_FL;
+
+       return iflags;
+}
+
 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
@@ -217,11 +450,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
                return put_user(flags, (int __user *) arg);
        case EXT4_IOC_SETFLAGS: {
-               handle_t *handle = NULL;
-               int err, migrate = 0;
-               struct ext4_iloc iloc;
-               unsigned int oldflags, mask, i;
-               unsigned int jflag;
+               int err;
 
                if (!inode_owner_or_capable(inode))
                        return -EACCES;
@@ -235,90 +464,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
                flags = ext4_mask_flags(inode->i_mode, flags);
 
-               err = -EPERM;
-               mutex_lock(&inode->i_mutex);
-               /* Is it quota file? Do not allow user to mess with it */
-               if (IS_NOQUOTA(inode))
-                       goto flags_out;
-
-               oldflags = ei->i_flags;
-
-               /* The JOURNAL_DATA flag is modifiable only by root */
-               jflag = flags & EXT4_JOURNAL_DATA_FL;
-
-               /*
-                * The IMMUTABLE and APPEND_ONLY flags can only be changed by
-                * the relevant capability.
-                *
-                * This test looks nicer. Thanks to Pauline Middelink
-                */
-               if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
-                       if (!capable(CAP_LINUX_IMMUTABLE))
-                               goto flags_out;
-               }
-
-               /*
-                * The JOURNAL_DATA flag can only be changed by
-                * the relevant capability.
-                */
-               if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
-                       if (!capable(CAP_SYS_RESOURCE))
-                               goto flags_out;
-               }
-               if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
-                       migrate = 1;
-
-               if (flags & EXT4_EOFBLOCKS_FL) {
-                       /* we don't support adding EOFBLOCKS flag */
-                       if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
-                               err = -EOPNOTSUPP;
-                               goto flags_out;
-                       }
-               } else if (oldflags & EXT4_EOFBLOCKS_FL)
-                       ext4_truncate(inode);
-
-               handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
-               if (IS_ERR(handle)) {
-                       err = PTR_ERR(handle);
-                       goto flags_out;
-               }
-               if (IS_SYNC(inode))
-                       ext4_handle_sync(handle);
-               err = ext4_reserve_inode_write(handle, inode, &iloc);
-               if (err)
-                       goto flags_err;
-
-               for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
-                       if (!(mask & EXT4_FL_USER_MODIFIABLE))
-                               continue;
-                       if (mask & flags)
-                               ext4_set_inode_flag(inode, i);
-                       else
-                               ext4_clear_inode_flag(inode, i);
-               }
-
-               ext4_set_inode_flags(inode);
-               inode->i_ctime = ext4_current_time(inode);
-
-               err = ext4_mark_iloc_dirty(handle, inode, &iloc);
-flags_err:
-               ext4_journal_stop(handle);
-               if (err)
-                       goto flags_out;
-
-               if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
-                       err = ext4_change_inode_journal_flag(inode, jflag);
-               if (err)
-                       goto flags_out;
-               if (migrate) {
-                       if (flags & EXT4_EXTENTS_FL)
-                               err = ext4_ext_migrate(inode);
-                       else
-                               err = ext4_ind_migrate(inode);
-               }
-
-flags_out:
-               mutex_unlock(&inode->i_mutex);
+               inode_lock(inode);
+               err = ext4_ioctl_setflags(inode, flags);
+               inode_unlock(inode);
                mnt_drop_write_file(filp);
                return err;
        }
@@ -349,7 +497,7 @@ flags_out:
                        goto setversion_out;
                }
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
                if (IS_ERR(handle)) {
                        err = PTR_ERR(handle);
@@ -364,7 +512,7 @@ flags_out:
                ext4_journal_stop(handle);
 
 unlock_out:
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 setversion_out:
                mnt_drop_write_file(filp);
                return err;
@@ -510,9 +658,9 @@ group_add_out:
                 * ext4_ext_swap_inode_data before we switch the
                 * inode format to prevent read.
                 */
-               mutex_lock(&(inode->i_mutex));
+               inode_lock((inode));
                err = ext4_ext_migrate(inode);
-               mutex_unlock(&(inode->i_mutex));
+               inode_unlock((inode));
                mnt_drop_write_file(filp);
                return err;
        }
@@ -689,6 +837,60 @@ encryption_policy_out:
                return -EOPNOTSUPP;
 #endif
        }
+       case EXT4_IOC_FSGETXATTR:
+       {
+               struct fsxattr fa;
+
+               memset(&fa, 0, sizeof(struct fsxattr));
+               ext4_get_inode_flags(ei);
+               fa.fsx_xflags = ext4_iflags_to_xflags(ei->i_flags & EXT4_FL_USER_VISIBLE);
+
+               if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
+                               EXT4_FEATURE_RO_COMPAT_PROJECT)) {
+                       fa.fsx_projid = (__u32)from_kprojid(&init_user_ns,
+                               EXT4_I(inode)->i_projid);
+               }
+
+               if (copy_to_user((struct fsxattr __user *)arg,
+                                &fa, sizeof(fa)))
+                       return -EFAULT;
+               return 0;
+       }
+       case EXT4_IOC_FSSETXATTR:
+       {
+               struct fsxattr fa;
+               int err;
+
+               if (copy_from_user(&fa, (struct fsxattr __user *)arg,
+                                  sizeof(fa)))
+                       return -EFAULT;
+
+               /* Make sure caller has proper permission */
+               if (!inode_owner_or_capable(inode))
+                       return -EACCES;
+
+               err = mnt_want_write_file(filp);
+               if (err)
+                       return err;
+
+               flags = ext4_xflags_to_iflags(fa.fsx_xflags);
+               flags = ext4_mask_flags(inode->i_mode, flags);
+
+               inode_lock(inode);
+               flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
+                        (flags & EXT4_FL_XFLAG_VISIBLE);
+               err = ext4_ioctl_setflags(inode, flags);
+               inode_unlock(inode);
+               mnt_drop_write_file(filp);
+               if (err)
+                       return err;
+
+               err = ext4_ioctl_setproject(filp, fa.fsx_projid);
+               if (err)
+                       return err;
+
+               return 0;
+       }
        default:
                return -ENOTTY;
        }
index f27e0c2..06574dd 100644 (file)
@@ -273,7 +273,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
                struct ext4_filename *fname,
                struct ext4_dir_entry_2 **res_dir);
 static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
-                            struct dentry *dentry, struct inode *inode);
+                            struct inode *dir, struct inode *inode);
 
 /* checksumming functions */
 void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
@@ -1928,10 +1928,9 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname,
  * directory, and adds the dentry to the indexed directory.
  */
 static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
-                           struct dentry *dentry,
+                           struct inode *dir,
                            struct inode *inode, struct buffer_head *bh)
 {
-       struct inode    *dir = d_inode(dentry->d_parent);
        struct buffer_head *bh2;
        struct dx_root  *root;
        struct dx_frame frames[2], *frame;
@@ -2086,8 +2085,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
                return retval;
 
        if (ext4_has_inline_data(dir)) {
-               retval = ext4_try_add_inline_entry(handle, &fname,
-                                                  dentry, inode);
+               retval = ext4_try_add_inline_entry(handle, &fname, dir, inode);
                if (retval < 0)
                        goto out;
                if (retval == 1) {
@@ -2097,7 +2095,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
        }
 
        if (is_dx(dir)) {
-               retval = ext4_dx_add_entry(handle, &fname, dentry, inode);
+               retval = ext4_dx_add_entry(handle, &fname, dir, inode);
                if (!retval || (retval != ERR_BAD_DX_DIR))
                        goto out;
                ext4_clear_inode_flag(dir, EXT4_INODE_INDEX);
@@ -2119,7 +2117,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
 
                if (blocks == 1 && !dx_fallback &&
                    ext4_has_feature_dir_index(sb)) {
-                       retval = make_indexed_dir(handle, &fname, dentry,
+                       retval = make_indexed_dir(handle, &fname, dir,
                                                  inode, bh);
                        bh = NULL; /* make_indexed_dir releases bh */
                        goto out;
@@ -2154,12 +2152,11 @@ out:
  * Returns 0 for success, or a negative error value
  */
 static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
-                            struct dentry *dentry, struct inode *inode)
+                            struct inode *dir, struct inode *inode)
 {
        struct dx_frame frames[2], *frame;
        struct dx_entry *entries, *at;
        struct buffer_head *bh;
-       struct inode *dir = d_inode(dentry->d_parent);
        struct super_block *sb = dir->i_sb;
        struct ext4_dir_entry_2 *de;
        int err;
@@ -2756,7 +2753,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
                return 0;
 
        WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) &&
-                    !mutex_is_locked(&inode->i_mutex));
+                    !inode_is_locked(inode));
        /*
         * Exit early if inode already is on orphan list. This is a big speedup
         * since we don't have to contend on the global s_orphan_lock.
@@ -2838,7 +2835,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
                return 0;
 
        WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) &&
-                    !mutex_is_locked(&inode->i_mutex));
+                    !inode_is_locked(inode));
        /* Do this quick check before taking global s_orphan_lock. */
        if (list_empty(&ei->i_orphan))
                return 0;
@@ -3212,6 +3209,12 @@ static int ext4_link(struct dentry *old_dentry,
        if (ext4_encrypted_inode(dir) &&
            !ext4_is_child_context_consistent_with_parent(dir, inode))
                return -EPERM;
+
+       if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) &&
+          (!projid_eq(EXT4_I(dir)->i_projid,
+                      EXT4_I(old_dentry->d_inode)->i_projid)))
+               return -EXDEV;
+
        err = dquot_initialize(dir);
        if (err)
                return err;
@@ -3492,6 +3495,11 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
        int credits;
        u8 old_file_type;
 
+       if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT)) &&
+           (!projid_eq(EXT4_I(new_dir)->i_projid,
+                       EXT4_I(old_dentry->d_inode)->i_projid)))
+               return -EXDEV;
+
        retval = dquot_initialize(old.dir);
        if (retval)
                return retval;
@@ -3701,6 +3709,14 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
                                                           new.inode)))
                return -EPERM;
 
+       if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT) &&
+            !projid_eq(EXT4_I(new_dir)->i_projid,
+                       EXT4_I(old_dentry->d_inode)->i_projid)) ||
+           (ext4_test_inode_flag(old_dir, EXT4_INODE_PROJINHERIT) &&
+            !projid_eq(EXT4_I(old_dir)->i_projid,
+                       EXT4_I(new_dentry->d_inode)->i_projid)))
+               return -EXDEV;
+
        retval = dquot_initialize(old.dir);
        if (retval)
                return retval;
index f1b56ff..3ed01ec 100644 (file)
@@ -80,6 +80,36 @@ static void ext4_destroy_lazyinit_thread(void);
 static void ext4_unregister_li_request(struct super_block *sb);
 static void ext4_clear_request_list(void);
 
+/*
+ * Lock ordering
+ *
+ * Note the difference between i_mmap_sem (EXT4_I(inode)->i_mmap_sem) and
+ * i_mmap_rwsem (inode->i_mmap_rwsem)!
+ *
+ * page fault path:
+ * mmap_sem -> sb_start_pagefault -> i_mmap_sem (r) -> transaction start ->
+ *   page lock -> i_data_sem (rw)
+ *
+ * buffered write path:
+ * sb_start_write -> i_mutex -> mmap_sem
+ * sb_start_write -> i_mutex -> transaction start -> page lock ->
+ *   i_data_sem (rw)
+ *
+ * truncate:
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (w) -> i_mmap_sem (w) ->
+ *   i_mmap_rwsem (w) -> page lock
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (w) -> i_mmap_sem (w) ->
+ *   transaction start -> i_data_sem (rw)
+ *
+ * direct IO:
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (r) -> mmap_sem
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (r) ->
+ *   transaction start -> i_data_sem (rw)
+ *
+ * writepages:
+ * transaction start -> page lock(s) -> i_data_sem (rw)
+ */
+
 #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
 static struct file_system_type ext2_fs_type = {
        .owner          = THIS_MODULE,
@@ -958,6 +988,7 @@ static void init_once(void *foo)
        INIT_LIST_HEAD(&ei->i_orphan);
        init_rwsem(&ei->xattr_sem);
        init_rwsem(&ei->i_data_sem);
+       init_rwsem(&ei->i_mmap_sem);
        inode_init_once(&ei->vfs_inode);
 }
 
@@ -1066,8 +1097,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
 }
 
 #ifdef CONFIG_QUOTA
-#define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
-#define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
+static char *quotatypes[] = INITQFNAMES;
+#define QTYPE2NAME(t) (quotatypes[t])
 
 static int ext4_write_dquot(struct dquot *dquot);
 static int ext4_acquire_dquot(struct dquot *dquot);
@@ -1100,6 +1131,7 @@ static const struct dquot_operations ext4_quota_operations = {
        .write_info     = ext4_write_info,
        .alloc_dquot    = dquot_alloc,
        .destroy_dquot  = dquot_destroy,
+       .get_projid     = ext4_get_projid,
 };
 
 static const struct quotactl_ops ext4_qctl_operations = {
@@ -2254,10 +2286,10 @@ static void ext4_orphan_cleanup(struct super_block *sb,
                                        __func__, inode->i_ino, inode->i_size);
                        jbd_debug(2, "truncating inode %lu to %lld bytes\n",
                                  inode->i_ino, inode->i_size);
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
                        truncate_inode_pages(inode->i_mapping, inode->i_size);
                        ext4_truncate(inode);
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        nr_truncates++;
                } else {
                        if (test_opt(sb, DEBUG))
@@ -2526,6 +2558,12 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
                         "without CONFIG_QUOTA");
                return 0;
        }
+       if (ext4_has_feature_project(sb) && !readonly) {
+               ext4_msg(sb, KERN_ERR,
+                        "Filesystem with project quota feature cannot be mounted RDWR "
+                        "without CONFIG_QUOTA");
+               return 0;
+       }
 #endif  /* CONFIG_QUOTA */
        return 1;
 }
@@ -3654,7 +3692,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                sb->s_qcop = &dquot_quotactl_sysfile_ops;
        else
                sb->s_qcop = &ext4_qctl_operations;
-       sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+       sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
 #endif
        memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
 
@@ -4790,6 +4828,48 @@ restore_opts:
        return err;
 }
 
+#ifdef CONFIG_QUOTA
+static int ext4_statfs_project(struct super_block *sb,
+                              kprojid_t projid, struct kstatfs *buf)
+{
+       struct kqid qid;
+       struct dquot *dquot;
+       u64 limit;
+       u64 curblock;
+
+       qid = make_kqid_projid(projid);
+       dquot = dqget(sb, qid);
+       if (IS_ERR(dquot))
+               return PTR_ERR(dquot);
+       spin_lock(&dq_data_lock);
+
+       limit = (dquot->dq_dqb.dqb_bsoftlimit ?
+                dquot->dq_dqb.dqb_bsoftlimit :
+                dquot->dq_dqb.dqb_bhardlimit) >> sb->s_blocksize_bits;
+       if (limit && buf->f_blocks > limit) {
+               curblock = dquot->dq_dqb.dqb_curspace >> sb->s_blocksize_bits;
+               buf->f_blocks = limit;
+               buf->f_bfree = buf->f_bavail =
+                       (buf->f_blocks > curblock) ?
+                        (buf->f_blocks - curblock) : 0;
+       }
+
+       limit = dquot->dq_dqb.dqb_isoftlimit ?
+               dquot->dq_dqb.dqb_isoftlimit :
+               dquot->dq_dqb.dqb_ihardlimit;
+       if (limit && buf->f_files > limit) {
+               buf->f_files = limit;
+               buf->f_ffree =
+                       (buf->f_files > dquot->dq_dqb.dqb_curinodes) ?
+                        (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
+       }
+
+       spin_unlock(&dq_data_lock);
+       dqput(dquot);
+       return 0;
+}
+#endif
+
 static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct super_block *sb = dentry->d_sb;
@@ -4822,6 +4902,11 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL;
        buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL;
 
+#ifdef CONFIG_QUOTA
+       if (ext4_test_inode_flag(dentry->d_inode, EXT4_INODE_PROJINHERIT) &&
+           sb_has_quota_limits_enabled(sb, PRJQUOTA))
+               ext4_statfs_project(sb, EXT4_I(dentry->d_inode)->i_projid, buf);
+#endif
        return 0;
 }
 
@@ -4986,7 +5071,8 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
        struct inode *qf_inode;
        unsigned long qf_inums[EXT4_MAXQUOTAS] = {
                le32_to_cpu(EXT4_SB(sb)->s_es->s_usr_quota_inum),
-               le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
+               le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
+               le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
        };
 
        BUG_ON(!ext4_has_feature_quota(sb));
@@ -5014,7 +5100,8 @@ static int ext4_enable_quotas(struct super_block *sb)
        int type, err = 0;
        unsigned long qf_inums[EXT4_MAXQUOTAS] = {
                le32_to_cpu(EXT4_SB(sb)->s_es->s_usr_quota_inum),
-               le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
+               le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
+               le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
        };
 
        sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
index 011ba66..c70d06a 100644 (file)
  */
 static inline void ext4_truncate_failed_write(struct inode *inode)
 {
+       down_write(&EXT4_I(inode)->i_mmap_sem);
        truncate_inode_pages(inode->i_mapping, inode->i_size);
        ext4_truncate(inode);
+       up_write(&EXT4_I(inode)->i_mmap_sem);
 }
 
 /*
index ac9e7c6..5c06db1 100644 (file)
@@ -794,7 +794,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        return ret;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        isize = i_size_read(inode);
        if (start >= isize)
@@ -860,7 +860,7 @@ out:
        if (ret == 1)
                ret = 0;
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index 18ddb1e..ea272be 100644 (file)
@@ -333,7 +333,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
        loff_t isize;
        int err = 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        isize = i_size_read(inode);
        if (offset >= isize)
@@ -388,10 +388,10 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
 found:
        if (whence == SEEK_HOLE && data_ofs > isize)
                data_ofs = isize;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return vfs_setpos(file, data_ofs, maxbytes);
 fail:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return -ENXIO;
 }
 
@@ -1219,7 +1219,7 @@ static long f2fs_fallocate(struct file *file, int mode,
                        FALLOC_FL_INSERT_RANGE))
                return -EOPNOTSUPP;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (mode & FALLOC_FL_PUNCH_HOLE) {
                if (offset >= inode->i_size)
@@ -1243,7 +1243,7 @@ static long f2fs_fallocate(struct file *file, int mode,
        }
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        trace_f2fs_fallocate(inode, mode, offset, len, ret);
        return ret;
@@ -1307,13 +1307,13 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
 
        flags = f2fs_mask_flags(inode->i_mode, flags);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        oldflags = fi->i_flags;
 
        if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
                if (!capable(CAP_LINUX_IMMUTABLE)) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        ret = -EPERM;
                        goto out;
                }
@@ -1322,7 +1322,7 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
        flags = flags & FS_FL_USER_MODIFIABLE;
        flags |= oldflags & ~FS_FL_USER_MODIFIABLE;
        fi->i_flags = flags;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        f2fs_set_inode_flags(inode);
        inode->i_ctime = CURRENT_TIME;
@@ -1667,7 +1667,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
 
        f2fs_balance_fs(sbi, true);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* writeback all dirty pages in the range */
        err = filemap_write_and_wait_range(inode->i_mapping, range->start,
@@ -1778,7 +1778,7 @@ do_map:
 clear_out:
        clear_inode_flag(F2FS_I(inode), FI_DO_DEFRAG);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (!err)
                range->len = (u64)total << PAGE_CACHE_SHIFT;
        return err;
index 93fc622..5d38492 100644 (file)
@@ -301,15 +301,59 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
        return dclus;
 }
 
-int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
-            unsigned long *mapped_blocks, int create)
+int fat_get_mapped_cluster(struct inode *inode, sector_t sector,
+                          sector_t last_block,
+                          unsigned long *mapped_blocks, sector_t *bmap)
 {
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
+       int cluster, offset;
+
+       cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
+       offset  = sector & (sbi->sec_per_clus - 1);
+       cluster = fat_bmap_cluster(inode, cluster);
+       if (cluster < 0)
+               return cluster;
+       else if (cluster) {
+               *bmap = fat_clus_to_blknr(sbi, cluster) + offset;
+               *mapped_blocks = sbi->sec_per_clus - offset;
+               if (*mapped_blocks > last_block - sector)
+                       *mapped_blocks = last_block - sector;
+       }
+
+       return 0;
+}
+
+static int is_exceed_eof(struct inode *inode, sector_t sector,
+                        sector_t *last_block, int create)
+{
+       struct super_block *sb = inode->i_sb;
        const unsigned long blocksize = sb->s_blocksize;
        const unsigned char blocksize_bits = sb->s_blocksize_bits;
+
+       *last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
+       if (sector >= *last_block) {
+               if (!create)
+                       return 1;
+
+               /*
+                * ->mmu_private can access on only allocation path.
+                * (caller must hold ->i_mutex)
+                */
+               *last_block = (MSDOS_I(inode)->mmu_private + (blocksize - 1))
+                       >> blocksize_bits;
+               if (sector >= *last_block)
+                       return 1;
+       }
+
+       return 0;
+}
+
+int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
+            unsigned long *mapped_blocks, int create, bool from_bmap)
+{
+       struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
        sector_t last_block;
-       int cluster, offset;
 
        *phys = 0;
        *mapped_blocks = 0;
@@ -321,31 +365,16 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
                return 0;
        }
 
-       last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
-       if (sector >= last_block) {
-               if (!create)
+       if (!from_bmap) {
+               if (is_exceed_eof(inode, sector, &last_block, create))
                        return 0;
-
-               /*
-                * ->mmu_private can access on only allocation path.
-                * (caller must hold ->i_mutex)
-                */
-               last_block = (MSDOS_I(inode)->mmu_private + (blocksize - 1))
-                       >> blocksize_bits;
+       } else {
+               last_block = inode->i_blocks >>
+                               (inode->i_sb->s_blocksize_bits - 9);
                if (sector >= last_block)
                        return 0;
        }
 
-       cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
-       offset  = sector & (sbi->sec_per_clus - 1);
-       cluster = fat_bmap_cluster(inode, cluster);
-       if (cluster < 0)
-               return cluster;
-       else if (cluster) {
-               *phys = fat_clus_to_blknr(sbi, cluster) + offset;
-               *mapped_blocks = sbi->sec_per_clus - offset;
-               if (*mapped_blocks > last_block - sector)
-                       *mapped_blocks = last_block - sector;
-       }
-       return 0;
+       return fat_get_mapped_cluster(inode, sector, last_block, mapped_blocks,
+                                     phys);
 }
index 8b2127f..d0b95c9 100644 (file)
@@ -91,7 +91,7 @@ next:
 
        *bh = NULL;
        iblock = *pos >> sb->s_blocksize_bits;
-       err = fat_bmap(dir, iblock, &phys, &mapped_blocks, 0);
+       err = fat_bmap(dir, iblock, &phys, &mapped_blocks, 0, false);
        if (err || !phys)
                return -1;      /* beyond EOF or error */
 
@@ -769,7 +769,7 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *file,
 
        buf.dirent = dirent;
        buf.result = 0;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        buf.ctx.pos = file->f_pos;
        ret = -ENOENT;
        if (!IS_DEADDIR(inode)) {
@@ -777,7 +777,7 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *file,
                                    short_only, both ? &buf : NULL);
                file->f_pos = buf.ctx.pos;
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (ret >= 0)
                ret = buf.result;
        return ret;
index be5e153..e6b764a 100644 (file)
@@ -87,7 +87,7 @@ struct msdos_sb_info {
        unsigned int vol_id;            /*volume ID*/
 
        int fatent_shift;
-       struct fatent_operations *fatent_ops;
+       const struct fatent_operations *fatent_ops;
        struct inode *fat_inode;
        struct inode *fsinfo_inode;
 
@@ -285,8 +285,11 @@ static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len)
 extern void fat_cache_inval_inode(struct inode *inode);
 extern int fat_get_cluster(struct inode *inode, int cluster,
                           int *fclus, int *dclus);
+extern int fat_get_mapped_cluster(struct inode *inode, sector_t sector,
+                                 sector_t last_block,
+                                 unsigned long *mapped_blocks, sector_t *bmap);
 extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
-                   unsigned long *mapped_blocks, int create);
+                   unsigned long *mapped_blocks, int create, bool from_bmap);
 
 /* fat/dir.c */
 extern const struct file_operations fat_dir_operations;
@@ -384,6 +387,7 @@ static inline unsigned long fat_dir_hash(int logstart)
 {
        return hash_32(logstart, FAT_HASH_BITS);
 }
+extern int fat_add_cluster(struct inode *inode);
 
 /* fat/misc.c */
 extern __printf(3, 4) __cold
index 8226557..1d9a8c4 100644 (file)
@@ -99,7 +99,7 @@ err:
 static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent,
                         int offset, sector_t blocknr)
 {
-       struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
+       const struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
 
        WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
        fatent->fat_inode = MSDOS_SB(sb)->fat_inode;
@@ -246,7 +246,7 @@ static int fat32_ent_next(struct fat_entry *fatent)
        return 0;
 }
 
-static struct fatent_operations fat12_ops = {
+static const struct fatent_operations fat12_ops = {
        .ent_blocknr    = fat12_ent_blocknr,
        .ent_set_ptr    = fat12_ent_set_ptr,
        .ent_bread      = fat12_ent_bread,
@@ -255,7 +255,7 @@ static struct fatent_operations fat12_ops = {
        .ent_next       = fat12_ent_next,
 };
 
-static struct fatent_operations fat16_ops = {
+static const struct fatent_operations fat16_ops = {
        .ent_blocknr    = fat_ent_blocknr,
        .ent_set_ptr    = fat16_ent_set_ptr,
        .ent_bread      = fat_ent_bread,
@@ -264,7 +264,7 @@ static struct fatent_operations fat16_ops = {
        .ent_next       = fat16_ent_next,
 };
 
-static struct fatent_operations fat32_ops = {
+static const struct fatent_operations fat32_ops = {
        .ent_blocknr    = fat_ent_blocknr,
        .ent_set_ptr    = fat32_ent_set_ptr,
        .ent_bread      = fat_ent_bread,
@@ -320,7 +320,7 @@ static inline int fat_ent_update_ptr(struct super_block *sb,
                                     int offset, sector_t blocknr)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
-       struct fatent_operations *ops = sbi->fatent_ops;
+       const struct fatent_operations *ops = sbi->fatent_ops;
        struct buffer_head **bhs = fatent->bhs;
 
        /* Is this fatent's blocks including this entry? */
@@ -349,7 +349,7 @@ int fat_ent_read(struct inode *inode, struct fat_entry *fatent, int entry)
 {
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
-       struct fatent_operations *ops = sbi->fatent_ops;
+       const struct fatent_operations *ops = sbi->fatent_ops;
        int err, offset;
        sector_t blocknr;
 
@@ -407,7 +407,7 @@ int fat_ent_write(struct inode *inode, struct fat_entry *fatent,
                  int new, int wait)
 {
        struct super_block *sb = inode->i_sb;
-       struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
+       const struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
        int err;
 
        ops->ent_put(fatent, new);
@@ -432,7 +432,7 @@ static inline int fat_ent_next(struct msdos_sb_info *sbi,
 static inline int fat_ent_read_block(struct super_block *sb,
                                     struct fat_entry *fatent)
 {
-       struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
+       const struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
        sector_t blocknr;
        int offset;
 
@@ -463,7 +463,7 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
 {
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
-       struct fatent_operations *ops = sbi->fatent_ops;
+       const struct fatent_operations *ops = sbi->fatent_ops;
        struct fat_entry fatent, prev_ent;
        struct buffer_head *bhs[MAX_BUF_PER_PAGE];
        int i, count, err, nr_bhs, idx_clus;
@@ -551,7 +551,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
 {
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
-       struct fatent_operations *ops = sbi->fatent_ops;
+       const struct fatent_operations *ops = sbi->fatent_ops;
        struct fat_entry fatent;
        struct buffer_head *bhs[MAX_BUF_PER_PAGE];
        int i, err, nr_bhs;
@@ -636,7 +636,7 @@ EXPORT_SYMBOL_GPL(fat_free_clusters);
 static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent,
                          unsigned long reada_blocks)
 {
-       struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
+       const struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
        sector_t blocknr;
        int i, offset;
 
@@ -649,7 +649,7 @@ static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent,
 int fat_count_free_clusters(struct super_block *sb)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
-       struct fatent_operations *ops = sbi->fatent_ops;
+       const struct fatent_operations *ops = sbi->fatent_ops;
        struct fat_entry fatent;
        unsigned long reada_blocks, reada_mask, cur_block;
        int err = 0, free;
index a08f103..f701856 100644 (file)
 #include <linux/backing-dev.h>
 #include <linux/fsnotify.h>
 #include <linux/security.h>
+#include <linux/falloc.h>
 #include "fat.h"
 
+static long fat_fallocate(struct file *file, int mode,
+                         loff_t offset, loff_t len);
+
 static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr)
 {
        u32 attr;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        attr = fat_make_attrs(inode);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return put_user(attr, user_attr);
 }
@@ -43,7 +47,7 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
        err = mnt_want_write_file(file);
        if (err)
                goto out;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * ATTR_VOLUME and ATTR_DIR cannot be changed; this also
@@ -105,7 +109,7 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
        fat_save_attrs(inode, attr);
        mark_inode_dirty(inode);
 out_unlock_inode:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        mnt_drop_write_file(file);
 out:
        return err;
@@ -177,6 +181,7 @@ const struct file_operations fat_file_operations = {
 #endif
        .fsync          = fat_file_fsync,
        .splice_read    = generic_file_splice_read,
+       .fallocate      = fat_fallocate,
 };
 
 static int fat_cont_expand(struct inode *inode, loff_t size)
@@ -215,6 +220,62 @@ out:
        return err;
 }
 
+/*
+ * Preallocate space for a file. This implements fat's fallocate file
+ * operation, which gets called from sys_fallocate system call. User
+ * space requests len bytes at offset. If FALLOC_FL_KEEP_SIZE is set
+ * we just allocate clusters without zeroing them out. Otherwise we
+ * allocate and zero out clusters via an expanding truncate.
+ */
+static long fat_fallocate(struct file *file, int mode,
+                         loff_t offset, loff_t len)
+{
+       int nr_cluster; /* Number of clusters to be allocated */
+       loff_t mm_bytes; /* Number of bytes to be allocated for file */
+       loff_t ondisksize; /* block aligned on-disk size in bytes*/
+       struct inode *inode = file->f_mapping->host;
+       struct super_block *sb = inode->i_sb;
+       struct msdos_sb_info *sbi = MSDOS_SB(sb);
+       int err = 0;
+
+       /* No support for hole punch or other fallocate flags. */
+       if (mode & ~FALLOC_FL_KEEP_SIZE)
+               return -EOPNOTSUPP;
+
+       /* No support for dir */
+       if (!S_ISREG(inode->i_mode))
+               return -EOPNOTSUPP;
+
+       inode_lock(inode);
+       if (mode & FALLOC_FL_KEEP_SIZE) {
+               ondisksize = inode->i_blocks << 9;
+               if ((offset + len) <= ondisksize)
+                       goto error;
+
+               /* First compute the number of clusters to be allocated */
+               mm_bytes = offset + len - ondisksize;
+               nr_cluster = (mm_bytes + (sbi->cluster_size - 1)) >>
+                       sbi->cluster_bits;
+
+               /* Start the allocation.We are not zeroing out the clusters */
+               while (nr_cluster-- > 0) {
+                       err = fat_add_cluster(inode);
+                       if (err)
+                               goto error;
+               }
+       } else {
+               if ((offset + len) <= i_size_read(inode))
+                       goto error;
+
+               /* This is just an expanding truncate */
+               err = fat_cont_expand(inode, (offset + len));
+       }
+
+error:
+       inode_unlock(inode);
+       return err;
+}
+
 /* Free all clusters after the skip'th cluster. */
 static int fat_free(struct inode *inode, int skip)
 {
index 6aece96..a559905 100644 (file)
@@ -93,7 +93,7 @@ static struct fat_floppy_defaults {
 },
 };
 
-static int fat_add_cluster(struct inode *inode)
+int fat_add_cluster(struct inode *inode)
 {
        int err, cluster;
 
@@ -115,10 +115,10 @@ static inline int __fat_get_block(struct inode *inode, sector_t iblock,
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        unsigned long mapped_blocks;
-       sector_t phys;
+       sector_t phys, last_block;
        int err, offset;
 
-       err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create);
+       err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create, false);
        if (err)
                return err;
        if (phys) {
@@ -135,8 +135,14 @@ static inline int __fat_get_block(struct inode *inode, sector_t iblock,
                return -EIO;
        }
 
+       last_block = inode->i_blocks >> (sb->s_blocksize_bits - 9);
        offset = (unsigned long)iblock & (sbi->sec_per_clus - 1);
-       if (!offset) {
+       /*
+        * allocate a cluster according to the following.
+        * 1) no more available blocks
+        * 2) not part of fallocate region
+        */
+       if (!offset && !(iblock < last_block)) {
                /* TODO: multiple cluster allocation would be desirable. */
                err = fat_add_cluster(inode);
                if (err)
@@ -148,7 +154,7 @@ static inline int __fat_get_block(struct inode *inode, sector_t iblock,
        *max_blocks = min(mapped_blocks, *max_blocks);
        MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits;
 
-       err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create);
+       err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create, false);
        if (err)
                return err;
 
@@ -273,13 +279,38 @@ static ssize_t fat_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
        return ret;
 }
 
+static int fat_get_block_bmap(struct inode *inode, sector_t iblock,
+               struct buffer_head *bh_result, int create)
+{
+       struct super_block *sb = inode->i_sb;
+       unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
+       int err;
+       sector_t bmap;
+       unsigned long mapped_blocks;
+
+       BUG_ON(create != 0);
+
+       err = fat_bmap(inode, iblock, &bmap, &mapped_blocks, create, true);
+       if (err)
+               return err;
+
+       if (bmap) {
+               map_bh(bh_result, sb, bmap);
+               max_blocks = min(mapped_blocks, max_blocks);
+       }
+
+       bh_result->b_size = max_blocks << sb->s_blocksize_bits;
+
+       return 0;
+}
+
 static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
 {
        sector_t blocknr;
 
        /* fat_get_cluster() assumes the requested blocknr isn't truncated. */
        down_read(&MSDOS_I(mapping->host)->truncate_lock);
-       blocknr = generic_block_bmap(mapping, block, fat_get_block);
+       blocknr = generic_block_bmap(mapping, block, fat_get_block_bmap);
        up_read(&MSDOS_I(mapping->host)->truncate_lock);
 
        return blocknr;
@@ -449,6 +480,24 @@ static int fat_calc_dir_size(struct inode *inode)
        return 0;
 }
 
+static int fat_validate_dir(struct inode *dir)
+{
+       struct super_block *sb = dir->i_sb;
+
+       if (dir->i_nlink < 2) {
+               /* Directory should have "."/".." entries at least. */
+               fat_fs_error(sb, "corrupted directory (invalid entries)");
+               return -EIO;
+       }
+       if (MSDOS_I(dir)->i_start == 0 ||
+           MSDOS_I(dir)->i_start == MSDOS_SB(sb)->root_cluster) {
+               /* Directory should point valid cluster. */
+               fat_fs_error(sb, "corrupted directory (invalid i_start)");
+               return -EIO;
+       }
+       return 0;
+}
+
 /* doesn't deal with root inode */
 int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
 {
@@ -475,6 +524,10 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
                MSDOS_I(inode)->mmu_private = inode->i_size;
 
                set_nlink(inode, fat_subdirs(inode));
+
+               error = fat_validate_dir(inode);
+               if (error < 0)
+                       return error;
        } else { /* not a directory */
                inode->i_generation |= 1;
                inode->i_mode = fat_make_mode(sbi, de->attr,
@@ -553,13 +606,43 @@ out:
 
 EXPORT_SYMBOL_GPL(fat_build_inode);
 
+static int __fat_write_inode(struct inode *inode, int wait);
+
+static void fat_free_eofblocks(struct inode *inode)
+{
+       /* Release unwritten fallocated blocks on inode eviction. */
+       if ((inode->i_blocks << 9) >
+                       round_up(MSDOS_I(inode)->mmu_private,
+                               MSDOS_SB(inode->i_sb)->cluster_size)) {
+               int err;
+
+               fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private);
+               /* Fallocate results in updating the i_start/iogstart
+                * for the zero byte file. So, make it return to
+                * original state during evict and commit it to avoid
+                * any corruption on the next access to the cluster
+                * chain for the file.
+                */
+               err = __fat_write_inode(inode, inode_needs_sync(inode));
+               if (err) {
+                       fat_msg(inode->i_sb, KERN_WARNING, "Failed to "
+                                       "update on disk inode for unused "
+                                       "fallocated blocks, inode could be "
+                                       "corrupted. Please run fsck");
+               }
+
+       }
+}
+
 static void fat_evict_inode(struct inode *inode)
 {
        truncate_inode_pages_final(&inode->i_data);
        if (!inode->i_nlink) {
                inode->i_size = 0;
                fat_truncate_blocks(inode, 0);
-       }
+       } else
+               fat_free_eofblocks(inode);
+
        invalidate_inode_buffers(inode);
        clear_inode(inode);
        fat_cache_inval_inode(inode);
@@ -1146,7 +1229,12 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
                case Opt_time_offset:
                        if (match_int(&args[0], &option))
                                return -EINVAL;
-                       if (option < -12 * 60 || option > 12 * 60)
+                       /*
+                        * GMT+-12 zones may have DST corrections so at least
+                        * 13 hours difference is needed. Make the limit 24
+                        * just in case someone invents something unusual.
+                        */
+                       if (option < -24 * 60 || option > 24 * 60)
                                return -EINVAL;
                        opts->tz_set = 1;
                        opts->time_offset = option;
index 5797d45..c5618db 100644 (file)
@@ -46,9 +46,9 @@ void put_filesystem(struct file_system_type *fs)
 static struct file_system_type **find_filesystem(const char *name, unsigned len)
 {
        struct file_system_type **p;
-       for (p=&file_systems; *p; p=&(*p)->next)
-               if (strlen((*p)->name) == len &&
-                   strncmp((*p)->name, name, len) == 0)
+       for (p = &file_systems; *p; p = &(*p)->next)
+               if (strncmp((*p)->name, name, len) == 0 &&
+                   !(*p)->name[len])
                        break;
        return p;
 }
index 712601f..4b855b6 100644 (file)
@@ -944,7 +944,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
        if (!parent)
                return -ENOENT;
 
-       mutex_lock(&parent->i_mutex);
+       inode_lock(parent);
        if (!S_ISDIR(parent->i_mode))
                goto unlock;
 
@@ -962,7 +962,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
        fuse_invalidate_entry(entry);
 
        if (child_nodeid != 0 && d_really_is_positive(entry)) {
-               mutex_lock(&d_inode(entry)->i_mutex);
+               inode_lock(d_inode(entry));
                if (get_node_id(d_inode(entry)) != child_nodeid) {
                        err = -ENOENT;
                        goto badentry;
@@ -983,7 +983,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
                clear_nlink(d_inode(entry));
                err = 0;
  badentry:
-               mutex_unlock(&d_inode(entry)->i_mutex);
+               inode_unlock(d_inode(entry));
                if (!err)
                        d_delete(entry);
        } else {
@@ -992,7 +992,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
        dput(entry);
 
  unlock:
-       mutex_unlock(&parent->i_mutex);
+       inode_unlock(parent);
        iput(parent);
        return err;
 }
@@ -1504,7 +1504,7 @@ void fuse_set_nowrite(struct inode *inode)
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
 
-       BUG_ON(!mutex_is_locked(&inode->i_mutex));
+       BUG_ON(!inode_is_locked(inode));
 
        spin_lock(&fc->lock);
        BUG_ON(fi->writectr < 0);
index 570ca40..b03d253 100644 (file)
@@ -207,7 +207,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
                return err;
 
        if (lock_inode)
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
 
        err = fuse_do_open(fc, get_node_id(inode), file, isdir);
 
@@ -215,7 +215,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
                fuse_finish_open(inode, file);
 
        if (lock_inode)
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
        return err;
 }
@@ -413,9 +413,9 @@ static int fuse_flush(struct file *file, fl_owner_t id)
        if (err)
                return err;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        fuse_sync_writes(inode);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        req = fuse_get_req_nofail_nopages(fc, file);
        memset(&inarg, 0, sizeof(inarg));
@@ -450,7 +450,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
        if (is_bad_inode(inode))
                return -EIO;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * Start writeback against all dirty pages of the inode, then
@@ -486,7 +486,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
                err = 0;
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err;
 }
 
@@ -1160,7 +1160,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
                return generic_file_write_iter(iocb, from);
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* We can write back this queue in page reclaim */
        current->backing_dev_info = inode_to_bdi(inode);
@@ -1210,7 +1210,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        }
 out:
        current->backing_dev_info = NULL;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return written ? written : err;
 }
@@ -1322,10 +1322,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
 
        if (!cuse && fuse_range_is_writeback(inode, idx_from, idx_to)) {
                if (!write)
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
                fuse_sync_writes(inode);
                if (!write)
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
        }
 
        while (count) {
@@ -1413,14 +1413,14 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
                return -EIO;
 
        /* Don't allow parallel writes to the same file */
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        res = generic_write_checks(iocb, from);
        if (res > 0)
                res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE);
        fuse_invalidate_attr(inode);
        if (res > 0)
                fuse_write_update_size(inode, iocb->ki_pos);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return res;
 }
@@ -2231,20 +2231,77 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
        return err ? 0 : outarg.block;
 }
 
+static loff_t fuse_lseek(struct file *file, loff_t offset, int whence)
+{
+       struct inode *inode = file->f_mapping->host;
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_file *ff = file->private_data;
+       FUSE_ARGS(args);
+       struct fuse_lseek_in inarg = {
+               .fh = ff->fh,
+               .offset = offset,
+               .whence = whence
+       };
+       struct fuse_lseek_out outarg;
+       int err;
+
+       if (fc->no_lseek)
+               goto fallback;
+
+       args.in.h.opcode = FUSE_LSEEK;
+       args.in.h.nodeid = ff->nodeid;
+       args.in.numargs = 1;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       args.out.numargs = 1;
+       args.out.args[0].size = sizeof(outarg);
+       args.out.args[0].value = &outarg;
+       err = fuse_simple_request(fc, &args);
+       if (err) {
+               if (err == -ENOSYS) {
+                       fc->no_lseek = 1;
+                       goto fallback;
+               }
+               return err;
+       }
+
+       return vfs_setpos(file, outarg.offset, inode->i_sb->s_maxbytes);
+
+fallback:
+       err = fuse_update_attributes(inode, NULL, file, NULL);
+       if (!err)
+               return generic_file_llseek(file, offset, whence);
+       else
+               return err;
+}
+
 static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence)
 {
        loff_t retval;
        struct inode *inode = file_inode(file);
 
-       /* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */
-       if (whence == SEEK_CUR || whence == SEEK_SET)
-               return generic_file_llseek(file, offset, whence);
-
-       mutex_lock(&inode->i_mutex);
-       retval = fuse_update_attributes(inode, NULL, file, NULL);
-       if (!retval)
+       switch (whence) {
+       case SEEK_SET:
+       case SEEK_CUR:
+                /* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */
                retval = generic_file_llseek(file, offset, whence);
-       mutex_unlock(&inode->i_mutex);
+               break;
+       case SEEK_END:
+               inode_lock(inode);
+               retval = fuse_update_attributes(inode, NULL, file, NULL);
+               if (!retval)
+                       retval = generic_file_llseek(file, offset, whence);
+               inode_unlock(inode);
+               break;
+       case SEEK_HOLE:
+       case SEEK_DATA:
+               inode_lock(inode);
+               retval = fuse_lseek(file, offset, whence);
+               inode_unlock(inode);
+               break;
+       default:
+               retval = -EINVAL;
+       }
 
        return retval;
 }
@@ -2887,7 +2944,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
                return -EOPNOTSUPP;
 
        if (lock_inode) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if (mode & FALLOC_FL_PUNCH_HOLE) {
                        loff_t endbyte = offset + length - 1;
                        err = filemap_write_and_wait_range(inode->i_mapping,
@@ -2933,7 +2990,7 @@ out:
                clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
 
        if (lock_inode)
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
        return err;
 }
index 4051131..ce394b5 100644 (file)
@@ -605,6 +605,9 @@ struct fuse_conn {
        /** Does the filesystem support asynchronous direct-IO submission? */
        unsigned async_dio:1;
 
+       /** Is lseek not implemented by fs? */
+       unsigned no_lseek:1;
+
        /** The number of requests waiting for completion */
        atomic_t num_waiting;
 
index 7412863..c9384f9 100644 (file)
@@ -914,7 +914,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t le
        if ((mode & ~FALLOC_FL_KEEP_SIZE) || gfs2_is_jdata(ip))
                return -EOPNOTSUPP;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        ret = gfs2_glock_nq(&gh);
@@ -946,7 +946,7 @@ out_unlock:
        gfs2_glock_dq(&gh);
 out_uninit:
        gfs2_holder_uninit(&gh);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index 3e94400..352f958 100644 (file)
@@ -2067,7 +2067,7 @@ static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
        if (ret)
@@ -2094,7 +2094,7 @@ static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 
        gfs2_glock_dq_uninit(&gh);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index be6d9c4..a398913 100644 (file)
@@ -888,7 +888,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
                return -ENOMEM;
 
        sort(qda, num_qd, sizeof(struct gfs2_quota_data *), sort_qd, NULL);
-       mutex_lock(&ip->i_inode.i_mutex);
+       inode_lock(&ip->i_inode);
        for (qx = 0; qx < num_qd; qx++) {
                error = gfs2_glock_nq_init(qda[qx]->qd_gl, LM_ST_EXCLUSIVE,
                                           GL_NOCACHE, &ghs[qx]);
@@ -953,7 +953,7 @@ out_alloc:
 out:
        while (qx--)
                gfs2_glock_dq_uninit(&ghs[qx]);
-       mutex_unlock(&ip->i_inode.i_mutex);
+       inode_unlock(&ip->i_inode);
        kfree(ghs);
        gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, NORMAL_FLUSH);
        return error;
@@ -1674,7 +1674,7 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
        if (error)
                goto out_put;
 
-       mutex_lock(&ip->i_inode.i_mutex);
+       inode_lock(&ip->i_inode);
        error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh);
        if (error)
                goto out_unlockput;
@@ -1739,7 +1739,7 @@ out_i:
 out_q:
        gfs2_glock_dq_uninit(&q_gh);
 out_unlockput:
-       mutex_unlock(&ip->i_inode.i_mutex);
+       inode_unlock(&ip->i_inode);
 out_put:
        qd_put(qd);
        return error;
index db458ee..1eb5d41 100644 (file)
@@ -214,7 +214,7 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str)
 {
        struct super_block *sb;
        struct hfs_find_data fd;
-       struct list_head *pos;
+       struct hfs_readdir_data *rd;
        int res, type;
 
        hfs_dbg(CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid);
@@ -240,9 +240,7 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str)
                }
        }
 
-       list_for_each(pos, &HFS_I(dir)->open_dir_list) {
-               struct hfs_readdir_data *rd =
-                       list_entry(pos, struct hfs_readdir_data, list);
+       list_for_each_entry(rd, &HFS_I(dir)->open_dir_list, list) {
                if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0)
                        rd->file->f_pos--;
        }
index 70788e0..e9f2b85 100644 (file)
@@ -173,9 +173,9 @@ static int hfs_dir_release(struct inode *inode, struct file *file)
 {
        struct hfs_readdir_data *rd = file->private_data;
        if (rd) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                list_del(&rd->list);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                kfree(rd);
        }
        return 0;
index b99ebdd..6686bf3 100644 (file)
@@ -570,13 +570,13 @@ static int hfs_file_release(struct inode *inode, struct file *file)
        if (HFS_IS_RSRC(inode))
                inode = HFS_I(inode)->rsrc_inode;
        if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                hfs_file_truncate(inode);
                //if (inode->i_flags & S_DEAD) {
                //      hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
                //      hfs_delete_inode(inode);
                //}
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        return 0;
 }
@@ -656,7 +656,7 @@ static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,
        ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (ret)
                return ret;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* sync the inode to buffers */
        ret = write_inode_now(inode, 0);
@@ -668,7 +668,7 @@ static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,
        err = sync_blockdev(sb->s_bdev);
        if (!ret)
                ret = err;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
index d0f39dc..a4e867e 100644 (file)
@@ -284,9 +284,9 @@ static int hfsplus_dir_release(struct inode *inode, struct file *file)
 {
        struct hfsplus_readdir_data *rd = file->private_data;
        if (rd) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                list_del(&rd->list);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                kfree(rd);
        }
        return 0;
index 19b33f8..1a6394c 100644 (file)
@@ -229,14 +229,14 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
        if (HFSPLUS_IS_RSRC(inode))
                inode = HFSPLUS_I(inode)->rsrc_inode;
        if (atomic_dec_and_test(&HFSPLUS_I(inode)->opencnt)) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                hfsplus_file_truncate(inode);
                if (inode->i_flags & S_DEAD) {
                        hfsplus_delete_cat(inode->i_ino,
                                           HFSPLUS_SB(sb)->hidden_dir, NULL);
                        hfsplus_delete_inode(inode);
                }
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        return 0;
 }
@@ -286,7 +286,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
        error = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (error)
                return error;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * Sync inode metadata into the catalog and extent trees.
@@ -327,7 +327,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
        if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
                blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return error;
 }
index 0624ce4..32a49e2 100644 (file)
@@ -93,7 +93,7 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags)
                goto out_drop_write;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if ((flags & (FS_IMMUTABLE_FL|FS_APPEND_FL)) ||
            inode->i_flags & (S_IMMUTABLE|S_APPEND)) {
@@ -126,7 +126,7 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags)
        mark_inode_dirty(inode);
 
 out_unlock_inode:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 out_drop_write:
        mnt_drop_write_file(file);
 out:
index cfaa18c..d1abbee 100644 (file)
@@ -378,9 +378,9 @@ static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
index dc540bf..e57a53c 100644 (file)
@@ -33,7 +33,7 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence)
        if (whence == SEEK_DATA || whence == SEEK_HOLE)
                return -EINVAL;
 
-       mutex_lock(&i->i_mutex);
+       inode_lock(i);
        hpfs_lock(s);
 
        /*pr_info("dir lseek\n");*/
@@ -48,12 +48,12 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence)
 ok:
        filp->f_pos = new_off;
        hpfs_unlock(s);
-       mutex_unlock(&i->i_mutex);
+       inode_unlock(i);
        return new_off;
 fail:
        /*pr_warn("illegal lseek: %016llx\n", new_off);*/
        hpfs_unlock(s);
-       mutex_unlock(&i->i_mutex);
+       inode_unlock(i);
        return -ESPIPE;
 }
 
index 8bbf7f3..e1f465a 100644 (file)
@@ -141,7 +141,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
 
        vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        file_accessed(file);
 
        ret = -ENOMEM;
@@ -157,7 +157,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
        if (vma->vm_flags & VM_WRITE && inode->i_size < len)
                inode->i_size = len;
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
@@ -530,7 +530,7 @@ static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
        if (hole_end > hole_start) {
                struct address_space *mapping = inode->i_mapping;
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                i_mmap_lock_write(mapping);
                if (!RB_EMPTY_ROOT(&mapping->i_mmap))
                        hugetlb_vmdelete_list(&mapping->i_mmap,
@@ -538,7 +538,7 @@ static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
                                                hole_end  >> PAGE_SHIFT);
                i_mmap_unlock_write(mapping);
                remove_inode_hugepages(inode, hole_start, hole_end);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
        return 0;
@@ -572,7 +572,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
        start = offset >> hpage_shift;
        end = (offset + len + hpage_size - 1) >> hpage_shift;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* We need to check rlimit even when FALLOC_FL_KEEP_SIZE */
        error = inode_newsize_ok(inode, offset + len);
@@ -659,7 +659,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
                i_size_write(inode, offset + len);
        inode->i_ctime = CURRENT_TIME;
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return error;
 }
 
index e491e54..9f62db3 100644 (file)
@@ -495,7 +495,7 @@ void clear_inode(struct inode *inode)
         */
        spin_lock_irq(&inode->i_data.tree_lock);
        BUG_ON(inode->i_data.nrpages);
-       BUG_ON(inode->i_data.nrshadows);
+       BUG_ON(inode->i_data.nrexceptional);
        spin_unlock_irq(&inode->i_data.tree_lock);
        BUG_ON(!list_empty(&inode->i_data.private_list));
        BUG_ON(!(inode->i_state & I_FREEING));
@@ -966,9 +966,9 @@ void lock_two_nondirectories(struct inode *inode1, struct inode *inode2)
                swap(inode1, inode2);
 
        if (inode1 && !S_ISDIR(inode1->i_mode))
-               mutex_lock(&inode1->i_mutex);
+               inode_lock(inode1);
        if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1)
-               mutex_lock_nested(&inode2->i_mutex, I_MUTEX_NONDIR2);
+               inode_lock_nested(inode2, I_MUTEX_NONDIR2);
 }
 EXPORT_SYMBOL(lock_two_nondirectories);
 
@@ -980,9 +980,9 @@ EXPORT_SYMBOL(lock_two_nondirectories);
 void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2)
 {
        if (inode1 && !S_ISDIR(inode1->i_mode))
-               mutex_unlock(&inode1->i_mutex);
+               inode_unlock(inode1);
        if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1)
-               mutex_unlock(&inode2->i_mutex);
+               inode_unlock(inode2);
 }
 EXPORT_SYMBOL(unlock_two_nondirectories);
 
index 29466c3..116a333 100644 (file)
@@ -434,9 +434,9 @@ int generic_block_fiemap(struct inode *inode,
                         u64 len, get_block_t *get_block)
 {
        int ret;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 EXPORT_SYMBOL(generic_block_fiemap);
index a3750f9..0ae91ad 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mm.h> /* kvfree() */
 #include "nodelist.h"
 
 static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
@@ -383,12 +384,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
        return 0;
 
  out_free:
-#ifndef __ECOS
-       if (jffs2_blocks_use_vmalloc(c))
-               vfree(c->blocks);
-       else
-#endif
-               kfree(c->blocks);
+       kvfree(c->blocks);
 
        return ret;
 }
index f509f62..c5ac594 100644 (file)
@@ -39,10 +39,10 @@ int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        /* Trigger GC to flush any pending writes for this inode */
        jffs2_flush_wbuf_gc(c, inode->i_ino);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return 0;
 }
index 2caf168..bead25a 100644 (file)
@@ -596,10 +596,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
 out_root:
        jffs2_free_ino_caches(c);
        jffs2_free_raw_node_refs(c);
-       if (jffs2_blocks_use_vmalloc(c))
-               vfree(c->blocks);
-       else
-               kfree(c->blocks);
+       kvfree(c->blocks);
  out_inohash:
        jffs2_clear_xattr_subsystem(c);
        kfree(c->inocache_list);
index bb080c2..0a9a114 100644 (file)
@@ -331,10 +331,7 @@ static void jffs2_put_super (struct super_block *sb)
 
        jffs2_free_ino_caches(c);
        jffs2_free_raw_node_refs(c);
-       if (jffs2_blocks_use_vmalloc(c))
-               vfree(c->blocks);
-       else
-               kfree(c->blocks);
+       kvfree(c->blocks);
        jffs2_flash_cleanup(c);
        kfree(c->inocache_list);
        jffs2_clear_xattr_subsystem(c);
index 0e026a7..4ce7735 100644 (file)
@@ -38,17 +38,17 @@ int jfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        if (rc)
                return rc;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        if (!(inode->i_state & I_DIRTY_ALL) ||
            (datasync && !(inode->i_state & I_DIRTY_DATASYNC))) {
                /* Make sure committed changes hit the disk */
                jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                return rc;
        }
 
        rc |= jfs_commit_inode(inode, 1);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return rc ? -EIO : 0;
 }
index 8db8b7d..8653cac 100644 (file)
@@ -96,7 +96,7 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                }
 
                /* Lock against other parallel changes of flags */
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
 
                jfs_get_inode_flags(jfs_inode);
                oldflags = jfs_inode->mode2;
@@ -109,7 +109,7 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        ((flags ^ oldflags) &
                        (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
                        if (!capable(CAP_LINUX_IMMUTABLE)) {
-                               mutex_unlock(&inode->i_mutex);
+                               inode_unlock(inode);
                                err = -EPERM;
                                goto setflags_out;
                        }
@@ -120,7 +120,7 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                jfs_inode->mode2 = flags;
 
                jfs_set_inode_flags(inode);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                inode->i_ctime = CURRENT_TIME_SEC;
                mark_inode_dirty(inode);
 setflags_out:
index 900925b..4f5d85b 100644 (file)
@@ -792,7 +792,7 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type,
        struct buffer_head tmp_bh;
        struct buffer_head *bh;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        while (towrite > 0) {
                tocopy = sb->s_blocksize - offset < towrite ?
                                sb->s_blocksize - offset : towrite;
@@ -824,7 +824,7 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type,
        }
 out:
        if (len == towrite) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                return err;
        }
        if (inode->i_size < off+len-towrite)
@@ -832,7 +832,7 @@ out:
        inode->i_version++;
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        mark_inode_dirty(inode);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return len - towrite;
 }
 
index 8219738..996b774 100644 (file)
@@ -1511,9 +1511,9 @@ static loff_t kernfs_dir_fop_llseek(struct file *file, loff_t offset,
        struct inode *inode = file_inode(file);
        loff_t ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = generic_file_llseek(file, offset, whence);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
index 0149129..0ca80b2 100644 (file)
@@ -89,7 +89,7 @@ EXPORT_SYMBOL(dcache_dir_close);
 loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
 {
        struct dentry *dentry = file->f_path.dentry;
-       mutex_lock(&d_inode(dentry)->i_mutex);
+       inode_lock(d_inode(dentry));
        switch (whence) {
                case 1:
                        offset += file->f_pos;
@@ -97,7 +97,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
                        if (offset >= 0)
                                break;
                default:
-                       mutex_unlock(&d_inode(dentry)->i_mutex);
+                       inode_unlock(d_inode(dentry));
                        return -EINVAL;
        }
        if (offset != file->f_pos) {
@@ -124,7 +124,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
                        spin_unlock(&dentry->d_lock);
                }
        }
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
        return offset;
 }
 EXPORT_SYMBOL(dcache_dir_lseek);
@@ -941,7 +941,7 @@ int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
        if (err)
                return err;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = sync_mapping_buffers(inode->i_mapping);
        if (!(inode->i_state & I_DIRTY_ALL))
                goto out;
@@ -953,7 +953,7 @@ int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
                ret = err;
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 EXPORT_SYMBOL(__generic_file_fsync);
index af1ed74..7c5f91b 100644 (file)
@@ -1650,12 +1650,12 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
         * bother, maybe that's a sign this just isn't a good file to
         * hand out a delegation on.
         */
-       if (is_deleg && !mutex_trylock(&inode->i_mutex))
+       if (is_deleg && !inode_trylock(inode))
                return -EAGAIN;
 
        if (is_deleg && arg == F_WRLCK) {
                /* Write delegations are not currently supported: */
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                WARN_ON_ONCE(1);
                return -EINVAL;
        }
@@ -1732,7 +1732,7 @@ out:
        spin_unlock(&ctx->flc_lock);
        locks_dispose_list(&dispose);
        if (is_deleg)
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        if (!error && !my_fl)
                *flp = NULL;
        return error;
index 1a6f016..61eaeb1 100644 (file)
@@ -204,12 +204,12 @@ long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                if (err)
                        return err;
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                oldflags = li->li_flags;
                flags &= LOGFS_FL_USER_MODIFIABLE;
                flags |= oldflags & ~LOGFS_FL_USER_MODIFIABLE;
                li->li_flags = flags;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
                inode->i_ctime = CURRENT_TIME;
                mark_inode_dirty_sync(inode);
@@ -230,11 +230,11 @@ int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        logfs_get_wblocks(sb, NULL, WF_LOCK);
        logfs_write_anchor(sb);
        logfs_put_wblocks(sb, NULL, WF_LOCK);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return 0;
 }
index bceefd5..f624d13 100644 (file)
@@ -1629,9 +1629,9 @@ static int lookup_slow(struct nameidata *nd, struct path *path)
        parent = nd->path.dentry;
        BUG_ON(nd->inode != parent->d_inode);
 
-       mutex_lock(&parent->d_inode->i_mutex);
+       inode_lock(parent->d_inode);
        dentry = __lookup_hash(&nd->last, parent, nd->flags);
-       mutex_unlock(&parent->d_inode->i_mutex);
+       inode_unlock(parent->d_inode);
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
        path->mnt = nd->path.mnt;
@@ -2229,10 +2229,10 @@ struct dentry *kern_path_locked(const char *name, struct path *path)
                putname(filename);
                return ERR_PTR(-EINVAL);
        }
-       mutex_lock_nested(&path->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
        d = __lookup_hash(&last, path->dentry, 0);
        if (IS_ERR(d)) {
-               mutex_unlock(&path->dentry->d_inode->i_mutex);
+               inode_unlock(path->dentry->d_inode);
                path_put(path);
        }
        putname(filename);
@@ -2282,7 +2282,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
        unsigned int c;
        int err;
 
-       WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
+       WARN_ON_ONCE(!inode_is_locked(base->d_inode));
 
        this.name = name;
        this.len = len;
@@ -2380,9 +2380,9 @@ struct dentry *lookup_one_len_unlocked(const char *name,
        if (ret)
                return ret;
 
-       mutex_lock(&base->d_inode->i_mutex);
+       inode_lock(base->d_inode);
        ret =  __lookup_hash(&this, base, 0);
-       mutex_unlock(&base->d_inode->i_mutex);
+       inode_unlock(base->d_inode);
        return ret;
 }
 EXPORT_SYMBOL(lookup_one_len_unlocked);
@@ -2463,7 +2463,7 @@ mountpoint_last(struct nameidata *nd, struct path *path)
                goto done;
        }
 
-       mutex_lock(&dir->d_inode->i_mutex);
+       inode_lock(dir->d_inode);
        dentry = d_lookup(dir, &nd->last);
        if (!dentry) {
                /*
@@ -2473,16 +2473,16 @@ mountpoint_last(struct nameidata *nd, struct path *path)
                 */
                dentry = d_alloc(dir, &nd->last);
                if (!dentry) {
-                       mutex_unlock(&dir->d_inode->i_mutex);
+                       inode_unlock(dir->d_inode);
                        return -ENOMEM;
                }
                dentry = lookup_real(dir->d_inode, dentry, nd->flags);
                if (IS_ERR(dentry)) {
-                       mutex_unlock(&dir->d_inode->i_mutex);
+                       inode_unlock(dir->d_inode);
                        return PTR_ERR(dentry);
                }
        }
-       mutex_unlock(&dir->d_inode->i_mutex);
+       inode_unlock(dir->d_inode);
 
 done:
        if (d_is_negative(dentry)) {
@@ -2672,7 +2672,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
        struct dentry *p;
 
        if (p1 == p2) {
-               mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
+               inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
                return NULL;
        }
 
@@ -2680,29 +2680,29 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
 
        p = d_ancestor(p2, p1);
        if (p) {
-               mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
+               inode_lock_nested(p2->d_inode, I_MUTEX_PARENT);
+               inode_lock_nested(p1->d_inode, I_MUTEX_CHILD);
                return p;
        }
 
        p = d_ancestor(p1, p2);
        if (p) {
-               mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
+               inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
+               inode_lock_nested(p2->d_inode, I_MUTEX_CHILD);
                return p;
        }
 
-       mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
-       mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT2);
+       inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
+       inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2);
        return NULL;
 }
 EXPORT_SYMBOL(lock_rename);
 
 void unlock_rename(struct dentry *p1, struct dentry *p2)
 {
-       mutex_unlock(&p1->d_inode->i_mutex);
+       inode_unlock(p1->d_inode);
        if (p1 != p2) {
-               mutex_unlock(&p2->d_inode->i_mutex);
+               inode_unlock(p2->d_inode);
                mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
        }
 }
@@ -3141,9 +3141,9 @@ retry_lookup:
                 * dropping this one anyway.
                 */
        }
-       mutex_lock(&dir->d_inode->i_mutex);
+       inode_lock(dir->d_inode);
        error = lookup_open(nd, &path, file, op, got_write, opened);
-       mutex_unlock(&dir->d_inode->i_mutex);
+       inode_unlock(dir->d_inode);
 
        if (error <= 0) {
                if (error)
@@ -3489,7 +3489,7 @@ static struct dentry *filename_create(int dfd, struct filename *name,
         * Do the final lookup.
         */
        lookup_flags |= LOOKUP_CREATE | LOOKUP_EXCL;
-       mutex_lock_nested(&path->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
        dentry = __lookup_hash(&last, path->dentry, lookup_flags);
        if (IS_ERR(dentry))
                goto unlock;
@@ -3518,7 +3518,7 @@ fail:
        dput(dentry);
        dentry = ERR_PTR(error);
 unlock:
-       mutex_unlock(&path->dentry->d_inode->i_mutex);
+       inode_unlock(path->dentry->d_inode);
        if (!err2)
                mnt_drop_write(path->mnt);
 out:
@@ -3538,7 +3538,7 @@ EXPORT_SYMBOL(kern_path_create);
 void done_path_create(struct path *path, struct dentry *dentry)
 {
        dput(dentry);
-       mutex_unlock(&path->dentry->d_inode->i_mutex);
+       inode_unlock(path->dentry->d_inode);
        mnt_drop_write(path->mnt);
        path_put(path);
 }
@@ -3735,7 +3735,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
                return -EPERM;
 
        dget(dentry);
-       mutex_lock(&dentry->d_inode->i_mutex);
+       inode_lock(dentry->d_inode);
 
        error = -EBUSY;
        if (is_local_mountpoint(dentry))
@@ -3755,7 +3755,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
        detach_mounts(dentry);
 
 out:
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       inode_unlock(dentry->d_inode);
        dput(dentry);
        if (!error)
                d_delete(dentry);
@@ -3794,7 +3794,7 @@ retry:
        if (error)
                goto exit1;
 
-       mutex_lock_nested(&path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
        dentry = __lookup_hash(&last, path.dentry, lookup_flags);
        error = PTR_ERR(dentry);
        if (IS_ERR(dentry))
@@ -3810,7 +3810,7 @@ retry:
 exit3:
        dput(dentry);
 exit2:
-       mutex_unlock(&path.dentry->d_inode->i_mutex);
+       inode_unlock(path.dentry->d_inode);
        mnt_drop_write(path.mnt);
 exit1:
        path_put(&path);
@@ -3856,7 +3856,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate
        if (!dir->i_op->unlink)
                return -EPERM;
 
-       mutex_lock(&target->i_mutex);
+       inode_lock(target);
        if (is_local_mountpoint(dentry))
                error = -EBUSY;
        else {
@@ -3873,7 +3873,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate
                }
        }
 out:
-       mutex_unlock(&target->i_mutex);
+       inode_unlock(target);
 
        /* We don't d_delete() NFS sillyrenamed files--they still exist. */
        if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
@@ -3916,7 +3916,7 @@ retry:
        if (error)
                goto exit1;
 retry_deleg:
-       mutex_lock_nested(&path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
        dentry = __lookup_hash(&last, path.dentry, lookup_flags);
        error = PTR_ERR(dentry);
        if (!IS_ERR(dentry)) {
@@ -3934,7 +3934,7 @@ retry_deleg:
 exit2:
                dput(dentry);
        }
-       mutex_unlock(&path.dentry->d_inode->i_mutex);
+       inode_unlock(path.dentry->d_inode);
        if (inode)
                iput(inode);    /* truncate the inode here */
        inode = NULL;
@@ -4086,7 +4086,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
        if (error)
                return error;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        /* Make sure we don't allow creating hardlink to an unlinked file */
        if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
                error =  -ENOENT;
@@ -4103,7 +4103,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
                inode->i_state &= ~I_LINKABLE;
                spin_unlock(&inode->i_lock);
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (!error)
                fsnotify_link(dir, inode, new_dentry);
        return error;
@@ -4303,7 +4303,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (!is_dir || (flags & RENAME_EXCHANGE))
                lock_two_nondirectories(source, target);
        else if (target)
-               mutex_lock(&target->i_mutex);
+               inode_lock(target);
 
        error = -EBUSY;
        if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry))
@@ -4356,7 +4356,7 @@ out:
        if (!is_dir || (flags & RENAME_EXCHANGE))
                unlock_two_nondirectories(source, target);
        else if (target)
-               mutex_unlock(&target->i_mutex);
+               inode_unlock(target);
        dput(new_dentry);
        if (!error) {
                fsnotify_move(old_dir, new_dir, old_name, is_dir,
index a830e14..4fb1691 100644 (file)
@@ -1961,9 +1961,9 @@ static struct mountpoint *lock_mount(struct path *path)
        struct vfsmount *mnt;
        struct dentry *dentry = path->dentry;
 retry:
-       mutex_lock(&dentry->d_inode->i_mutex);
+       inode_lock(dentry->d_inode);
        if (unlikely(cant_mount(dentry))) {
-               mutex_unlock(&dentry->d_inode->i_mutex);
+               inode_unlock(dentry->d_inode);
                return ERR_PTR(-ENOENT);
        }
        namespace_lock();
@@ -1974,13 +1974,13 @@ retry:
                        mp = new_mountpoint(dentry);
                if (IS_ERR(mp)) {
                        namespace_unlock();
-                       mutex_unlock(&dentry->d_inode->i_mutex);
+                       inode_unlock(dentry->d_inode);
                        return mp;
                }
                return mp;
        }
        namespace_unlock();
-       mutex_unlock(&path->dentry->d_inode->i_mutex);
+       inode_unlock(path->dentry->d_inode);
        path_put(path);
        path->mnt = mnt;
        dentry = path->dentry = dget(mnt->mnt_root);
@@ -1992,7 +1992,7 @@ static void unlock_mount(struct mountpoint *where)
        struct dentry *dentry = where->m_dentry;
        put_mountpoint(where);
        namespace_unlock();
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       inode_unlock(dentry->d_inode);
 }
 
 static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
index f0e3e9e..26c2de2 100644 (file)
@@ -369,7 +369,7 @@ ncp_lookup_validate(struct dentry *dentry, unsigned int flags)
        if (!res) {
                struct inode *inode = d_inode(dentry);
 
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if (finfo.i.dirEntNum == NCP_FINFO(inode)->dirEntNum) {
                        ncp_new_dentry(dentry);
                        val=1;
@@ -377,7 +377,7 @@ ncp_lookup_validate(struct dentry *dentry, unsigned int flags)
                        ncp_dbg(2, "found, but dirEntNum changed\n");
 
                ncp_update_inode2(inode, &finfo);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
 finished:
@@ -639,9 +639,9 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
        } else {
                struct inode *inode = d_inode(newdent);
 
-               mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
+               inode_lock_nested(inode, I_MUTEX_CHILD);
                ncp_update_inode2(inode, entry);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
        if (ctl.idx >= NCP_DIRCACHE_SIZE) {
index 011324c..dd38ca1 100644 (file)
@@ -224,10 +224,10 @@ ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        iocb->ki_pos = pos;
 
        if (pos > i_size_read(inode)) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if (pos > i_size_read(inode))
                        i_size_write(inode, pos);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        ncp_dbg(1, "exit %pD2\n", file);
 outrel:
index c82a212..9cce670 100644 (file)
@@ -940,7 +940,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
        dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
                        filp, offset, whence);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        switch (whence) {
                case 1:
                        offset += filp->f_pos;
@@ -957,7 +957,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
                dir_ctx->duped = 0;
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return offset;
 }
 
@@ -972,9 +972,9 @@ static int nfs_fsync_dir(struct file *filp, loff_t start, loff_t end,
 
        dfprintk(FILE, "NFS: fsync dir(%pD2) datasync %d\n", filp, datasync);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return 0;
 }
 
index 7ab7ec9..7a0cfd3 100644 (file)
@@ -580,7 +580,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
        if (!count)
                goto out;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        result = nfs_sync_mapping(mapping);
        if (result)
                goto out_unlock;
@@ -608,7 +608,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
        NFS_I(inode)->read_io += count;
        result = nfs_direct_read_schedule_iovec(dreq, iter, pos);
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (!result) {
                result = nfs_direct_wait(dreq);
@@ -622,7 +622,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
 out_release:
        nfs_direct_req_release(dreq);
 out_unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 out:
        return result;
 }
@@ -1005,7 +1005,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
        pos = iocb->ki_pos;
        end = (pos + iov_iter_count(iter) - 1) >> PAGE_CACHE_SHIFT;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        result = nfs_sync_mapping(mapping);
        if (result)
@@ -1045,7 +1045,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
                                              pos >> PAGE_CACHE_SHIFT, end);
        }
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (!result) {
                result = nfs_direct_wait(dreq);
@@ -1066,7 +1066,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
 out_release:
        nfs_direct_req_release(dreq);
 out_unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return result;
 }
 
index 4ef8f5a..748bb81 100644 (file)
@@ -278,9 +278,9 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
                if (ret != 0)
                        break;
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                ret = nfs_file_fsync_commit(file, start, end, datasync);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                /*
                 * If nfs_file_fsync_commit detected a server reboot, then
                 * resend all dirty pages that might have been covered by
index bb1f4e7..3384dc8 100644 (file)
@@ -971,7 +971,7 @@ filelayout_mark_request_commit(struct nfs_page *req,
        u32 i, j;
 
        if (fl->commit_through_mds) {
-               nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo);
+               nfs_request_add_commit_list(req, cinfo);
        } else {
                /* Note that we are calling nfs4_fl_calc_j_index on each page
                 * that ends up being committed to a data server.  An attractive
index 6594e9f..5bcd92d 100644 (file)
@@ -1948,11 +1948,9 @@ ff_layout_encode_layoutreturn(struct pnfs_layout_hdr *lo,
        start = xdr_reserve_space(xdr, 4);
        BUG_ON(!start);
 
-       if (ff_layout_encode_ioerr(flo, xdr, args))
-               goto out;
-
+       ff_layout_encode_ioerr(flo, xdr, args);
        ff_layout_encode_iostats(flo, xdr, args);
-out:
+
        *start = cpu_to_be32((xdr->p - start - 1) * 4);
        dprintk("%s: Return\n", __func__);
 }
index bd03275..29898a9 100644 (file)
@@ -218,63 +218,55 @@ static void extend_ds_error(struct nfs4_ff_layout_ds_err *err,
        err->length = end - err->offset;
 }
 
-static bool ds_error_can_merge(struct nfs4_ff_layout_ds_err *err,  u64 offset,
-                              u64 length, int status, enum nfs_opnum4 opnum,
-                              nfs4_stateid *stateid,
-                              struct nfs4_deviceid *deviceid)
+static int
+ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1,
+               const struct nfs4_ff_layout_ds_err *e2)
 {
-       return err->status == status && err->opnum == opnum &&
-              nfs4_stateid_match(&err->stateid, stateid) &&
-              !memcmp(&err->deviceid, deviceid, sizeof(*deviceid)) &&
-              end_offset(err->offset, err->length) >= offset &&
-              err->offset <= end_offset(offset, length);
-}
-
-static bool merge_ds_error(struct nfs4_ff_layout_ds_err *old,
-                          struct nfs4_ff_layout_ds_err *new)
-{
-       if (!ds_error_can_merge(old, new->offset, new->length, new->status,
-                               new->opnum, &new->stateid, &new->deviceid))
-               return false;
-
-       extend_ds_error(old, new->offset, new->length);
-       return true;
+       int ret;
+
+       if (e1->opnum != e2->opnum)
+               return e1->opnum < e2->opnum ? -1 : 1;
+       if (e1->status != e2->status)
+               return e1->status < e2->status ? -1 : 1;
+       ret = memcmp(&e1->stateid, &e2->stateid, sizeof(e1->stateid));
+       if (ret != 0)
+               return ret;
+       ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
+       if (ret != 0)
+               return ret;
+       if (end_offset(e1->offset, e1->length) < e2->offset)
+               return -1;
+       if (e1->offset > end_offset(e2->offset, e2->length))
+               return 1;
+       /* If ranges overlap or are contiguous, they are the same */
+       return 0;
 }
 
-static bool
+static void
 ff_layout_add_ds_error_locked(struct nfs4_flexfile_layout *flo,
                              struct nfs4_ff_layout_ds_err *dserr)
 {
-       struct nfs4_ff_layout_ds_err *err;
-
-       list_for_each_entry(err, &flo->error_list, list) {
-               if (merge_ds_error(err, dserr)) {
-                       return true;
-               }
-       }
-
-       list_add(&dserr->list, &flo->error_list);
-       return false;
-}
-
-static bool
-ff_layout_update_ds_error(struct nfs4_flexfile_layout *flo, u64 offset,
-                         u64 length, int status, enum nfs_opnum4 opnum,
-                         nfs4_stateid *stateid, struct nfs4_deviceid *deviceid)
-{
-       bool found = false;
-       struct nfs4_ff_layout_ds_err *err;
-
-       list_for_each_entry(err, &flo->error_list, list) {
-               if (ds_error_can_merge(err, offset, length, status, opnum,
-                                      stateid, deviceid)) {
-                       found = true;
-                       extend_ds_error(err, offset, length);
+       struct nfs4_ff_layout_ds_err *err, *tmp;
+       struct list_head *head = &flo->error_list;
+       int match;
+
+       /* Do insertion sort w/ merges */
+       list_for_each_entry_safe(err, tmp, &flo->error_list, list) {
+               match = ff_ds_error_match(err, dserr);
+               if (match < 0)
+                       continue;
+               if (match > 0) {
+                       /* Add entry "dserr" _before_ entry "err" */
+                       head = &err->list;
                        break;
                }
+               /* Entries match, so merge "err" into "dserr" */
+               extend_ds_error(dserr, err->offset, err->length);
+               list_del(&err->list);
+               kfree(err);
        }
 
-       return found;
+       list_add_tail(&dserr->list, head);
 }
 
 int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
@@ -283,7 +275,6 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
                             gfp_t gfp_flags)
 {
        struct nfs4_ff_layout_ds_err *dserr;
-       bool needfree;
 
        if (status == 0)
                return 0;
@@ -291,14 +282,6 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
        if (mirror->mirror_ds == NULL)
                return -EINVAL;
 
-       spin_lock(&flo->generic_hdr.plh_inode->i_lock);
-       if (ff_layout_update_ds_error(flo, offset, length, status, opnum,
-                                     &mirror->stateid,
-                                     &mirror->mirror_ds->id_node.deviceid)) {
-               spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
-               return 0;
-       }
-       spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
        dserr = kmalloc(sizeof(*dserr), gfp_flags);
        if (!dserr)
                return -ENOMEM;
@@ -313,10 +296,8 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
               NFS4_DEVICEID4_SIZE);
 
        spin_lock(&flo->generic_hdr.plh_inode->i_lock);
-       needfree = ff_layout_add_ds_error_locked(flo, dserr);
+       ff_layout_add_ds_error_locked(flo, dserr);
        spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
-       if (needfree)
-               kfree(dserr);
 
        return 0;
 }
index 8e24d88..86faecf 100644 (file)
@@ -661,9 +661,9 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
        trace_nfs_getattr_enter(inode);
        /* Flush out writes to the server in order to update c/mtime.  */
        if (S_ISREG(inode->i_mode)) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                err = nfs_sync_inode(inode);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                if (err)
                        goto out;
        }
@@ -1178,9 +1178,9 @@ static int __nfs_revalidate_mapping(struct inode *inode,
        spin_unlock(&inode->i_lock);
        trace_nfs_invalidate_mapping_enter(inode);
        if (may_lock) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                ret = nfs_invalidate_mapping(inode, mapping);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        } else
                ret = nfs_invalidate_mapping(inode, mapping);
        trace_nfs_invalidate_mapping_exit(inode, ret);
index 4e8cc94..9a547aa 100644 (file)
@@ -484,7 +484,7 @@ void nfs_retry_commit(struct list_head *page_list,
                      struct nfs_commit_info *cinfo,
                      u32 ds_commit_idx);
 void nfs_commitdata_release(struct nfs_commit_data *data);
-void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
+void nfs_request_add_commit_list(struct nfs_page *req,
                                 struct nfs_commit_info *cinfo);
 void nfs_request_add_commit_list_locked(struct nfs_page *req,
                struct list_head *dst,
index 6e81749..bd25dc7 100644 (file)
@@ -101,13 +101,13 @@ int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
        if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
                return -EOPNOTSUPP;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        err = nfs42_proc_fallocate(&msg, filep, offset, len);
        if (err == -EOPNOTSUPP)
                NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err;
 }
 
@@ -123,7 +123,7 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
                return -EOPNOTSUPP;
 
        nfs_wb_all(inode);
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        err = nfs42_proc_fallocate(&msg, filep, offset, len);
        if (err == 0)
@@ -131,7 +131,7 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
        if (err == -EOPNOTSUPP)
                NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err;
 }
 
index 26f9a23..57ca1c8 100644 (file)
@@ -141,11 +141,11 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
                if (ret != 0)
                        break;
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                ret = nfs_file_fsync_commit(file, start, end, datasync);
                if (!ret)
                        ret = pnfs_sync_inode(inode, !!datasync);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                /*
                 * If nfs_file_fsync_commit detected a server reboot, then
                 * resend all dirty pages that might have been covered by
@@ -219,13 +219,13 @@ static int nfs42_clone_file_range(struct file *src_file, loff_t src_off,
 
        /* XXX: do we lock at all? what if server needs CB_RECALL_LAYOUT? */
        if (same_inode) {
-               mutex_lock(&src_inode->i_mutex);
+               inode_lock(src_inode);
        } else if (dst_inode < src_inode) {
-               mutex_lock_nested(&dst_inode->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD);
+               inode_lock_nested(dst_inode, I_MUTEX_PARENT);
+               inode_lock_nested(src_inode, I_MUTEX_CHILD);
        } else {
-               mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&dst_inode->i_mutex, I_MUTEX_CHILD);
+               inode_lock_nested(src_inode, I_MUTEX_PARENT);
+               inode_lock_nested(dst_inode, I_MUTEX_CHILD);
        }
 
        /* flush all pending writes on both src and dst so that server
@@ -246,13 +246,13 @@ static int nfs42_clone_file_range(struct file *src_file, loff_t src_off,
 
 out_unlock:
        if (same_inode) {
-               mutex_unlock(&src_inode->i_mutex);
+               inode_unlock(src_inode);
        } else if (dst_inode < src_inode) {
-               mutex_unlock(&src_inode->i_mutex);
-               mutex_unlock(&dst_inode->i_mutex);
+               inode_unlock(src_inode);
+               inode_unlock(dst_inode);
        } else {
-               mutex_unlock(&dst_inode->i_mutex);
-               mutex_unlock(&src_inode->i_mutex);
+               inode_unlock(dst_inode);
+               inode_unlock(src_inode);
        }
 out:
        return ret;
index ce43cd6..5754835 100644 (file)
@@ -830,11 +830,10 @@ EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked);
  * holding the nfs_page lock.
  */
 void
-nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
-                           struct nfs_commit_info *cinfo)
+nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo)
 {
        spin_lock(cinfo->lock);
-       nfs_request_add_commit_list_locked(req, dst, cinfo);
+       nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo);
        spin_unlock(cinfo->lock);
        nfs_mark_page_unstable(req->wb_page, cinfo);
 }
@@ -892,7 +891,7 @@ nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
 {
        if (pnfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx))
                return;
-       nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo);
+       nfs_request_add_commit_list(req, cinfo);
 }
 
 static void
index 819ad81..4cba786 100644 (file)
@@ -55,10 +55,10 @@ nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u
        struct inode *inode = d_inode(resfh->fh_dentry);
        int status;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        status = security_inode_setsecctx(resfh->fh_dentry,
                label->data, label->len);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (status)
                /*
index 79f0307..dc8ebec 100644 (file)
@@ -192,7 +192,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 
        dir = nn->rec_file->f_path.dentry;
        /* lock the parent */
-       mutex_lock(&d_inode(dir)->i_mutex);
+       inode_lock(d_inode(dir));
 
        dentry = lookup_one_len(dname, dir, HEXDIR_LEN-1);
        if (IS_ERR(dentry)) {
@@ -213,7 +213,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 out_put:
        dput(dentry);
 out_unlock:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        if (status == 0) {
                if (nn->in_grace) {
                        crp = nfs4_client_to_reclaim(dname, nn);
@@ -286,7 +286,7 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
        }
 
        status = iterate_dir(nn->rec_file, &ctx.ctx);
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
        list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
                if (!status) {
@@ -302,7 +302,7 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
                list_del(&entry->list);
                kfree(entry);
        }
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        nfs4_reset_creds(original_cred);
 
        list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
@@ -322,7 +322,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
        dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
 
        dir = nn->rec_file->f_path.dentry;
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
        dentry = lookup_one_len(name, dir, namlen);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
@@ -335,7 +335,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
 out:
        dput(dentry);
 out_unlock:
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
        return status;
 }
 
index 0770bcb..f84fe6b 100644 (file)
@@ -288,7 +288,7 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
        }
 
        inode = d_inode(dentry);
-       mutex_lock_nested(&inode->i_mutex, subclass);
+       inode_lock_nested(inode, subclass);
        fill_pre_wcc(fhp);
        fhp->fh_locked = true;
 }
@@ -307,7 +307,7 @@ fh_unlock(struct svc_fh *fhp)
 {
        if (fhp->fh_locked) {
                fill_post_wcc(fhp);
-               mutex_unlock(&d_inode(fhp->fh_dentry)->i_mutex);
+               inode_unlock(d_inode(fhp->fh_dentry));
                fhp->fh_locked = false;
        }
 }
index 6739077..5d2a57e 100644 (file)
@@ -493,9 +493,9 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
 
        dentry = fhp->fh_dentry;
 
-       mutex_lock(&d_inode(dentry)->i_mutex);
+       inode_lock(d_inode(dentry));
        host_error = security_inode_setsecctx(dentry, label->data, label->len);
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
        return nfserrno(host_error);
 }
 #else
index 10b2252..21a1e2e 100644 (file)
@@ -1003,7 +1003,7 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        if (ret)
                return ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        isize = i_size_read(inode);
 
@@ -1113,6 +1113,6 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        if (ret == 1)
                ret = 0;
 
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
index aba4381..e8fe248 100644 (file)
@@ -158,7 +158,7 @@ static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
 
        flags = nilfs_mask_flags(inode->i_mode, flags);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        oldflags = NILFS_I(inode)->i_flags;
 
@@ -186,7 +186,7 @@ static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
        nilfs_mark_inode_dirty(inode);
        ret = nilfs_transaction_commit(inode->i_sb);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        mnt_drop_write_file(filp);
        return ret;
 }
index 9e38daf..b2eff58 100644 (file)
@@ -1509,7 +1509,7 @@ static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
        err = filemap_write_and_wait_range(vi->i_mapping, start, end);
        if (err)
                return err;
-       mutex_lock(&vi->i_mutex);
+       inode_lock(vi);
 
        BUG_ON(!S_ISDIR(vi->i_mode));
        /* If the bitmap attribute inode is in memory sync it, too. */
@@ -1532,7 +1532,7 @@ static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
        else
                ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx.  Error "
                                "%u.", datasync ? "data" : "", vi->i_ino, -ret);
-       mutex_unlock(&vi->i_mutex);
+       inode_unlock(vi);
        return ret;
 }
 
index 9d383e5..bed4d42 100644 (file)
@@ -1944,14 +1944,14 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        ssize_t written = 0;
        ssize_t err;
 
-       mutex_lock(&vi->i_mutex);
+       inode_lock(vi);
        /* We can write back this queue in page reclaim. */
        current->backing_dev_info = inode_to_bdi(vi);
        err = ntfs_prepare_file_for_write(iocb, from);
        if (iov_iter_count(from) && !err)
                written = ntfs_perform_write(file, from, iocb->ki_pos);
        current->backing_dev_info = NULL;
-       mutex_unlock(&vi->i_mutex);
+       inode_unlock(vi);
        if (likely(written > 0)) {
                err = generic_write_sync(file, iocb->ki_pos, written);
                if (err < 0)
@@ -1996,7 +1996,7 @@ static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end,
        err = filemap_write_and_wait_range(vi->i_mapping, start, end);
        if (err)
                return err;
-       mutex_lock(&vi->i_mutex);
+       inode_lock(vi);
 
        BUG_ON(S_ISDIR(vi->i_mode));
        if (!datasync || !NInoNonResident(NTFS_I(vi)))
@@ -2015,7 +2015,7 @@ static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end,
        else
                ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx.  Error "
                                "%u.", datasync ? "data" : "", vi->i_ino, -ret);
-       mutex_unlock(&vi->i_mutex);
+       inode_unlock(vi);
        return ret;
 }
 
index d80e331..9793e68 100644 (file)
@@ -48,7 +48,7 @@ bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
                ntfs_error(vol->sb, "Quota inodes are not open.");
                return false;
        }
-       mutex_lock(&vol->quota_q_ino->i_mutex);
+       inode_lock(vol->quota_q_ino);
        ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino));
        if (!ictx) {
                ntfs_error(vol->sb, "Failed to get index context.");
@@ -98,7 +98,7 @@ bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
        ntfs_index_entry_mark_dirty(ictx);
 set_done:
        ntfs_index_ctx_put(ictx);
-       mutex_unlock(&vol->quota_q_ino->i_mutex);
+       inode_unlock(vol->quota_q_ino);
        /*
         * We set the flag so we do not try to mark the quotas out of date
         * again on remount.
@@ -110,7 +110,7 @@ done:
 err_out:
        if (ictx)
                ntfs_index_ctx_put(ictx);
-       mutex_unlock(&vol->quota_q_ino->i_mutex);
+       inode_unlock(vol->quota_q_ino);
        return false;
 }
 
index 2f77f8d..1b38abd 100644 (file)
@@ -1284,10 +1284,10 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
         * Find the inode number for the hibernation file by looking up the
         * filename hiberfil.sys in the root directory.
         */
-       mutex_lock(&vol->root_ino->i_mutex);
+       inode_lock(vol->root_ino);
        mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12,
                        &name);
-       mutex_unlock(&vol->root_ino->i_mutex);
+       inode_unlock(vol->root_ino);
        if (IS_ERR_MREF(mref)) {
                ret = MREF_ERR(mref);
                /* If the file does not exist, Windows is not hibernated. */
@@ -1377,10 +1377,10 @@ static bool load_and_init_quota(ntfs_volume *vol)
         * Find the inode number for the quota file by looking up the filename
         * $Quota in the extended system files directory $Extend.
         */
-       mutex_lock(&vol->extend_ino->i_mutex);
+       inode_lock(vol->extend_ino);
        mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), Quota, 6,
                        &name);
-       mutex_unlock(&vol->extend_ino->i_mutex);
+       inode_unlock(vol->extend_ino);
        if (IS_ERR_MREF(mref)) {
                /*
                 * If the file does not exist, quotas are disabled and have
@@ -1460,10 +1460,10 @@ static bool load_and_init_usnjrnl(ntfs_volume *vol)
         * Find the inode number for the transaction log file by looking up the
         * filename $UsnJrnl in the extended system files directory $Extend.
         */
-       mutex_lock(&vol->extend_ino->i_mutex);
+       inode_lock(vol->extend_ino);
        mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8,
                        &name);
-       mutex_unlock(&vol->extend_ino->i_mutex);
+       inode_unlock(vol->extend_ino);
        if (IS_ERR_MREF(mref)) {
                /*
                 * If the file does not exist, transaction logging is disabled,
index a3ded88..d002579 100644 (file)
@@ -5719,7 +5719,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
                goto bail;
        }
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
 
        if (ocfs2_truncate_log_needs_flush(osb)) {
                ret = __ocfs2_flush_truncate_log(osb);
@@ -5776,7 +5776,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
 out_commit:
        ocfs2_commit_trans(osb, handle);
 out:
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 bail:
        if (meta_ac)
                ocfs2_free_alloc_context(meta_ac);
@@ -5832,7 +5832,7 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
        struct ocfs2_dinode *di;
        struct ocfs2_truncate_log *tl;
 
-       BUG_ON(mutex_trylock(&tl_inode->i_mutex));
+       BUG_ON(inode_trylock(tl_inode));
 
        start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk);
 
@@ -5980,7 +5980,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
        struct ocfs2_dinode *di;
        struct ocfs2_truncate_log *tl;
 
-       BUG_ON(mutex_trylock(&tl_inode->i_mutex));
+       BUG_ON(inode_trylock(tl_inode));
 
        di = (struct ocfs2_dinode *) tl_bh->b_data;
 
@@ -6008,7 +6008,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
                goto out;
        }
 
-       mutex_lock(&data_alloc_inode->i_mutex);
+       inode_lock(data_alloc_inode);
 
        status = ocfs2_inode_lock(data_alloc_inode, &data_alloc_bh, 1);
        if (status < 0) {
@@ -6035,7 +6035,7 @@ out_unlock:
        ocfs2_inode_unlock(data_alloc_inode, 1);
 
 out_mutex:
-       mutex_unlock(&data_alloc_inode->i_mutex);
+       inode_unlock(data_alloc_inode);
        iput(data_alloc_inode);
 
 out:
@@ -6047,9 +6047,9 @@ int ocfs2_flush_truncate_log(struct ocfs2_super *osb)
        int status;
        struct inode *tl_inode = osb->osb_tl_inode;
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
        status = __ocfs2_flush_truncate_log(osb);
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        return status;
 }
@@ -6208,7 +6208,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
                (unsigned long long)le64_to_cpu(tl_copy->i_blkno),
                num_recs);
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
        for(i = 0; i < num_recs; i++) {
                if (ocfs2_truncate_log_needs_flush(osb)) {
                        status = __ocfs2_flush_truncate_log(osb);
@@ -6239,7 +6239,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
        }
 
 bail_up:
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        return status;
 }
@@ -6346,7 +6346,7 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb,
                goto out;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        ret = ocfs2_inode_lock(inode, &di_bh, 1);
        if (ret) {
@@ -6395,7 +6395,7 @@ out_unlock:
        ocfs2_inode_unlock(inode, 1);
        brelse(di_bh);
 out_mutex:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        iput(inode);
 out:
        while(head) {
@@ -6439,7 +6439,7 @@ static int ocfs2_free_cached_clusters(struct ocfs2_super *osb,
        handle_t *handle;
        int ret = 0;
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
 
        while (head) {
                if (ocfs2_truncate_log_needs_flush(osb)) {
@@ -6471,7 +6471,7 @@ static int ocfs2_free_cached_clusters(struct ocfs2_super *osb,
                }
        }
 
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        while (head) {
                /* Premature exit may have left some dangling items. */
@@ -7355,7 +7355,7 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range)
                goto out;
        }
 
-       mutex_lock(&main_bm_inode->i_mutex);
+       inode_lock(main_bm_inode);
 
        ret = ocfs2_inode_lock(main_bm_inode, &main_bm_bh, 0);
        if (ret < 0) {
@@ -7422,7 +7422,7 @@ out_unlock:
        ocfs2_inode_unlock(main_bm_inode, 0);
        brelse(main_bm_bh);
 out_mutex:
-       mutex_unlock(&main_bm_inode->i_mutex);
+       inode_unlock(main_bm_inode);
        iput(main_bm_inode);
 out:
        return ret;
index 7f60472..794fd15 100644 (file)
@@ -2046,9 +2046,9 @@ static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb,
        int ret = 0;
        unsigned int truncated_clusters;
 
-       mutex_lock(&osb->osb_tl_inode->i_mutex);
+       inode_lock(osb->osb_tl_inode);
        truncated_clusters = osb->truncated_clusters;
-       mutex_unlock(&osb->osb_tl_inode->i_mutex);
+       inode_unlock(osb->osb_tl_inode);
 
        /*
         * Check whether we can succeed in allocating if we free
index 72afdca..ebe5438 100644 (file)
@@ -757,7 +757,7 @@ int o2nm_depend_item(struct config_item *item)
 
 void o2nm_undepend_item(struct config_item *item)
 {
-       configfs_undepend_item(&o2nm_cluster_group.cs_subsys, item);
+       configfs_undepend_item(item);
 }
 
 int o2nm_depend_this_node(void)
index ffecf89..e1adf28 100644 (file)
@@ -4361,7 +4361,7 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir,
                mlog_errno(ret);
                goto out;
        }
-       mutex_lock(&dx_alloc_inode->i_mutex);
+       inode_lock(dx_alloc_inode);
 
        ret = ocfs2_inode_lock(dx_alloc_inode, &dx_alloc_bh, 1);
        if (ret) {
@@ -4410,7 +4410,7 @@ out_unlock:
        ocfs2_inode_unlock(dx_alloc_inode, 1);
 
 out_mutex:
-       mutex_unlock(&dx_alloc_inode->i_mutex);
+       inode_unlock(dx_alloc_inode);
        brelse(dx_alloc_bh);
 out:
        iput(dx_alloc_inode);
index f92612e..474e57f 100644 (file)
@@ -1390,6 +1390,7 @@ static int __ocfs2_cluster_lock(struct ocfs2_super *osb,
        unsigned int gen;
        int noqueue_attempted = 0;
        int dlm_locked = 0;
+       int kick_dc = 0;
 
        if (!(lockres->l_flags & OCFS2_LOCK_INITIALIZED)) {
                mlog_errno(-EINVAL);
@@ -1524,7 +1525,12 @@ update_holders:
 unlock:
        lockres_clear_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING);
 
+       /* ocfs2_unblock_lock reques on seeing OCFS2_LOCK_UPCONVERT_FINISHING */
+       kick_dc = (lockres->l_flags & OCFS2_LOCK_BLOCKED);
+
        spin_unlock_irqrestore(&lockres->l_lock, flags);
+       if (kick_dc)
+               ocfs2_wake_downconvert_thread(osb);
 out:
        /*
         * This is helping work around a lock inversion between the page lock
index d631279..7cb38fd 100644 (file)
@@ -1872,7 +1872,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
        if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
                return -EROFS;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * This prevents concurrent writes on other nodes
@@ -1991,7 +1991,7 @@ out_rw_unlock:
        ocfs2_rw_unlock(inode, 1);
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return ret;
 }
 
@@ -2299,7 +2299,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
        appending = iocb->ki_flags & IOCB_APPEND ? 1 : 0;
        direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
 relock:
        /*
@@ -2435,7 +2435,7 @@ out:
                ocfs2_rw_unlock(inode, rw_level);
 
 out_mutex:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (written)
                ret = written;
@@ -2547,7 +2547,7 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence)
        struct inode *inode = file->f_mapping->host;
        int ret = 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        switch (whence) {
        case SEEK_SET:
@@ -2585,7 +2585,7 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence)
        offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (ret)
                return ret;
        return offset;
index 97a563b..3629444 100644 (file)
@@ -630,10 +630,10 @@ static int ocfs2_remove_inode(struct inode *inode,
                goto bail;
        }
 
-       mutex_lock(&inode_alloc_inode->i_mutex);
+       inode_lock(inode_alloc_inode);
        status = ocfs2_inode_lock(inode_alloc_inode, &inode_alloc_bh, 1);
        if (status < 0) {
-               mutex_unlock(&inode_alloc_inode->i_mutex);
+               inode_unlock(inode_alloc_inode);
 
                mlog_errno(status);
                goto bail;
@@ -680,7 +680,7 @@ bail_commit:
        ocfs2_commit_trans(osb, handle);
 bail_unlock:
        ocfs2_inode_unlock(inode_alloc_inode, 1);
-       mutex_unlock(&inode_alloc_inode->i_mutex);
+       inode_unlock(inode_alloc_inode);
        brelse(inode_alloc_bh);
 bail:
        iput(inode_alloc_inode);
@@ -751,10 +751,10 @@ static int ocfs2_wipe_inode(struct inode *inode,
                /* Lock the orphan dir. The lock will be held for the entire
                 * delete_inode operation. We do this now to avoid races with
                 * recovery completion on other nodes. */
-               mutex_lock(&orphan_dir_inode->i_mutex);
+               inode_lock(orphan_dir_inode);
                status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
                if (status < 0) {
-                       mutex_unlock(&orphan_dir_inode->i_mutex);
+                       inode_unlock(orphan_dir_inode);
 
                        mlog_errno(status);
                        goto bail;
@@ -803,7 +803,7 @@ bail_unlock_dir:
                return status;
 
        ocfs2_inode_unlock(orphan_dir_inode, 1);
-       mutex_unlock(&orphan_dir_inode->i_mutex);
+       inode_unlock(orphan_dir_inode);
        brelse(orphan_dir_bh);
 bail:
        iput(orphan_dir_inode);
index 16b0bb4..4506ec5 100644 (file)
@@ -86,7 +86,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
        unsigned oldflags;
        int status;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        status = ocfs2_inode_lock(inode, &bh, 1);
        if (status < 0) {
@@ -135,7 +135,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
 bail_unlock:
        ocfs2_inode_unlock(inode, 1);
 bail:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        brelse(bh);
 
@@ -287,7 +287,7 @@ static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb,
        struct ocfs2_dinode *dinode_alloc = NULL;
 
        if (inode_alloc)
-               mutex_lock(&inode_alloc->i_mutex);
+               inode_lock(inode_alloc);
 
        if (o2info_coherent(&fi->ifi_req)) {
                status = ocfs2_inode_lock(inode_alloc, &bh, 0);
@@ -317,7 +317,7 @@ bail:
                ocfs2_inode_unlock(inode_alloc, 0);
 
        if (inode_alloc)
-               mutex_unlock(&inode_alloc->i_mutex);
+               inode_unlock(inode_alloc);
 
        brelse(bh);
 
@@ -547,7 +547,7 @@ static int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
        struct ocfs2_dinode *gb_dinode = NULL;
 
        if (gb_inode)
-               mutex_lock(&gb_inode->i_mutex);
+               inode_lock(gb_inode);
 
        if (o2info_coherent(&ffg->iff_req)) {
                status = ocfs2_inode_lock(gb_inode, &bh, 0);
@@ -604,7 +604,7 @@ bail:
                ocfs2_inode_unlock(gb_inode, 0);
 
        if (gb_inode)
-               mutex_unlock(&gb_inode->i_mutex);
+               inode_unlock(gb_inode);
 
        iput(gb_inode);
        brelse(bh);
index 3772a2d..61b833b 100644 (file)
@@ -2088,7 +2088,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
                return status;
        }
 
-       mutex_lock(&orphan_dir_inode->i_mutex);
+       inode_lock(orphan_dir_inode);
        status = ocfs2_inode_lock(orphan_dir_inode, NULL, 0);
        if (status < 0) {
                mlog_errno(status);
@@ -2106,7 +2106,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
 out_cluster:
        ocfs2_inode_unlock(orphan_dir_inode, 0);
 out:
-       mutex_unlock(&orphan_dir_inode->i_mutex);
+       inode_unlock(orphan_dir_inode);
        iput(orphan_dir_inode);
        return status;
 }
@@ -2196,7 +2196,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
                oi->ip_next_orphan = NULL;
 
                if (oi->ip_flags & OCFS2_INODE_DIO_ORPHAN_ENTRY) {
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
                        ret = ocfs2_rw_lock(inode, 1);
                        if (ret < 0) {
                                mlog_errno(ret);
@@ -2235,7 +2235,7 @@ unlock_inode:
 unlock_rw:
                        ocfs2_rw_unlock(inode, 1);
 unlock_mutex:
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
 
                        /* clear dio flag in ocfs2_inode_info */
                        oi->ip_flags &= ~OCFS2_INODE_DIO_ORPHAN_ENTRY;
index e9c99e3..7d62c43 100644 (file)
@@ -414,7 +414,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
                goto out;
        }
 
-       mutex_lock(&main_bm_inode->i_mutex);
+       inode_lock(main_bm_inode);
 
        status = ocfs2_inode_lock(main_bm_inode, &main_bm_bh, 1);
        if (status < 0) {
@@ -468,7 +468,7 @@ out_unlock:
        ocfs2_inode_unlock(main_bm_inode, 1);
 
 out_mutex:
-       mutex_unlock(&main_bm_inode->i_mutex);
+       inode_unlock(main_bm_inode);
        iput(main_bm_inode);
 
 out:
@@ -506,7 +506,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
                goto bail;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        status = ocfs2_read_inode_block_full(inode, &alloc_bh,
                                             OCFS2_BH_IGNORE_CACHE);
@@ -539,7 +539,7 @@ bail:
        brelse(alloc_bh);
 
        if (inode) {
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                iput(inode);
        }
 
@@ -571,7 +571,7 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb,
                goto out;
        }
 
-       mutex_lock(&main_bm_inode->i_mutex);
+       inode_lock(main_bm_inode);
 
        status = ocfs2_inode_lock(main_bm_inode, &main_bm_bh, 1);
        if (status < 0) {
@@ -601,7 +601,7 @@ out_unlock:
        ocfs2_inode_unlock(main_bm_inode, 1);
 
 out_mutex:
-       mutex_unlock(&main_bm_inode->i_mutex);
+       inode_unlock(main_bm_inode);
 
        brelse(main_bm_bh);
 
@@ -643,7 +643,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
                goto bail;
        }
 
-       mutex_lock(&local_alloc_inode->i_mutex);
+       inode_lock(local_alloc_inode);
 
        /*
         * We must double check state and allocator bits because
@@ -709,7 +709,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
        status = 0;
 bail:
        if (status < 0 && local_alloc_inode) {
-               mutex_unlock(&local_alloc_inode->i_mutex);
+               inode_unlock(local_alloc_inode);
                iput(local_alloc_inode);
        }
 
index 124471d..e3d05d9 100644 (file)
@@ -276,7 +276,7 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
         *      context->data_ac->ac_resv = &OCFS2_I(inode)->ip_la_data_resv;
         */
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
 
        if (ocfs2_truncate_log_needs_flush(osb)) {
                ret = __ocfs2_flush_truncate_log(osb);
@@ -338,7 +338,7 @@ out_commit:
        ocfs2_commit_trans(osb, handle);
 
 out_unlock_mutex:
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        if (context->data_ac) {
                ocfs2_free_alloc_context(context->data_ac);
@@ -632,7 +632,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
                goto out;
        }
 
-       mutex_lock(&gb_inode->i_mutex);
+       inode_lock(gb_inode);
 
        ret = ocfs2_inode_lock(gb_inode, &gb_bh, 1);
        if (ret) {
@@ -640,7 +640,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
                goto out_unlock_gb_mutex;
        }
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
 
        handle = ocfs2_start_trans(osb, credits);
        if (IS_ERR(handle)) {
@@ -708,11 +708,11 @@ out_commit:
        brelse(gd_bh);
 
 out_unlock_tl_inode:
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        ocfs2_inode_unlock(gb_inode, 1);
 out_unlock_gb_mutex:
-       mutex_unlock(&gb_inode->i_mutex);
+       inode_unlock(gb_inode);
        brelse(gb_bh);
        iput(gb_inode);
 
@@ -905,7 +905,7 @@ static int ocfs2_move_extents(struct ocfs2_move_extents_context *context)
        if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
                return -EROFS;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /*
         * This prevents concurrent writes from other nodes
@@ -969,7 +969,7 @@ out_inode_unlock:
 out_rw_unlock:
        ocfs2_rw_unlock(inode, 1);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return status;
 }
index ab42c38..6b3e871 100644 (file)
@@ -1045,7 +1045,7 @@ leave:
        if (orphan_dir) {
                /* This was locked for us in ocfs2_prepare_orphan_dir() */
                ocfs2_inode_unlock(orphan_dir, 1);
-               mutex_unlock(&orphan_dir->i_mutex);
+               inode_unlock(orphan_dir);
                iput(orphan_dir);
        }
 
@@ -1664,7 +1664,7 @@ bail:
        if (orphan_dir) {
                /* This was locked for us in ocfs2_prepare_orphan_dir() */
                ocfs2_inode_unlock(orphan_dir, 1);
-               mutex_unlock(&orphan_dir->i_mutex);
+               inode_unlock(orphan_dir);
                iput(orphan_dir);
        }
 
@@ -2121,11 +2121,11 @@ static int ocfs2_lookup_lock_orphan_dir(struct ocfs2_super *osb,
                return ret;
        }
 
-       mutex_lock(&orphan_dir_inode->i_mutex);
+       inode_lock(orphan_dir_inode);
 
        ret = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
        if (ret < 0) {
-               mutex_unlock(&orphan_dir_inode->i_mutex);
+               inode_unlock(orphan_dir_inode);
                iput(orphan_dir_inode);
 
                mlog_errno(ret);
@@ -2226,7 +2226,7 @@ out:
 
        if (ret) {
                ocfs2_inode_unlock(orphan_dir_inode, 1);
-               mutex_unlock(&orphan_dir_inode->i_mutex);
+               inode_unlock(orphan_dir_inode);
                iput(orphan_dir_inode);
        }
 
@@ -2495,7 +2495,7 @@ out:
                        ocfs2_free_alloc_context(inode_ac);
 
                /* Unroll orphan dir locking */
-               mutex_unlock(&orphan_dir->i_mutex);
+               inode_unlock(orphan_dir);
                ocfs2_inode_unlock(orphan_dir, 1);
                iput(orphan_dir);
        }
@@ -2602,7 +2602,7 @@ leave:
        if (orphan_dir) {
                /* This was locked for us in ocfs2_prepare_orphan_dir() */
                ocfs2_inode_unlock(orphan_dir, 1);
-               mutex_unlock(&orphan_dir->i_mutex);
+               inode_unlock(orphan_dir);
                iput(orphan_dir);
        }
 
@@ -2689,7 +2689,7 @@ int ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
 
 bail_unlock_orphan:
        ocfs2_inode_unlock(orphan_dir_inode, 1);
-       mutex_unlock(&orphan_dir_inode->i_mutex);
+       inode_unlock(orphan_dir_inode);
        iput(orphan_dir_inode);
 
        ocfs2_free_dir_lookup_result(&orphan_insert);
@@ -2721,10 +2721,10 @@ int ocfs2_del_inode_from_orphan(struct ocfs2_super *osb,
                goto bail;
        }
 
-       mutex_lock(&orphan_dir_inode->i_mutex);
+       inode_lock(orphan_dir_inode);
        status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
        if (status < 0) {
-               mutex_unlock(&orphan_dir_inode->i_mutex);
+               inode_unlock(orphan_dir_inode);
                iput(orphan_dir_inode);
                mlog_errno(status);
                goto bail;
@@ -2770,7 +2770,7 @@ bail_commit:
 
 bail_unlock_orphan:
        ocfs2_inode_unlock(orphan_dir_inode, 1);
-       mutex_unlock(&orphan_dir_inode->i_mutex);
+       inode_unlock(orphan_dir_inode);
        brelse(orphan_dir_bh);
        iput(orphan_dir_inode);
 
@@ -2834,12 +2834,12 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
                goto leave;
        }
 
-       mutex_lock(&orphan_dir_inode->i_mutex);
+       inode_lock(orphan_dir_inode);
 
        status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
        if (status < 0) {
                mlog_errno(status);
-               mutex_unlock(&orphan_dir_inode->i_mutex);
+               inode_unlock(orphan_dir_inode);
                iput(orphan_dir_inode);
                goto leave;
        }
@@ -2901,7 +2901,7 @@ out_commit:
        ocfs2_commit_trans(osb, handle);
 orphan_unlock:
        ocfs2_inode_unlock(orphan_dir_inode, 1);
-       mutex_unlock(&orphan_dir_inode->i_mutex);
+       inode_unlock(orphan_dir_inode);
        iput(orphan_dir_inode);
 leave:
 
index fde9ef1..9c9dd30 100644 (file)
@@ -308,7 +308,7 @@ int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex)
                WARN_ON(bh != oinfo->dqi_gqi_bh);
        spin_unlock(&dq_data_lock);
        if (ex) {
-               mutex_lock(&oinfo->dqi_gqinode->i_mutex);
+               inode_lock(oinfo->dqi_gqinode);
                down_write(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
        } else {
                down_read(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
@@ -320,7 +320,7 @@ void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex)
 {
        if (ex) {
                up_write(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
-               mutex_unlock(&oinfo->dqi_gqinode->i_mutex);
+               inode_unlock(oinfo->dqi_gqinode);
        } else {
                up_read(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
        }
index 2521198..3eff031 100644 (file)
@@ -807,7 +807,7 @@ int ocfs2_remove_refcount_tree(struct inode *inode, struct buffer_head *di_bh)
                        mlog_errno(ret);
                        goto out;
                }
-               mutex_lock(&alloc_inode->i_mutex);
+               inode_lock(alloc_inode);
 
                ret = ocfs2_inode_lock(alloc_inode, &alloc_bh, 1);
                if (ret) {
@@ -867,7 +867,7 @@ out_unlock:
        }
 out_mutex:
        if (alloc_inode) {
-               mutex_unlock(&alloc_inode->i_mutex);
+               inode_unlock(alloc_inode);
                iput(alloc_inode);
        }
 out:
@@ -4197,7 +4197,7 @@ static int __ocfs2_reflink(struct dentry *old_dentry,
                goto out;
        }
 
-       mutex_lock_nested(&new_inode->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(new_inode, I_MUTEX_CHILD);
        ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1,
                                      OI_LS_REFLINK_TARGET);
        if (ret) {
@@ -4231,7 +4231,7 @@ inode_unlock:
        ocfs2_inode_unlock(new_inode, 1);
        brelse(new_bh);
 out_unlock:
-       mutex_unlock(&new_inode->i_mutex);
+       inode_unlock(new_inode);
 out:
        if (!ret) {
                ret = filemap_fdatawait(inode->i_mapping);
@@ -4402,11 +4402,11 @@ static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
                        return error;
        }
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        error = dquot_initialize(dir);
        if (!error)
                error = ocfs2_reflink(old_dentry, dir, new_dentry, preserve);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (!error)
                fsnotify_create(dir, new_dentry);
        return error;
index 79b8021..576b9a0 100644 (file)
@@ -301,7 +301,7 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters)
                goto out;
        }
 
-       mutex_lock(&main_bm_inode->i_mutex);
+       inode_lock(main_bm_inode);
 
        ret = ocfs2_inode_lock(main_bm_inode, &main_bm_bh, 1);
        if (ret < 0) {
@@ -375,7 +375,7 @@ out_unlock:
        ocfs2_inode_unlock(main_bm_inode, 1);
 
 out_mutex:
-       mutex_unlock(&main_bm_inode->i_mutex);
+       inode_unlock(main_bm_inode);
        iput(main_bm_inode);
 
 out:
@@ -486,7 +486,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
                goto out;
        }
 
-       mutex_lock(&main_bm_inode->i_mutex);
+       inode_lock(main_bm_inode);
 
        ret = ocfs2_inode_lock(main_bm_inode, &main_bm_bh, 1);
        if (ret < 0) {
@@ -590,7 +590,7 @@ out_unlock:
        ocfs2_inode_unlock(main_bm_inode, 1);
 
 out_mutex:
-       mutex_unlock(&main_bm_inode->i_mutex);
+       inode_unlock(main_bm_inode);
        iput(main_bm_inode);
 
 out:
index fc6d25f..2f19aee 100644 (file)
@@ -141,7 +141,7 @@ void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac)
                if (ac->ac_which != OCFS2_AC_USE_LOCAL)
                        ocfs2_inode_unlock(inode, 1);
 
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
 
                iput(inode);
                ac->ac_inode = NULL;
@@ -797,11 +797,11 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
                return -EINVAL;
        }
 
-       mutex_lock(&alloc_inode->i_mutex);
+       inode_lock(alloc_inode);
 
        status = ocfs2_inode_lock(alloc_inode, &bh, 1);
        if (status < 0) {
-               mutex_unlock(&alloc_inode->i_mutex);
+               inode_unlock(alloc_inode);
                iput(alloc_inode);
 
                mlog_errno(status);
@@ -2875,10 +2875,10 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
                goto bail;
        }
 
-       mutex_lock(&inode_alloc_inode->i_mutex);
+       inode_lock(inode_alloc_inode);
        status = ocfs2_inode_lock(inode_alloc_inode, &alloc_bh, 0);
        if (status < 0) {
-               mutex_unlock(&inode_alloc_inode->i_mutex);
+               inode_unlock(inode_alloc_inode);
                iput(inode_alloc_inode);
                mlog(ML_ERROR, "lock on alloc inode on slot %u failed %d\n",
                     (u32)suballoc_slot, status);
@@ -2891,7 +2891,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
                mlog(ML_ERROR, "test suballoc bit failed %d\n", status);
 
        ocfs2_inode_unlock(inode_alloc_inode, 0);
-       mutex_unlock(&inode_alloc_inode->i_mutex);
+       inode_unlock(inode_alloc_inode);
 
        iput(inode_alloc_inode);
        brelse(alloc_bh);
index f0e241f..7d3d979 100644 (file)
@@ -2524,7 +2524,7 @@ static int ocfs2_xattr_free_block(struct inode *inode,
                mlog_errno(ret);
                goto out;
        }
-       mutex_lock(&xb_alloc_inode->i_mutex);
+       inode_lock(xb_alloc_inode);
 
        ret = ocfs2_inode_lock(xb_alloc_inode, &xb_alloc_bh, 1);
        if (ret < 0) {
@@ -2549,7 +2549,7 @@ out_unlock:
        ocfs2_inode_unlock(xb_alloc_inode, 1);
        brelse(xb_alloc_bh);
 out_mutex:
-       mutex_unlock(&xb_alloc_inode->i_mutex);
+       inode_unlock(xb_alloc_inode);
        iput(xb_alloc_inode);
 out:
        brelse(blk_bh);
@@ -3619,17 +3619,17 @@ int ocfs2_xattr_set(struct inode *inode,
                }
        }
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
 
        if (ocfs2_truncate_log_needs_flush(osb)) {
                ret = __ocfs2_flush_truncate_log(osb);
                if (ret < 0) {
-                       mutex_unlock(&tl_inode->i_mutex);
+                       inode_unlock(tl_inode);
                        mlog_errno(ret);
                        goto cleanup;
                }
        }
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis,
                                        &xbs, &ctxt, ref_meta, &credits);
@@ -5460,7 +5460,7 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
                return ret;
        }
 
-       mutex_lock(&tl_inode->i_mutex);
+       inode_lock(tl_inode);
 
        if (ocfs2_truncate_log_needs_flush(osb)) {
                ret = __ocfs2_flush_truncate_log(osb);
@@ -5504,7 +5504,7 @@ out_commit:
 out:
        ocfs2_schedule_truncate_log_flush(osb, 1);
 
-       mutex_unlock(&tl_inode->i_mutex);
+       inode_unlock(tl_inode);
 
        if (meta_ac)
                ocfs2_free_alloc_context(meta_ac);
index b25b154..55bdc75 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -58,10 +58,10 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
        if (ret)
                newattrs.ia_valid |= ret | ATTR_FORCE;
 
-       mutex_lock(&dentry->d_inode->i_mutex);
+       inode_lock(dentry->d_inode);
        /* Note any delegations or leases have already been broken: */
        ret = notify_change(dentry, &newattrs, NULL);
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       inode_unlock(dentry->d_inode);
        return ret;
 }
 
@@ -510,7 +510,7 @@ static int chmod_common(struct path *path, umode_t mode)
        if (error)
                return error;
 retry_deleg:
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        error = security_path_chmod(path, mode);
        if (error)
                goto out_unlock;
@@ -518,7 +518,7 @@ retry_deleg:
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
        error = notify_change(path->dentry, &newattrs, &delegated_inode);
 out_unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (delegated_inode) {
                error = break_deleg_wait(&delegated_inode);
                if (!error)
@@ -593,11 +593,11 @@ retry_deleg:
        if (!S_ISDIR(inode->i_mode))
                newattrs.ia_valid |=
                        ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        error = security_path_chown(path, uid, gid);
        if (!error)
                error = notify_change(path->dentry, &newattrs, &delegated_inode);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (delegated_inode) {
                error = break_deleg_wait(&delegated_inode);
                if (!error)
index 0a89834..d894e7c 100644 (file)
@@ -22,9 +22,9 @@
 
 int ovl_copy_xattr(struct dentry *old, struct dentry *new)
 {
-       ssize_t list_size, size;
-       char *buf, *name, *value;
-       int error;
+       ssize_t list_size, size, value_size = 0;
+       char *buf, *name, *value = NULL;
+       int uninitialized_var(error);
 
        if (!old->d_inode->i_op->getxattr ||
            !new->d_inode->i_op->getxattr)
@@ -41,29 +41,40 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
        if (!buf)
                return -ENOMEM;
 
-       error = -ENOMEM;
-       value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL);
-       if (!value)
-               goto out;
-
        list_size = vfs_listxattr(old, buf, list_size);
        if (list_size <= 0) {
                error = list_size;
-               goto out_free_value;
+               goto out;
        }
 
        for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
-               size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX);
-               if (size <= 0) {
+retry:
+               size = vfs_getxattr(old, name, value, value_size);
+               if (size == -ERANGE)
+                       size = vfs_getxattr(old, name, NULL, 0);
+
+               if (size < 0) {
                        error = size;
-                       goto out_free_value;
+                       break;
+               }
+
+               if (size > value_size) {
+                       void *new;
+
+                       new = krealloc(value, size, GFP_KERNEL);
+                       if (!new) {
+                               error = -ENOMEM;
+                               break;
+                       }
+                       value = new;
+                       value_size = size;
+                       goto retry;
                }
+
                error = vfs_setxattr(new, name, value, size, 0);
                if (error)
-                       goto out_free_value;
+                       break;
        }
-
-out_free_value:
        kfree(value);
 out:
        kfree(buf);
@@ -237,9 +248,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
        if (err)
                goto out_cleanup;
 
-       mutex_lock(&newdentry->d_inode->i_mutex);
+       inode_lock(newdentry->d_inode);
        err = ovl_set_attr(newdentry, stat);
-       mutex_unlock(&newdentry->d_inode->i_mutex);
+       inode_unlock(newdentry->d_inode);
        if (err)
                goto out_cleanup;
 
index 692ceda..ed95272 100644 (file)
@@ -167,7 +167,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
        struct dentry *newdentry;
        int err;
 
-       mutex_lock_nested(&udir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(udir, I_MUTEX_PARENT);
        newdentry = lookup_one_len(dentry->d_name.name, upperdir,
                                   dentry->d_name.len);
        err = PTR_ERR(newdentry);
@@ -185,7 +185,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
 out_dput:
        dput(newdentry);
 out_unlock:
-       mutex_unlock(&udir->i_mutex);
+       inode_unlock(udir);
        return err;
 }
 
@@ -258,9 +258,9 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
        if (err)
                goto out_cleanup;
 
-       mutex_lock(&opaquedir->d_inode->i_mutex);
+       inode_lock(opaquedir->d_inode);
        err = ovl_set_attr(opaquedir, &stat);
-       mutex_unlock(&opaquedir->d_inode->i_mutex);
+       inode_unlock(opaquedir->d_inode);
        if (err)
                goto out_cleanup;
 
@@ -599,7 +599,7 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir)
        struct dentry *upper = ovl_dentry_upper(dentry);
        int err;
 
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
        err = -ESTALE;
        if (upper->d_parent == upperdir) {
                /* Don't let d_delete() think it can reset d_inode */
@@ -619,7 +619,7 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir)
         * now.
         */
        d_drop(dentry);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
 
        return err;
 }
index 964a60f..49e2045 100644 (file)
@@ -42,6 +42,19 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
        int err;
        struct dentry *upperdentry;
 
+       /*
+        * Check for permissions before trying to copy-up.  This is redundant
+        * since it will be rechecked later by ->setattr() on upper dentry.  But
+        * without this, copy-up can be triggered by just about anybody.
+        *
+        * We don't initialize inode->size, which just means that
+        * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
+        * check for a swapfile (which this won't be anyway).
+        */
+       err = inode_change_ok(dentry->d_inode, attr);
+       if (err)
+               return err;
+
        err = ovl_want_write(dentry);
        if (err)
                goto out;
@@ -50,9 +63,9 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
        if (!err) {
                upperdentry = ovl_dentry_upper(dentry);
 
-               mutex_lock(&upperdentry->d_inode->i_mutex);
+               inode_lock(upperdentry->d_inode);
                err = notify_change(upperdentry, attr, NULL);
-               mutex_unlock(&upperdentry->d_inode->i_mutex);
+               inode_unlock(upperdentry->d_inode);
        }
        ovl_drop_write(dentry);
 out:
@@ -95,6 +108,29 @@ int ovl_permission(struct inode *inode, int mask)
 
        realdentry = ovl_entry_real(oe, &is_upper);
 
+       if (ovl_is_default_permissions(inode)) {
+               struct kstat stat;
+               struct path realpath = { .dentry = realdentry };
+
+               if (mask & MAY_NOT_BLOCK)
+                       return -ECHILD;
+
+               realpath.mnt = ovl_entry_mnt_real(oe, inode, is_upper);
+
+               err = vfs_getattr(&realpath, &stat);
+               if (err)
+                       return err;
+
+               if ((stat.mode ^ inode->i_mode) & S_IFMT)
+                       return -ESTALE;
+
+               inode->i_mode = stat.mode;
+               inode->i_uid = stat.uid;
+               inode->i_gid = stat.gid;
+
+               return generic_permission(inode, mask);
+       }
+
        /* Careful in RCU walk mode */
        realinode = ACCESS_ONCE(realdentry->d_inode);
        if (!realinode) {
index e17154a..99b4168 100644 (file)
@@ -142,7 +142,10 @@ struct dentry *ovl_dentry_upper(struct dentry *dentry);
 struct dentry *ovl_dentry_lower(struct dentry *dentry);
 struct dentry *ovl_dentry_real(struct dentry *dentry);
 struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper);
+struct vfsmount *ovl_entry_mnt_real(struct ovl_entry *oe, struct inode *inode,
+                                   bool is_upper);
 struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry);
+bool ovl_is_default_permissions(struct inode *inode);
 void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache);
 struct dentry *ovl_workdir(struct dentry *dentry);
 int ovl_want_write(struct dentry *dentry);
index 70e9af5..fdaf28f 100644 (file)
@@ -228,7 +228,7 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
                                dput(dentry);
                        }
                }
-               mutex_unlock(&dir->d_inode->i_mutex);
+               inode_unlock(dir->d_inode);
        }
        revert_creds(old_cred);
        put_cred(override_cred);
@@ -399,7 +399,7 @@ static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)
        loff_t res;
        struct ovl_dir_file *od = file->private_data;
 
-       mutex_lock(&file_inode(file)->i_mutex);
+       inode_lock(file_inode(file));
        if (!file->f_pos)
                ovl_dir_reset(file);
 
@@ -429,7 +429,7 @@ static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)
                res = offset;
        }
 out_unlock:
-       mutex_unlock(&file_inode(file)->i_mutex);
+       inode_unlock(file_inode(file));
 
        return res;
 }
@@ -454,10 +454,10 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
                        ovl_path_upper(dentry, &upperpath);
                        realfile = ovl_path_open(&upperpath, O_RDONLY);
                        smp_mb__before_spinlock();
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
                        if (!od->upperfile) {
                                if (IS_ERR(realfile)) {
-                                       mutex_unlock(&inode->i_mutex);
+                                       inode_unlock(inode);
                                        return PTR_ERR(realfile);
                                }
                                od->upperfile = realfile;
@@ -467,7 +467,7 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
                                        fput(realfile);
                                realfile = od->upperfile;
                        }
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                }
        }
 
@@ -479,9 +479,9 @@ static int ovl_dir_release(struct inode *inode, struct file *file)
        struct ovl_dir_file *od = file->private_data;
 
        if (od->cache) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                ovl_cache_put(od, file->f_path.dentry);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        fput(od->realfile);
        if (od->upperfile)
@@ -557,7 +557,7 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list)
 {
        struct ovl_cache_entry *p;
 
-       mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(upper->d_inode, I_MUTEX_CHILD);
        list_for_each_entry(p, list, l_node) {
                struct dentry *dentry;
 
@@ -571,8 +571,9 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list)
                               (int) PTR_ERR(dentry));
                        continue;
                }
-               ovl_cleanup(upper->d_inode, dentry);
+               if (dentry->d_inode)
+                       ovl_cleanup(upper->d_inode, dentry);
                dput(dentry);
        }
-       mutex_unlock(&upper->d_inode->i_mutex);
+       inode_unlock(upper->d_inode);
 }
index e38ee0f..8d826bd 100644 (file)
@@ -9,12 +9,14 @@
 
 #include <linux/fs.h>
 #include <linux/namei.h>
+#include <linux/pagemap.h>
 #include <linux/xattr.h>
 #include <linux/security.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/parser.h>
 #include <linux/module.h>
+#include <linux/pagemap.h>
 #include <linux/sched.h>
 #include <linux/statfs.h>
 #include <linux/seq_file.h>
@@ -24,12 +26,11 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
 MODULE_DESCRIPTION("Overlay filesystem");
 MODULE_LICENSE("GPL");
 
-#define OVERLAYFS_SUPER_MAGIC 0x794c7630
-
 struct ovl_config {
        char *lowerdir;
        char *upperdir;
        char *workdir;
+       bool default_permissions;
 };
 
 /* private information held for overlayfs's superblock */
@@ -154,6 +155,18 @@ struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper)
        return realdentry;
 }
 
+struct vfsmount *ovl_entry_mnt_real(struct ovl_entry *oe, struct inode *inode,
+                                   bool is_upper)
+{
+       if (is_upper) {
+               struct ovl_fs *ofs = inode->i_sb->s_fs_info;
+
+               return ofs->upper_mnt;
+       } else {
+               return oe->numlower ? oe->lowerstack[0].mnt : NULL;
+       }
+}
+
 struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
@@ -161,6 +174,13 @@ struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry)
        return oe->cache;
 }
 
+bool ovl_is_default_permissions(struct inode *inode)
+{
+       struct ovl_fs *ofs = inode->i_sb->s_fs_info;
+
+       return ofs->config.default_permissions;
+}
+
 void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
@@ -209,7 +229,7 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
 
-       WARN_ON(!mutex_is_locked(&upperdentry->d_parent->d_inode->i_mutex));
+       WARN_ON(!inode_is_locked(upperdentry->d_parent->d_inode));
        WARN_ON(oe->__upperdentry);
        BUG_ON(!upperdentry->d_inode);
        /*
@@ -224,7 +244,7 @@ void ovl_dentry_version_inc(struct dentry *dentry)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
 
-       WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+       WARN_ON(!inode_is_locked(dentry->d_inode));
        oe->version++;
 }
 
@@ -232,7 +252,7 @@ u64 ovl_dentry_version_get(struct dentry *dentry)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
 
-       WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+       WARN_ON(!inode_is_locked(dentry->d_inode));
        return oe->version;
 }
 
@@ -355,9 +375,9 @@ static inline struct dentry *ovl_lookup_real(struct dentry *dir,
 {
        struct dentry *dentry;
 
-       mutex_lock(&dir->d_inode->i_mutex);
+       inode_lock(dir->d_inode);
        dentry = lookup_one_len(name->name, dir, name->len);
-       mutex_unlock(&dir->d_inode->i_mutex);
+       inode_unlock(dir->d_inode);
 
        if (IS_ERR(dentry)) {
                if (PTR_ERR(dentry) == -ENOENT)
@@ -594,6 +614,8 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
                seq_show_option(m, "upperdir", ufs->config.upperdir);
                seq_show_option(m, "workdir", ufs->config.workdir);
        }
+       if (ufs->config.default_permissions)
+               seq_puts(m, ",default_permissions");
        return 0;
 }
 
@@ -618,6 +640,7 @@ enum {
        OPT_LOWERDIR,
        OPT_UPPERDIR,
        OPT_WORKDIR,
+       OPT_DEFAULT_PERMISSIONS,
        OPT_ERR,
 };
 
@@ -625,6 +648,7 @@ static const match_table_t ovl_tokens = {
        {OPT_LOWERDIR,                  "lowerdir=%s"},
        {OPT_UPPERDIR,                  "upperdir=%s"},
        {OPT_WORKDIR,                   "workdir=%s"},
+       {OPT_DEFAULT_PERMISSIONS,       "default_permissions"},
        {OPT_ERR,                       NULL}
 };
 
@@ -685,6 +709,10 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                                return -ENOMEM;
                        break;
 
+               case OPT_DEFAULT_PERMISSIONS:
+                       config->default_permissions = true;
+                       break;
+
                default:
                        pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
                        return -EINVAL;
@@ -716,7 +744,7 @@ static struct dentry *ovl_workdir_create(struct vfsmount *mnt,
        if (err)
                return ERR_PTR(err);
 
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
 retry:
        work = lookup_one_len(OVL_WORKDIR_NAME, dentry,
                              strlen(OVL_WORKDIR_NAME));
@@ -742,7 +770,7 @@ retry:
                        goto out_dput;
        }
 out_unlock:
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        mnt_drop_write(mnt);
 
        return work;
@@ -910,6 +938,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        sb->s_stack_depth = 0;
+       sb->s_maxbytes = MAX_LFS_FILESIZE;
        if (ufs->config.upperdir) {
                if (!ufs->config.workdir) {
                        pr_err("overlayfs: missing 'workdir'\n");
@@ -1053,6 +1082,9 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
        root_dentry->d_fsdata = oe;
 
+       ovl_copyattr(ovl_dentry_real(root_dentry)->d_inode,
+                    root_dentry->d_inode);
+
        sb->s_magic = OVERLAYFS_SUPER_MAGIC;
        sb->s_op = &ovl_super_operations;
        sb->s_root = root_dentry;
index 42cf8dd..ab8dad3 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -38,6 +38,12 @@ unsigned int pipe_max_size = 1048576;
  */
 unsigned int pipe_min_size = PAGE_SIZE;
 
+/* Maximum allocatable pages per user. Hard limit is unset by default, soft
+ * matches default values.
+ */
+unsigned long pipe_user_pages_hard;
+unsigned long pipe_user_pages_soft = PIPE_DEF_BUFFERS * INR_OPEN_CUR;
+
 /*
  * We use a start+len construction, which provides full use of the 
  * allocated memory.
@@ -583,20 +589,49 @@ pipe_fasync(int fd, struct file *filp, int on)
        return retval;
 }
 
+static void account_pipe_buffers(struct pipe_inode_info *pipe,
+                                 unsigned long old, unsigned long new)
+{
+       atomic_long_add(new - old, &pipe->user->pipe_bufs);
+}
+
+static bool too_many_pipe_buffers_soft(struct user_struct *user)
+{
+       return pipe_user_pages_soft &&
+              atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_soft;
+}
+
+static bool too_many_pipe_buffers_hard(struct user_struct *user)
+{
+       return pipe_user_pages_hard &&
+              atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_hard;
+}
+
 struct pipe_inode_info *alloc_pipe_info(void)
 {
        struct pipe_inode_info *pipe;
 
        pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
        if (pipe) {
-               pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL);
+               unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
+               struct user_struct *user = get_current_user();
+
+               if (!too_many_pipe_buffers_hard(user)) {
+                       if (too_many_pipe_buffers_soft(user))
+                               pipe_bufs = 1;
+                       pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * pipe_bufs, GFP_KERNEL);
+               }
+
                if (pipe->bufs) {
                        init_waitqueue_head(&pipe->wait);
                        pipe->r_counter = pipe->w_counter = 1;
-                       pipe->buffers = PIPE_DEF_BUFFERS;
+                       pipe->buffers = pipe_bufs;
+                       pipe->user = user;
+                       account_pipe_buffers(pipe, 0, pipe_bufs);
                        mutex_init(&pipe->mutex);
                        return pipe;
                }
+               free_uid(user);
                kfree(pipe);
        }
 
@@ -607,6 +642,8 @@ void free_pipe_info(struct pipe_inode_info *pipe)
 {
        int i;
 
+       account_pipe_buffers(pipe, pipe->buffers, 0);
+       free_uid(pipe->user);
        for (i = 0; i < pipe->buffers; i++) {
                struct pipe_buffer *buf = pipe->bufs + i;
                if (buf->ops)
@@ -998,6 +1035,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
                        memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
        }
 
+       account_pipe_buffers(pipe, pipe->buffers, nr_pages);
        pipe->curbuf = 0;
        kfree(pipe->bufs);
        pipe->bufs = bufs;
@@ -1069,6 +1107,11 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
                if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
                        ret = -EPERM;
                        goto out;
+               } else if ((too_many_pipe_buffers_hard(pipe->user) ||
+                           too_many_pipe_buffers_soft(pipe->user)) &&
+                          !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+                       ret = -EPERM;
+                       goto out;
                }
                ret = pipe_set_size(pipe, nr_pages);
                break;
index d73291f..b6c00ce 100644 (file)
@@ -395,7 +395,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 
        state = *get_task_state(task);
        vsize = eip = esp = 0;
-       permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);
+       permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
        mm = get_task_mm(task);
        if (mm) {
                vsize = task_vsize(mm);
index 2cf5d7e..4f764c2 100644 (file)
@@ -403,7 +403,7 @@ static const struct file_operations proc_pid_cmdline_ops = {
 static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
                         struct pid *pid, struct task_struct *task)
 {
-       struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
+       struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
        if (mm && !IS_ERR(mm)) {
                unsigned int nwords = 0;
                do {
@@ -430,7 +430,8 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
 
        wchan = get_wchan(task);
 
-       if (wchan && ptrace_may_access(task, PTRACE_MODE_READ) && !lookup_symbol_name(wchan, symname))
+       if (wchan && ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)
+                       && !lookup_symbol_name(wchan, symname))
                seq_printf(m, "%s", symname);
        else
                seq_putc(m, '0');
@@ -444,7 +445,7 @@ static int lock_trace(struct task_struct *task)
        int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
        if (err)
                return err;
-       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
                mutex_unlock(&task->signal->cred_guard_mutex);
                return -EPERM;
        }
@@ -697,7 +698,7 @@ static int proc_fd_access_allowed(struct inode *inode)
         */
        task = get_proc_task(inode);
        if (task) {
-               allowed = ptrace_may_access(task, PTRACE_MODE_READ);
+               allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
                put_task_struct(task);
        }
        return allowed;
@@ -732,7 +733,7 @@ static bool has_pid_permissions(struct pid_namespace *pid,
                return true;
        if (in_group_p(pid->pid_gid))
                return true;
-       return ptrace_may_access(task, PTRACE_MODE_READ);
+       return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
 }
 
 
@@ -809,7 +810,7 @@ struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
        struct mm_struct *mm = ERR_PTR(-ESRCH);
 
        if (task) {
-               mm = mm_access(task, mode);
+               mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
                put_task_struct(task);
 
                if (!IS_ERR_OR_NULL(mm)) {
@@ -952,6 +953,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
        unsigned long src = *ppos;
        int ret = 0;
        struct mm_struct *mm = file->private_data;
+       unsigned long env_start, env_end;
 
        if (!mm)
                return 0;
@@ -963,19 +965,25 @@ static ssize_t environ_read(struct file *file, char __user *buf,
        ret = 0;
        if (!atomic_inc_not_zero(&mm->mm_users))
                goto free;
+
+       down_read(&mm->mmap_sem);
+       env_start = mm->env_start;
+       env_end = mm->env_end;
+       up_read(&mm->mmap_sem);
+
        while (count > 0) {
                size_t this_len, max_len;
                int retval;
 
-               if (src >= (mm->env_end - mm->env_start))
+               if (src >= (env_end - env_start))
                        break;
 
-               this_len = mm->env_end - (mm->env_start + src);
+               this_len = env_end - (env_start + src);
 
                max_len = min_t(size_t, PAGE_SIZE, count);
                this_len = min(max_len, this_len);
 
-               retval = access_remote_vm(mm, (mm->env_start + src),
+               retval = access_remote_vm(mm, (env_start + src),
                        page, this_len, 0);
 
                if (retval <= 0) {
@@ -1860,7 +1868,7 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
        if (!task)
                goto out_notask;
 
-       mm = mm_access(task, PTRACE_MODE_READ);
+       mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
        if (IS_ERR_OR_NULL(mm))
                goto out;
 
@@ -2013,7 +2021,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
                goto out;
 
        result = -EACCES;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                goto out_put_task;
 
        result = -ENOENT;
@@ -2066,7 +2074,7 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
                goto out;
 
        ret = -EACCES;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
                goto out_put_task;
 
        ret = 0;
@@ -2533,7 +2541,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh
        if (result)
                return result;
 
-       if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                result = -EACCES;
                goto out_unlock;
        }
index 92e6726..a939f5e 100644 (file)
@@ -552,9 +552,9 @@ static int open_kcore(struct inode *inode, struct file *filp)
        if (kcore_need_update)
                kcore_update_ram();
        if (i_size_read(inode) != proc_root_kcore->size) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                i_size_write(inode, proc_root_kcore->size);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        return 0;
 }
index 1dece87..276f124 100644 (file)
@@ -46,7 +46,7 @@ static const char *proc_ns_get_link(struct dentry *dentry,
        if (!task)
                return error;
 
-       if (ptrace_may_access(task, PTRACE_MODE_READ)) {
+       if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                error = ns_get_path(&ns_path, task, ns_ops);
                if (!error)
                        nd_jump_link(&ns_path);
@@ -67,7 +67,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
        if (!task)
                return res;
 
-       if (ptrace_may_access(task, PTRACE_MODE_READ)) {
+       if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
                res = ns_get_name(name, sizeof(name), task, ns_ops);
                if (res >= 0)
                        res = readlink_copy(buffer, buflen, name);
index 67e8db4..b6a8d35 100644 (file)
@@ -50,7 +50,7 @@ int proc_setup_self(struct super_block *s)
        struct pid_namespace *ns = s->s_fs_info;
        struct dentry *self;
        
-       mutex_lock(&root_inode->i_mutex);
+       inode_lock(root_inode);
        self = d_alloc_name(s->s_root, "self");
        if (self) {
                struct inode *inode = new_inode_pseudo(s);
@@ -69,7 +69,7 @@ int proc_setup_self(struct super_block *s)
        } else {
                self = ERR_PTR(-ENOMEM);
        }
-       mutex_unlock(&root_inode->i_mutex);
+       inode_unlock(root_inode);
        if (IS_ERR(self)) {
                pr_err("proc_fill_super: can't allocate /proc/self\n");
                return PTR_ERR(self);
index 65a1b6c..85d16c6 100644 (file)
@@ -468,7 +468,7 @@ struct mem_size_stats {
 static void smaps_account(struct mem_size_stats *mss, struct page *page,
                bool compound, bool young, bool dirty)
 {
-       int i, nr = compound ? HPAGE_PMD_NR : 1;
+       int i, nr = compound ? 1 << compound_order(page) : 1;
        unsigned long size = nr * PAGE_SIZE;
 
        if (PageAnon(page))
@@ -602,7 +602,8 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
        pte_t *pte;
        spinlock_t *ptl;
 
-       if (pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                smaps_pmd_entry(pmd, addr, walk);
                spin_unlock(ptl);
                return 0;
@@ -913,7 +914,8 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
        spinlock_t *ptl;
        struct page *page;
 
-       if (pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                if (cp->type == CLEAR_REFS_SOFT_DIRTY) {
                        clear_soft_dirty_pmd(vma, addr, pmd);
                        goto out;
@@ -1187,7 +1189,8 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
        int err = 0;
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-       if (pmd_trans_huge_lock(pmdp, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmdp, vma);
+       if (ptl) {
                u64 flags = 0, frame = 0;
                pmd_t pmd = *pmdp;
 
@@ -1519,7 +1522,8 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
        pte_t *orig_pte;
        pte_t *pte;
 
-       if (pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                pte_t huge_pte = *(pte_t *)pmd;
                struct page *page;
 
index 9eacd59..e58a31e 100644 (file)
@@ -52,7 +52,7 @@ int proc_setup_thread_self(struct super_block *s)
        struct pid_namespace *ns = s->s_fs_info;
        struct dentry *thread_self;
 
-       mutex_lock(&root_inode->i_mutex);
+       inode_lock(root_inode);
        thread_self = d_alloc_name(s->s_root, "thread-self");
        if (thread_self) {
                struct inode *inode = new_inode_pseudo(s);
@@ -71,7 +71,7 @@ int proc_setup_thread_self(struct super_block *s)
        } else {
                thread_self = ERR_PTR(-ENOMEM);
        }
-       mutex_unlock(&root_inode->i_mutex);
+       inode_unlock(root_inode);
        if (IS_ERR(thread_self)) {
                pr_err("proc_fill_super: can't allocate /proc/thread_self\n");
                return PTR_ERR(thread_self);
index d8c439d..dc645b6 100644 (file)
@@ -377,7 +377,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,
                break;
        }
 
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
 
        dentry = d_alloc_name(root, name);
        if (!dentry)
@@ -397,12 +397,12 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,
        list_add(&private->list, &allpstore);
        spin_unlock_irqrestore(&allpstore_lock, flags);
 
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
 
        return 0;
 
 fail_lockedalloc:
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        kfree(private);
 fail_alloc:
        iput(inode);
index fbd70af..3c3b81b 100644 (file)
@@ -682,9 +682,9 @@ int dquot_quota_sync(struct super_block *sb, int type)
                        continue;
                if (!sb_has_quota_active(sb, cnt))
                        continue;
-               mutex_lock(&dqopt->files[cnt]->i_mutex);
+               inode_lock(dqopt->files[cnt]);
                truncate_inode_pages(&dqopt->files[cnt]->i_data, 0);
-               mutex_unlock(&dqopt->files[cnt]->i_mutex);
+               inode_unlock(dqopt->files[cnt]);
        }
        mutex_unlock(&dqopt->dqonoff_mutex);
 
@@ -2162,12 +2162,12 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
                        /* If quota was reenabled in the meantime, we have
                         * nothing to do */
                        if (!sb_has_quota_loaded(sb, cnt)) {
-                               mutex_lock(&toputinode[cnt]->i_mutex);
+                               inode_lock(toputinode[cnt]);
                                toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
                                  S_NOATIME | S_NOQUOTA);
                                truncate_inode_pages(&toputinode[cnt]->i_data,
                                                     0);
-                               mutex_unlock(&toputinode[cnt]->i_mutex);
+                               inode_unlock(toputinode[cnt]);
                                mark_inode_dirty_sync(toputinode[cnt]);
                        }
                        mutex_unlock(&dqopt->dqonoff_mutex);
@@ -2258,11 +2258,11 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
                /* We don't want quota and atime on quota files (deadlocks
                 * possible) Also nobody should write to the file - we use
                 * special IO operations which ignore the immutable bit. */
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
                                             S_NOQUOTA);
                inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                /*
                 * When S_NOQUOTA is set, remove dquot references as no more
                 * references can be added
@@ -2305,12 +2305,12 @@ out_file_init:
        iput(inode);
 out_lock:
        if (oldflags != -1) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                /* Set the flags back (in the case of accidental quotaon()
                 * on a wrong file we don't want to mess up the flags) */
                inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);
                inode->i_flags |= oldflags;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        mutex_unlock(&dqopt->dqonoff_mutex);
 out_fmt:
@@ -2430,9 +2430,9 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
        struct dentry *dentry;
        int error;
 
-       mutex_lock(&d_inode(sb->s_root)->i_mutex);
+       inode_lock(d_inode(sb->s_root));
        dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
-       mutex_unlock(&d_inode(sb->s_root)->i_mutex);
+       inode_unlock(d_inode(sb->s_root));
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
 
index 06b07d5..324ec27 100644 (file)
@@ -238,7 +238,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int whence)
        struct inode *inode = file_inode(file);
        loff_t retval;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        switch (whence) {
                case SEEK_END:
                        offset += i_size_read(inode);
@@ -283,7 +283,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int whence)
                retval = offset;
        }
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return retval;
 }
 EXPORT_SYMBOL(default_llseek);
@@ -1656,6 +1656,9 @@ next_file:
                mnt_drop_write_file(dst_file);
 next_loop:
                fdput(dst_fd);
+
+               if (fatal_signal_pending(current))
+                       goto out;
        }
 
 out:
index ced6791..e69ef3b 100644 (file)
@@ -44,7 +44,7 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
                fsnotify_access(file);
                file_accessed(file);
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 out:
        return res;
 }
index 4a024e2..3abd400 100644 (file)
@@ -38,11 +38,11 @@ static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
        if (err)
                return err;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        reiserfs_write_lock(inode->i_sb);
        err = reiserfs_commit_for_inode(inode);
        reiserfs_write_unlock(inode->i_sb);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (err < 0)
                return err;
        return 0;
index 96a1bcf..9424a4b 100644 (file)
@@ -158,7 +158,7 @@ static int reiserfs_sync_file(struct file *filp, loff_t start, loff_t end,
        if (err)
                return err;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        BUG_ON(!S_ISREG(inode->i_mode));
        err = sync_mapping_buffers(inode->i_mapping);
        reiserfs_write_lock(inode->i_sb);
@@ -166,7 +166,7 @@ static int reiserfs_sync_file(struct file *filp, loff_t start, loff_t end,
        reiserfs_write_unlock(inode->i_sb);
        if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb))
                blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (barrier_done < 0)
                return barrier_done;
        return (err < 0) ? -EIO : 0;
index 6ec8a30..036a1fc 100644 (file)
@@ -224,7 +224,7 @@ out_unlock:
        page_cache_release(page);
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        reiserfs_write_unlock(inode->i_sb);
        return retval;
 }
index 05db747..c0306ec 100644 (file)
@@ -288,7 +288,7 @@ static int finish_unfinished(struct super_block *s)
                pathrelse(&path);
 
                inode = reiserfs_iget(s, &obj_key);
-               if (!inode) {
+               if (IS_ERR_OR_NULL(inode)) {
                        /*
                         * the unlink almost completed, it just did not
                         * manage to remove "save" link and release objectid
index e5ddb4e..57e0b23 100644 (file)
 #ifdef CONFIG_REISERFS_FS_XATTR
 static int xattr_create(struct inode *dir, struct dentry *dentry, int mode)
 {
-       BUG_ON(!mutex_is_locked(&dir->i_mutex));
+       BUG_ON(!inode_is_locked(dir));
        return dir->i_op->create(dir, dentry, mode, true);
 }
 #endif
 
 static int xattr_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
-       BUG_ON(!mutex_is_locked(&dir->i_mutex));
+       BUG_ON(!inode_is_locked(dir));
        return dir->i_op->mkdir(dir, dentry, mode);
 }
 
@@ -85,11 +85,11 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry)
 {
        int error;
 
-       BUG_ON(!mutex_is_locked(&dir->i_mutex));
+       BUG_ON(!inode_is_locked(dir));
 
-       mutex_lock_nested(&d_inode(dentry)->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
        error = dir->i_op->unlink(dir, dentry);
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
 
        if (!error)
                d_delete(dentry);
@@ -100,13 +100,13 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
 {
        int error;
 
-       BUG_ON(!mutex_is_locked(&dir->i_mutex));
+       BUG_ON(!inode_is_locked(dir));
 
-       mutex_lock_nested(&d_inode(dentry)->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
        error = dir->i_op->rmdir(dir, dentry);
        if (!error)
                d_inode(dentry)->i_flags |= S_DEAD;
-       mutex_unlock(&d_inode(dentry)->i_mutex);
+       inode_unlock(d_inode(dentry));
        if (!error)
                d_delete(dentry);
 
@@ -123,7 +123,7 @@ static struct dentry *open_xa_root(struct super_block *sb, int flags)
        if (d_really_is_negative(privroot))
                return ERR_PTR(-ENODATA);
 
-       mutex_lock_nested(&d_inode(privroot)->i_mutex, I_MUTEX_XATTR);
+       inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR);
 
        xaroot = dget(REISERFS_SB(sb)->xattr_root);
        if (!xaroot)
@@ -139,7 +139,7 @@ static struct dentry *open_xa_root(struct super_block *sb, int flags)
                }
        }
 
-       mutex_unlock(&d_inode(privroot)->i_mutex);
+       inode_unlock(d_inode(privroot));
        return xaroot;
 }
 
@@ -156,7 +156,7 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
                 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
                 inode->i_generation);
 
-       mutex_lock_nested(&d_inode(xaroot)->i_mutex, I_MUTEX_XATTR);
+       inode_lock_nested(d_inode(xaroot), I_MUTEX_XATTR);
 
        xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
        if (!IS_ERR(xadir) && d_really_is_negative(xadir)) {
@@ -170,7 +170,7 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
                }
        }
 
-       mutex_unlock(&d_inode(xaroot)->i_mutex);
+       inode_unlock(d_inode(xaroot));
        dput(xaroot);
        return xadir;
 }
@@ -195,7 +195,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
                container_of(ctx, struct reiserfs_dentry_buf, ctx);
        struct dentry *dentry;
 
-       WARN_ON_ONCE(!mutex_is_locked(&d_inode(dbuf->xadir)->i_mutex));
+       WARN_ON_ONCE(!inode_is_locked(d_inode(dbuf->xadir)));
 
        if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
                return -ENOSPC;
@@ -254,7 +254,7 @@ static int reiserfs_for_each_xattr(struct inode *inode,
                goto out_dir;
        }
 
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_XATTR);
+       inode_lock_nested(d_inode(dir), I_MUTEX_XATTR);
 
        buf.xadir = dir;
        while (1) {
@@ -276,7 +276,7 @@ static int reiserfs_for_each_xattr(struct inode *inode,
                        break;
                buf.count = 0;
        }
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 
        cleanup_dentry_buf(&buf);
 
@@ -298,13 +298,13 @@ static int reiserfs_for_each_xattr(struct inode *inode,
                if (!err) {
                        int jerror;
 
-                       mutex_lock_nested(&d_inode(dir->d_parent)->i_mutex,
+                       inode_lock_nested(d_inode(dir->d_parent),
                                          I_MUTEX_XATTR);
                        err = action(dir, data);
                        reiserfs_write_lock(inode->i_sb);
                        jerror = journal_end(&th);
                        reiserfs_write_unlock(inode->i_sb);
-                       mutex_unlock(&d_inode(dir->d_parent)->i_mutex);
+                       inode_unlock(d_inode(dir->d_parent));
                        err = jerror ?: err;
                }
        }
@@ -384,7 +384,7 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
        if (IS_ERR(xadir))
                return ERR_CAST(xadir);
 
-       mutex_lock_nested(&d_inode(xadir)->i_mutex, I_MUTEX_XATTR);
+       inode_lock_nested(d_inode(xadir), I_MUTEX_XATTR);
        xafile = lookup_one_len(name, xadir, strlen(name));
        if (IS_ERR(xafile)) {
                err = PTR_ERR(xafile);
@@ -404,7 +404,7 @@ static struct dentry *xattr_lookup(struct inode *inode, const char *name,
        if (err)
                dput(xafile);
 out:
-       mutex_unlock(&d_inode(xadir)->i_mutex);
+       inode_unlock(d_inode(xadir));
        dput(xadir);
        if (err)
                return ERR_PTR(err);
@@ -469,7 +469,7 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
        if (IS_ERR(xadir))
                return PTR_ERR(xadir);
 
-       mutex_lock_nested(&d_inode(xadir)->i_mutex, I_MUTEX_XATTR);
+       inode_lock_nested(d_inode(xadir), I_MUTEX_XATTR);
        dentry = lookup_one_len(name, xadir, strlen(name));
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
@@ -483,7 +483,7 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name)
 
        dput(dentry);
 out_dput:
-       mutex_unlock(&d_inode(xadir)->i_mutex);
+       inode_unlock(d_inode(xadir));
        dput(xadir);
        return err;
 }
@@ -580,11 +580,11 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
                        .ia_valid = ATTR_SIZE | ATTR_CTIME,
                };
 
-               mutex_lock_nested(&d_inode(dentry)->i_mutex, I_MUTEX_XATTR);
+               inode_lock_nested(d_inode(dentry), I_MUTEX_XATTR);
                inode_dio_wait(d_inode(dentry));
 
                err = reiserfs_setattr(dentry, &newattrs);
-               mutex_unlock(&d_inode(dentry)->i_mutex);
+               inode_unlock(d_inode(dentry));
        } else
                update_ctime(inode);
 out_unlock:
@@ -888,9 +888,9 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
                goto out;
        }
 
-       mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_XATTR);
+       inode_lock_nested(d_inode(dir), I_MUTEX_XATTR);
        err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx);
-       mutex_unlock(&d_inode(dir)->i_mutex);
+       inode_unlock(d_inode(dir));
 
        if (!err)
                err = buf.pos;
@@ -905,7 +905,7 @@ static int create_privroot(struct dentry *dentry)
        int err;
        struct inode *inode = d_inode(dentry->d_parent);
 
-       WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
+       WARN_ON_ONCE(!inode_is_locked(inode));
 
        err = xattr_mkdir(inode, dentry, 0700);
        if (err || d_really_is_negative(dentry)) {
@@ -995,7 +995,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
        int err = 0;
 
        /* If we don't have the privroot located yet - go find it */
-       mutex_lock(&d_inode(s->s_root)->i_mutex);
+       inode_lock(d_inode(s->s_root));
        dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
                                strlen(PRIVROOT_NAME));
        if (!IS_ERR(dentry)) {
@@ -1005,7 +1005,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
                        d_inode(dentry)->i_flags |= S_PRIVATE;
        } else
                err = PTR_ERR(dentry);
-       mutex_unlock(&d_inode(s->s_root)->i_mutex);
+       inode_unlock(d_inode(s->s_root));
 
        return err;
 }
@@ -1025,14 +1025,14 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
                goto error;
 
        if (d_really_is_negative(privroot) && !(mount_flags & MS_RDONLY)) {
-               mutex_lock(&d_inode(s->s_root)->i_mutex);
+               inode_lock(d_inode(s->s_root));
                err = create_privroot(REISERFS_SB(s)->priv_root);
-               mutex_unlock(&d_inode(s->s_root)->i_mutex);
+               inode_unlock(d_inode(s->s_root));
        }
 
        if (d_really_is_positive(privroot)) {
                s->s_xattr = reiserfs_xattr_handlers;
-               mutex_lock(&d_inode(privroot)->i_mutex);
+               inode_lock(d_inode(privroot));
                if (!REISERFS_SB(s)->xattr_root) {
                        struct dentry *dentry;
 
@@ -1043,7 +1043,7 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
                        else
                                err = PTR_ERR(dentry);
                }
-               mutex_unlock(&d_inode(privroot)->i_mutex);
+               inode_unlock(d_inode(privroot));
        }
 
 error:
index c66f242..4a0e48f 100644 (file)
@@ -84,9 +84,9 @@ static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umo
         * the files within the tracefs system. It is up to the individual
         * mkdir routine to handle races.
         */
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        ret = tracefs_ops.mkdir(name);
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        kfree(name);
 
@@ -109,13 +109,13 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
         * This time we need to unlock not only the parent (inode) but
         * also the directory that is being deleted.
         */
-       mutex_unlock(&inode->i_mutex);
-       mutex_unlock(&dentry->d_inode->i_mutex);
+       inode_unlock(inode);
+       inode_unlock(dentry->d_inode);
 
        ret = tracefs_ops.rmdir(name);
 
-       mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
-       mutex_lock(&dentry->d_inode->i_mutex);
+       inode_lock_nested(inode, I_MUTEX_PARENT);
+       inode_lock(dentry->d_inode);
 
        kfree(name);
 
@@ -334,7 +334,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
        if (!parent)
                parent = tracefs_mount->mnt_root;
 
-       mutex_lock(&parent->d_inode->i_mutex);
+       inode_lock(parent->d_inode);
        dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(dentry) && dentry->d_inode) {
                dput(dentry);
@@ -342,7 +342,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
        }
 
        if (IS_ERR(dentry)) {
-               mutex_unlock(&parent->d_inode->i_mutex);
+               inode_unlock(parent->d_inode);
                simple_release_fs(&tracefs_mount, &tracefs_mount_count);
        }
 
@@ -351,7 +351,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
 
 static struct dentry *failed_creating(struct dentry *dentry)
 {
-       mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
+       inode_unlock(dentry->d_parent->d_inode);
        dput(dentry);
        simple_release_fs(&tracefs_mount, &tracefs_mount_count);
        return NULL;
@@ -359,7 +359,7 @@ static struct dentry *failed_creating(struct dentry *dentry)
 
 static struct dentry *end_creating(struct dentry *dentry)
 {
-       mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
+       inode_unlock(dentry->d_parent->d_inode);
        return dentry;
 }
 
@@ -544,9 +544,9 @@ void tracefs_remove(struct dentry *dentry)
        if (!parent || !parent->d_inode)
                return;
 
-       mutex_lock(&parent->d_inode->i_mutex);
+       inode_lock(parent->d_inode);
        ret = __tracefs_remove(dentry, parent);
-       mutex_unlock(&parent->d_inode->i_mutex);
+       inode_unlock(parent->d_inode);
        if (!ret)
                simple_release_fs(&tracefs_mount, &tracefs_mount_count);
 }
@@ -572,7 +572,7 @@ void tracefs_remove_recursive(struct dentry *dentry)
 
        parent = dentry;
  down:
-       mutex_lock(&parent->d_inode->i_mutex);
+       inode_lock(parent->d_inode);
  loop:
        /*
         * The parent->d_subdirs is protected by the d_lock. Outside that
@@ -587,7 +587,7 @@ void tracefs_remove_recursive(struct dentry *dentry)
                /* perhaps simple_empty(child) makes more sense */
                if (!list_empty(&child->d_subdirs)) {
                        spin_unlock(&parent->d_lock);
-                       mutex_unlock(&parent->d_inode->i_mutex);
+                       inode_unlock(parent->d_inode);
                        parent = child;
                        goto down;
                }
@@ -608,10 +608,10 @@ void tracefs_remove_recursive(struct dentry *dentry)
        }
        spin_unlock(&parent->d_lock);
 
-       mutex_unlock(&parent->d_inode->i_mutex);
+       inode_unlock(parent->d_inode);
        child = parent;
        parent = parent->d_parent;
-       mutex_lock(&parent->d_inode->i_mutex);
+       inode_lock(parent->d_inode);
 
        if (child != dentry)
                /* go up */
@@ -619,7 +619,7 @@ void tracefs_remove_recursive(struct dentry *dentry)
 
        if (!__tracefs_remove(child, parent))
                simple_release_fs(&tracefs_mount, &tracefs_mount_count);
-       mutex_unlock(&parent->d_inode->i_mutex);
+       inode_unlock(parent->d_inode);
 }
 
 /**
index e49bd28..795992a 100644 (file)
@@ -515,8 +515,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
        dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu",
                dentry, inode->i_ino,
                inode->i_nlink, dir->i_ino);
-       ubifs_assert(mutex_is_locked(&dir->i_mutex));
-       ubifs_assert(mutex_is_locked(&inode->i_mutex));
+       ubifs_assert(inode_is_locked(dir));
+       ubifs_assert(inode_is_locked(inode));
 
        err = dbg_check_synced_i_size(c, inode);
        if (err)
@@ -572,8 +572,8 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
        dbg_gen("dent '%pd' from ino %lu (nlink %d) in dir ino %lu",
                dentry, inode->i_ino,
                inode->i_nlink, dir->i_ino);
-       ubifs_assert(mutex_is_locked(&dir->i_mutex));
-       ubifs_assert(mutex_is_locked(&inode->i_mutex));
+       ubifs_assert(inode_is_locked(dir));
+       ubifs_assert(inode_is_locked(inode));
        err = dbg_check_synced_i_size(c, inode);
        if (err)
                return err;
@@ -661,8 +661,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
 
        dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry,
                inode->i_ino, dir->i_ino);
-       ubifs_assert(mutex_is_locked(&dir->i_mutex));
-       ubifs_assert(mutex_is_locked(&inode->i_mutex));
+       ubifs_assert(inode_is_locked(dir));
+       ubifs_assert(inode_is_locked(inode));
        err = check_dir_empty(c, d_inode(dentry));
        if (err)
                return err;
@@ -996,10 +996,10 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
        dbg_gen("dent '%pd' ino %lu in dir ino %lu to dent '%pd' in dir ino %lu",
                old_dentry, old_inode->i_ino, old_dir->i_ino,
                new_dentry, new_dir->i_ino);
-       ubifs_assert(mutex_is_locked(&old_dir->i_mutex));
-       ubifs_assert(mutex_is_locked(&new_dir->i_mutex));
+       ubifs_assert(inode_is_locked(old_dir));
+       ubifs_assert(inode_is_locked(new_dir));
        if (unlink)
-               ubifs_assert(mutex_is_locked(&new_inode->i_mutex));
+               ubifs_assert(inode_is_locked(new_inode));
 
 
        if (unlink && is_dir) {
index eff6280..065c88f 100644 (file)
@@ -1317,7 +1317,7 @@ int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        err = filemap_write_and_wait_range(inode->i_mapping, start, end);
        if (err)
                return err;
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        /* Synchronize the inode unless this is a 'datasync()' call. */
        if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) {
@@ -1332,7 +1332,7 @@ int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
         */
        err = ubifs_sync_wbufs_by_inode(c, inode);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err;
 }
 
index e53292d..c7f4d43 100644 (file)
@@ -313,7 +313,7 @@ static int setxattr(struct inode *host, const char *name, const void *value,
        union ubifs_key key;
        int err, type;
 
-       ubifs_assert(mutex_is_locked(&host->i_mutex));
+       ubifs_assert(inode_is_locked(host));
 
        if (size > UBIFS_MAX_INO_DATA)
                return -ERANGE;
@@ -550,7 +550,7 @@ int ubifs_removexattr(struct dentry *dentry, const char *name)
 
        dbg_gen("xattr '%s', ino %lu ('%pd')", name,
                host->i_ino, dentry);
-       ubifs_assert(mutex_is_locked(&host->i_mutex));
+       ubifs_assert(inode_is_locked(host));
 
        err = check_namespace(&nm);
        if (err < 0)
index bddf3d0..1af9896 100644 (file)
@@ -122,7 +122,7 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        struct udf_inode_info *iinfo = UDF_I(inode);
        int err;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        retval = generic_write_checks(iocb, from);
        if (retval <= 0)
@@ -136,7 +136,7 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
                                (udf_file_entry_alloc_offset(inode) + end)) {
                        err = udf_expand_file_adinicb(inode);
                        if (err) {
-                               mutex_unlock(&inode->i_mutex);
+                               inode_unlock(inode);
                                udf_debug("udf_expand_adinicb: err=%d\n", err);
                                return err;
                        }
@@ -149,7 +149,7 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 
        retval = __generic_file_write_iter(iocb, from);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (retval > 0) {
                mark_inode_dirty(inode);
@@ -223,12 +223,12 @@ static int udf_release_file(struct inode *inode, struct file *filp)
                 * Grab i_mutex to avoid races with writes changing i_size
                 * while we are running.
                 */
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                down_write(&UDF_I(inode)->i_data_sem);
                udf_discard_prealloc(inode);
                udf_truncate_tail_extent(inode);
                up_write(&UDF_I(inode)->i_data_sem);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        return 0;
 }
index 87dc16d..166d3ed 100644 (file)
@@ -262,7 +262,7 @@ int udf_expand_file_adinicb(struct inode *inode)
                .nr_to_write = 1,
        };
 
-       WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
+       WARN_ON_ONCE(!inode_is_locked(inode));
        if (!iinfo->i_lenAlloc) {
                if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
                        iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
index 0fbb4c7..a522c15 100644 (file)
@@ -279,17 +279,12 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
 {
        int i;
        int nr_groups = bitmap->s_nr_groups;
-       int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) *
-                                               nr_groups);
 
        for (i = 0; i < nr_groups; i++)
                if (bitmap->s_block_bitmap[i])
                        brelse(bitmap->s_block_bitmap[i]);
 
-       if (size <= PAGE_SIZE)
-               kfree(bitmap);
-       else
-               vfree(bitmap);
+       kvfree(bitmap);
 }
 
 static void udf_free_partition(struct udf_part_map *map)
index aa138d6..85c40f4 100644 (file)
@@ -103,9 +103,9 @@ static int utimes_common(struct path *path, struct timespec *times)
                }
        }
 retry_deleg:
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        error = notify_change(path->dentry, &newattrs, &delegated_inode);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (delegated_inode) {
                error = break_deleg_wait(&delegated_inode);
                if (!error)
index d5dd6c8..07d0e47 100644 (file)
@@ -129,7 +129,7 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
        if (error)
                return error;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        error = security_inode_setxattr(dentry, name, value, size, flags);
        if (error)
                goto out;
@@ -137,7 +137,7 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
        error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return error;
 }
 EXPORT_SYMBOL_GPL(vfs_setxattr);
@@ -277,7 +277,7 @@ vfs_removexattr(struct dentry *dentry, const char *name)
        if (error)
                return error;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        error = security_inode_removexattr(dentry, name);
        if (error)
                goto out;
@@ -290,7 +290,7 @@ vfs_removexattr(struct dentry *dentry, const char *name)
        }
 
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return error;
 }
 EXPORT_SYMBOL_GPL(vfs_removexattr);
index e2536bb..dc97eb2 100644 (file)
@@ -984,8 +984,6 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
 
 /*
  * Values for di_flags
- * There should be a one-to-one correspondence between these flags and the
- * XFS_XFLAG_s.
  */
 #define XFS_DIFLAG_REALTIME_BIT  0     /* file's blocks come from rt area */
 #define XFS_DIFLAG_PREALLOC_BIT  1     /* file space has been preallocated */
@@ -1025,6 +1023,15 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
         XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
         XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM)
 
+/*
+ * Values for di_flags2 These start by being exposed to userspace in the upper
+ * 16 bits of the XFS_XFLAG_s range.
+ */
+#define XFS_DIFLAG2_DAX_BIT    0       /* use DAX for this inode */
+#define XFS_DIFLAG2_DAX                (1 << XFS_DIFLAG2_DAX_BIT)
+
+#define XFS_DIFLAG2_ANY                (XFS_DIFLAG2_DAX)
+
 /*
  * Inode number format:
  * low inopblog bits - offset in block
index b2b73a9..fffe3d0 100644 (file)
@@ -35,40 +35,6 @@ struct dioattr {
 };
 #endif
 
-/*
- * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR.
- */
-#ifndef HAVE_FSXATTR
-struct fsxattr {
-       __u32           fsx_xflags;     /* xflags field value (get/set) */
-       __u32           fsx_extsize;    /* extsize field value (get/set)*/
-       __u32           fsx_nextents;   /* nextents field value (get)   */
-       __u32           fsx_projid;     /* project identifier (get/set) */
-       unsigned char   fsx_pad[12];
-};
-#endif
-
-/*
- * Flags for the bs_xflags/fsx_xflags field
- * There should be a one-to-one correspondence between these flags and the
- * XFS_DIFLAG_s.
- */
-#define XFS_XFLAG_REALTIME     0x00000001      /* data in realtime volume */
-#define XFS_XFLAG_PREALLOC     0x00000002      /* preallocated file extents */
-#define XFS_XFLAG_IMMUTABLE    0x00000008      /* file cannot be modified */
-#define XFS_XFLAG_APPEND       0x00000010      /* all writes append */
-#define XFS_XFLAG_SYNC         0x00000020      /* all writes synchronous */
-#define XFS_XFLAG_NOATIME      0x00000040      /* do not update access time */
-#define XFS_XFLAG_NODUMP       0x00000080      /* do not include in backups */
-#define XFS_XFLAG_RTINHERIT    0x00000100      /* create with rt bit set */
-#define XFS_XFLAG_PROJINHERIT  0x00000200      /* create with parents projid */
-#define XFS_XFLAG_NOSYMLINKS   0x00000400      /* disallow symlink creation */
-#define XFS_XFLAG_EXTSIZE      0x00000800      /* extent size allocator hint */
-#define XFS_XFLAG_EXTSZINHERIT 0x00001000      /* inherit inode extent size */
-#define XFS_XFLAG_NODEFRAG     0x00002000      /* do not defragment */
-#define XFS_XFLAG_FILESTREAM   0x00004000      /* use filestream allocator */
-#define XFS_XFLAG_HASATTR      0x80000000      /* no DIFLAG for this   */
-
 /*
  * Structure for XFS_IOC_GETBMAP.
  * On input, fill in bmv_offset and bmv_length of the first structure
@@ -514,8 +480,8 @@ typedef struct xfs_swapext
 #define XFS_IOC_ALLOCSP                _IOW ('X', 10, struct xfs_flock64)
 #define XFS_IOC_FREESP         _IOW ('X', 11, struct xfs_flock64)
 #define XFS_IOC_DIOINFO                _IOR ('X', 30, struct dioattr)
-#define XFS_IOC_FSGETXATTR     _IOR ('X', 31, struct fsxattr)
-#define XFS_IOC_FSSETXATTR     _IOW ('X', 32, struct fsxattr)
+#define XFS_IOC_FSGETXATTR     FS_IOC_FSGETXATTR
+#define XFS_IOC_FSSETXATTR     FS_IOC_FSSETXATTR
 #define XFS_IOC_ALLOCSP64      _IOW ('X', 36, struct xfs_flock64)
 #define XFS_IOC_FREESP64       _IOW ('X', 37, struct xfs_flock64)
 #define XFS_IOC_GETBMAP                _IOWR('X', 38, struct getbmap)
index daed4bf..435c7de 100644 (file)
@@ -1527,6 +1527,16 @@ xfs_wait_buftarg(
        LIST_HEAD(dispose);
        int loop = 0;
 
+       /*
+        * We need to flush the buffer workqueue to ensure that all IO
+        * completion processing is 100% done. Just waiting on buffer locks is
+        * not sufficient for async IO as the reference count held over IO is
+        * not released until after the buffer lock is dropped. Hence we need to
+        * ensure here that all reference counts have been dropped before we
+        * start walking the LRU list.
+        */
+       drain_workqueue(btp->bt_mount->m_buf_workqueue);
+
        /* loop until there is nothing left on the lru list. */
        while (list_lru_count(&btp->bt_lru)) {
                list_lru_walk(&btp->bt_lru, xfs_buftarg_wait_rele,
index ebe9b82..52883ac 100644 (file)
@@ -55,7 +55,7 @@ xfs_rw_ilock(
        int                     type)
 {
        if (type & XFS_IOLOCK_EXCL)
-               mutex_lock(&VFS_I(ip)->i_mutex);
+               inode_lock(VFS_I(ip));
        xfs_ilock(ip, type);
 }
 
@@ -66,7 +66,7 @@ xfs_rw_iunlock(
 {
        xfs_iunlock(ip, type);
        if (type & XFS_IOLOCK_EXCL)
-               mutex_unlock(&VFS_I(ip)->i_mutex);
+               inode_unlock(VFS_I(ip));
 }
 
 static inline void
@@ -76,7 +76,7 @@ xfs_rw_ilock_demote(
 {
        xfs_ilock_demote(ip, type);
        if (type & XFS_IOLOCK_EXCL)
-               mutex_unlock(&VFS_I(ip)->i_mutex);
+               inode_unlock(VFS_I(ip));
 }
 
 /*
@@ -1610,9 +1610,8 @@ xfs_filemap_pmd_fault(
 /*
  * pfn_mkwrite was originally inteneded to ensure we capture time stamp
  * updates on write faults. In reality, it's need to serialise against
- * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite()
- * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault
- * barrier in place.
+ * truncate similar to page_mkwrite. Hence we cycle the XFS_MMAPLOCK_SHARED
+ * to ensure we serialise the fault barrier in place.
  */
 static int
 xfs_filemap_pfn_mkwrite(
@@ -1635,6 +1634,8 @@ xfs_filemap_pfn_mkwrite(
        size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
        if (vmf->pgoff >= size)
                ret = VM_FAULT_SIGBUS;
+       else if (IS_DAX(inode))
+               ret = dax_pfn_mkwrite(vma, vmf);
        xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
        sb_end_pagefault(inode->i_sb);
        return ret;
index ae3758a..ceba1a8 100644 (file)
@@ -610,60 +610,69 @@ __xfs_iflock(
 
 STATIC uint
 _xfs_dic2xflags(
-       __uint16_t              di_flags)
+       __uint16_t              di_flags,
+       uint64_t                di_flags2,
+       bool                    has_attr)
 {
        uint                    flags = 0;
 
        if (di_flags & XFS_DIFLAG_ANY) {
                if (di_flags & XFS_DIFLAG_REALTIME)
-                       flags |= XFS_XFLAG_REALTIME;
+                       flags |= FS_XFLAG_REALTIME;
                if (di_flags & XFS_DIFLAG_PREALLOC)
-                       flags |= XFS_XFLAG_PREALLOC;
+                       flags |= FS_XFLAG_PREALLOC;
                if (di_flags & XFS_DIFLAG_IMMUTABLE)
-                       flags |= XFS_XFLAG_IMMUTABLE;
+                       flags |= FS_XFLAG_IMMUTABLE;
                if (di_flags & XFS_DIFLAG_APPEND)
-                       flags |= XFS_XFLAG_APPEND;
+                       flags |= FS_XFLAG_APPEND;
                if (di_flags & XFS_DIFLAG_SYNC)
-                       flags |= XFS_XFLAG_SYNC;
+                       flags |= FS_XFLAG_SYNC;
                if (di_flags & XFS_DIFLAG_NOATIME)
-                       flags |= XFS_XFLAG_NOATIME;
+                       flags |= FS_XFLAG_NOATIME;
                if (di_flags & XFS_DIFLAG_NODUMP)
-                       flags |= XFS_XFLAG_NODUMP;
+                       flags |= FS_XFLAG_NODUMP;
                if (di_flags & XFS_DIFLAG_RTINHERIT)
-                       flags |= XFS_XFLAG_RTINHERIT;
+                       flags |= FS_XFLAG_RTINHERIT;
                if (di_flags & XFS_DIFLAG_PROJINHERIT)
-                       flags |= XFS_XFLAG_PROJINHERIT;
+                       flags |= FS_XFLAG_PROJINHERIT;
                if (di_flags & XFS_DIFLAG_NOSYMLINKS)
-                       flags |= XFS_XFLAG_NOSYMLINKS;
+                       flags |= FS_XFLAG_NOSYMLINKS;
                if (di_flags & XFS_DIFLAG_EXTSIZE)
-                       flags |= XFS_XFLAG_EXTSIZE;
+                       flags |= FS_XFLAG_EXTSIZE;
                if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
-                       flags |= XFS_XFLAG_EXTSZINHERIT;
+                       flags |= FS_XFLAG_EXTSZINHERIT;
                if (di_flags & XFS_DIFLAG_NODEFRAG)
-                       flags |= XFS_XFLAG_NODEFRAG;
+                       flags |= FS_XFLAG_NODEFRAG;
                if (di_flags & XFS_DIFLAG_FILESTREAM)
-                       flags |= XFS_XFLAG_FILESTREAM;
+                       flags |= FS_XFLAG_FILESTREAM;
        }
 
+       if (di_flags2 & XFS_DIFLAG2_ANY) {
+               if (di_flags2 & XFS_DIFLAG2_DAX)
+                       flags |= FS_XFLAG_DAX;
+       }
+
+       if (has_attr)
+               flags |= FS_XFLAG_HASATTR;
+
        return flags;
 }
 
 uint
 xfs_ip2xflags(
-       xfs_inode_t             *ip)
+       struct xfs_inode        *ip)
 {
-       xfs_icdinode_t          *dic = &ip->i_d;
+       struct xfs_icdinode     *dic = &ip->i_d;
 
-       return _xfs_dic2xflags(dic->di_flags) |
-                               (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
+       return _xfs_dic2xflags(dic->di_flags, dic->di_flags2, XFS_IFORK_Q(ip));
 }
 
 uint
 xfs_dic2xflags(
-       xfs_dinode_t            *dip)
+       struct xfs_dinode       *dip)
 {
-       return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) |
-                               (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0);
+       return _xfs_dic2xflags(be16_to_cpu(dip->di_flags),
+                               be64_to_cpu(dip->di_flags2), XFS_DFORK_Q(dip));
 }
 
 /*
@@ -862,7 +871,8 @@ xfs_ialloc(
        case S_IFREG:
        case S_IFDIR:
                if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
-                       uint    di_flags = 0;
+                       uint64_t        di_flags2 = 0;
+                       uint            di_flags = 0;
 
                        if (S_ISDIR(mode)) {
                                if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
@@ -898,7 +908,11 @@ xfs_ialloc(
                                di_flags |= XFS_DIFLAG_NODEFRAG;
                        if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
                                di_flags |= XFS_DIFLAG_FILESTREAM;
+                       if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
+                               di_flags2 |= XFS_DIFLAG2_DAX;
+
                        ip->i_d.di_flags |= di_flags;
+                       ip->i_d.di_flags2 |= di_flags2;
                }
                /* FALLTHROUGH */
        case S_IFLNK:
index d42738d..478d04e 100644 (file)
@@ -859,25 +859,25 @@ xfs_merge_ioc_xflags(
        unsigned int    xflags = start;
 
        if (flags & FS_IMMUTABLE_FL)
-               xflags |= XFS_XFLAG_IMMUTABLE;
+               xflags |= FS_XFLAG_IMMUTABLE;
        else
-               xflags &= ~XFS_XFLAG_IMMUTABLE;
+               xflags &= ~FS_XFLAG_IMMUTABLE;
        if (flags & FS_APPEND_FL)
-               xflags |= XFS_XFLAG_APPEND;
+               xflags |= FS_XFLAG_APPEND;
        else
-               xflags &= ~XFS_XFLAG_APPEND;
+               xflags &= ~FS_XFLAG_APPEND;
        if (flags & FS_SYNC_FL)
-               xflags |= XFS_XFLAG_SYNC;
+               xflags |= FS_XFLAG_SYNC;
        else
-               xflags &= ~XFS_XFLAG_SYNC;
+               xflags &= ~FS_XFLAG_SYNC;
        if (flags & FS_NOATIME_FL)
-               xflags |= XFS_XFLAG_NOATIME;
+               xflags |= FS_XFLAG_NOATIME;
        else
-               xflags &= ~XFS_XFLAG_NOATIME;
+               xflags &= ~FS_XFLAG_NOATIME;
        if (flags & FS_NODUMP_FL)
-               xflags |= XFS_XFLAG_NODUMP;
+               xflags |= FS_XFLAG_NODUMP;
        else
-               xflags &= ~XFS_XFLAG_NODUMP;
+               xflags &= ~FS_XFLAG_NODUMP;
 
        return xflags;
 }
@@ -945,40 +945,51 @@ xfs_set_diflags(
        unsigned int            xflags)
 {
        unsigned int            di_flags;
+       uint64_t                di_flags2;
 
        /* can't set PREALLOC this way, just preserve it */
        di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
-       if (xflags & XFS_XFLAG_IMMUTABLE)
+       if (xflags & FS_XFLAG_IMMUTABLE)
                di_flags |= XFS_DIFLAG_IMMUTABLE;
-       if (xflags & XFS_XFLAG_APPEND)
+       if (xflags & FS_XFLAG_APPEND)
                di_flags |= XFS_DIFLAG_APPEND;
-       if (xflags & XFS_XFLAG_SYNC)
+       if (xflags & FS_XFLAG_SYNC)
                di_flags |= XFS_DIFLAG_SYNC;
-       if (xflags & XFS_XFLAG_NOATIME)
+       if (xflags & FS_XFLAG_NOATIME)
                di_flags |= XFS_DIFLAG_NOATIME;
-       if (xflags & XFS_XFLAG_NODUMP)
+       if (xflags & FS_XFLAG_NODUMP)
                di_flags |= XFS_DIFLAG_NODUMP;
-       if (xflags & XFS_XFLAG_NODEFRAG)
+       if (xflags & FS_XFLAG_NODEFRAG)
                di_flags |= XFS_DIFLAG_NODEFRAG;
-       if (xflags & XFS_XFLAG_FILESTREAM)
+       if (xflags & FS_XFLAG_FILESTREAM)
                di_flags |= XFS_DIFLAG_FILESTREAM;
        if (S_ISDIR(ip->i_d.di_mode)) {
-               if (xflags & XFS_XFLAG_RTINHERIT)
+               if (xflags & FS_XFLAG_RTINHERIT)
                        di_flags |= XFS_DIFLAG_RTINHERIT;
-               if (xflags & XFS_XFLAG_NOSYMLINKS)
+               if (xflags & FS_XFLAG_NOSYMLINKS)
                        di_flags |= XFS_DIFLAG_NOSYMLINKS;
-               if (xflags & XFS_XFLAG_EXTSZINHERIT)
+               if (xflags & FS_XFLAG_EXTSZINHERIT)
                        di_flags |= XFS_DIFLAG_EXTSZINHERIT;
-               if (xflags & XFS_XFLAG_PROJINHERIT)
+               if (xflags & FS_XFLAG_PROJINHERIT)
                        di_flags |= XFS_DIFLAG_PROJINHERIT;
        } else if (S_ISREG(ip->i_d.di_mode)) {
-               if (xflags & XFS_XFLAG_REALTIME)
+               if (xflags & FS_XFLAG_REALTIME)
                        di_flags |= XFS_DIFLAG_REALTIME;
-               if (xflags & XFS_XFLAG_EXTSIZE)
+               if (xflags & FS_XFLAG_EXTSIZE)
                        di_flags |= XFS_DIFLAG_EXTSIZE;
        }
-
        ip->i_d.di_flags = di_flags;
+
+       /* diflags2 only valid for v3 inodes. */
+       if (ip->i_d.di_version < 3)
+               return;
+
+       di_flags2 = 0;
+       if (xflags & FS_XFLAG_DAX)
+               di_flags2 |= XFS_DIFLAG2_DAX;
+
+       ip->i_d.di_flags2 = di_flags2;
+
 }
 
 STATIC void
@@ -988,22 +999,27 @@ xfs_diflags_to_linux(
        struct inode            *inode = VFS_I(ip);
        unsigned int            xflags = xfs_ip2xflags(ip);
 
-       if (xflags & XFS_XFLAG_IMMUTABLE)
+       if (xflags & FS_XFLAG_IMMUTABLE)
                inode->i_flags |= S_IMMUTABLE;
        else
                inode->i_flags &= ~S_IMMUTABLE;
-       if (xflags & XFS_XFLAG_APPEND)
+       if (xflags & FS_XFLAG_APPEND)
                inode->i_flags |= S_APPEND;
        else
                inode->i_flags &= ~S_APPEND;
-       if (xflags & XFS_XFLAG_SYNC)
+       if (xflags & FS_XFLAG_SYNC)
                inode->i_flags |= S_SYNC;
        else
                inode->i_flags &= ~S_SYNC;
-       if (xflags & XFS_XFLAG_NOATIME)
+       if (xflags & FS_XFLAG_NOATIME)
                inode->i_flags |= S_NOATIME;
        else
                inode->i_flags &= ~S_NOATIME;
+       if (xflags & FS_XFLAG_DAX)
+               inode->i_flags |= S_DAX;
+       else
+               inode->i_flags &= ~S_DAX;
+
 }
 
 static int
@@ -1016,11 +1032,11 @@ xfs_ioctl_setattr_xflags(
 
        /* Can't change realtime flag if any extents are allocated. */
        if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
-           XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & XFS_XFLAG_REALTIME))
+           XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
                return -EINVAL;
 
        /* If realtime flag is set then must have realtime device */
-       if (fa->fsx_xflags & XFS_XFLAG_REALTIME) {
+       if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
                if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
                    (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
                        return -EINVAL;
@@ -1031,7 +1047,7 @@ xfs_ioctl_setattr_xflags(
         * we have appropriate permission.
         */
        if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) ||
-            (fa->fsx_xflags & (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
+            (fa->fsx_xflags & (FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND))) &&
            !capable(CAP_LINUX_IMMUTABLE))
                return -EPERM;
 
@@ -1095,8 +1111,8 @@ out_cancel:
  * extent size hint validation is somewhat cumbersome. Rules are:
  *
  * 1. extent size hint is only valid for directories and regular files
- * 2. XFS_XFLAG_EXTSIZE is only valid for regular files
- * 3. XFS_XFLAG_EXTSZINHERIT is only valid for directories.
+ * 2. FS_XFLAG_EXTSIZE is only valid for regular files
+ * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
  * 4. can only be changed on regular files if no extents are allocated
  * 5. can be changed on directories at any time
  * 6. extsize hint of 0 turns off hints, clears inode flags.
@@ -1112,10 +1128,10 @@ xfs_ioctl_setattr_check_extsize(
 {
        struct xfs_mount        *mp = ip->i_mount;
 
-       if ((fa->fsx_xflags & XFS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode))
+       if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode))
                return -EINVAL;
 
-       if ((fa->fsx_xflags & XFS_XFLAG_EXTSZINHERIT) &&
+       if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
            !S_ISDIR(ip->i_d.di_mode))
                return -EINVAL;
 
@@ -1132,7 +1148,7 @@ xfs_ioctl_setattr_check_extsize(
                        return -EINVAL;
 
                if (XFS_IS_REALTIME_INODE(ip) ||
-                   (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
+                   (fa->fsx_xflags & FS_XFLAG_REALTIME)) {
                        size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
                } else {
                        size = mp->m_sb.sb_blocksize;
@@ -1143,7 +1159,7 @@ xfs_ioctl_setattr_check_extsize(
                if (fa->fsx_extsize % size)
                        return -EINVAL;
        } else
-               fa->fsx_xflags &= ~(XFS_XFLAG_EXTSIZE | XFS_XFLAG_EXTSZINHERIT);
+               fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
 
        return 0;
 }
@@ -1168,7 +1184,7 @@ xfs_ioctl_setattr_check_projid(
 
        if (xfs_get_projid(ip) != fa->fsx_projid)
                return -EINVAL;
-       if ((fa->fsx_xflags & XFS_XFLAG_PROJINHERIT) !=
+       if ((fa->fsx_xflags & FS_XFLAG_PROJINHERIT) !=
            (ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
                return -EINVAL;
 
index 06eafaf..76b71a1 100644 (file)
@@ -1205,8 +1205,8 @@ xfs_diflags_to_iflags(
                inode->i_flags |= S_SYNC;
        if (flags & XFS_DIFLAG_NOATIME)
                inode->i_flags |= S_NOATIME;
-       /* XXX: Also needs an on-disk per inode flag! */
-       if (ip->i_mount->m_flags & XFS_MOUNT_DAX)
+       if (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
+           ip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
                inode->i_flags |= S_DAX;
 }
 
index dc62219..ade236e 100644 (file)
@@ -42,11 +42,11 @@ xfs_break_layouts(
        while ((error = break_layout(inode, false) == -EWOULDBLOCK)) {
                xfs_iunlock(ip, *iolock);
                if (with_imutex && (*iolock & XFS_IOLOCK_EXCL))
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                error = break_layout(inode, true);
                *iolock = XFS_IOLOCK_EXCL;
                if (with_imutex)
-                       mutex_lock(&inode->i_mutex);
+                       inode_lock(inode);
                xfs_ilock(ip, *iolock);
        }
 
index aa67339..4f18fd9 100644 (file)
@@ -497,7 +497,6 @@ xfsaild(
        long            tout = 0;       /* milliseconds */
 
        current->flags |= PF_MEMALLOC;
-       set_freezable();
 
        while (!kthread_should_stop()) {
                if (tout && tout <= 20)
index fcf9080..cd20d55 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e11611c..fe2e3ac 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index cd84b12..2c39634 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b52c0dc..be779db 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 908d4f9..5bfc619 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b0bb30e..82803ae 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0d824a2..d1e34d1 100644 (file)
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 012b2ee..c96621e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20151218
+#define ACPI_CA_VERSION                 0x20160108
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
index ebe2426..cf2acb8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2d5faf5..0cb1a00 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1bb979e..16e0136 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6e28f54..a4ef625 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 1df8916..ddf5e66 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9633f60..db46546 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 80fe8cf..0f269e0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 056f245..7c0595b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2f296cb..4f15c1d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5457a06..c5a216c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e21857d..45c2d65 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f903fe6..f8bb0d8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b647974..28084a1 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6ed1d71..a00b3e4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f11d342..5ca2f2c 100644 (file)
@@ -32,6 +32,10 @@ extern int acpi_video_get_edid(struct acpi_device *device, int type,
                               int device_id, void **edid);
 extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
 extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
+/*
+ * Note: The value returned by acpi_video_handles_brightness_key_presses()
+ * may change over time and should not be cached.
+ */
 extern bool acpi_video_handles_brightness_key_presses(void);
 #else
 static inline int acpi_video_register(void) { return 0; }
index 8f4e319..163f779 100644 (file)
@@ -4,6 +4,9 @@
  * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
  * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
  *
+ * Optimization for constant divisors on 32-bit machines:
+ * Copyright (C) 2006-2015 Nicolas Pitre
+ *
  * The semantics of do_div() are:
  *
  * uint32_t do_div(uint64_t *n, uint32_t base)
 
 #elif BITS_PER_LONG == 32
 
+#include <linux/log2.h>
+
+/*
+ * If the divisor happens to be constant, we determine the appropriate
+ * inverse at compile time to turn the division into a few inline
+ * multiplications which ought to be much faster. And yet only if compiling
+ * with a sufficiently recent gcc version to perform proper 64-bit constant
+ * propagation.
+ *
+ * (It is unfortunate that gcc doesn't perform all this internally.)
+ */
+
+#ifndef __div64_const32_is_OK
+#define __div64_const32_is_OK (__GNUC__ >= 4)
+#endif
+
+#define __div64_const32(n, ___b)                                       \
+({                                                                     \
+       /*                                                              \
+        * Multiplication by reciprocal of b: n / b = n * (p / b) / p   \
+        *                                                              \
+        * We rely on the fact that most of this code gets optimized    \
+        * away at compile time due to constant propagation and only    \
+        * a few multiplication instructions should remain.             \
+        * Hence this monstrous macro (static inline doesn't always     \
+        * do the trick here).                                          \
+        */                                                             \
+       uint64_t ___res, ___x, ___t, ___m, ___n = (n);                  \
+       uint32_t ___p, ___bias;                                         \
+                                                                       \
+       /* determine MSB of b */                                        \
+       ___p = 1 << ilog2(___b);                                        \
+                                                                       \
+       /* compute m = ((p << 64) + b - 1) / b */                       \
+       ___m = (~0ULL / ___b) * ___p;                                   \
+       ___m += (((~0ULL % ___b + 1) * ___p) + ___b - 1) / ___b;        \
+                                                                       \
+       /* one less than the dividend with highest result */            \
+       ___x = ~0ULL / ___b * ___b - 1;                                 \
+                                                                       \
+       /* test our ___m with res = m * x / (p << 64) */                \
+       ___res = ((___m & 0xffffffff) * (___x & 0xffffffff)) >> 32;     \
+       ___t = ___res += (___m & 0xffffffff) * (___x >> 32);            \
+       ___res += (___x & 0xffffffff) * (___m >> 32);                   \
+       ___t = (___res < ___t) ? (1ULL << 32) : 0;                      \
+       ___res = (___res >> 32) + ___t;                                 \
+       ___res += (___m >> 32) * (___x >> 32);                          \
+       ___res /= ___p;                                                 \
+                                                                       \
+       /* Now sanitize and optimize what we've got. */                 \
+       if (~0ULL % (___b / (___b & -___b)) == 0) {                     \
+               /* special case, can be simplified to ... */            \
+               ___n /= (___b & -___b);                                 \
+               ___m = ~0ULL / (___b / (___b & -___b));                 \
+               ___p = 1;                                               \
+               ___bias = 1;                                            \
+       } else if (___res != ___x / ___b) {                             \
+               /*                                                      \
+                * We can't get away without a bias to compensate       \
+                * for bit truncation errors.  To avoid it we'd need an \
+                * additional bit to represent m which would overflow   \
+                * a 64-bit variable.                                   \
+                *                                                      \
+                * Instead we do m = p / b and n / b = (n * m + m) / p. \
+                */                                                     \
+               ___bias = 1;                                            \
+               /* Compute m = (p << 64) / b */                         \
+               ___m = (~0ULL / ___b) * ___p;                           \
+               ___m += ((~0ULL % ___b + 1) * ___p) / ___b;             \
+       } else {                                                        \
+               /*                                                      \
+                * Reduce m / p, and try to clear bit 31 of m when      \
+                * possible, otherwise that'll need extra overflow      \
+                * handling later.                                      \
+                */                                                     \
+               uint32_t ___bits = -(___m & -___m);                     \
+               ___bits |= ___m >> 32;                                  \
+               ___bits = (~___bits) << 1;                              \
+               /*                                                      \
+                * If ___bits == 0 then setting bit 31 is  unavoidable. \
+                * Simply apply the maximum possible reduction in that  \
+                * case. Otherwise the MSB of ___bits indicates the     \
+                * best reduction we should apply.                      \
+                */                                                     \
+               if (!___bits) {                                         \
+                       ___p /= (___m & -___m);                         \
+                       ___m /= (___m & -___m);                         \
+               } else {                                                \
+                       ___p >>= ilog2(___bits);                        \
+                       ___m >>= ilog2(___bits);                        \
+               }                                                       \
+               /* No bias needed. */                                   \
+               ___bias = 0;                                            \
+       }                                                               \
+                                                                       \
+       /*                                                              \
+        * Now we have a combination of 2 conditions:                   \
+        *                                                              \
+        * 1) whether or not we need to apply a bias, and               \
+        *                                                              \
+        * 2) whether or not there might be an overflow in the cross    \
+        *    product determined by (___m & ((1 << 63) | (1 << 31))).   \
+        *                                                              \
+        * Select the best way to do (m_bias + m * n) / (1 << 64).      \
+        * From now on there will be actual runtime code generated.     \
+        */                                                             \
+       ___res = __arch_xprod_64(___m, ___n, ___bias);                  \
+                                                                       \
+       ___res /= ___p;                                                 \
+})
+
+#ifndef __arch_xprod_64
+/*
+ * Default C implementation for __arch_xprod_64()
+ *
+ * Prototype: uint64_t __arch_xprod_64(const uint64_t m, uint64_t n, bool bias)
+ * Semantic:  retval = ((bias ? m : 0) + m * n) >> 64
+ *
+ * The product is a 128-bit value, scaled down to 64 bits.
+ * Assuming constant propagation to optimize away unused conditional code.
+ * Architectures may provide their own optimized assembly implementation.
+ */
+static inline uint64_t __arch_xprod_64(const uint64_t m, uint64_t n, bool bias)
+{
+       uint32_t m_lo = m;
+       uint32_t m_hi = m >> 32;
+       uint32_t n_lo = n;
+       uint32_t n_hi = n >> 32;
+       uint64_t res, tmp;
+
+       if (!bias) {
+               res = ((uint64_t)m_lo * n_lo) >> 32;
+       } else if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
+               /* there can't be any overflow here */
+               res = (m + (uint64_t)m_lo * n_lo) >> 32;
+       } else {
+               res = m + (uint64_t)m_lo * n_lo;
+               tmp = (res < m) ? (1ULL << 32) : 0;
+               res = (res >> 32) + tmp;
+       }
+
+       if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
+               /* there can't be any overflow here */
+               res += (uint64_t)m_lo * n_hi;
+               res += (uint64_t)m_hi * n_lo;
+               res >>= 32;
+       } else {
+               tmp = res += (uint64_t)m_lo * n_hi;
+               res += (uint64_t)m_hi * n_lo;
+               tmp = (res < tmp) ? (1ULL << 32) : 0;
+               res = (res >> 32) + tmp;
+       }
+
+       res += (uint64_t)m_hi * n_hi;
+
+       return res;
+}
+#endif
+
+#ifndef __div64_32
 extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
+#endif
 
 /* The unnecessary pointer compare is there
  * to check for type safety (n must be 64bit)
@@ -41,7 +205,19 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
        uint32_t __base = (base);                       \
        uint32_t __rem;                                 \
        (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
-       if (likely(((n) >> 32) == 0)) {                 \
+       if (__builtin_constant_p(__base) &&             \
+           is_power_of_2(__base)) {                    \
+               __rem = (n) & (__base - 1);             \
+               (n) >>= ilog2(__base);                  \
+       } else if (__div64_const32_is_OK &&             \
+                  __builtin_constant_p(__base) &&      \
+                  __base != 0) {                       \
+               uint32_t __res_lo, __n_lo = (n);        \
+               (n) = __div64_const32(n, __base);       \
+               /* the remainder can be computed with 32-bit regs */ \
+               __res_lo = (n);                         \
+               __rem = __n_lo - __res_lo * __base;     \
+       } else if (likely(((n) >> 32) == 0)) {          \
                __rem = (uint32_t)(n) % __base;         \
                (n) = (uint32_t)(n) / __base;           \
        } else                                          \
diff --git a/include/asm-generic/dma-coherent.h b/include/asm-generic/dma-coherent.h
deleted file mode 100644 (file)
index 0297e58..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef DMA_COHERENT_H
-#define DMA_COHERENT_H
-
-#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
-/*
- * These three functions are only for dma allocator.
- * Don't use them in device drivers.
- */
-int dma_alloc_from_coherent(struct device *dev, ssize_t size,
-                                      dma_addr_t *dma_handle, void **ret);
-int dma_release_from_coherent(struct device *dev, int order, void *vaddr);
-
-int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
-                           void *cpu_addr, size_t size, int *ret);
-/*
- * Standard interface
- */
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
-                               dma_addr_t device_addr, size_t size, int flags);
-
-void dma_release_declared_memory(struct device *dev);
-
-void *dma_mark_declared_memory_occupied(struct device *dev,
-                                       dma_addr_t device_addr, size_t size);
-#else
-#define dma_alloc_from_coherent(dev, size, handle, ret) (0)
-#define dma_release_from_coherent(dev, order, vaddr) (0)
-#define dma_mmap_from_coherent(dev, vma, vaddr, order, ret) (0)
-#endif
-
-#endif
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
deleted file mode 100644 (file)
index 6c32af9..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef _ASM_GENERIC_DMA_MAPPING_H
-#define _ASM_GENERIC_DMA_MAPPING_H
-
-/* define the dma api to allow compilation but not linking of
- * dma dependent code.  Code that depends on the dma-mapping
- * API needs to set 'depends on HAS_DMA' in its Kconfig
- */
-
-struct scatterlist;
-
-extern void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-                  gfp_t flag);
-
-extern void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-                   dma_addr_t dma_handle);
-
-static inline void *dma_alloc_attrs(struct device *dev, size_t size,
-                                   dma_addr_t *dma_handle, gfp_t flag,
-                                   struct dma_attrs *attrs)
-{
-       /* attrs is not supported and ignored */
-       return dma_alloc_coherent(dev, size, dma_handle, flag);
-}
-
-static inline void dma_free_attrs(struct device *dev, size_t size,
-                                 void *cpu_addr, dma_addr_t dma_handle,
-                                 struct dma_attrs *attrs)
-{
-       /* attrs is not supported and ignored */
-       dma_free_coherent(dev, size, cpu_addr, dma_handle);
-}
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-extern dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-              enum dma_data_direction direction);
-
-extern void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction);
-
-extern int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-          enum dma_data_direction direction);
-
-extern void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction);
-
-extern dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-            size_t size, enum dma_data_direction direction);
-
-extern void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction);
-
-extern void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-                       enum dma_data_direction direction);
-
-extern void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction);
-
-extern void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                   enum dma_data_direction direction);
-
-#define dma_sync_single_for_device dma_sync_single_for_cpu
-#define dma_sync_single_range_for_device dma_sync_single_range_for_cpu
-#define dma_sync_sg_for_device dma_sync_sg_for_cpu
-
-extern int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
-
-extern int
-dma_supported(struct device *dev, u64 mask);
-
-extern int
-dma_set_mask(struct device *dev, u64 mask);
-
-extern int
-dma_get_cache_alignment(void);
-
-extern void
-dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-              enum dma_data_direction direction);
-
-#endif /* _ASM_GENERIC_DMA_MAPPING_H */
diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h
deleted file mode 100644 (file)
index b1bc954..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-#ifndef _ASM_GENERIC_DMA_MAPPING_H
-#define _ASM_GENERIC_DMA_MAPPING_H
-
-#include <linux/kmemcheck.h>
-#include <linux/bug.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <linux/dma-attrs.h>
-#include <asm-generic/dma-coherent.h>
-
-static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
-                                             size_t size,
-                                             enum dma_data_direction dir,
-                                             struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-       dma_addr_t addr;
-
-       kmemcheck_mark_initialized(ptr, size);
-       BUG_ON(!valid_dma_direction(dir));
-       addr = ops->map_page(dev, virt_to_page(ptr),
-                            (unsigned long)ptr & ~PAGE_MASK, size,
-                            dir, attrs);
-       debug_dma_map_page(dev, virt_to_page(ptr),
-                          (unsigned long)ptr & ~PAGE_MASK, size,
-                          dir, addr, true);
-       return addr;
-}
-
-static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
-                                         size_t size,
-                                         enum dma_data_direction dir,
-                                         struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->unmap_page)
-               ops->unmap_page(dev, addr, size, dir, attrs);
-       debug_dma_unmap_page(dev, addr, size, dir, true);
-}
-
-/*
- * dma_maps_sg_attrs returns 0 on error and > 0 on success.
- * It should never return a value < 0.
- */
-static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
-                                  int nents, enum dma_data_direction dir,
-                                  struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-       int i, ents;
-       struct scatterlist *s;
-
-       for_each_sg(sg, s, nents, i)
-               kmemcheck_mark_initialized(sg_virt(s), s->length);
-       BUG_ON(!valid_dma_direction(dir));
-       ents = ops->map_sg(dev, sg, nents, dir, attrs);
-       BUG_ON(ents < 0);
-       debug_dma_map_sg(dev, sg, nents, ents, dir);
-
-       return ents;
-}
-
-static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
-                                     int nents, enum dma_data_direction dir,
-                                     struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       debug_dma_unmap_sg(dev, sg, nents, dir);
-       if (ops->unmap_sg)
-               ops->unmap_sg(dev, sg, nents, dir, attrs);
-}
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-                                     size_t offset, size_t size,
-                                     enum dma_data_direction dir)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-       dma_addr_t addr;
-
-       kmemcheck_mark_initialized(page_address(page) + offset, size);
-       BUG_ON(!valid_dma_direction(dir));
-       addr = ops->map_page(dev, page, offset, size, dir, NULL);
-       debug_dma_map_page(dev, page, offset, size, dir, addr, false);
-
-       return addr;
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
-                                 size_t size, enum dma_data_direction dir)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->unmap_page)
-               ops->unmap_page(dev, addr, size, dir, NULL);
-       debug_dma_unmap_page(dev, addr, size, dir, false);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
-                                          size_t size,
-                                          enum dma_data_direction dir)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->sync_single_for_cpu)
-               ops->sync_single_for_cpu(dev, addr, size, dir);
-       debug_dma_sync_single_for_cpu(dev, addr, size, dir);
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
-                                             dma_addr_t addr, size_t size,
-                                             enum dma_data_direction dir)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->sync_single_for_device)
-               ops->sync_single_for_device(dev, addr, size, dir);
-       debug_dma_sync_single_for_device(dev, addr, size, dir);
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
-                                                dma_addr_t addr,
-                                                unsigned long offset,
-                                                size_t size,
-                                                enum dma_data_direction dir)
-{
-       const struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->sync_single_for_cpu)
-               ops->sync_single_for_cpu(dev, addr + offset, size, dir);
-       debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir);
-}
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
-                                                   dma_addr_t addr,
-                                                   unsigned long offset,
-                                                   size_t size,
-                                                   enum dma_data_direction dir)
-{
-       const struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->sync_single_for_device)
-               ops->sync_single_for_device(dev, addr + offset, size, dir);
-       debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-                   int nelems, enum dma_data_direction dir)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->sync_sg_for_cpu)
-               ops->sync_sg_for_cpu(dev, sg, nelems, dir);
-       debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-                      int nelems, enum dma_data_direction dir)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!valid_dma_direction(dir));
-       if (ops->sync_sg_for_device)
-               ops->sync_sg_for_device(dev, sg, nelems, dir);
-       debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
-
-}
-
-#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
-#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
-#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
-#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
-
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
-                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
-
-void *dma_common_contiguous_remap(struct page *page, size_t size,
-                       unsigned long vm_flags,
-                       pgprot_t prot, const void *caller);
-
-void *dma_common_pages_remap(struct page **pages, size_t size,
-                       unsigned long vm_flags, pgprot_t prot,
-                       const void *caller);
-void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
-
-/**
- * dma_mmap_attrs - map a coherent DMA allocation into user space
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @vma: vm_area_struct describing requested user mapping
- * @cpu_addr: kernel CPU-view address returned from dma_alloc_attrs
- * @handle: device-view address returned from dma_alloc_attrs
- * @size: size of memory originally requested in dma_alloc_attrs
- * @attrs: attributes of mapping properties requested in dma_alloc_attrs
- *
- * Map a coherent DMA buffer previously allocated by dma_alloc_attrs
- * into user space.  The coherent DMA buffer must not be freed by the
- * driver until the user space mapping has been released.
- */
-static inline int
-dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
-              dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-       BUG_ON(!ops);
-       if (ops->mmap)
-               return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
-       return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
-
-int
-dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
-                      void *cpu_addr, dma_addr_t dma_addr, size_t size);
-
-static inline int
-dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
-                     dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-       BUG_ON(!ops);
-       if (ops->get_sgtable)
-               return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
-                                       attrs);
-       return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
-}
-
-#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
-
-#ifndef arch_dma_alloc_attrs
-#define arch_dma_alloc_attrs(dev, flag)        (true)
-#endif
-
-static inline void *dma_alloc_attrs(struct device *dev, size_t size,
-                                      dma_addr_t *dma_handle, gfp_t flag,
-                                      struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-       void *cpu_addr;
-
-       BUG_ON(!ops);
-
-       if (dma_alloc_from_coherent(dev, size, dma_handle, &cpu_addr))
-               return cpu_addr;
-
-       if (!arch_dma_alloc_attrs(&dev, &flag))
-               return NULL;
-       if (!ops->alloc)
-               return NULL;
-
-       cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
-       debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
-       return cpu_addr;
-}
-
-static inline void dma_free_attrs(struct device *dev, size_t size,
-                                    void *cpu_addr, dma_addr_t dma_handle,
-                                    struct dma_attrs *attrs)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       BUG_ON(!ops);
-       WARN_ON(irqs_disabled());
-
-       if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
-               return;
-
-       if (!ops->free)
-               return;
-
-       debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
-       ops->free(dev, size, cpu_addr, dma_handle, attrs);
-}
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-               dma_addr_t *dma_handle, gfp_t flag)
-{
-       return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
-               void *cpu_addr, dma_addr_t dma_handle)
-{
-       return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
-}
-
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
-               dma_addr_t *dma_handle, gfp_t gfp)
-{
-       DEFINE_DMA_ATTRS(attrs);
-
-       dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-       return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
-}
-
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
-               void *cpu_addr, dma_addr_t dma_handle)
-{
-       DEFINE_DMA_ATTRS(attrs);
-
-       dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
-       dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       debug_dma_mapping_error(dev, dma_addr);
-
-       if (get_dma_ops(dev)->mapping_error)
-               return get_dma_ops(dev)->mapping_error(dev, dma_addr);
-
-#ifdef DMA_ERROR_CODE
-       return dma_addr == DMA_ERROR_CODE;
-#else
-       return 0;
-#endif
-}
-
-#ifndef HAVE_ARCH_DMA_SUPPORTED
-static inline int dma_supported(struct device *dev, u64 mask)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       if (!ops)
-               return 0;
-       if (!ops->dma_supported)
-               return 1;
-       return ops->dma_supported(dev, mask);
-}
-#endif
-
-#ifndef HAVE_ARCH_DMA_SET_MASK
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-       struct dma_map_ops *ops = get_dma_ops(dev);
-
-       if (ops->set_dma_mask)
-               return ops->set_dma_mask(dev, mask);
-
-       if (!dev->dma_mask || !dma_supported(dev, mask))
-               return -EIO;
-       *dev->dma_mask = mask;
-       return 0;
-}
-#endif
-
-#endif
index 3d69c93..6361892 100644 (file)
@@ -204,6 +204,7 @@ struct crypto_ahash {
                      unsigned int keylen);
 
        unsigned int reqsize;
+       bool has_setkey;
        struct crypto_tfm base;
 };
 
@@ -375,6 +376,11 @@ static inline void *ahash_request_ctx(struct ahash_request *req)
 int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
                        unsigned int keylen);
 
+static inline bool crypto_ahash_has_setkey(struct crypto_ahash *tfm)
+{
+       return tfm->has_setkey;
+}
+
 /**
  * crypto_ahash_finup() - update and finalize message digest
  * @req: reference to the ahash_request handle that holds all information
index 018afb2..a2bfd78 100644 (file)
@@ -30,6 +30,9 @@ struct alg_sock {
 
        struct sock *parent;
 
+       unsigned int refcnt;
+       unsigned int nokey_refcnt;
+
        const struct af_alg_type *type;
        void *private;
 };
@@ -50,9 +53,11 @@ struct af_alg_type {
        void (*release)(void *private);
        int (*setkey)(void *private, const u8 *key, unsigned int keylen);
        int (*accept)(void *private, struct sock *sk);
+       int (*accept_nokey)(void *private, struct sock *sk);
        int (*setauthsize)(void *private, unsigned int authsize);
 
        struct proto_ops *ops;
+       struct proto_ops *ops_nokey;
        struct module *owner;
        char name[14];
 };
@@ -67,6 +72,7 @@ int af_alg_register_type(const struct af_alg_type *type);
 int af_alg_unregister_type(const struct af_alg_type *type);
 
 int af_alg_release(struct socket *sock);
+void af_alg_release_parent(struct sock *sk);
 int af_alg_accept(struct sock *sk, struct socket *newsock);
 
 int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len);
@@ -83,11 +89,6 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
        return (struct alg_sock *)sk;
 }
 
-static inline void af_alg_release_parent(struct sock *sk)
-{
-       sock_put(alg_sk(sk)->parent);
-}
-
 static inline void af_alg_init_completion(struct af_alg_completion *completion)
 {
        init_completion(&completion->completion);
index d8dd41f..fd8742a 100644 (file)
@@ -61,6 +61,8 @@ struct crypto_skcipher {
        unsigned int ivsize;
        unsigned int reqsize;
 
+       bool has_setkey;
+
        struct crypto_tfm base;
 };
 
@@ -305,6 +307,11 @@ static inline int crypto_skcipher_setkey(struct crypto_skcipher *tfm,
        return tfm->setkey(tfm, key, keylen);
 }
 
+static inline bool crypto_skcipher_has_setkey(struct crypto_skcipher *tfm)
+{
+       return tfm->has_setkey;
+}
+
 /**
  * crypto_skcipher_reqtfm() - obtain cipher handle from request
  * @req: skcipher_request out of which the cipher handle is to be obtained
index c4b1676..c40111f 100644 (file)
@@ -93,6 +93,7 @@
 #define CLK_SCLK_FIMG2D                177
 
 /* gate clocks */
+#define CLK_SSS                        255
 #define CLK_FIMC0              256
 #define CLK_FIMC1              257
 #define CLK_FIMC2              258
index dd09b73..ffa1137 100644 (file)
 #define R8A7791_CLK_VIN2               9
 #define R8A7791_CLK_VIN1               10
 #define R8A7791_CLK_VIN0               11
+#define R8A7791_CLK_ETHERAVB           12
 #define R8A7791_CLK_ETHER              13
 #define R8A7791_CLK_SATA1              14
 #define R8A7791_CLK_SATA0              15
index 09da38a..a7a7e03 100644 (file)
@@ -79,6 +79,7 @@
 #define R8A7794_CLK_SCIF2              19
 #define R8A7794_CLK_SCIF1              20
 #define R8A7794_CLK_SCIF0              21
+#define R8A7794_CLK_DU0                        24
 
 /* MSTP8 */
 #define R8A7794_CLK_VIN1               10
index 5336956..2eca353 100644 (file)
@@ -28,7 +28,8 @@
 #define SH73A0_CLK_HP          14
 
 /* MSTP0 */
-#define SH73A0_CLK_IIC2        1
+#define SH73A0_CLK_IIC2                1
+#define SH73A0_CLK_MSIOF0      0
 
 /* MSTP1 */
 #define SH73A0_CLK_CEU1                29
 #define SH73A0_CLK_SCIFA7      19
 #define SH73A0_CLK_SY_DMAC     18
 #define SH73A0_CLK_MP_DMAC     17
+#define SH73A0_CLK_MSIOF3      15
+#define SH73A0_CLK_MSIOF1      8
 #define SH73A0_CLK_SCIFA5      7
 #define SH73A0_CLK_SCIFB       6
+#define SH73A0_CLK_MSIOF2      5
 #define SH73A0_CLK_SCIFA0      4
 #define SH73A0_CLK_SCIFA1      3
 #define SH73A0_CLK_SCIFA2      2
index 774dc1e..344bd1e 100644 (file)
 #define PIN_INPUT_PULLUP       (INPUT_EN | PULL_UP)
 #define PIN_INPUT_PULLDOWN     (INPUT_EN)
 
+/*
+ * Macro to allow using the absolute physical address instead of the
+ * padconf registers instead of the offset from padconf base.
+ */
+#define AM4372_IOPAD(pa, val)  (((pa) & 0xffff) - 0x0800) (val)
+
 #endif
 
diff --git a/include/dt-bindings/pinctrl/dm814x.h b/include/dt-bindings/pinctrl/dm814x.h
new file mode 100644 (file)
index 0000000..0f48427
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * This header provides constants specific to DM814X pinctrl bindings.
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_DM814X_H
+#define _DT_BINDINGS_PINCTRL_DM814X_H
+
+#include <dt-bindings/pinctrl/omap.h>
+
+#undef INPUT_EN
+#undef PULL_UP
+#undef PULL_ENA
+
+/*
+ * Note that dm814x silicon revision 2.1 and older require input enabled
+ * (bit 18 set) for all 3.3V I/Os to avoid cumulative hardware damage. For
+ * more info, see errata advisory 2.1.87. We leave bit 18 out of
+ * function-mask in dm814x.h and rely on the bootloader for it.
+ */
+#define INPUT_EN               (1 << 18)
+#define PULL_UP                        (1 << 17)
+#define PULL_DISABLE           (1 << 16)
+
+/* update macro depending on INPUT_EN and PULL_ENA */
+#undef PIN_OUTPUT
+#undef PIN_OUTPUT_PULLUP
+#undef PIN_OUTPUT_PULLDOWN
+#undef PIN_INPUT
+#undef PIN_INPUT_PULLUP
+#undef PIN_INPUT_PULLDOWN
+
+#define PIN_OUTPUT             (PULL_DISABLE)
+#define PIN_OUTPUT_PULLUP      (PULL_UP)
+#define PIN_OUTPUT_PULLDOWN    0
+#define PIN_INPUT              (INPUT_EN | PULL_DISABLE)
+#define PIN_INPUT_PULLUP       (INPUT_EN | PULL_UP)
+#define PIN_INPUT_PULLDOWN     (INPUT_EN)
+
+/* undef non-existing modes */
+#undef PIN_OFF_NONE
+#undef PIN_OFF_OUTPUT_HIGH
+#undef PIN_OFF_OUTPUT_LOW
+#undef PIN_OFF_INPUT_PULLUP
+#undef PIN_OFF_INPUT_PULLDOWN
+#undef PIN_OFF_WAKEUPENABLE
+
+#endif
+
index 4379e29..5c75e80 100644 (file)
 #define PIN_INPUT_PULLUP       (PULL_ENA | INPUT_EN | PULL_UP)
 #define PIN_INPUT_PULLDOWN     (PULL_ENA | INPUT_EN)
 
+/*
+ * Macro to allow using the absolute physical address instead of the
+ * padconf registers instead of the offset from padconf base.
+ */
+#define DRA7XX_CORE_IOPAD(pa, val)     (((pa) & 0xffff) - 0x3400) (val)
+
 #endif
 
index 1394925..effadd0 100644 (file)
 #define OMAP3430_CORE2_IOPAD(pa, val)  OMAP_IOPAD_OFFSET((pa), 0x25d8) (val)
 #define OMAP3630_CORE2_IOPAD(pa, val)  OMAP_IOPAD_OFFSET((pa), 0x25a0) (val)
 #define OMAP3_WKUP_IOPAD(pa, val)      OMAP_IOPAD_OFFSET((pa), 0x2a00) (val)
+#define DM814X_IOPAD(pa, val)          OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
 #define DM816X_IOPAD(pa, val)          OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
 #define AM33XX_IOPAD(pa, val)          OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
-#define AM4372_IOPAD(pa, val)          OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
-#define DRA7XX_CORE_IOPAD(pa, val)     OMAP_IOPAD_OFFSET((pa), 0x3400) (val)
 
 /*
  * Macros to allow using the offset from the padconf physical address
diff --git a/include/dt-bindings/power/raspberrypi-power.h b/include/dt-bindings/power/raspberrypi-power.h
new file mode 100644 (file)
index 0000000..b3ff8e0
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright Â© 2015 Broadcom
+ *
+ * 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 _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
+#define _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
+
+/* These power domain indices are the firmware interface's indices
+ * minus one.
+ */
+#define RPI_POWER_DOMAIN_I2C0          0
+#define RPI_POWER_DOMAIN_I2C1          1
+#define RPI_POWER_DOMAIN_I2C2          2
+#define RPI_POWER_DOMAIN_VIDEO_SCALER  3
+#define RPI_POWER_DOMAIN_VPU1          4
+#define RPI_POWER_DOMAIN_HDMI          5
+#define RPI_POWER_DOMAIN_USB           6
+#define RPI_POWER_DOMAIN_VEC           7
+#define RPI_POWER_DOMAIN_JPEG          8
+#define RPI_POWER_DOMAIN_H264          9
+#define RPI_POWER_DOMAIN_V3D           10
+#define RPI_POWER_DOMAIN_ISP           11
+#define RPI_POWER_DOMAIN_UNICAM0       12
+#define RPI_POWER_DOMAIN_UNICAM1       13
+#define RPI_POWER_DOMAIN_CCP2RX                14
+#define RPI_POWER_DOMAIN_CSI2          15
+#define RPI_POWER_DOMAIN_CPI           16
+#define RPI_POWER_DOMAIN_DSI0          17
+#define RPI_POWER_DOMAIN_DSI1          18
+#define RPI_POWER_DOMAIN_TRANSPOSER    19
+#define RPI_POWER_DOMAIN_CCP2TX                20
+#define RPI_POWER_DOMAIN_CDP           21
+#define RPI_POWER_DOMAIN_ARM           22
+
+#define RPI_POWER_DOMAIN_COUNT         23
+
+#endif /* _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H */
diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
deleted file mode 100644 (file)
index 1fb6295..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2014 MediaTek Inc.
- * Author: Flora Fu, MediaTek
- *
- * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
-#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
-
-/* INFRACFG resets */
-#define MT8135_INFRA_EMI_REG_RST        0
-#define MT8135_INFRA_DRAMC0_A0_RST      1
-#define MT8135_INFRA_CCIF0_RST          2
-#define MT8135_INFRA_APCIRQ_EINT_RST    3
-#define MT8135_INFRA_APXGPT_RST         4
-#define MT8135_INFRA_SCPSYS_RST         5
-#define MT8135_INFRA_CCIF1_RST          6
-#define MT8135_INFRA_PMIC_WRAP_RST      7
-#define MT8135_INFRA_KP_RST             8
-#define MT8135_INFRA_EMI_RST            32
-#define MT8135_INFRA_DRAMC0_RST         34
-#define MT8135_INFRA_SMI_RST            35
-#define MT8135_INFRA_M4U_RST            36
-
-/*  PERICFG resets */
-#define MT8135_PERI_UART0_SW_RST        0
-#define MT8135_PERI_UART1_SW_RST        1
-#define MT8135_PERI_UART2_SW_RST        2
-#define MT8135_PERI_UART3_SW_RST        3
-#define MT8135_PERI_IRDA_SW_RST         4
-#define MT8135_PERI_PTP_SW_RST          5
-#define MT8135_PERI_AP_HIF_SW_RST       6
-#define MT8135_PERI_GPCU_SW_RST         7
-#define MT8135_PERI_MD_HIF_SW_RST       8
-#define MT8135_PERI_NLI_SW_RST          9
-#define MT8135_PERI_AUXADC_SW_RST       10
-#define MT8135_PERI_DMA_SW_RST          11
-#define MT8135_PERI_NFI_SW_RST          14
-#define MT8135_PERI_PWM_SW_RST          15
-#define MT8135_PERI_THERM_SW_RST        16
-#define MT8135_PERI_MSDC0_SW_RST        17
-#define MT8135_PERI_MSDC1_SW_RST        18
-#define MT8135_PERI_MSDC2_SW_RST        19
-#define MT8135_PERI_MSDC3_SW_RST        20
-#define MT8135_PERI_I2C0_SW_RST         22
-#define MT8135_PERI_I2C1_SW_RST         23
-#define MT8135_PERI_I2C2_SW_RST         24
-#define MT8135_PERI_I2C3_SW_RST         25
-#define MT8135_PERI_I2C4_SW_RST         26
-#define MT8135_PERI_I2C5_SW_RST         27
-#define MT8135_PERI_I2C6_SW_RST         28
-#define MT8135_PERI_USB_SW_RST          29
-#define MT8135_PERI_SPI1_SW_RST         33
-#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
-
-#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
diff --git a/include/dt-bindings/reset-controller/mt8173-resets.h b/include/dt-bindings/reset-controller/mt8173-resets.h
deleted file mode 100644 (file)
index 9464b37..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2014 MediaTek Inc.
- * Author: Flora Fu, MediaTek
- *
- * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8173
-#define _DT_BINDINGS_RESET_CONTROLLER_MT8173
-
-/* INFRACFG resets */
-#define MT8173_INFRA_EMI_REG_RST        0
-#define MT8173_INFRA_DRAMC0_A0_RST      1
-#define MT8173_INFRA_APCIRQ_EINT_RST    3
-#define MT8173_INFRA_APXGPT_RST         4
-#define MT8173_INFRA_SCPSYS_RST         5
-#define MT8173_INFRA_KP_RST             6
-#define MT8173_INFRA_PMIC_WRAP_RST      7
-#define MT8173_INFRA_MPIP_RST           8
-#define MT8173_INFRA_CEC_RST            9
-#define MT8173_INFRA_EMI_RST            32
-#define MT8173_INFRA_DRAMC0_RST         34
-#define MT8173_INFRA_APMIXEDSYS_RST     35
-#define MT8173_INFRA_MIPI_DSI_RST       36
-#define MT8173_INFRA_TRNG_RST           37
-#define MT8173_INFRA_SYSIRQ_RST         38
-#define MT8173_INFRA_MIPI_CSI_RST       39
-#define MT8173_INFRA_GCE_FAXI_RST       40
-#define MT8173_INFRA_MMIOMMURST         47
-
-
-/*  PERICFG resets */
-#define MT8173_PERI_UART0_SW_RST        0
-#define MT8173_PERI_UART1_SW_RST        1
-#define MT8173_PERI_UART2_SW_RST        2
-#define MT8173_PERI_UART3_SW_RST        3
-#define MT8173_PERI_IRRX_SW_RST         4
-#define MT8173_PERI_PWM_SW_RST          8
-#define MT8173_PERI_AUXADC_SW_RST       10
-#define MT8173_PERI_DMA_SW_RST          11
-#define MT8173_PERI_I2C6_SW_RST         13
-#define MT8173_PERI_NFI_SW_RST          14
-#define MT8173_PERI_THERM_SW_RST        16
-#define MT8173_PERI_MSDC2_SW_RST        17
-#define MT8173_PERI_MSDC3_SW_RST        18
-#define MT8173_PERI_MSDC0_SW_RST        19
-#define MT8173_PERI_MSDC1_SW_RST        20
-#define MT8173_PERI_I2C0_SW_RST         22
-#define MT8173_PERI_I2C1_SW_RST         23
-#define MT8173_PERI_I2C2_SW_RST         24
-#define MT8173_PERI_I2C3_SW_RST         25
-#define MT8173_PERI_I2C4_SW_RST         26
-#define MT8173_PERI_HDMI_SW_RST         29
-#define MT8173_PERI_SPI0_SW_RST         33
-
-#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8173 */
diff --git a/include/dt-bindings/reset/hisi,hi6220-resets.h b/include/dt-bindings/reset/hisi,hi6220-resets.h
new file mode 100644 (file)
index 0000000..ca08a7e
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * This header provides index for the reset controller
+ * based on hi6220 SoC.
+ */
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_HI6220
+#define _DT_BINDINGS_RESET_CONTROLLER_HI6220
+
+#define PERIPH_RSTDIS0_MMC0             0x000
+#define PERIPH_RSTDIS0_MMC1             0x001
+#define PERIPH_RSTDIS0_MMC2             0x002
+#define PERIPH_RSTDIS0_NANDC            0x003
+#define PERIPH_RSTDIS0_USBOTG_BUS       0x004
+#define PERIPH_RSTDIS0_POR_PICOPHY      0x005
+#define PERIPH_RSTDIS0_USBOTG           0x006
+#define PERIPH_RSTDIS0_USBOTG_32K       0x007
+#define PERIPH_RSTDIS1_HIFI             0x100
+#define PERIPH_RSTDIS1_DIGACODEC        0x105
+#define PERIPH_RSTEN2_IPF               0x200
+#define PERIPH_RSTEN2_SOCP              0x201
+#define PERIPH_RSTEN2_DMAC              0x202
+#define PERIPH_RSTEN2_SECENG            0x203
+#define PERIPH_RSTEN2_ABB               0x204
+#define PERIPH_RSTEN2_HPM0              0x205
+#define PERIPH_RSTEN2_HPM1              0x206
+#define PERIPH_RSTEN2_HPM2              0x207
+#define PERIPH_RSTEN2_HPM3              0x208
+#define PERIPH_RSTEN3_CSSYS             0x300
+#define PERIPH_RSTEN3_I2C0              0x301
+#define PERIPH_RSTEN3_I2C1              0x302
+#define PERIPH_RSTEN3_I2C2              0x303
+#define PERIPH_RSTEN3_I2C3              0x304
+#define PERIPH_RSTEN3_UART1             0x305
+#define PERIPH_RSTEN3_UART2             0x306
+#define PERIPH_RSTEN3_UART3             0x307
+#define PERIPH_RSTEN3_UART4             0x308
+#define PERIPH_RSTEN3_SSP               0x309
+#define PERIPH_RSTEN3_PWM               0x30a
+#define PERIPH_RSTEN3_BLPWM             0x30b
+#define PERIPH_RSTEN3_TSENSOR           0x30c
+#define PERIPH_RSTEN3_DAPB              0x312
+#define PERIPH_RSTEN3_HKADC             0x313
+#define PERIPH_RSTEN3_CODEC_SSI         0x314
+#define PERIPH_RSTEN3_PMUSSI1           0x316
+#define PERIPH_RSTEN8_RS0               0x400
+#define PERIPH_RSTEN8_RS2               0x401
+#define PERIPH_RSTEN8_RS3               0x402
+#define PERIPH_RSTEN8_MS0               0x403
+#define PERIPH_RSTEN8_MS2               0x405
+#define PERIPH_RSTEN8_XG2RAM0           0x406
+#define PERIPH_RSTEN8_X2SRAM_TZMA       0x407
+#define PERIPH_RSTEN8_SRAM              0x408
+#define PERIPH_RSTEN8_HARQ              0x40a
+#define PERIPH_RSTEN8_DDRC              0x40c
+#define PERIPH_RSTEN8_DDRC_APB          0x40d
+#define PERIPH_RSTEN8_DDRPACK_APB       0x40e
+#define PERIPH_RSTEN8_DDRT              0x411
+#define PERIPH_RSDIST9_CARM_DAP         0x500
+#define PERIPH_RSDIST9_CARM_ATB         0x501
+#define PERIPH_RSDIST9_CARM_LBUS        0x502
+#define PERIPH_RSDIST9_CARM_POR         0x503
+#define PERIPH_RSDIST9_CARM_CORE        0x504
+#define PERIPH_RSDIST9_CARM_DBG         0x505
+#define PERIPH_RSDIST9_CARM_L2          0x506
+#define PERIPH_RSDIST9_CARM_SOCDBG      0x507
+#define PERIPH_RSDIST9_CARM_ETM         0x508
+
+#endif /*_DT_BINDINGS_RESET_CONTROLLER_HI6220*/
diff --git a/include/dt-bindings/reset/mt8135-resets.h b/include/dt-bindings/reset/mt8135-resets.h
new file mode 100644 (file)
index 0000000..1fb6295
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu, MediaTek
+ *
+ * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8135
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
+
+/* INFRACFG resets */
+#define MT8135_INFRA_EMI_REG_RST        0
+#define MT8135_INFRA_DRAMC0_A0_RST      1
+#define MT8135_INFRA_CCIF0_RST          2
+#define MT8135_INFRA_APCIRQ_EINT_RST    3
+#define MT8135_INFRA_APXGPT_RST         4
+#define MT8135_INFRA_SCPSYS_RST         5
+#define MT8135_INFRA_CCIF1_RST          6
+#define MT8135_INFRA_PMIC_WRAP_RST      7
+#define MT8135_INFRA_KP_RST             8
+#define MT8135_INFRA_EMI_RST            32
+#define MT8135_INFRA_DRAMC0_RST         34
+#define MT8135_INFRA_SMI_RST            35
+#define MT8135_INFRA_M4U_RST            36
+
+/*  PERICFG resets */
+#define MT8135_PERI_UART0_SW_RST        0
+#define MT8135_PERI_UART1_SW_RST        1
+#define MT8135_PERI_UART2_SW_RST        2
+#define MT8135_PERI_UART3_SW_RST        3
+#define MT8135_PERI_IRDA_SW_RST         4
+#define MT8135_PERI_PTP_SW_RST          5
+#define MT8135_PERI_AP_HIF_SW_RST       6
+#define MT8135_PERI_GPCU_SW_RST         7
+#define MT8135_PERI_MD_HIF_SW_RST       8
+#define MT8135_PERI_NLI_SW_RST          9
+#define MT8135_PERI_AUXADC_SW_RST       10
+#define MT8135_PERI_DMA_SW_RST          11
+#define MT8135_PERI_NFI_SW_RST          14
+#define MT8135_PERI_PWM_SW_RST          15
+#define MT8135_PERI_THERM_SW_RST        16
+#define MT8135_PERI_MSDC0_SW_RST        17
+#define MT8135_PERI_MSDC1_SW_RST        18
+#define MT8135_PERI_MSDC2_SW_RST        19
+#define MT8135_PERI_MSDC3_SW_RST        20
+#define MT8135_PERI_I2C0_SW_RST         22
+#define MT8135_PERI_I2C1_SW_RST         23
+#define MT8135_PERI_I2C2_SW_RST         24
+#define MT8135_PERI_I2C3_SW_RST         25
+#define MT8135_PERI_I2C4_SW_RST         26
+#define MT8135_PERI_I2C5_SW_RST         27
+#define MT8135_PERI_I2C6_SW_RST         28
+#define MT8135_PERI_USB_SW_RST          29
+#define MT8135_PERI_SPI1_SW_RST         33
+#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
diff --git a/include/dt-bindings/reset/mt8173-resets.h b/include/dt-bindings/reset/mt8173-resets.h
new file mode 100644 (file)
index 0000000..9464b37
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu, MediaTek
+ *
+ * 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 _DT_BINDINGS_RESET_CONTROLLER_MT8173
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8173
+
+/* INFRACFG resets */
+#define MT8173_INFRA_EMI_REG_RST        0
+#define MT8173_INFRA_DRAMC0_A0_RST      1
+#define MT8173_INFRA_APCIRQ_EINT_RST    3
+#define MT8173_INFRA_APXGPT_RST         4
+#define MT8173_INFRA_SCPSYS_RST         5
+#define MT8173_INFRA_KP_RST             6
+#define MT8173_INFRA_PMIC_WRAP_RST      7
+#define MT8173_INFRA_MPIP_RST           8
+#define MT8173_INFRA_CEC_RST            9
+#define MT8173_INFRA_EMI_RST            32
+#define MT8173_INFRA_DRAMC0_RST         34
+#define MT8173_INFRA_APMIXEDSYS_RST     35
+#define MT8173_INFRA_MIPI_DSI_RST       36
+#define MT8173_INFRA_TRNG_RST           37
+#define MT8173_INFRA_SYSIRQ_RST         38
+#define MT8173_INFRA_MIPI_CSI_RST       39
+#define MT8173_INFRA_GCE_FAXI_RST       40
+#define MT8173_INFRA_MMIOMMURST         47
+
+
+/*  PERICFG resets */
+#define MT8173_PERI_UART0_SW_RST        0
+#define MT8173_PERI_UART1_SW_RST        1
+#define MT8173_PERI_UART2_SW_RST        2
+#define MT8173_PERI_UART3_SW_RST        3
+#define MT8173_PERI_IRRX_SW_RST         4
+#define MT8173_PERI_PWM_SW_RST          8
+#define MT8173_PERI_AUXADC_SW_RST       10
+#define MT8173_PERI_DMA_SW_RST          11
+#define MT8173_PERI_I2C6_SW_RST         13
+#define MT8173_PERI_NFI_SW_RST          14
+#define MT8173_PERI_THERM_SW_RST        16
+#define MT8173_PERI_MSDC2_SW_RST        17
+#define MT8173_PERI_MSDC3_SW_RST        18
+#define MT8173_PERI_MSDC0_SW_RST        19
+#define MT8173_PERI_MSDC1_SW_RST        20
+#define MT8173_PERI_I2C0_SW_RST         22
+#define MT8173_PERI_I2C1_SW_RST         23
+#define MT8173_PERI_I2C2_SW_RST         24
+#define MT8173_PERI_I2C3_SW_RST         25
+#define MT8173_PERI_I2C4_SW_RST         26
+#define MT8173_PERI_HDMI_SW_RST         29
+#define MT8173_PERI_SPI0_SW_RST         33
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8173 */
index 02d4328..4ab3a1c 100644 (file)
 #define STIH407_KEYSCAN_SOFTRESET      26
 #define STIH407_USB2_PORT0_SOFTRESET   27
 #define STIH407_USB2_PORT1_SOFTRESET   28
+#define STIH407_ST231_AUD_SOFTRESET    29
+#define STIH407_ST231_DMU_SOFTRESET    30
+#define STIH407_ST231_GP0_SOFTRESET    31
+#define STIH407_ST231_GP1_SOFTRESET    32
 
 /* Picophy reset defines */
 #define STIH407_PICOPHY0_RESET         0
index 744b997..1640493 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef _AER_H_
 #define _AER_H_
 
+#include <linux/errno.h>
 #include <linux/types.h>
 
 #define AER_NONFATAL                   0
diff --git a/include/linux/bcm963xx_nvram.h b/include/linux/bcm963xx_nvram.h
new file mode 100644 (file)
index 0000000..290c231
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef __LINUX_BCM963XX_NVRAM_H__
+#define __LINUX_BCM963XX_NVRAM_H__
+
+#include <linux/crc32.h>
+#include <linux/if_ether.h>
+#include <linux/sizes.h>
+#include <linux/types.h>
+
+/*
+ * Broadcom BCM963xx SoC board nvram data structure.
+ *
+ * The nvram structure varies in size depending on the SoC board version. Use
+ * the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information
+ * you need instead of sizeof(struct bcm963xx_nvram) as this may change.
+ */
+
+#define BCM963XX_NVRAM_V4_SIZE         300
+#define BCM963XX_NVRAM_V5_SIZE         (1 * SZ_1K)
+
+#define BCM963XX_DEFAULT_PSI_SIZE      64
+
+enum bcm963xx_nvram_nand_part {
+       BCM963XX_NVRAM_NAND_PART_BOOT = 0,
+       BCM963XX_NVRAM_NAND_PART_ROOTFS_1,
+       BCM963XX_NVRAM_NAND_PART_ROOTFS_2,
+       BCM963XX_NVRAM_NAND_PART_DATA,
+       BCM963XX_NVRAM_NAND_PART_BBT,
+
+       __BCM963XX_NVRAM_NAND_NR_PARTS
+};
+
+struct bcm963xx_nvram {
+       u32     version;
+       char    bootline[256];
+       char    name[16];
+       u32     main_tp_number;
+       u32     psi_size;
+       u32     mac_addr_count;
+       u8      mac_addr_base[ETH_ALEN];
+       u8      __reserved1[2];
+       u32     checksum_v4;
+
+       u8      __reserved2[292];
+       u32     nand_part_offset[__BCM963XX_NVRAM_NAND_NR_PARTS];
+       u32     nand_part_size[__BCM963XX_NVRAM_NAND_NR_PARTS];
+       u8      __reserved3[388];
+       u32     checksum_v5;
+};
+
+#define BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, part) \
+       bcm963xx_nvram_nand_part_offset(nvram, BCM963XX_NVRAM_NAND_PART_ ##part)
+
+static inline u64 __pure bcm963xx_nvram_nand_part_offset(
+       const struct bcm963xx_nvram *nvram,
+       enum bcm963xx_nvram_nand_part part)
+{
+       return nvram->nand_part_offset[part] * SZ_1K;
+}
+
+#define BCM963XX_NVRAM_NAND_PART_SIZE(nvram, part) \
+       bcm963xx_nvram_nand_part_size(nvram, BCM963XX_NVRAM_NAND_PART_ ##part)
+
+static inline u64 __pure bcm963xx_nvram_nand_part_size(
+       const struct bcm963xx_nvram *nvram,
+       enum bcm963xx_nvram_nand_part part)
+{
+       return nvram->nand_part_size[part] * SZ_1K;
+}
+
+/*
+ * bcm963xx_nvram_checksum - Verify nvram checksum
+ *
+ * @nvram: pointer to full size nvram data structure
+ * @expected_out: optional pointer to store expected checksum value
+ * @actual_out: optional pointer to store actual checksum value
+ *
+ * Return: 0 if the checksum is valid, otherwise -EINVAL
+ */
+static int __maybe_unused bcm963xx_nvram_checksum(
+       const struct bcm963xx_nvram *nvram,
+       u32 *expected_out, u32 *actual_out)
+{
+       u32 expected, actual;
+       size_t len;
+
+       if (nvram->version <= 4) {
+               expected = nvram->checksum_v4;
+               len = BCM963XX_NVRAM_V4_SIZE - sizeof(u32);
+       } else {
+               expected = nvram->checksum_v5;
+               len = BCM963XX_NVRAM_V5_SIZE - sizeof(u32);
+       }
+
+       /*
+        * Calculate the CRC32 value for the nvram with a checksum value
+        * of 0 without modifying or copying the nvram by combining:
+        * - The CRC32 of the nvram without the checksum value
+        * - The CRC32 of a zero checksum value (which is also 0)
+        */
+       actual = crc32_le_combine(
+               crc32_le(~0, (u8 *)nvram, len), 0, sizeof(u32));
+
+       if (expected_out)
+               *expected_out = expected;
+
+       if (actual_out)
+               *actual_out = actual;
+
+       return expected == actual ? 0 : -EINVAL;
+};
+
+#endif /* __LINUX_BCM963XX_NVRAM_H__ */
diff --git a/include/linux/bcm963xx_tag.h b/include/linux/bcm963xx_tag.h
new file mode 100644 (file)
index 0000000..161c7b3
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef __LINUX_BCM963XX_TAG_H__
+#define __LINUX_BCM963XX_TAG_H__
+
+#include <linux/types.h>
+
+#define TAGVER_LEN             4       /* Length of Tag Version */
+#define TAGLAYOUT_LEN          4       /* Length of FlashLayoutVer */
+#define SIG1_LEN               20      /* Company Signature 1 Length */
+#define SIG2_LEN               14      /* Company Signature 2 Length */
+#define BOARDID_LEN            16      /* Length of BoardId */
+#define ENDIANFLAG_LEN         2       /* Endian Flag Length */
+#define CHIPID_LEN             6       /* Chip Id Length */
+#define IMAGE_LEN              10      /* Length of Length Field */
+#define ADDRESS_LEN            12      /* Length of Address field */
+#define IMAGE_SEQUENCE_LEN     4       /* Image sequence Length */
+#define RSASIG_LEN             20      /* Length of RSA Signature in tag */
+#define TAGINFO1_LEN           30      /* Length of vendor information field1 in tag */
+#define FLASHLAYOUTVER_LEN     4       /* Length of Flash Layout Version String tag */
+#define TAGINFO2_LEN           16      /* Length of vendor information field2 in tag */
+#define ALTTAGINFO_LEN         54      /* Alternate length for vendor information; Pirelli */
+
+#define NUM_PIRELLI            2
+#define IMAGETAG_CRC_START     0xFFFFFFFF
+
+#define PIRELLI_BOARDS { \
+       "AGPF-S0", \
+       "DWV-S0", \
+}
+
+/* Extended flash address, needs to be subtracted
+ * from bcm_tag flash image offsets.
+ */
+#define BCM963XX_EXTENDED_SIZE 0xBFC00000
+
+/*
+ * The broadcom firmware assumes the rootfs starts the image,
+ * therefore uses the rootfs start (flash_image_address)
+ * to determine where to flash the image.  Since we have the kernel first
+ * we have to give it the kernel address, but the crc uses the length
+ * associated with this address (root_length), which is added to the kernel
+ * length (kernel_length) to determine the length of image to flash and thus
+ * needs to be rootfs + deadcode (jffs2 EOF marker)
+*/
+
+struct bcm_tag {
+       /* 0-3: Version of the image tag */
+       char tag_version[TAGVER_LEN];
+       /* 4-23: Company Line 1 */
+       char sig_1[SIG1_LEN];
+       /*  24-37: Company Line 2 */
+       char sig_2[SIG2_LEN];
+       /* 38-43: Chip this image is for */
+       char chip_id[CHIPID_LEN];
+       /* 44-59: Board name */
+       char board_id[BOARDID_LEN];
+       /* 60-61: Map endianness -- 1 BE 0 LE */
+       char big_endian[ENDIANFLAG_LEN];
+       /* 62-71: Total length of image */
+       char total_length[IMAGE_LEN];
+       /* 72-83: Address in memory of CFE */
+       char cfe__address[ADDRESS_LEN];
+       /* 84-93: Size of CFE */
+       char cfe_length[IMAGE_LEN];
+       /* 94-105: Address in memory of image start
+        * (kernel for OpenWRT, rootfs for stock firmware)
+        */
+       char flash_image_start[ADDRESS_LEN];
+       /* 106-115: Size of rootfs */
+       char root_length[IMAGE_LEN];
+       /* 116-127: Address in memory of kernel */
+       char kernel_address[ADDRESS_LEN];
+       /* 128-137: Size of kernel */
+       char kernel_length[IMAGE_LEN];
+       /* 138-141: Image sequence number
+        * (to be incremented when flashed with a new image)
+        */
+       char image_sequence[IMAGE_SEQUENCE_LEN];
+       /* 142-161: RSA Signature (not used; some vendors may use this) */
+       char rsa_signature[RSASIG_LEN];
+       /* 162-191: Compilation and related information (not used in OpenWrt) */
+       char information1[TAGINFO1_LEN];
+       /* 192-195: Version flash layout */
+       char flash_layout_ver[FLASHLAYOUTVER_LEN];
+       /* 196-199: kernel+rootfs CRC32 */
+       __u32 fskernel_crc;
+       /* 200-215: Unused except on Alice Gate where is is information */
+       char information2[TAGINFO2_LEN];
+       /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
+       __u32 image_crc;
+       /* 220-223: CRC32 of rootfs partition */
+       __u32 rootfs_crc;
+       /* 224-227: CRC32 of kernel partition */
+       __u32 kernel_crc;
+       /* 228-235: Unused at present */
+       char reserved1[8];
+       /* 236-239: CRC32 of header excluding last 20 bytes */
+       __u32 header_crc;
+       /* 240-255: Unused at present */
+       char reserved2[16];
+};
+
+#endif /* __LINUX_BCM63XX_TAG_H__ */
index b9b6e04..5349e68 100644 (file)
@@ -318,16 +318,6 @@ enum bip_flags {
        BIP_IP_CHECKSUM         = 1 << 4, /* IP checksum */
 };
 
-#if defined(CONFIG_BLK_DEV_INTEGRITY)
-
-static inline struct bio_integrity_payload *bio_integrity(struct bio *bio)
-{
-       if (bio->bi_rw & REQ_INTEGRITY)
-               return bio->bi_integrity;
-
-       return NULL;
-}
-
 /*
  * bio integrity payload
  */
@@ -349,6 +339,16 @@ struct bio_integrity_payload {
        struct bio_vec          bip_inline_vecs[0];/* embedded bvec array */
 };
 
+#if defined(CONFIG_BLK_DEV_INTEGRITY)
+
+static inline struct bio_integrity_payload *bio_integrity(struct bio *bio)
+{
+       if (bio->bi_rw & REQ_INTEGRITY)
+               return bio->bi_integrity;
+
+       return NULL;
+}
+
 static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag)
 {
        struct bio_integrity_payload *bip = bio_integrity(bio);
@@ -795,6 +795,18 @@ static inline bool bio_integrity_flagged(struct bio *bio, enum bip_flags flag)
        return false;
 }
 
+static inline void *bio_integrity_alloc(struct bio * bio, gfp_t gfp,
+                                                               unsigned int nr)
+{
+       return ERR_PTR(-EINVAL);
+}
+
+static inline int bio_integrity_add_page(struct bio *bio, struct page *page,
+                                       unsigned int len, unsigned int offset)
+{
+       return 0;
+}
+
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
 #endif /* CONFIG_BLOCK */
diff --git a/include/linux/blk-iopoll.h b/include/linux/blk-iopoll.h
deleted file mode 100644 (file)
index 77ae77c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef BLK_IOPOLL_H
-#define BLK_IOPOLL_H
-
-struct blk_iopoll;
-typedef int (blk_iopoll_fn)(struct blk_iopoll *, int);
-
-struct blk_iopoll {
-       struct list_head list;
-       unsigned long state;
-       unsigned long data;
-       int weight;
-       int max;
-       blk_iopoll_fn *poll;
-};
-
-enum {
-       IOPOLL_F_SCHED          = 0,
-       IOPOLL_F_DISABLE        = 1,
-};
-
-/*
- * Returns 0 if we successfully set the IOPOLL_F_SCHED bit, indicating
- * that we were the first to acquire this iop for scheduling. If this iop
- * is currently disabled, return "failure".
- */
-static inline int blk_iopoll_sched_prep(struct blk_iopoll *iop)
-{
-       if (!test_bit(IOPOLL_F_DISABLE, &iop->state))
-               return test_and_set_bit(IOPOLL_F_SCHED, &iop->state);
-
-       return 1;
-}
-
-static inline int blk_iopoll_disable_pending(struct blk_iopoll *iop)
-{
-       return test_bit(IOPOLL_F_DISABLE, &iop->state);
-}
-
-extern void blk_iopoll_sched(struct blk_iopoll *);
-extern void blk_iopoll_init(struct blk_iopoll *, int, blk_iopoll_fn *);
-extern void blk_iopoll_complete(struct blk_iopoll *);
-extern void __blk_iopoll_complete(struct blk_iopoll *);
-extern void blk_iopoll_enable(struct blk_iopoll *);
-extern void blk_iopoll_disable(struct blk_iopoll *);
-
-#endif
index 0fb6584..86a38ea 100644 (file)
@@ -188,7 +188,6 @@ enum rq_flag_bits {
        __REQ_PM,               /* runtime pm request */
        __REQ_HASHED,           /* on IO scheduler merge hash */
        __REQ_MQ_INFLIGHT,      /* track inflight for MQ */
-       __REQ_NO_TIMEOUT,       /* requests may never expire */
        __REQ_NR_BITS,          /* stops here */
 };
 
@@ -242,7 +241,6 @@ enum rq_flag_bits {
 #define REQ_PM                 (1ULL << __REQ_PM)
 #define REQ_HASHED             (1ULL << __REQ_HASHED)
 #define REQ_MQ_INFLIGHT                (1ULL << __REQ_MQ_INFLIGHT)
-#define REQ_NO_TIMEOUT         (1ULL << __REQ_NO_TIMEOUT)
 
 typedef unsigned int blk_qc_t;
 #define BLK_QC_T_NONE  -1U
index d372ea8..29189ae 100644 (file)
@@ -409,6 +409,7 @@ struct request_queue {
 
        unsigned int            rq_timeout;
        struct timer_list       timeout;
+       struct work_struct      timeout_work;
        struct list_head        timeout_list;
 
        struct list_head        icq_list;
index 5babb8e..b827e06 100644 (file)
@@ -40,46 +40,11 @@ static inline __u32 ceph_frag_mask_shift(__u32 f)
        return 24 - ceph_frag_bits(f);
 }
 
-static inline int ceph_frag_contains_value(__u32 f, __u32 v)
+static inline bool ceph_frag_contains_value(__u32 f, __u32 v)
 {
        return (v & ceph_frag_mask(f)) == ceph_frag_value(f);
 }
-static inline int ceph_frag_contains_frag(__u32 f, __u32 sub)
-{
-       /* is sub as specific as us, and contained by us? */
-       return ceph_frag_bits(sub) >= ceph_frag_bits(f) &&
-              (ceph_frag_value(sub) & ceph_frag_mask(f)) == ceph_frag_value(f);
-}
 
-static inline __u32 ceph_frag_parent(__u32 f)
-{
-       return ceph_frag_make(ceph_frag_bits(f) - 1,
-                        ceph_frag_value(f) & (ceph_frag_mask(f) << 1));
-}
-static inline int ceph_frag_is_left_child(__u32 f)
-{
-       return ceph_frag_bits(f) > 0 &&
-               (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 0;
-}
-static inline int ceph_frag_is_right_child(__u32 f)
-{
-       return ceph_frag_bits(f) > 0 &&
-               (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 1;
-}
-static inline __u32 ceph_frag_sibling(__u32 f)
-{
-       return ceph_frag_make(ceph_frag_bits(f),
-                     ceph_frag_value(f) ^ (0x1000000 >> ceph_frag_bits(f)));
-}
-static inline __u32 ceph_frag_left_child(__u32 f)
-{
-       return ceph_frag_make(ceph_frag_bits(f)+1, ceph_frag_value(f));
-}
-static inline __u32 ceph_frag_right_child(__u32 f)
-{
-       return ceph_frag_make(ceph_frag_bits(f)+1,
-             ceph_frag_value(f) | (0x1000000 >> (1+ceph_frag_bits(f))));
-}
 static inline __u32 ceph_frag_make_child(__u32 f, int by, int i)
 {
        int newbits = ceph_frag_bits(f) + by;
index 71b1d6c..8dbd787 100644 (file)
@@ -220,6 +220,7 @@ struct ceph_connection {
        struct ceph_entity_addr actual_peer_addr;
 
        /* message out temps */
+       struct ceph_msg_header out_hdr;
        struct ceph_msg *out_msg;        /* sending message (== tail of
                                            out_sent) */
        bool out_msg_done;
@@ -229,7 +230,6 @@ struct ceph_connection {
        int out_kvec_left;   /* kvec's left in out_kvec */
        int out_skip;        /* skip this many bytes */
        int out_kvec_bytes;  /* total bytes left */
-       bool out_kvec_is_msg; /* kvec refers to out_msg */
        int out_more;        /* there is more data after the kvecs */
        __le64 out_temp_ack; /* for writing an ack */
        struct ceph_timespec out_temp_keepalive2; /* for writing keepalive2
diff --git a/include/linux/clk/mmp.h b/include/linux/clk/mmp.h
new file mode 100644 (file)
index 0000000..607321f
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __CLK_MMP_H
+#define __CLK_MMP_H
+
+#include <linux/types.h>
+
+extern void pxa168_clk_init(phys_addr_t mpmu_phys,
+                           phys_addr_t apmu_phys,
+                           phys_addr_t apbc_phys);
+extern void pxa910_clk_init(phys_addr_t mpmu_phys,
+                           phys_addr_t apmu_phys,
+                           phys_addr_t apbc_phys,
+                           phys_addr_t apbcp_phys);
+extern void mmp2_clk_init(phys_addr_t mpmu_phys,
+                         phys_addr_t apmu_phys,
+                         phys_addr_t apbc_phys);
+
+#endif
index 75205df..9a63860 100644 (file)
@@ -195,6 +195,7 @@ enum {
        TI_CLKM_PRM,
        TI_CLKM_SCRM,
        TI_CLKM_CTRL,
+       TI_CLKM_PLLSS,
        CLK_MAX_MEMMAPS
 };
 
diff --git a/include/linux/clksrc-dbx500-prcmu.h b/include/linux/clksrc-dbx500-prcmu.h
deleted file mode 100644 (file)
index 4fb8119..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * License Terms: GNU General Public License v2
- * Author: Mattias Wallin <mattias.wallin@stericsson.com>
- *
- */
-#ifndef __CLKSRC_DBX500_PRCMU_H
-#define __CLKSRC_DBX500_PRCMU_H
-
-#include <linux/init.h>
-#include <linux/io.h>
-
-#ifdef CONFIG_CLKSRC_DBX500_PRCMU
-void __init clksrc_dbx500_prcmu_init(void __iomem *base);
-#else
-static inline void __init clksrc_dbx500_prcmu_init(void __iomem *base) {}
-#endif
-
-#endif
index f7300d0..f8165c1 100644 (file)
@@ -259,7 +259,24 @@ void configfs_unregister_default_group(struct config_group *group);
 
 /* These functions can sleep and can alloc with GFP_KERNEL */
 /* WARNING: These cannot be called underneath configfs callbacks!! */
-int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target);
-void configfs_undepend_item(struct configfs_subsystem *subsys, struct config_item *target);
+int configfs_depend_item(struct configfs_subsystem *subsys,
+                        struct config_item *target);
+void configfs_undepend_item(struct config_item *target);
+
+/*
+ * These functions can sleep and can alloc with GFP_KERNEL
+ * NOTE: These should be called only underneath configfs callbacks.
+ * NOTE: First parameter is a caller's subsystem, not target's.
+ * WARNING: These cannot be called on newly created item
+ *        (in make_group()/make_item() callback)
+ */
+int configfs_depend_item_unlocked(struct configfs_subsystem *caller_subsys,
+                                 struct config_item *target);
+
+
+static inline void configfs_undepend_item_unlocked(struct config_item *target)
+{
+       configfs_undepend_item(target);
+}
 
 #endif /* _CONFIGFS_H_ */
index 59915ea..fc14275 100644 (file)
@@ -85,10 +85,14 @@ extern int nr_cpu_ids;
  *    only one CPU.
  */
 
-extern const struct cpumask *const cpu_possible_mask;
-extern const struct cpumask *const cpu_online_mask;
-extern const struct cpumask *const cpu_present_mask;
-extern const struct cpumask *const cpu_active_mask;
+extern struct cpumask __cpu_possible_mask;
+extern struct cpumask __cpu_online_mask;
+extern struct cpumask __cpu_present_mask;
+extern struct cpumask __cpu_active_mask;
+#define cpu_possible_mask ((const struct cpumask *)&__cpu_possible_mask)
+#define cpu_online_mask   ((const struct cpumask *)&__cpu_online_mask)
+#define cpu_present_mask  ((const struct cpumask *)&__cpu_present_mask)
+#define cpu_active_mask   ((const struct cpumask *)&__cpu_active_mask)
 
 #if NR_CPUS > 1
 #define num_online_cpus()      cpumask_weight(cpu_online_mask)
@@ -716,14 +720,49 @@ extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS);
 #define for_each_present_cpu(cpu)  for_each_cpu((cpu), cpu_present_mask)
 
 /* Wrappers for arch boot code to manipulate normally-constant masks */
-void set_cpu_possible(unsigned int cpu, bool possible);
-void set_cpu_present(unsigned int cpu, bool present);
-void set_cpu_online(unsigned int cpu, bool online);
-void set_cpu_active(unsigned int cpu, bool active);
 void init_cpu_present(const struct cpumask *src);
 void init_cpu_possible(const struct cpumask *src);
 void init_cpu_online(const struct cpumask *src);
 
+static inline void
+set_cpu_possible(unsigned int cpu, bool possible)
+{
+       if (possible)
+               cpumask_set_cpu(cpu, &__cpu_possible_mask);
+       else
+               cpumask_clear_cpu(cpu, &__cpu_possible_mask);
+}
+
+static inline void
+set_cpu_present(unsigned int cpu, bool present)
+{
+       if (present)
+               cpumask_set_cpu(cpu, &__cpu_present_mask);
+       else
+               cpumask_clear_cpu(cpu, &__cpu_present_mask);
+}
+
+static inline void
+set_cpu_online(unsigned int cpu, bool online)
+{
+       if (online) {
+               cpumask_set_cpu(cpu, &__cpu_online_mask);
+               cpumask_set_cpu(cpu, &__cpu_active_mask);
+       } else {
+               cpumask_clear_cpu(cpu, &__cpu_online_mask);
+       }
+}
+
+static inline void
+set_cpu_active(unsigned int cpu, bool active)
+{
+       if (active)
+               cpumask_set_cpu(cpu, &__cpu_active_mask);
+       else
+               cpumask_clear_cpu(cpu, &__cpu_active_mask);
+}
+
+
 /**
  * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask *
  * @bitmap: the bitmap
index b415e52..8204c3d 100644 (file)
@@ -36,4 +36,11 @@ static inline bool vma_is_dax(struct vm_area_struct *vma)
 {
        return vma->vm_file && IS_DAX(vma->vm_file->f_mapping->host);
 }
+
+static inline bool dax_mapping(struct address_space *mapping)
+{
+       return mapping->host && IS_DAX(mapping->host);
+}
+int dax_writeback_mapping_range(struct address_space *mapping, loff_t start,
+               loff_t end);
 #endif
index 68030e2..6fa02a2 100644 (file)
@@ -89,7 +89,7 @@ struct devfreq_dev_profile {
        int (*get_cur_freq)(struct device *dev, unsigned long *freq);
        void (*exit)(struct device *dev);
 
-       unsigned int *freq_table;
+       unsigned long *freq_table;
        unsigned int max_state;
 };
 
index f627ba2..6d6f1fe 100644 (file)
@@ -1044,6 +1044,8 @@ extern int __must_check driver_attach(struct device_driver *drv);
 extern void device_initial_probe(struct device *dev);
 extern int __must_check device_reprobe(struct device *dev);
 
+extern bool device_is_bound(struct device *dev);
+
 /*
  * Easy functions for dynamically creating devices on the fly
  */
index c8e1831..99c0be0 100644 (file)
@@ -41,7 +41,6 @@ static inline void init_dma_attrs(struct dma_attrs *attrs)
        bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
 }
 
-#ifdef CONFIG_HAVE_DMA_ATTRS
 /**
  * dma_set_attr - set a specific attribute
  * @attr: attribute to set
@@ -67,14 +66,5 @@ static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
        BUG_ON(attr >= DMA_ATTR_MAX);
        return test_bit(attr, attrs->flags);
 }
-#else /* !CONFIG_HAVE_DMA_ATTRS */
-static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-}
 
-static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
-{
-       return 0;
-}
-#endif /* CONFIG_HAVE_DMA_ATTRS */
 #endif /* _DMA_ATTR_H */
index 2e551e2..75857cd 100644 (file)
@@ -6,8 +6,11 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/dma-attrs.h>
+#include <linux/dma-debug.h>
 #include <linux/dma-direction.h>
 #include <linux/scatterlist.h>
+#include <linux/kmemcheck.h>
+#include <linux/bug.h>
 
 /*
  * A dma_addr_t can hold any valid DMA or bus address for the platform.
@@ -83,10 +86,383 @@ static inline int is_device_dma_capable(struct device *dev)
        return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
 }
 
+#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
+/*
+ * These three functions are only for dma allocator.
+ * Don't use them in device drivers.
+ */
+int dma_alloc_from_coherent(struct device *dev, ssize_t size,
+                                      dma_addr_t *dma_handle, void **ret);
+int dma_release_from_coherent(struct device *dev, int order, void *vaddr);
+
+int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
+                           void *cpu_addr, size_t size, int *ret);
+#else
+#define dma_alloc_from_coherent(dev, size, handle, ret) (0)
+#define dma_release_from_coherent(dev, order, vaddr) (0)
+#define dma_mmap_from_coherent(dev, vma, vaddr, order, ret) (0)
+#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
+
 #ifdef CONFIG_HAS_DMA
 #include <asm/dma-mapping.h>
 #else
-#include <asm-generic/dma-mapping-broken.h>
+/*
+ * Define the dma api to allow compilation but not linking of
+ * dma dependent code.  Code that depends on the dma-mapping
+ * API needs to set 'depends on HAS_DMA' in its Kconfig
+ */
+extern struct dma_map_ops bad_dma_ops;
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+       return &bad_dma_ops;
+}
+#endif
+
+static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
+                                             size_t size,
+                                             enum dma_data_direction dir,
+                                             struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       dma_addr_t addr;
+
+       kmemcheck_mark_initialized(ptr, size);
+       BUG_ON(!valid_dma_direction(dir));
+       addr = ops->map_page(dev, virt_to_page(ptr),
+                            offset_in_page(ptr), size,
+                            dir, attrs);
+       debug_dma_map_page(dev, virt_to_page(ptr),
+                          offset_in_page(ptr), size,
+                          dir, addr, true);
+       return addr;
+}
+
+static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
+                                         size_t size,
+                                         enum dma_data_direction dir,
+                                         struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->unmap_page)
+               ops->unmap_page(dev, addr, size, dir, attrs);
+       debug_dma_unmap_page(dev, addr, size, dir, true);
+}
+
+/*
+ * dma_maps_sg_attrs returns 0 on error and > 0 on success.
+ * It should never return a value < 0.
+ */
+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+                                  int nents, enum dma_data_direction dir,
+                                  struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       int i, ents;
+       struct scatterlist *s;
+
+       for_each_sg(sg, s, nents, i)
+               kmemcheck_mark_initialized(sg_virt(s), s->length);
+       BUG_ON(!valid_dma_direction(dir));
+       ents = ops->map_sg(dev, sg, nents, dir, attrs);
+       BUG_ON(ents < 0);
+       debug_dma_map_sg(dev, sg, nents, ents, dir);
+
+       return ents;
+}
+
+static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
+                                     int nents, enum dma_data_direction dir,
+                                     struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       debug_dma_unmap_sg(dev, sg, nents, dir);
+       if (ops->unmap_sg)
+               ops->unmap_sg(dev, sg, nents, dir, attrs);
+}
+
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+                                     size_t offset, size_t size,
+                                     enum dma_data_direction dir)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       dma_addr_t addr;
+
+       kmemcheck_mark_initialized(page_address(page) + offset, size);
+       BUG_ON(!valid_dma_direction(dir));
+       addr = ops->map_page(dev, page, offset, size, dir, NULL);
+       debug_dma_map_page(dev, page, offset, size, dir, addr, false);
+
+       return addr;
+}
+
+static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
+                                 size_t size, enum dma_data_direction dir)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->unmap_page)
+               ops->unmap_page(dev, addr, size, dir, NULL);
+       debug_dma_unmap_page(dev, addr, size, dir, false);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+                                          size_t size,
+                                          enum dma_data_direction dir)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->sync_single_for_cpu)
+               ops->sync_single_for_cpu(dev, addr, size, dir);
+       debug_dma_sync_single_for_cpu(dev, addr, size, dir);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+                                             dma_addr_t addr, size_t size,
+                                             enum dma_data_direction dir)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->sync_single_for_device)
+               ops->sync_single_for_device(dev, addr, size, dir);
+       debug_dma_sync_single_for_device(dev, addr, size, dir);
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+                                                dma_addr_t addr,
+                                                unsigned long offset,
+                                                size_t size,
+                                                enum dma_data_direction dir)
+{
+       const struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->sync_single_for_cpu)
+               ops->sync_single_for_cpu(dev, addr + offset, size, dir);
+       debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+                                                   dma_addr_t addr,
+                                                   unsigned long offset,
+                                                   size_t size,
+                                                   enum dma_data_direction dir)
+{
+       const struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->sync_single_for_device)
+               ops->sync_single_for_device(dev, addr + offset, size, dir);
+       debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir);
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+                   int nelems, enum dma_data_direction dir)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->sync_sg_for_cpu)
+               ops->sync_sg_for_cpu(dev, sg, nelems, dir);
+       debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+                      int nelems, enum dma_data_direction dir)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!valid_dma_direction(dir));
+       if (ops->sync_sg_for_device)
+               ops->sync_sg_for_device(dev, sg, nelems, dir);
+       debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
+
+}
+
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
+
+void *dma_common_contiguous_remap(struct page *page, size_t size,
+                       unsigned long vm_flags,
+                       pgprot_t prot, const void *caller);
+
+void *dma_common_pages_remap(struct page **pages, size_t size,
+                       unsigned long vm_flags, pgprot_t prot,
+                       const void *caller);
+void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
+
+/**
+ * dma_mmap_attrs - map a coherent DMA allocation into user space
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @vma: vm_area_struct describing requested user mapping
+ * @cpu_addr: kernel CPU-view address returned from dma_alloc_attrs
+ * @handle: device-view address returned from dma_alloc_attrs
+ * @size: size of memory originally requested in dma_alloc_attrs
+ * @attrs: attributes of mapping properties requested in dma_alloc_attrs
+ *
+ * Map a coherent DMA buffer previously allocated by dma_alloc_attrs
+ * into user space.  The coherent DMA buffer must not be freed by the
+ * driver until the user space mapping has been released.
+ */
+static inline int
+dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
+              dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       BUG_ON(!ops);
+       if (ops->mmap)
+               return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+       return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+
+int
+dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+                      void *cpu_addr, dma_addr_t dma_addr, size_t size);
+
+static inline int
+dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
+                     dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       BUG_ON(!ops);
+       if (ops->get_sgtable)
+               return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
+                                       attrs);
+       return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
+}
+
+#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
+
+#ifndef arch_dma_alloc_attrs
+#define arch_dma_alloc_attrs(dev, flag)        (true)
+#endif
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+                                      dma_addr_t *dma_handle, gfp_t flag,
+                                      struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       void *cpu_addr;
+
+       BUG_ON(!ops);
+
+       if (dma_alloc_from_coherent(dev, size, dma_handle, &cpu_addr))
+               return cpu_addr;
+
+       if (!arch_dma_alloc_attrs(&dev, &flag))
+               return NULL;
+       if (!ops->alloc)
+               return NULL;
+
+       cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
+       debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
+       return cpu_addr;
+}
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+                                    void *cpu_addr, dma_addr_t dma_handle,
+                                    struct dma_attrs *attrs)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!ops);
+       WARN_ON(irqs_disabled());
+
+       if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
+               return;
+
+       if (!ops->free)
+               return;
+
+       debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+       ops->free(dev, size, cpu_addr, dma_handle, attrs);
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t flag)
+{
+       return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+               void *cpu_addr, dma_addr_t dma_handle)
+{
+       return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
+}
+
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t gfp)
+{
+       DEFINE_DMA_ATTRS(attrs);
+
+       dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
+       return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs);
+}
+
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+               void *cpu_addr, dma_addr_t dma_handle)
+{
+       DEFINE_DMA_ATTRS(attrs);
+
+       dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs);
+       dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+       debug_dma_mapping_error(dev, dma_addr);
+
+       if (get_dma_ops(dev)->mapping_error)
+               return get_dma_ops(dev)->mapping_error(dev, dma_addr);
+
+#ifdef DMA_ERROR_CODE
+       return dma_addr == DMA_ERROR_CODE;
+#else
+       return 0;
+#endif
+}
+
+#ifndef HAVE_ARCH_DMA_SUPPORTED
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       if (!ops)
+               return 0;
+       if (!ops->dma_supported)
+               return 1;
+       return ops->dma_supported(dev, mask);
+}
+#endif
+
+#ifndef HAVE_ARCH_DMA_SET_MASK
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       if (ops->set_dma_mask)
+               return ops->set_dma_mask(dev, mask);
+
+       if (!dev->dma_mask || !dma_supported(dev, mask))
+               return -EIO;
+       *dev->dma_mask = mask;
+       return 0;
+}
 #endif
 
 static inline u64 dma_get_mask(struct device *dev)
@@ -208,7 +584,13 @@ static inline int dma_get_cache_alignment(void)
 #define DMA_MEMORY_INCLUDES_CHILDREN   0x04
 #define DMA_MEMORY_EXCLUSIVE           0x08
 
-#ifndef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
+int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
+                               dma_addr_t device_addr, size_t size, int flags);
+void dma_release_declared_memory(struct device *dev);
+void *dma_mark_declared_memory_occupied(struct device *dev,
+                                       dma_addr_t device_addr, size_t size);
+#else
 static inline int
 dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
                            dma_addr_t device_addr, size_t size, int flags)
@@ -227,7 +609,7 @@ dma_mark_declared_memory_occupied(struct device *dev,
 {
        return ERR_PTR(-EBUSY);
 }
-#endif
+#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
 /*
  * Managed DMA API
@@ -240,13 +622,13 @@ extern void *dmam_alloc_noncoherent(struct device *dev, size_t size,
                                    dma_addr_t *dma_handle, gfp_t gfp);
 extern void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
                                  dma_addr_t dma_handle);
-#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
 extern int dmam_declare_coherent_memory(struct device *dev,
                                        phys_addr_t phys_addr,
                                        dma_addr_t device_addr, size_t size,
                                        int flags);
 extern void dmam_release_declared_memory(struct device *dev);
-#else /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
+#else /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 static inline int dmam_declare_coherent_memory(struct device *dev,
                                phys_addr_t phys_addr, dma_addr_t device_addr,
                                size_t size, gfp_t gfp)
@@ -257,24 +639,8 @@ static inline int dmam_declare_coherent_memory(struct device *dev,
 static inline void dmam_release_declared_memory(struct device *dev)
 {
 }
-#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-
-#ifndef CONFIG_HAVE_DMA_ATTRS
-struct dma_attrs;
-
-#define dma_map_single_attrs(dev, cpu_addr, size, dir, attrs) \
-       dma_map_single(dev, cpu_addr, size, dir)
+#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
-#define dma_unmap_single_attrs(dev, dma_addr, size, dir, attrs) \
-       dma_unmap_single(dev, dma_addr, size, dir)
-
-#define dma_map_sg_attrs(dev, sgl, nents, dir, attrs) \
-       dma_map_sg(dev, sgl, nents, dir)
-
-#define dma_unmap_sg_attrs(dev, sgl, nents, dir, attrs) \
-       dma_unmap_sg(dev, sgl, nents, dir)
-
-#else
 static inline void *dma_alloc_writecombine(struct device *dev, size_t size,
                                           dma_addr_t *dma_addr, gfp_t gfp)
 {
@@ -300,7 +666,6 @@ static inline int dma_mmap_writecombine(struct device *dev,
        dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
        return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
 }
-#endif /* CONFIG_HAVE_DMA_ATTRS */
 
 #ifdef CONFIG_NEED_DMA_MAP_STATE
 #define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME)        dma_addr_t ADDR_NAME
index 8723f2a..d6b3c99 100644 (file)
@@ -25,7 +25,6 @@
 */
 #ifndef DRBD_H
 #define DRBD_H
-#include <linux/connector.h>
 #include <asm/types.h>
 
 #ifdef __KERNEL__
@@ -52,7 +51,7 @@
 #endif
 
 extern const char *drbd_buildtag(void);
-#define REL_VERSION "8.4.5"
+#define REL_VERSION "8.4.6"
 #define API_VERSION 1
 #define PRO_VERSION_MIN 86
 #define PRO_VERSION_MAX 101
@@ -339,6 +338,8 @@ enum drbd_state_rv {
 #define MDF_AL_CLEAN           (1 << 7)
 #define MDF_AL_DISABLED                (1 << 8)
 
+#define MAX_PEERS 32
+
 enum drbd_uuid_index {
        UI_CURRENT,
        UI_BITMAP,
@@ -349,14 +350,35 @@ enum drbd_uuid_index {
        UI_EXTENDED_SIZE   /* Everything. */
 };
 
+#define HISTORY_UUIDS MAX_PEERS
+
 enum drbd_timeout_flag {
        UT_DEFAULT      = 0,
        UT_DEGRADED     = 1,
        UT_PEER_OUTDATED = 2,
 };
 
+enum drbd_notification_type {
+       NOTIFY_EXISTS,
+       NOTIFY_CREATE,
+       NOTIFY_CHANGE,
+       NOTIFY_DESTROY,
+       NOTIFY_CALL,
+       NOTIFY_RESPONSE,
+
+       NOTIFY_CONTINUES = 0x8000,
+       NOTIFY_FLAGS = NOTIFY_CONTINUES,
+};
+
 #define UUID_JUST_CREATED ((__u64)4)
 
+enum write_ordering_e {
+       WO_NONE,
+       WO_DRAIN_IO,
+       WO_BDEV_FLUSH,
+       WO_BIO_BARRIER
+};
+
 /* magic numbers used in meta data and network packets */
 #define DRBD_MAGIC 0x83740267
 #define DRBD_MAGIC_BIG 0x835a
index 7b131ed..2d0e5ad 100644 (file)
@@ -250,6 +250,76 @@ GENL_struct(DRBD_NLA_DETACH_PARMS, 13, detach_parms,
        __flg_field(1, DRBD_GENLA_F_MANDATORY,  force_detach)
 )
 
+GENL_struct(DRBD_NLA_RESOURCE_INFO, 15, resource_info,
+       __u32_field(1, 0, res_role)
+       __flg_field(2, 0, res_susp)
+       __flg_field(3, 0, res_susp_nod)
+       __flg_field(4, 0, res_susp_fen)
+       /* __flg_field(5, 0, res_weak) */
+)
+
+GENL_struct(DRBD_NLA_DEVICE_INFO, 16, device_info,
+       __u32_field(1, 0, dev_disk_state)
+)
+
+GENL_struct(DRBD_NLA_CONNECTION_INFO, 17, connection_info,
+       __u32_field(1, 0, conn_connection_state)
+       __u32_field(2, 0, conn_role)
+)
+
+GENL_struct(DRBD_NLA_PEER_DEVICE_INFO, 18, peer_device_info,
+       __u32_field(1, 0, peer_repl_state)
+       __u32_field(2, 0, peer_disk_state)
+       __u32_field(3, 0, peer_resync_susp_user)
+       __u32_field(4, 0, peer_resync_susp_peer)
+       __u32_field(5, 0, peer_resync_susp_dependency)
+)
+
+GENL_struct(DRBD_NLA_RESOURCE_STATISTICS, 19, resource_statistics,
+       __u32_field(1, 0, res_stat_write_ordering)
+)
+
+GENL_struct(DRBD_NLA_DEVICE_STATISTICS, 20, device_statistics,
+       __u64_field(1, 0, dev_size)  /* (sectors) */
+       __u64_field(2, 0, dev_read)  /* (sectors) */
+       __u64_field(3, 0, dev_write)  /* (sectors) */
+       __u64_field(4, 0, dev_al_writes)  /* activity log writes (count) */
+       __u64_field(5, 0, dev_bm_writes)  /*  bitmap writes  (count) */
+       __u32_field(6, 0, dev_upper_pending)  /* application requests in progress */
+       __u32_field(7, 0, dev_lower_pending)  /* backing device requests in progress */
+       __flg_field(8, 0, dev_upper_blocked)
+       __flg_field(9, 0, dev_lower_blocked)
+       __flg_field(10, 0, dev_al_suspended)  /* activity log suspended */
+       __u64_field(11, 0, dev_exposed_data_uuid)
+       __u64_field(12, 0, dev_current_uuid)
+       __u32_field(13, 0, dev_disk_flags)
+       __bin_field(14, 0, history_uuids, HISTORY_UUIDS * sizeof(__u64))
+)
+
+GENL_struct(DRBD_NLA_CONNECTION_STATISTICS, 21, connection_statistics,
+       __flg_field(1, 0, conn_congested)
+)
+
+GENL_struct(DRBD_NLA_PEER_DEVICE_STATISTICS, 22, peer_device_statistics,
+       __u64_field(1, 0, peer_dev_received)  /* sectors */
+       __u64_field(2, 0, peer_dev_sent)  /* sectors */
+       __u32_field(3, 0, peer_dev_pending)  /* number of requests */
+       __u32_field(4, 0, peer_dev_unacked)  /* number of requests */
+       __u64_field(5, 0, peer_dev_out_of_sync)  /* sectors */
+       __u64_field(6, 0, peer_dev_resync_failed)  /* sectors */
+       __u64_field(7, 0, peer_dev_bitmap_uuid)
+       __u32_field(9, 0, peer_dev_flags)
+)
+
+GENL_struct(DRBD_NLA_NOTIFICATION_HEADER, 23, drbd_notification_header,
+       __u32_field(1, DRBD_GENLA_F_MANDATORY, nh_type)
+)
+
+GENL_struct(DRBD_NLA_HELPER, 24, drbd_helper_info,
+       __str_field(1, DRBD_GENLA_F_MANDATORY, helper_name, 32)
+       __u32_field(2, DRBD_GENLA_F_MANDATORY, helper_status)
+)
+
 /*
  * Notifications and commands (genlmsghdr->cmd)
  */
@@ -382,3 +452,82 @@ GENL_op(DRBD_ADM_GET_TIMEOUT_TYPE, 26, GENL_doit(drbd_adm_get_timeout_type),
        GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
 GENL_op(DRBD_ADM_DOWN,         27, GENL_doit(drbd_adm_down),
        GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
+
+GENL_op(DRBD_ADM_GET_RESOURCES, 30,
+        GENL_op_init(
+                .dumpit = drbd_adm_dump_resources,
+        ),
+        GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_RESOURCE_INFO, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_RESOURCE_STATISTICS, DRBD_GENLA_F_MANDATORY))
+
+GENL_op(DRBD_ADM_GET_DEVICES, 31,
+        GENL_op_init(
+                .dumpit = drbd_adm_dump_devices,
+                .done = drbd_adm_dump_devices_done,
+        ),
+        GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_DEVICE_INFO, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_DEVICE_STATISTICS, DRBD_GENLA_F_MANDATORY))
+
+GENL_op(DRBD_ADM_GET_CONNECTIONS, 32,
+        GENL_op_init(
+                .dumpit = drbd_adm_dump_connections,
+                .done = drbd_adm_dump_connections_done,
+        ),
+        GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_CONNECTION_INFO, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_CONNECTION_STATISTICS, DRBD_GENLA_F_MANDATORY))
+
+GENL_op(DRBD_ADM_GET_PEER_DEVICES, 33,
+        GENL_op_init(
+                .dumpit = drbd_adm_dump_peer_devices,
+                .done = drbd_adm_dump_peer_devices_done,
+        ),
+        GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_PEER_DEVICE_INFO, DRBD_GENLA_F_MANDATORY)
+        GENL_tla_expected(DRBD_NLA_PEER_DEVICE_STATISTICS, DRBD_GENLA_F_MANDATORY))
+
+GENL_notification(
+       DRBD_RESOURCE_STATE, 34, events,
+       GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_RESOURCE_INFO, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_RESOURCE_STATISTICS, DRBD_F_REQUIRED))
+
+GENL_notification(
+       DRBD_DEVICE_STATE, 35, events,
+       GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_DEVICE_INFO, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_DEVICE_STATISTICS, DRBD_F_REQUIRED))
+
+GENL_notification(
+       DRBD_CONNECTION_STATE, 36, events,
+       GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_CONNECTION_INFO, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_CONNECTION_STATISTICS, DRBD_F_REQUIRED))
+
+GENL_notification(
+       DRBD_PEER_DEVICE_STATE, 37, events,
+       GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_PEER_DEVICE_INFO, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_PEER_DEVICE_STATISTICS, DRBD_F_REQUIRED))
+
+GENL_op(
+       DRBD_ADM_GET_INITIAL_STATE, 38,
+       GENL_op_init(
+               .dumpit = drbd_adm_get_initial_state,
+       ),
+       GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY))
+
+GENL_notification(
+       DRBD_HELPER, 40, events,
+       GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
+       GENL_tla_expected(DRBD_NLA_HELPER, DRBD_F_REQUIRED))
+
+GENL_notification(
+       DRBD_INITIAL_STATE_DONE, 41, events,
+       GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED))
index eb73d74..1a20462 100644 (file)
@@ -433,7 +433,8 @@ struct address_space {
        struct rw_semaphore     i_mmap_rwsem;   /* protect tree, count, list */
        /* Protected by tree_lock together with the radix tree */
        unsigned long           nrpages;        /* number of total pages */
-       unsigned long           nrshadows;      /* number of shadow entries */
+       /* number of shadow or DAX exceptional entries */
+       unsigned long           nrexceptional;
        pgoff_t                 writeback_index;/* writeback starts here */
        const struct address_space_operations *a_ops;   /* methods */
        unsigned long           flags;          /* error bits/gfp mask */
@@ -714,6 +715,31 @@ enum inode_i_mutex_lock_class
        I_MUTEX_PARENT2,
 };
 
+static inline void inode_lock(struct inode *inode)
+{
+       mutex_lock(&inode->i_mutex);
+}
+
+static inline void inode_unlock(struct inode *inode)
+{
+       mutex_unlock(&inode->i_mutex);
+}
+
+static inline int inode_trylock(struct inode *inode)
+{
+       return mutex_trylock(&inode->i_mutex);
+}
+
+static inline int inode_is_locked(struct inode *inode)
+{
+       return mutex_is_locked(&inode->i_mutex);
+}
+
+static inline void inode_lock_nested(struct inode *inode, unsigned subclass)
+{
+       mutex_lock_nested(&inode->i_mutex, subclass);
+}
+
 void lock_two_nondirectories(struct inode *, struct inode*);
 void unlock_two_nondirectories(struct inode *, struct inode*);
 
@@ -3047,8 +3073,8 @@ static inline bool dir_emit_dots(struct file *file, struct dir_context *ctx)
 }
 static inline bool dir_relax(struct inode *inode)
 {
-       mutex_unlock(&inode->i_mutex);
-       mutex_lock(&inode->i_mutex);
+       inode_unlock(inode);
+       inode_lock(inode);
        return !IS_DEADDIR(inode);
 }
 
index cfe81e1..459fd25 100644 (file)
@@ -120,15 +120,15 @@ extern void vma_adjust_trans_huge(struct vm_area_struct *vma,
                                    unsigned long start,
                                    unsigned long end,
                                    long adjust_next);
-extern bool __pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma,
-               spinlock_t **ptl);
+extern spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd,
+               struct vm_area_struct *vma);
 /* mmap_sem must be held on entry */
-static inline bool pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma,
-               spinlock_t **ptl)
+static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
+               struct vm_area_struct *vma)
 {
        VM_BUG_ON_VMA(!rwsem_is_locked(&vma->vm_mm->mmap_sem), vma);
        if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd))
-               return __pmd_trans_huge_lock(pmd, vma, ptl);
+               return __pmd_trans_huge_lock(pmd, vma);
        else
                return false;
 }
@@ -190,10 +190,10 @@ static inline void vma_adjust_trans_huge(struct vm_area_struct *vma,
                                         long adjust_next)
 {
 }
-static inline bool pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma,
-               spinlock_t **ptl)
+static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
+               struct vm_area_struct *vma)
 {
-       return false;
+       return NULL;
 }
 
 static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
index 013fd9b..083d61e 100644 (file)
@@ -135,6 +135,20 @@ static inline void *idr_find(struct idr *idr, int id)
 #define idr_for_each_entry(idp, entry, id)                     \
        for (id = 0; ((entry) = idr_get_next(idp, &(id))) != NULL; ++id)
 
+/**
+ * idr_for_each_entry - continue iteration over an idr's elements of a given type
+ * @idp:     idr handle
+ * @entry:   the type * to use as cursor
+ * @id:      id entry's key
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define idr_for_each_entry_continue(idp, entry, id)                    \
+       for ((entry) = idr_get_next((idp), &(id));                      \
+            entry;                                                     \
+            ++id, (entry) = idr_get_next((idp), &(id)))
+
 /*
  * IDA - IDR based id allocator, use when translation from id to
  * pointer isn't necessary.
index cb30edb..0e95fcc 100644 (file)
@@ -413,7 +413,7 @@ enum
        NET_TX_SOFTIRQ,
        NET_RX_SOFTIRQ,
        BLOCK_SOFTIRQ,
-       BLOCK_IOPOLL_SOFTIRQ,
+       IRQ_POLL_SOFTIRQ,
        TASKLET_SOFTIRQ,
        SCHED_SOFTIRQ,
        HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on the
index fffd88d..32403b5 100644 (file)
@@ -29,6 +29,7 @@ struct device;
 struct resource;
 
 __visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
+void __ioread32_copy(void *to, const void __iomem *from, size_t count);
 void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
 
 #ifdef CONFIG_MMU
diff --git a/include/linux/irq_poll.h b/include/linux/irq_poll.h
new file mode 100644 (file)
index 0000000..3e8c1b8
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef IRQ_POLL_H
+#define IRQ_POLL_H
+
+struct irq_poll;
+typedef int (irq_poll_fn)(struct irq_poll *, int);
+
+struct irq_poll {
+       struct list_head list;
+       unsigned long state;
+       int weight;
+       irq_poll_fn *poll;
+};
+
+enum {
+       IRQ_POLL_F_SCHED        = 0,
+       IRQ_POLL_F_DISABLE      = 1,
+};
+
+extern void irq_poll_sched(struct irq_poll *);
+extern void irq_poll_init(struct irq_poll *, int, irq_poll_fn *);
+extern void irq_poll_complete(struct irq_poll *);
+extern void irq_poll_enable(struct irq_poll *);
+extern void irq_poll_disable(struct irq_poll *);
+
+#endif
index 7b68d27..2cc643c 100644 (file)
@@ -109,11 +109,7 @@ struct compat_kexec_segment {
 };
 #endif
 
-struct kexec_sha_region {
-       unsigned long start;
-       unsigned long len;
-};
-
+#ifdef CONFIG_KEXEC_FILE
 struct purgatory_info {
        /* Pointer to elf header of read only purgatory */
        Elf_Ehdr *ehdr;
@@ -130,6 +126,28 @@ struct purgatory_info {
        unsigned long purgatory_load_addr;
 };
 
+typedef int (kexec_probe_t)(const char *kernel_buf, unsigned long kernel_size);
+typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf,
+                            unsigned long kernel_len, char *initrd,
+                            unsigned long initrd_len, char *cmdline,
+                            unsigned long cmdline_len);
+typedef int (kexec_cleanup_t)(void *loader_data);
+
+#ifdef CONFIG_KEXEC_VERIFY_SIG
+typedef int (kexec_verify_sig_t)(const char *kernel_buf,
+                                unsigned long kernel_len);
+#endif
+
+struct kexec_file_ops {
+       kexec_probe_t *probe;
+       kexec_load_t *load;
+       kexec_cleanup_t *cleanup;
+#ifdef CONFIG_KEXEC_VERIFY_SIG
+       kexec_verify_sig_t *verify_sig;
+#endif
+};
+#endif
+
 struct kimage {
        kimage_entry_t head;
        kimage_entry_t *entry;
@@ -161,6 +179,7 @@ struct kimage {
        struct kimage_arch arch;
 #endif
 
+#ifdef CONFIG_KEXEC_FILE
        /* Additional fields for file based kexec syscall */
        void *kernel_buf;
        unsigned long kernel_buf_len;
@@ -179,38 +198,7 @@ struct kimage {
 
        /* Information for loading purgatory */
        struct purgatory_info purgatory_info;
-};
-
-/*
- * Keeps track of buffer parameters as provided by caller for requesting
- * memory placement of buffer.
- */
-struct kexec_buf {
-       struct kimage *image;
-       char *buffer;
-       unsigned long bufsz;
-       unsigned long mem;
-       unsigned long memsz;
-       unsigned long buf_align;
-       unsigned long buf_min;
-       unsigned long buf_max;
-       bool top_down;          /* allocate from top of memory hole */
-};
-
-typedef int (kexec_probe_t)(const char *kernel_buf, unsigned long kernel_size);
-typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf,
-                            unsigned long kernel_len, char *initrd,
-                            unsigned long initrd_len, char *cmdline,
-                            unsigned long cmdline_len);
-typedef int (kexec_cleanup_t)(void *loader_data);
-typedef int (kexec_verify_sig_t)(const char *kernel_buf,
-                                unsigned long kernel_len);
-
-struct kexec_file_ops {
-       kexec_probe_t *probe;
-       kexec_load_t *load;
-       kexec_cleanup_t *cleanup;
-       kexec_verify_sig_t *verify_sig;
+#endif
 };
 
 /* kexec interface functions */
index 034117b..d675011 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef NVM_H
 #define NVM_H
 
+#include <linux/types.h>
+
 enum {
        NVM_IO_OK = 0,
        NVM_IO_REQUEUE = 1,
@@ -11,12 +13,74 @@ enum {
        NVM_IOTYPE_GC = 1,
 };
 
+#define NVM_BLK_BITS (16)
+#define NVM_PG_BITS  (16)
+#define NVM_SEC_BITS (8)
+#define NVM_PL_BITS  (8)
+#define NVM_LUN_BITS (8)
+#define NVM_CH_BITS  (8)
+
+struct ppa_addr {
+       /* Generic structure for all addresses */
+       union {
+               struct {
+                       u64 blk         : NVM_BLK_BITS;
+                       u64 pg          : NVM_PG_BITS;
+                       u64 sec         : NVM_SEC_BITS;
+                       u64 pl          : NVM_PL_BITS;
+                       u64 lun         : NVM_LUN_BITS;
+                       u64 ch          : NVM_CH_BITS;
+               } g;
+
+               u64 ppa;
+       };
+};
+
+struct nvm_rq;
+struct nvm_id;
+struct nvm_dev;
+
+typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
+typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
+typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
+typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
+                               nvm_l2p_update_fn *, void *);
+typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
+                               nvm_bb_update_fn *, void *);
+typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
+typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
+typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
+typedef void (nvm_destroy_dma_pool_fn)(void *);
+typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
+                                                               dma_addr_t *);
+typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
+
+struct nvm_dev_ops {
+       nvm_id_fn               *identity;
+       nvm_get_l2p_tbl_fn      *get_l2p_tbl;
+       nvm_op_bb_tbl_fn        *get_bb_tbl;
+       nvm_op_set_bb_fn        *set_bb_tbl;
+
+       nvm_submit_io_fn        *submit_io;
+       nvm_erase_blk_fn        *erase_block;
+
+       nvm_create_dma_pool_fn  *create_dma_pool;
+       nvm_destroy_dma_pool_fn *destroy_dma_pool;
+       nvm_dev_dma_alloc_fn    *dev_dma_alloc;
+       nvm_dev_dma_free_fn     *dev_dma_free;
+
+       unsigned int            max_phys_sect;
+};
+
+
+
 #ifdef CONFIG_NVM
 
 #include <linux/blkdev.h>
-#include <linux/types.h>
 #include <linux/file.h>
 #include <linux/dmapool.h>
+#include <uapi/linux/lightnvm.h>
 
 enum {
        /* HW Responsibilities */
@@ -58,8 +122,29 @@ enum {
        /* Block Types */
        NVM_BLK_T_FREE          = 0x0,
        NVM_BLK_T_BAD           = 0x1,
-       NVM_BLK_T_DEV           = 0x2,
-       NVM_BLK_T_HOST          = 0x4,
+       NVM_BLK_T_GRWN_BAD      = 0x2,
+       NVM_BLK_T_DEV           = 0x4,
+       NVM_BLK_T_HOST          = 0x8,
+
+       /* Memory capabilities */
+       NVM_ID_CAP_SLC          = 0x1,
+       NVM_ID_CAP_CMD_SUSPEND  = 0x2,
+       NVM_ID_CAP_SCRAMBLE     = 0x4,
+       NVM_ID_CAP_ENCRYPT      = 0x8,
+
+       /* Memory types */
+       NVM_ID_FMTYPE_SLC       = 0,
+       NVM_ID_FMTYPE_MLC       = 1,
+};
+
+struct nvm_id_lp_mlc {
+       u16     num_pairs;
+       u8      pairs[886];
+};
+
+struct nvm_id_lp_tbl {
+       __u8    id[8];
+       struct nvm_id_lp_mlc mlc;
 };
 
 struct nvm_id_group {
@@ -82,6 +167,8 @@ struct nvm_id_group {
        u32     mpos;
        u32     mccap;
        u16     cpar;
+
+       struct nvm_id_lp_tbl lptbl;
 };
 
 struct nvm_addr_format {
@@ -125,28 +212,8 @@ struct nvm_tgt_instance {
 #define NVM_VERSION_MINOR 0
 #define NVM_VERSION_PATCH 0
 
-#define NVM_BLK_BITS (16)
-#define NVM_PG_BITS  (16)
-#define NVM_SEC_BITS (8)
-#define NVM_PL_BITS  (8)
-#define NVM_LUN_BITS (8)
-#define NVM_CH_BITS  (8)
-
-struct ppa_addr {
-       /* Generic structure for all addresses */
-       union {
-               struct {
-                       u64 blk         : NVM_BLK_BITS;
-                       u64 pg          : NVM_PG_BITS;
-                       u64 sec         : NVM_SEC_BITS;
-                       u64 pl          : NVM_PL_BITS;
-                       u64 lun         : NVM_LUN_BITS;
-                       u64 ch          : NVM_CH_BITS;
-               } g;
-
-               u64 ppa;
-       };
-};
+struct nvm_rq;
+typedef void (nvm_end_io_fn)(struct nvm_rq *);
 
 struct nvm_rq {
        struct nvm_tgt_instance *ins;
@@ -164,9 +231,14 @@ struct nvm_rq {
        void *metadata;
        dma_addr_t dma_metadata;
 
+       struct completion *wait;
+       nvm_end_io_fn *end_io;
+
        uint8_t opcode;
        uint16_t nr_pages;
        uint16_t flags;
+
+       int error;
 };
 
 static inline struct nvm_rq *nvm_rq_from_pdu(void *pdu)
@@ -181,51 +253,31 @@ static inline void *nvm_rq_to_pdu(struct nvm_rq *rqdata)
 
 struct nvm_block;
 
-typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
-typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
-typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
-typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
-                               nvm_l2p_update_fn *, void *);
-typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
-                               nvm_bb_update_fn *, void *);
-typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
-typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
-typedef void (nvm_destroy_dma_pool_fn)(void *);
-typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
-                                                               dma_addr_t *);
-typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
-
-struct nvm_dev_ops {
-       nvm_id_fn               *identity;
-       nvm_get_l2p_tbl_fn      *get_l2p_tbl;
-       nvm_op_bb_tbl_fn        *get_bb_tbl;
-       nvm_op_set_bb_fn        *set_bb_tbl;
-
-       nvm_submit_io_fn        *submit_io;
-       nvm_erase_blk_fn        *erase_block;
-
-       nvm_create_dma_pool_fn  *create_dma_pool;
-       nvm_destroy_dma_pool_fn *destroy_dma_pool;
-       nvm_dev_dma_alloc_fn    *dev_dma_alloc;
-       nvm_dev_dma_free_fn     *dev_dma_free;
-
-       unsigned int            max_phys_sect;
-};
-
 struct nvm_lun {
        int id;
 
        int lun_id;
        int chnl_id;
 
-       unsigned int nr_inuse_blocks;   /* Number of used blocks */
+       /* It is up to the target to mark blocks as closed. If the target does
+        * not do it, all blocks are marked as open, and nr_open_blocks
+        * represents the number of blocks in use
+        */
+       unsigned int nr_open_blocks;    /* Number of used, writable blocks */
+       unsigned int nr_closed_blocks;  /* Number of used, read-only blocks */
        unsigned int nr_free_blocks;    /* Number of unused blocks */
        unsigned int nr_bad_blocks;     /* Number of bad blocks */
-       struct nvm_block *blocks;
 
        spinlock_t lock;
+
+       struct nvm_block *blocks;
+};
+
+enum {
+       NVM_BLK_ST_FREE =       0x1,    /* Free block */
+       NVM_BLK_ST_OPEN =       0x2,    /* Open block - read-write */
+       NVM_BLK_ST_CLOSED =     0x4,    /* Closed block - read-only */
+       NVM_BLK_ST_BAD =        0x8,    /* Bad block */
 };
 
 struct nvm_block {
@@ -234,7 +286,16 @@ struct nvm_block {
        unsigned long id;
 
        void *priv;
-       int type;
+       int state;
+};
+
+/* system block cpu representation */
+struct nvm_sb_info {
+       unsigned long           seqnr;
+       unsigned long           erase_cnt;
+       unsigned int            version;
+       char                    mmtype[NVM_MMTYPE_LEN];
+       struct ppa_addr         fs_ppa;
 };
 
 struct nvm_dev {
@@ -247,6 +308,9 @@ struct nvm_dev {
        struct nvmm_type *mt;
        void *mp;
 
+       /* System blocks */
+       struct nvm_sb_info sb;
+
        /* Device information */
        int nr_chnls;
        int nr_planes;
@@ -256,6 +320,7 @@ struct nvm_dev {
        int blks_per_lun;
        int sec_size;
        int oob_size;
+       int mccap;
        struct nvm_addr_format ppaf;
 
        /* Calculated/Cached values. These do not reflect the actual usable
@@ -268,6 +333,10 @@ struct nvm_dev {
        int sec_per_blk;
        int sec_per_lun;
 
+       /* lower page table */
+       int lps_per_blk;
+       int *lptbl;
+
        unsigned long total_pages;
        unsigned long total_blocks;
        int nr_luns;
@@ -280,6 +349,8 @@ struct nvm_dev {
        /* Backend device */
        struct request_queue *q;
        char name[DISK_NAME_LEN];
+
+       struct mutex mlock;
 };
 
 static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev,
@@ -345,9 +416,13 @@ static inline struct ppa_addr block_to_ppa(struct nvm_dev *dev,
        return ppa;
 }
 
+static inline int ppa_to_slc(struct nvm_dev *dev, int slc_pg)
+{
+       return dev->lptbl[slc_pg];
+}
+
 typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *);
 typedef sector_t (nvm_tgt_capacity_fn)(void *);
-typedef int (nvm_tgt_end_io_fn)(struct nvm_rq *, int);
 typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int);
 typedef void (nvm_tgt_exit_fn)(void *);
 
@@ -358,7 +433,7 @@ struct nvm_tgt_type {
        /* target entry points */
        nvm_tgt_make_rq_fn *make_rq;
        nvm_tgt_capacity_fn *capacity;
-       nvm_tgt_end_io_fn *end_io;
+       nvm_end_io_fn *end_io;
 
        /* module-specific init/teardown */
        nvm_tgt_init_fn *init;
@@ -383,7 +458,6 @@ typedef int (nvmm_open_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef int (nvmm_close_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef void (nvmm_flush_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef int (nvmm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef int (nvmm_end_io_fn)(struct nvm_rq *, int);
 typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *,
                                                                unsigned long);
 typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int);
@@ -397,6 +471,8 @@ struct nvmm_type {
        nvmm_unregister_fn *unregister_mgr;
 
        /* Block administration callbacks */
+       nvmm_get_blk_fn *get_blk_unlocked;
+       nvmm_put_blk_fn *put_blk_unlocked;
        nvmm_get_blk_fn *get_blk;
        nvmm_put_blk_fn *put_blk;
        nvmm_open_blk_fn *open_blk;
@@ -404,7 +480,6 @@ struct nvmm_type {
        nvmm_flush_blk_fn *flush_blk;
 
        nvmm_submit_io_fn *submit_io;
-       nvmm_end_io_fn *end_io;
        nvmm_erase_blk_fn *erase_blk;
 
        /* Configuration management */
@@ -418,6 +493,10 @@ struct nvmm_type {
 extern int nvm_register_mgr(struct nvmm_type *);
 extern void nvm_unregister_mgr(struct nvmm_type *);
 
+extern struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *,
+                                       struct nvm_lun *, unsigned long);
+extern void nvm_put_blk_unlocked(struct nvm_dev *, struct nvm_block *);
+
 extern struct nvm_block *nvm_get_blk(struct nvm_dev *, struct nvm_lun *,
                                                                unsigned long);
 extern void nvm_put_blk(struct nvm_dev *, struct nvm_block *);
@@ -427,7 +506,36 @@ extern int nvm_register(struct request_queue *, char *,
 extern void nvm_unregister(char *);
 
 extern int nvm_submit_io(struct nvm_dev *, struct nvm_rq *);
+extern void nvm_generic_to_addr_mode(struct nvm_dev *, struct nvm_rq *);
+extern void nvm_addr_to_generic_mode(struct nvm_dev *, struct nvm_rq *);
+extern int nvm_set_rqd_ppalist(struct nvm_dev *, struct nvm_rq *,
+                                                       struct ppa_addr *, int);
+extern void nvm_free_rqd_ppalist(struct nvm_dev *, struct nvm_rq *);
+extern int nvm_erase_ppa(struct nvm_dev *, struct ppa_addr *, int);
 extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *);
+extern void nvm_end_io(struct nvm_rq *, int);
+extern int nvm_submit_ppa(struct nvm_dev *, struct ppa_addr *, int, int, int,
+                                                               void *, int);
+
+/* sysblk.c */
+#define NVM_SYSBLK_MAGIC 0x4E564D53 /* "NVMS" */
+
+/* system block on disk representation */
+struct nvm_system_block {
+       __be32                  magic;          /* magic signature */
+       __be32                  seqnr;          /* sequence number */
+       __be32                  erase_cnt;      /* erase count */
+       __be16                  version;        /* version number */
+       u8                      mmtype[NVM_MMTYPE_LEN]; /* media manager name */
+       __be64                  fs_ppa;         /* PPA for media manager
+                                                * superblock */
+};
+
+extern int nvm_get_sysblock(struct nvm_dev *, struct nvm_sb_info *);
+extern int nvm_update_sysblock(struct nvm_dev *, struct nvm_sb_info *);
+extern int nvm_init_sysblock(struct nvm_dev *, struct nvm_sb_info *);
+
+extern int nvm_dev_factory(struct nvm_dev *, int flags);
 #else /* CONFIG_NVM */
 struct nvm_dev_ops;
 
index 2a6b994..cb0ba9f 100644 (file)
@@ -40,7 +40,7 @@ struct list_lru_node {
        spinlock_t              lock;
        /* global list, used for the root cgroup in cgroup aware lrus */
        struct list_lru_one     lru;
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
        /* for cgroup aware lrus points to per cgroup lists, otherwise NULL */
        struct list_lru_memcg   *memcg_lrus;
 #endif
@@ -48,7 +48,7 @@ struct list_lru_node {
 
 struct list_lru {
        struct list_lru_node    *node;
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
        struct list_head        list;
 #endif
 };
index 4626228..04fc6e6 100644 (file)
@@ -264,7 +264,7 @@ extern unsigned int lc_put(struct lru_cache *lc, struct lc_element *e);
 extern void lc_committed(struct lru_cache *lc);
 
 struct seq_file;
-extern size_t lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc);
+extern void lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc);
 
 extern void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext,
                                void (*detail) (struct seq_file *, struct lc_element *));
index 4356686..6b784c5 100644 (file)
@@ -9,8 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define LZ4_MEM_COMPRESS       (4096 * sizeof(unsigned char *))
-#define LZ4HC_MEM_COMPRESS     (65538 * sizeof(unsigned char *))
+#define LZ4_MEM_COMPRESS       (16384)
+#define LZ4HC_MEM_COMPRESS     (262144 + (2 * sizeof(unsigned char *)))
 
 /*
  * lz4_compressbound()
index 189f04d..9ae48d4 100644 (file)
@@ -50,6 +50,9 @@ enum mem_cgroup_stat_index {
        MEM_CGROUP_STAT_WRITEBACK,      /* # of pages under writeback */
        MEM_CGROUP_STAT_SWAP,           /* # of pages, swapped out */
        MEM_CGROUP_STAT_NSTATS,
+       /* default hierarchy stats */
+       MEMCG_SOCK,
+       MEMCG_NR_STAT,
 };
 
 struct mem_cgroup_reclaim_cookie {
@@ -85,15 +88,9 @@ enum mem_cgroup_events_target {
        MEM_CGROUP_NTARGETS,
 };
 
-struct cg_proto {
-       struct page_counter     memory_allocated;       /* Current allocated memory. */
-       int                     memory_pressure;
-       bool                    active;
-};
-
 #ifdef CONFIG_MEMCG
 struct mem_cgroup_stat_cpu {
-       long count[MEM_CGROUP_STAT_NSTATS];
+       long count[MEMCG_NR_STAT];
        unsigned long events[MEMCG_NR_EVENTS];
        unsigned long nr_page_events;
        unsigned long targets[MEM_CGROUP_NTARGETS];
@@ -152,6 +149,12 @@ struct mem_cgroup_thresholds {
        struct mem_cgroup_threshold_ary *spare;
 };
 
+enum memcg_kmem_state {
+       KMEM_NONE,
+       KMEM_ALLOCATED,
+       KMEM_ONLINE,
+};
+
 /*
  * The memory controller data structure. The memory controller controls both
  * page cache and RSS per cgroup. We would eventually like to provide
@@ -163,8 +166,12 @@ struct mem_cgroup {
 
        /* Accounted resources */
        struct page_counter memory;
+       struct page_counter swap;
+
+       /* Legacy consumer-oriented counters */
        struct page_counter memsw;
        struct page_counter kmem;
+       struct page_counter tcpmem;
 
        /* Normal memory consumption range */
        unsigned long low;
@@ -178,9 +185,6 @@ struct mem_cgroup {
        /* vmpressure notifications */
        struct vmpressure vmpressure;
 
-       /* css_online() has been completed */
-       int initialized;
-
        /*
         * Should the accounting and control be hierarchical, per subtree?
         */
@@ -227,14 +231,16 @@ struct mem_cgroup {
         */
        struct mem_cgroup_stat_cpu __percpu *stat;
 
-#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET)
-       struct cg_proto tcp_mem;
-#endif
-#if defined(CONFIG_MEMCG_KMEM)
+       unsigned long           socket_pressure;
+
+       /* Legacy tcp memory accounting */
+       bool                    tcpmem_active;
+       int                     tcpmem_pressure;
+
+#ifndef CONFIG_SLOB
         /* Index in the kmem_cache->memcg_params.memcg_caches array */
        int kmemcg_id;
-       bool kmem_acct_activated;
-       bool kmem_acct_active;
+       enum memcg_kmem_state kmem_state;
 #endif
 
        int last_scanned_node;
@@ -249,10 +255,6 @@ struct mem_cgroup {
        struct wb_domain cgwb_domain;
 #endif
 
-#ifdef CONFIG_INET
-       unsigned long           socket_pressure;
-#endif
-
        /* List of events which userspace want to receive */
        struct list_head event_list;
        spinlock_t event_list_lock;
@@ -356,6 +358,13 @@ static inline bool mem_cgroup_disabled(void)
        return !cgroup_subsys_enabled(memory_cgrp_subsys);
 }
 
+static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
+{
+       if (mem_cgroup_disabled())
+               return true;
+       return !!(memcg->css.flags & CSS_ONLINE);
+}
+
 /*
  * For memory reclaim.
  */
@@ -364,20 +373,6 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *memcg);
 void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
                int nr_pages);
 
-static inline bool mem_cgroup_lruvec_online(struct lruvec *lruvec)
-{
-       struct mem_cgroup_per_zone *mz;
-       struct mem_cgroup *memcg;
-
-       if (mem_cgroup_disabled())
-               return true;
-
-       mz = container_of(lruvec, struct mem_cgroup_per_zone, lruvec);
-       memcg = mz->memcg;
-
-       return !!(memcg->css.flags & CSS_ONLINE);
-}
-
 static inline
 unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru)
 {
@@ -590,13 +585,13 @@ static inline bool mem_cgroup_disabled(void)
        return true;
 }
 
-static inline bool
-mem_cgroup_inactive_anon_is_low(struct lruvec *lruvec)
+static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
 {
        return true;
 }
 
-static inline bool mem_cgroup_lruvec_online(struct lruvec *lruvec)
+static inline bool
+mem_cgroup_inactive_anon_is_low(struct lruvec *lruvec)
 {
        return true;
 }
@@ -707,15 +702,13 @@ void sock_update_memcg(struct sock *sk);
 void sock_release_memcg(struct sock *sk);
 bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages);
 void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages);
-#if defined(CONFIG_MEMCG) && defined(CONFIG_INET)
+#ifdef CONFIG_MEMCG
 extern struct static_key_false memcg_sockets_enabled_key;
 #define mem_cgroup_sockets_enabled static_branch_unlikely(&memcg_sockets_enabled_key)
 static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
 {
-#ifdef CONFIG_MEMCG_KMEM
-       if (memcg->tcp_mem.memory_pressure)
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_pressure)
                return true;
-#endif
        do {
                if (time_before(jiffies, memcg->socket_pressure))
                        return true;
@@ -730,7 +723,7 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
 }
 #endif
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 extern struct static_key_false memcg_kmem_enabled_key;
 
 extern int memcg_nr_cache_ids;
@@ -750,9 +743,9 @@ static inline bool memcg_kmem_enabled(void)
        return static_branch_unlikely(&memcg_kmem_enabled_key);
 }
 
-static inline bool memcg_kmem_is_active(struct mem_cgroup *memcg)
+static inline bool memcg_kmem_online(struct mem_cgroup *memcg)
 {
-       return memcg->kmem_acct_active;
+       return memcg->kmem_state == KMEM_ONLINE;
 }
 
 /*
@@ -850,7 +843,7 @@ static inline bool memcg_kmem_enabled(void)
        return false;
 }
 
-static inline bool memcg_kmem_is_active(struct mem_cgroup *memcg)
+static inline bool memcg_kmem_online(struct mem_cgroup *memcg)
 {
        return false;
 }
@@ -886,5 +879,6 @@ memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
 static inline void memcg_kmem_put_cache(struct kmem_cache *cachep)
 {
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
+
 #endif /* _LINUX_MEMCONTROL_H */
index 58391f2..116b284 100644 (file)
@@ -206,7 +206,8 @@ enum {
        MLX4_SET_PORT_GID_TABLE = 0x5,
        MLX4_SET_PORT_PRIO2TC   = 0x8,
        MLX4_SET_PORT_SCHEDULER = 0x9,
-       MLX4_SET_PORT_VXLAN     = 0xB
+       MLX4_SET_PORT_VXLAN     = 0xB,
+       MLX4_SET_PORT_ROCE_ADDR = 0xD
 };
 
 enum {
index d3133be..430a929 100644 (file)
@@ -216,6 +216,7 @@ enum {
        MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN      = 1LL <<  30,
        MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB = 1ULL << 31,
        MLX4_DEV_CAP_FLAG2_LB_SRC_CHK           = 1ULL << 32,
+       MLX4_DEV_CAP_FLAG2_ROCE_V1_V2           = 1ULL <<  33,
 };
 
 enum {
@@ -267,12 +268,14 @@ enum {
        MLX4_BMME_FLAG_TYPE_2_WIN       = 1 <<  9,
        MLX4_BMME_FLAG_RESERVED_LKEY    = 1 << 10,
        MLX4_BMME_FLAG_FAST_REG_WR      = 1 << 11,
+       MLX4_BMME_FLAG_ROCE_V1_V2       = 1 << 19,
        MLX4_BMME_FLAG_PORT_REMAP       = 1 << 24,
        MLX4_BMME_FLAG_VSD_INIT2RTR     = 1 << 28,
 };
 
 enum {
-       MLX4_FLAG_PORT_REMAP            = MLX4_BMME_FLAG_PORT_REMAP
+       MLX4_FLAG_PORT_REMAP            = MLX4_BMME_FLAG_PORT_REMAP,
+       MLX4_FLAG_ROCE_V1_V2            = MLX4_BMME_FLAG_ROCE_V1_V2
 };
 
 enum mlx4_event {
@@ -979,14 +982,11 @@ struct mlx4_mad_ifc {
        for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++)     \
                if ((type) == (dev)->caps.port_mask[(port)])
 
-#define mlx4_foreach_non_ib_transport_port(port, dev)                     \
-       for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++)       \
-               if (((dev)->caps.port_mask[port] != MLX4_PORT_TYPE_IB))
-
 #define mlx4_foreach_ib_transport_port(port, dev)                         \
-       for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++)       \
+       for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++)       \
                if (((dev)->caps.port_mask[port] == MLX4_PORT_TYPE_IB) || \
-                       ((dev)->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
+                       ((dev)->caps.flags & MLX4_DEV_CAP_FLAG_IBOE) || \
+                       ((dev)->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2))
 
 #define MLX4_INVALID_SLAVE_ID  0xFF
 #define MLX4_SINK_COUNTER_INDEX(dev)   (dev->caps.max_counters - 1)
@@ -1457,6 +1457,7 @@ int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port);
 
 int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port);
 int mlx4_disable_rx_port_check(struct mlx4_dev *dev, bool dis);
+int mlx4_config_roce_v2_port(struct mlx4_dev *dev, u16 udp_port);
 int mlx4_virt2phy_port_map(struct mlx4_dev *dev, u32 port1, u32 port2);
 int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port);
 int mlx4_vf_get_enable_smi_admin(struct mlx4_dev *dev, int slave, int port);
index fe052e2..587cdf9 100644 (file)
@@ -194,7 +194,7 @@ struct mlx4_qp_context {
        u8                      mtu_msgmax;
        u8                      rq_size_stride;
        u8                      sq_size_stride;
-       u8                      rlkey;
+       u8                      rlkey_roce_mode;
        __be32                  usr_page;
        __be32                  local_qpn;
        __be32                  remote_qpn;
@@ -204,7 +204,8 @@ struct mlx4_qp_context {
        u32                     reserved1;
        __be32                  next_send_psn;
        __be32                  cqn_send;
-       u32                     reserved2[2];
+       __be16                  roce_entropy;
+       __be16                  reserved2[3];
        __be32                  last_acked_psn;
        __be32                  ssn;
        __be32                  params2;
@@ -487,4 +488,14 @@ static inline struct mlx4_qp *__mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
 
 void mlx4_qp_remove(struct mlx4_dev *dev, struct mlx4_qp *qp);
 
+static inline u16 folded_qp(u32 q)
+{
+       u16 res;
+
+       res = ((q & 0xff) ^ ((q & 0xff0000) >> 16)) | (q & 0xff00);
+       return res;
+}
+
+u16 mlx4_qp_roce_entropy(struct mlx4_dev *dev, u32 qpn);
+
 #endif /* MLX4_QP_H */
index 7be845e..987764a 100644 (file)
@@ -223,6 +223,14 @@ enum {
 #define MLX5_UMR_MTT_MASK      (MLX5_UMR_MTT_ALIGNMENT - 1)
 #define MLX5_UMR_MTT_MIN_CHUNK_SIZE MLX5_UMR_MTT_ALIGNMENT
 
+#define MLX5_USER_INDEX_LEN (MLX5_FLD_SZ_BYTES(qpc, user_index) * 8)
+
+enum {
+       MLX5_EVENT_QUEUE_TYPE_QP = 0,
+       MLX5_EVENT_QUEUE_TYPE_RQ = 1,
+       MLX5_EVENT_QUEUE_TYPE_SQ = 2,
+};
+
 enum mlx5_event {
        MLX5_EVENT_TYPE_COMP               = 0x0,
 
@@ -279,6 +287,26 @@ enum {
        MLX5_DEV_CAP_FLAG_CMDIF_CSUM    = 3LL << 46,
 };
 
+enum {
+       MLX5_ROCE_VERSION_1             = 0,
+       MLX5_ROCE_VERSION_2             = 2,
+};
+
+enum {
+       MLX5_ROCE_VERSION_1_CAP         = 1 << MLX5_ROCE_VERSION_1,
+       MLX5_ROCE_VERSION_2_CAP         = 1 << MLX5_ROCE_VERSION_2,
+};
+
+enum {
+       MLX5_ROCE_L3_TYPE_IPV4          = 0,
+       MLX5_ROCE_L3_TYPE_IPV6          = 1,
+};
+
+enum {
+       MLX5_ROCE_L3_TYPE_IPV4_CAP      = 1 << 1,
+       MLX5_ROCE_L3_TYPE_IPV6_CAP      = 1 << 2,
+};
+
 enum {
        MLX5_OPCODE_NOP                 = 0x00,
        MLX5_OPCODE_SEND_INVAL          = 0x01,
@@ -446,7 +474,7 @@ struct mlx5_init_seg {
        __be32                  rsvd2[880];
        __be32                  internal_timer_h;
        __be32                  internal_timer_l;
-       __be32                  rsrv3[2];
+       __be32                  rsvd3[2];
        __be32                  health_counter;
        __be32                  rsvd4[1019];
        __be64                  ieee1588_clk;
@@ -460,7 +488,9 @@ struct mlx5_eqe_comp {
 };
 
 struct mlx5_eqe_qp_srq {
-       __be32  reserved[6];
+       __be32  reserved1[5];
+       u8      type;
+       u8      reserved2[3];
        __be32  qp_srq_n;
 };
 
@@ -650,6 +680,12 @@ enum {
        CQE_RSS_HTYPE_L4        = 0x3 << 2,
 };
 
+enum {
+       MLX5_CQE_ROCE_L3_HEADER_TYPE_GRH        = 0x0,
+       MLX5_CQE_ROCE_L3_HEADER_TYPE_IPV6       = 0x1,
+       MLX5_CQE_ROCE_L3_HEADER_TYPE_IPV4       = 0x2,
+};
+
 enum {
        CQE_L2_OK       = 1 << 0,
        CQE_L3_OK       = 1 << 1,
index 5162f35..1e3006d 100644 (file)
@@ -115,6 +115,11 @@ enum {
        MLX5_REG_HOST_ENDIANNESS = 0x7004,
 };
 
+enum {
+       MLX5_ATOMIC_OPS_CMP_SWAP        = 1 << 0,
+       MLX5_ATOMIC_OPS_FETCH_ADD       = 1 << 1,
+};
+
 enum mlx5_page_fault_resume_flags {
        MLX5_PAGE_FAULT_RESUME_REQUESTOR = 1 << 0,
        MLX5_PAGE_FAULT_RESUME_WRITE     = 1 << 1,
@@ -341,9 +346,11 @@ struct mlx5_core_mr {
 };
 
 enum mlx5_res_type {
-       MLX5_RES_QP,
-       MLX5_RES_SRQ,
-       MLX5_RES_XSRQ,
+       MLX5_RES_QP     = MLX5_EVENT_QUEUE_TYPE_QP,
+       MLX5_RES_RQ     = MLX5_EVENT_QUEUE_TYPE_RQ,
+       MLX5_RES_SQ     = MLX5_EVENT_QUEUE_TYPE_SQ,
+       MLX5_RES_SRQ    = 3,
+       MLX5_RES_XSRQ   = 4,
 };
 
 struct mlx5_core_rsc_common {
@@ -651,13 +658,6 @@ extern struct workqueue_struct *mlx5_core_wq;
        .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field),      \
        .struct_size_bytes   = sizeof((struct ib_unpacked_ ## header *)0)->field
 
-struct ib_field {
-       size_t struct_offset_bytes;
-       size_t struct_size_bytes;
-       int    offset_bits;
-       int    size_bits;
-};
-
 static inline struct mlx5_core_dev *pci2mlx5_core_dev(struct pci_dev *pdev)
 {
        return pci_get_drvdata(pdev);
index 68d73f8..231ab6b 100644 (file)
@@ -66,6 +66,11 @@ enum {
        MLX5_MODIFY_TIR_BITMASK_TUNNELED_OFFLOAD_EN   = 0x3
 };
 
+enum {
+       MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE        = 0x0,
+       MLX5_SET_HCA_CAP_OP_MOD_ATOMIC                = 0x3,
+};
+
 enum {
        MLX5_CMD_OP_QUERY_HCA_CAP                 = 0x100,
        MLX5_CMD_OP_QUERY_ADAPTER                 = 0x101,
@@ -573,21 +578,24 @@ enum {
 struct mlx5_ifc_atomic_caps_bits {
        u8         reserved_0[0x40];
 
-       u8         atomic_req_endianness[0x1];
-       u8         reserved_1[0x1f];
+       u8         atomic_req_8B_endianess_mode[0x2];
+       u8         reserved_1[0x4];
+       u8         supported_atomic_req_8B_endianess_mode_1[0x1];
 
-       u8         reserved_2[0x20];
+       u8         reserved_2[0x19];
 
-       u8         reserved_3[0x10];
-       u8         atomic_operations[0x10];
+       u8         reserved_3[0x20];
 
        u8         reserved_4[0x10];
-       u8         atomic_size_qp[0x10];
+       u8         atomic_operations[0x10];
 
        u8         reserved_5[0x10];
+       u8         atomic_size_qp[0x10];
+
+       u8         reserved_6[0x10];
        u8         atomic_size_dc[0x10];
 
-       u8         reserved_6[0x720];
+       u8         reserved_7[0x720];
 };
 
 struct mlx5_ifc_odp_cap_bits {
@@ -850,7 +858,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
        u8         reserved_66[0x8];
        u8         log_uar_page_sz[0x10];
 
-       u8         reserved_67[0x40];
+       u8         reserved_67[0x20];
+       u8         device_frequency_mhz[0x20];
        u8         device_frequency_khz[0x20];
        u8         reserved_68[0x5f];
        u8         cqe_zip[0x1];
@@ -2215,19 +2224,25 @@ struct mlx5_ifc_nic_vport_context_bits {
 
        u8         mtu[0x10];
 
-       u8         reserved_3[0x640];
+       u8         system_image_guid[0x40];
+       u8         port_guid[0x40];
+       u8         node_guid[0x40];
+
+       u8         reserved_3[0x140];
+       u8         qkey_violation_counter[0x10];
+       u8         reserved_4[0x430];
 
        u8         promisc_uc[0x1];
        u8         promisc_mc[0x1];
        u8         promisc_all[0x1];
-       u8         reserved_4[0x2];
+       u8         reserved_5[0x2];
        u8         allowed_list_type[0x3];
-       u8         reserved_5[0xc];
+       u8         reserved_6[0xc];
        u8         allowed_list_size[0xc];
 
        struct mlx5_ifc_mac_address_layout_bits permanent_address;
 
-       u8         reserved_6[0x20];
+       u8         reserved_7[0x20];
 
        u8         current_uc_mac_address[0][0x40];
 };
@@ -4199,6 +4214,13 @@ struct mlx5_ifc_modify_tis_out_bits {
        u8         reserved_1[0x40];
 };
 
+struct mlx5_ifc_modify_tis_bitmask_bits {
+       u8         reserved_0[0x20];
+
+       u8         reserved_1[0x1f];
+       u8         prio[0x1];
+};
+
 struct mlx5_ifc_modify_tis_in_bits {
        u8         opcode[0x10];
        u8         reserved_0[0x10];
@@ -4211,7 +4233,7 @@ struct mlx5_ifc_modify_tis_in_bits {
 
        u8         reserved_3[0x20];
 
-       u8         modify_bitmask[0x40];
+       struct mlx5_ifc_modify_tis_bitmask_bits bitmask;
 
        u8         reserved_4[0x40];
 
index f079fb1..5b8c89f 100644 (file)
@@ -85,7 +85,16 @@ enum mlx5_qp_state {
        MLX5_QP_STATE_ERR                       = 6,
        MLX5_QP_STATE_SQ_DRAINING               = 7,
        MLX5_QP_STATE_SUSPENDED                 = 9,
-       MLX5_QP_NUM_STATE
+       MLX5_QP_NUM_STATE,
+       MLX5_QP_STATE,
+       MLX5_QP_STATE_BAD,
+};
+
+enum {
+       MLX5_SQ_STATE_NA        = MLX5_SQC_STATE_ERR + 1,
+       MLX5_SQ_NUM_STATE       = MLX5_SQ_STATE_NA + 1,
+       MLX5_RQ_STATE_NA        = MLX5_RQC_STATE_ERR + 1,
+       MLX5_RQ_NUM_STATE       = MLX5_RQ_STATE_NA + 1,
 };
 
 enum {
@@ -130,6 +139,9 @@ enum {
        MLX5_QP_BIT_RWE                         = 1 << 14,
        MLX5_QP_BIT_RAE                         = 1 << 13,
        MLX5_QP_BIT_RIC                         = 1 <<  4,
+       MLX5_QP_BIT_CC_SLAVE_RECV               = 1 <<  2,
+       MLX5_QP_BIT_CC_SLAVE_SEND               = 1 <<  1,
+       MLX5_QP_BIT_CC_MASTER                   = 1 <<  0
 };
 
 enum {
@@ -248,8 +260,12 @@ struct mlx5_av {
        __be32  dqp_dct;
        u8      stat_rate_sl;
        u8      fl_mlid;
-       __be16  rlid;
-       u8      reserved0[10];
+       union {
+               __be16  rlid;
+               __be16  udp_sport;
+       };
+       u8      reserved0[4];
+       u8      rmac[6];
        u8      tclass;
        u8      hop_limit;
        __be32  grh_gid_fl;
@@ -456,11 +472,16 @@ struct mlx5_qp_path {
        u8                      static_rate;
        u8                      hop_limit;
        __be32                  tclass_flowlabel;
-       u8                      rgid[16];
-       u8                      rsvd1[4];
-       u8                      sl;
+       union {
+               u8              rgid[16];
+               u8              rip[16];
+       };
+       u8                      f_dscp_ecn_prio;
+       u8                      ecn_dscp;
+       __be16                  udp_sport;
+       u8                      dci_cfi_prio_sl;
        u8                      port;
-       u8                      rsvd2[6];
+       u8                      rmac[6];
 };
 
 struct mlx5_qp_context {
@@ -620,8 +641,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
                        struct mlx5_core_qp *qp,
                        struct mlx5_create_qp_mbox_in *in,
                        int inlen);
-int mlx5_core_qp_modify(struct mlx5_core_dev *dev, enum mlx5_qp_state cur_state,
-                       enum mlx5_qp_state new_state,
+int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 operation,
                        struct mlx5_modify_qp_mbox_in *in, int sqd_event,
                        struct mlx5_core_qp *qp);
 int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
@@ -639,6 +659,14 @@ void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp);
 int mlx5_core_page_fault_resume(struct mlx5_core_dev *dev, u32 qpn,
                                u8 context, int error);
 #endif
+int mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                               struct mlx5_core_qp *rq);
+void mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
+                                 struct mlx5_core_qp *rq);
+int mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                               struct mlx5_core_qp *sq);
+void mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
+                                 struct mlx5_core_qp *sq);
 
 static inline const char *mlx5_qp_type_str(int type)
 {
diff --git a/include/linux/mlx5/transobj.h b/include/linux/mlx5/transobj.h
new file mode 100644 (file)
index 0000000..88441f5
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __TRANSOBJ_H__
+#define __TRANSOBJ_H__
+
+#include <linux/mlx5/driver.h>
+
+int mlx5_core_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn);
+void mlx5_core_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn);
+int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                       u32 *rqn);
+int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen);
+void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn);
+int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out);
+int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                       u32 *sqn);
+int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen);
+void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn);
+int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out);
+int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                        u32 *tirn);
+int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in,
+                        int inlen);
+void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn);
+int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                        u32 *tisn);
+int mlx5_core_modify_tis(struct mlx5_core_dev *dev, u32 tisn, u32 *in,
+                        int inlen);
+void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn);
+int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                        u32 *rmpn);
+int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen);
+int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn);
+int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out);
+int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm);
+int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                         u32 *rmpn);
+int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 rmpn);
+int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 rmpn, u32 *out);
+int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm);
+
+int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen,
+                        u32 *rqtn);
+int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in,
+                        int inlen);
+void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn);
+
+#endif /* __TRANSOBJ_H__ */
index 638f2ca..1237710 100644 (file)
@@ -45,6 +45,11 @@ int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
                                     u16 vport, u8 *addr);
 int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev,
                                      u16 vport, u8 *addr);
+int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
+                                          u64 *system_image_guid);
+int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid);
+int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
+                                       u16 *qkey_viol_cntr);
 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
                             u8 port_num, u16  vf_num, u16 gid_index,
                             union ib_gid *gid);
@@ -85,4 +90,7 @@ int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
                                u16 vlans[],
                                int list_size);
 
+int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev);
+int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev);
+
 #endif /* __MLX5_VPORT_H__ */
index 1c6342a..a2a0068 100644 (file)
@@ -187,7 +187,7 @@ struct msi_domain_info;
  * @msi_free:          Domain specific function to free a MSI interrupts
  * @msi_check:         Callback for verification of the domain/info/dev data
  * @msi_prepare:       Prepare the allocation of the interrupts in the domain
- * @msi_finish:                Optional callbacl to finalize the allocation
+ * @msi_finish:                Optional callback to finalize the allocation
  * @set_desc:          Set the msi descriptor for an interrupt
  * @handle_error:      Optional error handler if the allocation fails
  *
@@ -195,7 +195,7 @@ struct msi_domain_info;
  * msi_create_irq_domain() and related interfaces
  *
  * @msi_check, @msi_prepare, @msi_finish, @set_desc and @handle_error
- * are callbacks used by msi_irq_domain_alloc_irqs() and related
+ * are callbacks used by msi_domain_alloc_irqs() and related
  * interfaces which are based on msi_desc.
  */
 struct msi_domain_ops {
index 3af5f45..a55986f 100644 (file)
 
 #include <linux/types.h>
 
-struct nvme_bar {
-       __u64                   cap;    /* Controller Capabilities */
-       __u32                   vs;     /* Version */
-       __u32                   intms;  /* Interrupt Mask Set */
-       __u32                   intmc;  /* Interrupt Mask Clear */
-       __u32                   cc;     /* Controller Configuration */
-       __u32                   rsvd1;  /* Reserved */
-       __u32                   csts;   /* Controller Status */
-       __u32                   nssr;   /* Subsystem Reset */
-       __u32                   aqa;    /* Admin Queue Attributes */
-       __u64                   asq;    /* Admin SQ Base Address */
-       __u64                   acq;    /* Admin CQ Base Address */
-       __u32                   cmbloc; /* Controller Memory Buffer Location */
-       __u32                   cmbsz;  /* Controller Memory Buffer Size */
+enum {
+       NVME_REG_CAP    = 0x0000,       /* Controller Capabilities */
+       NVME_REG_VS     = 0x0008,       /* Version */
+       NVME_REG_INTMS  = 0x000c,       /* Interrupt Mask Set */
+       NVME_REG_INTMC  = 0x0010,       /* Interrupt Mask Set */
+       NVME_REG_CC     = 0x0014,       /* Controller Configuration */
+       NVME_REG_CSTS   = 0x001c,       /* Controller Status */
+       NVME_REG_NSSR   = 0x0020,       /* NVM Subsystem Reset */
+       NVME_REG_AQA    = 0x0024,       /* Admin Queue Attributes */
+       NVME_REG_ASQ    = 0x0028,       /* Admin SQ Base Address */
+       NVME_REG_ACQ    = 0x0030,       /* Admin SQ Base Address */
+       NVME_REG_CMBLOC = 0x0038,       /* Controller Memory Buffer Location */
+       NVME_REG_CMBSZ  = 0x003c,       /* Controller Memory Buffer Size */
 };
 
 #define NVME_CAP_MQES(cap)     ((cap) & 0xffff)
index 2c51ee7..f6e9e85 100644 (file)
@@ -59,6 +59,13 @@ static inline void of_pci_check_probe_only(void) { }
 int of_pci_get_host_bridge_resources(struct device_node *dev,
                        unsigned char busno, unsigned char bus_max,
                        struct list_head *resources, resource_size_t *io_base);
+#else
+static inline int of_pci_get_host_bridge_resources(struct device_node *dev,
+                       unsigned char busno, unsigned char bus_max,
+                       struct list_head *resources, resource_size_t *io_base)
+{
+       return -EINVAL;
+}
 #endif
 
 #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
index 4d08b6c..92395a0 100644 (file)
@@ -361,6 +361,9 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
                               unsigned int nr_pages, struct page **pages);
 unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
                        int tag, unsigned int nr_pages, struct page **pages);
+unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
+                       int tag, unsigned int nr_entries,
+                       struct page **entries, pgoff_t *indices);
 
 struct page *grab_cache_page_write_begin(struct address_space *mapping,
                        pgoff_t index, unsigned flags);
index d86378c..27df4a6 100644 (file)
@@ -1257,8 +1257,6 @@ struct msix_entry {
        u16     entry;  /* driver uses to specify entry, OS writes */
 };
 
-void pci_msi_setup_pci_dev(struct pci_dev *dev);
-
 #ifdef CONFIG_PCI_MSI
 int pci_msi_vec_count(struct pci_dev *dev);
 void pci_msi_shutdown(struct pci_dev *dev);
index 1acbefc..37f05cb 100644 (file)
 #define PCI_DEVICE_ID_KORENIX_JETCARDF3        0x17ff
 
 #define PCI_VENDOR_ID_NETRONOME                0x19ee
+#define PCI_DEVICE_ID_NETRONOME_NFP3200        0x3200
+#define PCI_DEVICE_ID_NETRONOME_NFP3240        0x3240
+#define PCI_DEVICE_ID_NETRONOME_NFP4000        0x4000
+#define PCI_DEVICE_ID_NETRONOME_NFP6000        0x6000
+#define PCI_DEVICE_ID_NETRONOME_NFP6000_VF     0x6003
 
 #define PCI_VENDOR_ID_QMI              0x1a32
 
index eb8b8ac..24f5470 100644 (file)
@@ -42,6 +42,7 @@ struct pipe_buffer {
  *     @fasync_readers: reader side fasync
  *     @fasync_writers: writer side fasync
  *     @bufs: the circular array of pipe buffers
+ *     @user: the user who created this pipe
  **/
 struct pipe_inode_info {
        struct mutex mutex;
@@ -57,6 +58,7 @@ struct pipe_inode_info {
        struct fasync_struct *fasync_readers;
        struct fasync_struct *fasync_writers;
        struct pipe_buffer *bufs;
+       struct user_struct *user;
 };
 
 /*
@@ -123,6 +125,8 @@ void pipe_unlock(struct pipe_inode_info *);
 void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);
 
 extern unsigned int pipe_max_size, pipe_min_size;
+extern unsigned long pipe_user_pages_hard;
+extern unsigned long pipe_user_pages_soft;
 int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
 
 
index 54a0a95..0496d17 100644 (file)
@@ -29,15 +29,6 @@ struct omap_iommu_arch_data {
        struct omap_iommu *iommu_dev;
 };
 
-/**
- * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
- * @nr_tlb_entries:    number of entries supported by the translation
- *                     look-aside buffer (TLB).
- */
-struct omap_mmu_dev_attr {
-       int nr_tlb_entries;
-};
-
 struct iommu_platform_data {
        const char *name;
        const char *reset_name;
diff --git a/include/linux/platform_data/pwm_omap_dmtimer.h b/include/linux/platform_data/pwm_omap_dmtimer.h
new file mode 100644 (file)
index 0000000..5938421
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * include/linux/platform_data/pwm_omap_dmtimer.h
+ *
+ * OMAP Dual-Mode Timer PWM platform data
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Platform device conversion and hwmod support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ * PWM and clock framework support by Timo Teras.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PWM_OMAP_DMTIMER_PDATA_H
+#define __PWM_OMAP_DMTIMER_PDATA_H
+
+/* trigger types */
+#define PWM_OMAP_DMTIMER_TRIGGER_NONE                  0x00
+#define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW              0x01
+#define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE  0x02
+
+struct omap_dm_timer;
+typedef struct omap_dm_timer pwm_omap_dmtimer;
+
+struct pwm_omap_dmtimer_pdata {
+       pwm_omap_dmtimer *(*request_by_node)(struct device_node *np);
+       int     (*free)(pwm_omap_dmtimer *timer);
+
+       void    (*enable)(pwm_omap_dmtimer *timer);
+       void    (*disable)(pwm_omap_dmtimer *timer);
+
+       struct clk *(*get_fclk)(pwm_omap_dmtimer *timer);
+
+       int     (*start)(pwm_omap_dmtimer *timer);
+       int     (*stop)(pwm_omap_dmtimer *timer);
+
+       int     (*set_load)(pwm_omap_dmtimer *timer, int autoreload,
+                       unsigned int value);
+       int     (*set_match)(pwm_omap_dmtimer *timer, int enable,
+                       unsigned int match);
+       int     (*set_pwm)(pwm_omap_dmtimer *timer, int def_on,
+                       int toggle, int trigger);
+       int     (*set_prescaler)(pwm_omap_dmtimer *timer, int prescaler);
+
+       int     (*write_counter)(pwm_omap_dmtimer *timer, unsigned int value);
+};
+
+#endif /* __PWM_OMAP_DMTIMER_PDATA_H */
diff --git a/include/linux/platform_data/sdhci-pic32.h b/include/linux/platform_data/sdhci-pic32.h
new file mode 100644 (file)
index 0000000..7e0efe6
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Purna Chandra Mandal, purna.mandal@microchip.com
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#ifndef __PIC32_SDHCI_PDATA_H__
+#define __PIC32_SDHCI_PDATA_H__
+
+struct pic32_sdhci_platform_data {
+       /* read & write fifo threshold */
+       int (*setup_dma)(u32 rfifo, u32 wfifo);
+};
+
+#endif
index 58dc7c5..71eccaa 100644 (file)
@@ -17,6 +17,7 @@ struct s3c2410_ts_mach_info {
 };
 
 extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+extern void s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
 
 /* defined by architecture to configure gpio */
 extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
index 528be67..6a5d654 100644 (file)
@@ -573,6 +573,7 @@ struct dev_pm_info {
        struct wakeup_source    *wakeup;
        bool                    wakeup_path:1;
        bool                    syscore:1;
+       bool                    no_pm_callbacks:1;      /* Owned by the PM core */
 #else
        unsigned int            should_wakeup:1;
 #endif
index ba4ced3..db21d39 100644 (file)
@@ -240,12 +240,15 @@ static inline int of_genpd_add_provider_onecell(struct device_node *np,
 #ifdef CONFIG_PM
 extern int dev_pm_domain_attach(struct device *dev, bool power_on);
 extern void dev_pm_domain_detach(struct device *dev, bool power_off);
+extern void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
 #else
 static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
 {
        return -ENODEV;
 }
 static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
+static inline void dev_pm_domain_set(struct device *dev,
+                                    struct dev_pm_domain *pd) {}
 #endif
 
 #endif /* _LINUX_PM_DOMAIN_H */
index acfea8c..7c3d11a 100644 (file)
@@ -53,12 +53,18 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size)
 {
        BUG();
 }
+
+static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size)
+{
+       BUG();
+}
 #endif
 
 /*
  * Architectures that define ARCH_HAS_PMEM_API must provide
  * implementations for arch_memcpy_to_pmem(), arch_wmb_pmem(),
- * arch_copy_from_iter_pmem(), arch_clear_pmem() and arch_has_wmb_pmem().
+ * arch_copy_from_iter_pmem(), arch_clear_pmem(), arch_wb_cache_pmem()
+ * and arch_has_wmb_pmem().
  */
 static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
 {
@@ -178,4 +184,18 @@ static inline void clear_pmem(void __pmem *addr, size_t size)
        else
                default_clear_pmem(addr, size);
 }
+
+/**
+ * wb_cache_pmem - write back processor cache for PMEM memory range
+ * @addr:      virtual start address
+ * @size:      number of bytes to write back
+ *
+ * Write back the processor cache range starting at 'addr' for 'size' bytes.
+ * This function requires explicit ordering with a wmb_pmem() call.
+ */
+static inline void wb_cache_pmem(void __pmem *addr, size_t size)
+{
+       if (arch_has_pmem_api())
+               arch_wb_cache_pmem(addr, size);
+}
 #endif /* __PMEM_H__ */
index 061265f..504c98a 100644 (file)
@@ -57,7 +57,29 @@ extern void exit_ptrace(struct task_struct *tracer, struct list_head *dead);
 #define PTRACE_MODE_READ       0x01
 #define PTRACE_MODE_ATTACH     0x02
 #define PTRACE_MODE_NOAUDIT    0x04
-/* Returns true on success, false on denial. */
+#define PTRACE_MODE_FSCREDS 0x08
+#define PTRACE_MODE_REALCREDS 0x10
+
+/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */
+#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS)
+#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS)
+
+/**
+ * ptrace_may_access - check whether the caller is permitted to access
+ * a target task.
+ * @task: target task
+ * @mode: selects type of access and caller credentials
+ *
+ * Returns true on success, false on denial.
+ *
+ * One of the flags PTRACE_MODE_FSCREDS and PTRACE_MODE_REALCREDS must
+ * be set in @mode to specify whether the access was requested through
+ * a filesystem syscall (should use effective capabilities and fsuid
+ * of the caller) or through an explicit syscall such as
+ * process_vm_writev or ptrace (and should use the real credentials).
+ */
 extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
 
 static inline int ptrace_reparented(struct task_struct *child)
index 33170db..7c88ad1 100644 (file)
 #define RADIX_TREE_EXCEPTIONAL_ENTRY   2
 #define RADIX_TREE_EXCEPTIONAL_SHIFT   2
 
+#define RADIX_DAX_MASK 0xf
+#define RADIX_DAX_SHIFT        4
+#define RADIX_DAX_PTE  (0x4 | RADIX_TREE_EXCEPTIONAL_ENTRY)
+#define RADIX_DAX_PMD  (0x8 | RADIX_TREE_EXCEPTIONAL_ENTRY)
+#define RADIX_DAX_TYPE(entry) ((unsigned long)entry & RADIX_DAX_MASK)
+#define RADIX_DAX_SECTOR(entry) (((unsigned long)entry >> RADIX_DAX_SHIFT))
+#define RADIX_DAX_ENTRY(sector, pmd) ((void *)((unsigned long)sector << \
+               RADIX_DAX_SHIFT | (pmd ? RADIX_DAX_PMD : RADIX_DAX_PTE)))
+
 static inline int radix_tree_is_indirect_ptr(void *ptr)
 {
        return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR);
@@ -154,7 +163,7 @@ do {                                                                        \
  * radix_tree_gang_lookup_tag_slot
  * radix_tree_tagged
  *
- * The first 7 functions are able to be called locklessly, using RCU. The
+ * The first 8 functions are able to be called locklessly, using RCU. The
  * caller must ensure calls to these functions are made within rcu_read_lock()
  * regions. Other readers (lock-free or otherwise) and modifications may be
  * running concurrently.
index a5aa7ae..b690009 100644 (file)
@@ -50,7 +50,7 @@ struct rb_root {
 #define RB_ROOT        (struct rb_root) { NULL, }
 #define        rb_entry(ptr, type, member) container_of(ptr, type, member)
 
-#define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)
+#define RB_EMPTY_ROOT(root)  (READ_ONCE((root)->rb_node) == NULL)
 
 /* 'empty' nodes are nodes that are known not to be inserted in an rbtree */
 #define RB_EMPTY_NODE(node)  \
index 7f65f9c..c4c097d 100644 (file)
@@ -38,6 +38,9 @@ static inline struct reset_control *devm_reset_control_get_optional(
 struct reset_control *of_reset_control_get(struct device_node *node,
                                           const char *id);
 
+struct reset_control *of_reset_control_get_by_index(
+                                       struct device_node *node, int index);
+
 #else
 
 static inline int reset_control_reset(struct reset_control *rstc)
@@ -71,7 +74,7 @@ static inline void reset_control_put(struct reset_control *rstc)
 
 static inline int device_reset_optional(struct device *dev)
 {
-       return -ENOSYS;
+       return -ENOTSUPP;
 }
 
 static inline struct reset_control *__must_check reset_control_get(
@@ -91,19 +94,25 @@ static inline struct reset_control *__must_check devm_reset_control_get(
 static inline struct reset_control *reset_control_get_optional(
                                        struct device *dev, const char *id)
 {
-       return ERR_PTR(-ENOSYS);
+       return ERR_PTR(-ENOTSUPP);
 }
 
 static inline struct reset_control *devm_reset_control_get_optional(
                                        struct device *dev, const char *id)
 {
-       return ERR_PTR(-ENOSYS);
+       return ERR_PTR(-ENOTSUPP);
 }
 
 static inline struct reset_control *of_reset_control_get(
                                struct device_node *node, const char *id)
 {
-       return ERR_PTR(-ENOSYS);
+       return ERR_PTR(-ENOTSUPP);
+}
+
+static inline struct reset_control *of_reset_control_get_by_index(
+                               struct device_node *node, int index)
+{
+       return ERR_PTR(-ENOTSUPP);
 }
 
 #endif /* CONFIG_RESET_CONTROLLER */
index 61aa9bb..a10494a 100644 (file)
@@ -835,6 +835,7 @@ struct user_struct {
 #endif
        unsigned long locked_shm; /* How many pages of mlocked shm ? */
        unsigned long unix_inflight;    /* How many files in flight in unix sockets */
+       atomic_long_t pipe_bufs;  /* how many pages are allocated in pipe buffers */
 
 #ifdef CONFIG_KEYS
        struct key *uid_keyring;        /* UID specific keyring */
@@ -1476,10 +1477,10 @@ struct task_struct {
        unsigned in_iowait:1;
 #ifdef CONFIG_MEMCG
        unsigned memcg_may_oom:1;
-#endif
-#ifdef CONFIG_MEMCG_KMEM
+#ifndef CONFIG_SLOB
        unsigned memcg_kmem_skip_account:1;
 #endif
+#endif
 #ifdef CONFIG_COMPAT_BRK
        unsigned brk_randomized:1;
 #endif
@@ -1643,6 +1644,9 @@ struct task_struct {
        struct held_lock held_locks[MAX_LOCK_DEPTH];
        gfp_t lockdep_reclaim_gfp;
 #endif
+#ifdef CONFIG_UBSAN
+       unsigned int in_ubsan;
+#endif
 
 /* journalling filesystem info */
        void *journal_info;
index 1f208b2..645896b 100644 (file)
@@ -113,10 +113,6 @@ long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
 long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
                               unsigned int mult_max, unsigned long rate);
 
-long clk_round_parent(struct clk *clk, unsigned long target,
-                     unsigned long *best_freq, unsigned long *parent_freq,
-                     unsigned int div_min, unsigned int div_max);
-
 #define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _status_reg, _flags) \
 {                                                                      \
        .parent         = _parent,                                      \
index 6fb8016..04e8818 100644 (file)
@@ -52,7 +52,7 @@ struct sysv_shm {
 
 long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr,
              unsigned long shmlba);
-int is_file_shm_hugepages(struct file *file);
+bool is_file_shm_hugepages(struct file *file);
 void exit_shm(struct task_struct *task);
 #define shm_init_task(task) INIT_LIST_HEAD(&(task)->sysvshm.shm_clist)
 #else
@@ -66,9 +66,9 @@ static inline long do_shmat(int shmid, char __user *shmaddr,
 {
        return -ENOSYS;
 }
-static inline int is_file_shm_hugepages(struct file *file)
+static inline bool is_file_shm_hugepages(struct file *file)
 {
-       return 0;
+       return false;
 }
 static inline void exit_shm(struct task_struct *task)
 {
index a43f41c..4d4780c 100644 (file)
@@ -15,10 +15,7 @@ struct shmem_inode_info {
        unsigned int            seals;          /* shmem seals */
        unsigned long           flags;
        unsigned long           alloced;        /* data pages alloced to file */
-       union {
-               unsigned long   swapped;        /* subtotal assigned to swap */
-               char            *symlink;       /* unswappable short symlink */
-       };
+       unsigned long           swapped;        /* subtotal assigned to swap */
        struct shared_policy    policy;         /* NUMA memory alloc policy */
        struct list_head        swaplist;       /* chain of maybes on swap */
        struct simple_xattrs    xattrs;         /* list of xattrs */
index 3ffee74..3627d5c 100644 (file)
@@ -86,7 +86,7 @@
 #else
 # define SLAB_FAILSLAB         0x00000000UL
 #endif
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 # define SLAB_ACCOUNT          0x04000000UL    /* Account to memcg */
 #else
 # define SLAB_ACCOUNT          0x00000000UL
index 33d0490..cf139d3 100644 (file)
@@ -69,7 +69,8 @@ struct kmem_cache {
         */
        int obj_offset;
 #endif /* CONFIG_DEBUG_SLAB */
-#ifdef CONFIG_MEMCG_KMEM
+
+#ifdef CONFIG_MEMCG
        struct memcg_cache_params memcg_params;
 #endif
 
index 3388511..b7e5792 100644 (file)
@@ -84,7 +84,7 @@ struct kmem_cache {
 #ifdef CONFIG_SYSFS
        struct kobject kobj;    /* For sysfs */
 #endif
-#ifdef CONFIG_MEMCG_KMEM
+#ifdef CONFIG_MEMCG
        struct memcg_cache_params memcg_params;
        int max_attr_size; /* for propagation, maximum size of a stored attr */
 #ifdef CONFIG_SYSFS
index 9c99f84..7653869 100644 (file)
@@ -1,6 +1,25 @@
 #ifndef LINUX_SOC_DOVE_PMU_H
 #define LINUX_SOC_DOVE_PMU_H
 
+#include <linux/types.h>
+
+struct dove_pmu_domain_initdata {
+       u32 pwr_mask;
+       u32 rst_mask;
+       u32 iso_mask;
+       const char *name;
+};
+
+struct dove_pmu_initdata {
+       void __iomem *pmc_base;
+       void __iomem *pmu_base;
+       int irq;
+       int irq_domain_start;
+       const struct dove_pmu_domain_initdata *domains;
+};
+
+int dove_init_pmu_legacy(const struct dove_pmu_initdata *);
+
 int dove_init_pmu(void);
 
 #endif
diff --git a/include/linux/soc/qcom/smem_state.h b/include/linux/soc/qcom/smem_state.h
new file mode 100644 (file)
index 0000000..f35e151
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __QCOM_SMEM_STATE__
+#define __QCOM_SMEM_STATE__
+
+struct qcom_smem_state;
+
+struct qcom_smem_state_ops {
+       int (*update_bits)(void *, u32, u32);
+};
+
+struct qcom_smem_state *qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit);
+void qcom_smem_state_put(struct qcom_smem_state *);
+
+int qcom_smem_state_update_bits(struct qcom_smem_state *state, u32 mask, u32 value);
+
+struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, const struct qcom_smem_state_ops *ops, void *data);
+void qcom_smem_state_unregister(struct qcom_smem_state *state);
+
+#endif
index f869807..5322fea 100644 (file)
@@ -51,6 +51,7 @@
 /* RPC/RDMA parameters and stats */
 extern unsigned int svcrdma_ord;
 extern unsigned int svcrdma_max_requests;
+extern unsigned int svcrdma_max_bc_requests;
 extern unsigned int svcrdma_max_req_size;
 
 extern atomic_t rdma_stat_recv;
@@ -69,6 +70,7 @@ extern atomic_t rdma_stat_sq_prod;
  * completes.
  */
 struct svc_rdma_op_ctxt {
+       struct list_head free;
        struct svc_rdma_op_ctxt *read_hdr;
        struct svc_rdma_fastreg_mr *frmr;
        int hdr_count;
@@ -112,6 +114,7 @@ struct svc_rdma_fastreg_mr {
        struct list_head frmr_list;
 };
 struct svc_rdma_req_map {
+       struct list_head free;
        unsigned long count;
        union {
                struct kvec sge[RPCSVC_MAXPAGES];
@@ -132,28 +135,32 @@ struct svcxprt_rdma {
        int                  sc_max_sge;
        int                  sc_max_sge_rd;     /* max sge for read target */
 
-       int                  sc_sq_depth;       /* Depth of SQ */
        atomic_t             sc_sq_count;       /* Number of SQ WR on queue */
-
-       int                  sc_max_requests;   /* Depth of RQ */
+       unsigned int         sc_sq_depth;       /* Depth of SQ */
+       unsigned int         sc_rq_depth;       /* Depth of RQ */
+       u32                  sc_max_requests;   /* Forward credits */
+       u32                  sc_max_bc_requests;/* Backward credits */
        int                  sc_max_req_size;   /* Size of each RQ WR buf */
 
        struct ib_pd         *sc_pd;
 
        atomic_t             sc_dma_used;
-       atomic_t             sc_ctxt_used;
+       spinlock_t           sc_ctxt_lock;
+       struct list_head     sc_ctxts;
+       int                  sc_ctxt_used;
+       spinlock_t           sc_map_lock;
+       struct list_head     sc_maps;
+
        struct list_head     sc_rq_dto_q;
        spinlock_t           sc_rq_dto_lock;
        struct ib_qp         *sc_qp;
        struct ib_cq         *sc_rq_cq;
        struct ib_cq         *sc_sq_cq;
-       struct ib_mr         *sc_phys_mr;       /* MR for server memory */
        int                  (*sc_reader)(struct svcxprt_rdma *,
                                          struct svc_rqst *,
                                          struct svc_rdma_op_ctxt *,
                                          int *, u32 *, u32, u32, u64, bool);
        u32                  sc_dev_caps;       /* distilled device caps */
-       u32                  sc_dma_lkey;       /* local dma key */
        unsigned int         sc_frmr_pg_list_len;
        struct list_head     sc_frmr_q;
        spinlock_t           sc_frmr_q_lock;
@@ -179,8 +186,18 @@ struct svcxprt_rdma {
 #define RPCRDMA_MAX_REQUESTS    32
 #define RPCRDMA_MAX_REQ_SIZE    4096
 
+/* Typical ULP usage of BC requests is NFSv4.1 backchannel. Our
+ * current NFSv4.1 implementation supports one backchannel slot.
+ */
+#define RPCRDMA_MAX_BC_REQUESTS        2
+
 #define RPCSVC_MAXPAYLOAD_RDMA RPCSVC_MAXPAYLOAD
 
+/* svc_rdma_backchannel.c */
+extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt,
+                                   struct rpcrdma_msg *rmsgp,
+                                   struct xdr_buf *rcvbuf);
+
 /* svc_rdma_marshal.c */
 extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *);
 extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *,
@@ -206,6 +223,8 @@ extern int rdma_read_chunk_frmr(struct svcxprt_rdma *, struct svc_rqst *,
                                u32, u32, u64, bool);
 
 /* svc_rdma_sendto.c */
+extern int svc_rdma_map_xdr(struct svcxprt_rdma *, struct xdr_buf *,
+                           struct svc_rdma_req_map *);
 extern int svc_rdma_sendto(struct svc_rqst *);
 extern struct rpcrdma_read_chunk *
        svc_rdma_get_read_chunk(struct rpcrdma_msg *);
@@ -214,13 +233,14 @@ extern struct rpcrdma_read_chunk *
 extern int svc_rdma_send(struct svcxprt_rdma *, struct ib_send_wr *);
 extern void svc_rdma_send_error(struct svcxprt_rdma *, struct rpcrdma_msg *,
                                enum rpcrdma_errcode);
-extern int svc_rdma_post_recv(struct svcxprt_rdma *);
+extern int svc_rdma_post_recv(struct svcxprt_rdma *, gfp_t);
 extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *);
 extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *);
 extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int);
 extern void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt);
-extern struct svc_rdma_req_map *svc_rdma_get_req_map(void);
-extern void svc_rdma_put_req_map(struct svc_rdma_req_map *);
+extern struct svc_rdma_req_map *svc_rdma_get_req_map(struct svcxprt_rdma *);
+extern void svc_rdma_put_req_map(struct svcxprt_rdma *,
+                                struct svc_rdma_req_map *);
 extern struct svc_rdma_fastreg_mr *svc_rdma_get_frmr(struct svcxprt_rdma *);
 extern void svc_rdma_put_frmr(struct svcxprt_rdma *,
                              struct svc_rdma_fastreg_mr *);
@@ -234,6 +254,7 @@ extern struct svc_xprt_class svc_rdma_bc_class;
 #endif
 
 /* svc_rdma.c */
+extern struct workqueue_struct *svc_rdma_wq;
 extern int svc_rdma_init(void);
 extern void svc_rdma_cleanup(void);
 
index 414e101..d18b65c 100644 (file)
@@ -350,33 +350,7 @@ extern void check_move_unevictable_pages(struct page **, int nr_pages);
 
 extern int kswapd_run(int nid);
 extern void kswapd_stop(int nid);
-#ifdef CONFIG_MEMCG
-static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
-{
-       /* root ? */
-       if (mem_cgroup_disabled() || !memcg->css.parent)
-               return vm_swappiness;
-
-       return memcg->swappiness;
-}
 
-#else
-static inline int mem_cgroup_swappiness(struct mem_cgroup *mem)
-{
-       return vm_swappiness;
-}
-#endif
-#ifdef CONFIG_MEMCG_SWAP
-extern void mem_cgroup_swapout(struct page *page, swp_entry_t entry);
-extern void mem_cgroup_uncharge_swap(swp_entry_t entry);
-#else
-static inline void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
-{
-}
-static inline void mem_cgroup_uncharge_swap(swp_entry_t entry)
-{
-}
-#endif
 #ifdef CONFIG_SWAP
 /* linux/mm/page_io.c */
 extern int swap_readpage(struct page *);
@@ -555,5 +529,55 @@ static inline swp_entry_t get_swap_page(void)
 }
 
 #endif /* CONFIG_SWAP */
+
+#ifdef CONFIG_MEMCG
+static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
+{
+       /* root ? */
+       if (mem_cgroup_disabled() || !memcg->css.parent)
+               return vm_swappiness;
+
+       return memcg->swappiness;
+}
+
+#else
+static inline int mem_cgroup_swappiness(struct mem_cgroup *mem)
+{
+       return vm_swappiness;
+}
+#endif
+
+#ifdef CONFIG_MEMCG_SWAP
+extern void mem_cgroup_swapout(struct page *page, swp_entry_t entry);
+extern int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry);
+extern void mem_cgroup_uncharge_swap(swp_entry_t entry);
+extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg);
+extern bool mem_cgroup_swap_full(struct page *page);
+#else
+static inline void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
+{
+}
+
+static inline int mem_cgroup_try_charge_swap(struct page *page,
+                                            swp_entry_t entry)
+{
+       return 0;
+}
+
+static inline void mem_cgroup_uncharge_swap(swp_entry_t entry)
+{
+}
+
+static inline long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg)
+{
+       return get_nr_swap_pages();
+}
+
+static inline bool mem_cgroup_swap_full(struct page *page)
+{
+       return vm_swap_full();
+}
+#endif
+
 #endif /* __KERNEL__*/
 #endif /* _LINUX_SWAP_H */
index 613c29b..e13a1ac 100644 (file)
@@ -43,6 +43,9 @@
 /* Default weight of a bound cooling device */
 #define THERMAL_WEIGHT_DEFAULT 0
 
+/* use value, which < 0K, to indicate an invalid/uninitialized temperature */
+#define THERMAL_TEMP_INVALID   -274000
+
 /* Unit conversion macros */
 #define DECI_KELVIN_TO_CELSIUS(t)      ({                      \
        long _t = (t);                                          \
@@ -167,6 +170,7 @@ struct thermal_attr {
  * @forced_passive:    If > 0, temperature at which to switch on all ACPI
  *                     processor cooling devices.  Currently only used by the
  *                     step-wise governor.
+ * @need_update:       if equals 1, thermal_zone_device_update needs to be invoked.
  * @ops:       operations this &thermal_zone_device supports
  * @tzp:       thermal zone parameters
  * @governor:  pointer to the governor for this thermal zone
@@ -194,6 +198,7 @@ struct thermal_zone_device {
        int emul_temperature;
        int passive;
        unsigned int forced_passive;
+       atomic_t need_update;
        struct thermal_zone_device_ops *ops;
        struct thermal_zone_params *tzp;
        struct thermal_governor *governor;
index e312219..97fd4e5 100644 (file)
@@ -98,6 +98,7 @@ static inline void tick_broadcast_exit(void)
 }
 
 #ifdef CONFIG_NO_HZ_COMMON
+extern int tick_nohz_enabled;
 extern int tick_nohz_tick_stopped(void);
 extern void tick_nohz_idle_enter(void);
 extern void tick_nohz_idle_exit(void);
@@ -106,6 +107,7 @@ extern ktime_t tick_nohz_get_sleep_length(void);
 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
 extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
 #else /* !CONFIG_NO_HZ_COMMON */
+#define tick_nohz_enabled (0)
 static inline int tick_nohz_tick_stopped(void) { return 0; }
 static inline void tick_nohz_idle_enter(void) { }
 static inline void tick_nohz_idle_exit(void) { }
index 558129a..3495578 100644 (file)
@@ -111,4 +111,11 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
 #define probe_kernel_address(addr, retval)             \
        probe_kernel_read(&retval, addr, sizeof(retval))
 
+#ifndef user_access_begin
+#define user_access_begin() do { } while (0)
+#define user_access_end() do { } while (0)
+#define unsafe_get_user(x, ptr) __get_user(x, ptr)
+#define unsafe_put_user(x, ptr) __put_user(x, ptr)
+#endif
+
 #endif         /* __LINUX_UACCESS_H__ */
diff --git a/include/linux/wkup_m3_ipc.h b/include/linux/wkup_m3_ipc.h
new file mode 100644 (file)
index 0000000..d6ba7d3
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * TI Wakeup M3 for AMx3 SoCs Power Management Routines
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Dave Gerlach <d-gerlach@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * 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 _LINUX_WKUP_M3_IPC_H
+#define _LINUX_WKUP_M3_IPC_H
+
+#define WKUP_M3_DEEPSLEEP      1
+#define WKUP_M3_STANDBY                2
+#define WKUP_M3_IDLE           3
+
+#include <linux/mailbox_client.h>
+
+struct wkup_m3_ipc_ops;
+
+struct wkup_m3_ipc {
+       struct rproc *rproc;
+
+       void __iomem *ipc_mem_base;
+       struct device *dev;
+
+       int mem_type;
+       unsigned long resume_addr;
+       int state;
+
+       struct completion sync_complete;
+       struct mbox_client mbox_client;
+       struct mbox_chan *mbox;
+
+       struct wkup_m3_ipc_ops *ops;
+};
+
+struct wkup_m3_ipc_ops {
+       void (*set_mem_type)(struct wkup_m3_ipc *m3_ipc, int mem_type);
+       void (*set_resume_address)(struct wkup_m3_ipc *m3_ipc, void *addr);
+       int (*prepare_low_power)(struct wkup_m3_ipc *m3_ipc, int state);
+       int (*finish_low_power)(struct wkup_m3_ipc *m3_ipc);
+       int (*request_pm_status)(struct wkup_m3_ipc *m3_ipc);
+};
+
+struct wkup_m3_ipc *wkup_m3_ipc_get(void);
+void wkup_m3_ipc_put(struct wkup_m3_ipc *m3_ipc);
+#endif /* _LINUX_WKUP_M3_IPC_H */
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
deleted file mode 100644 (file)
index 01ff7c6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TCP_MEMCG_H
-#define _TCP_MEMCG_H
-
-struct cgroup_subsys;
-struct mem_cgroup;
-
-int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct mem_cgroup *memcg);
-#endif /* _TCP_MEMCG_H */
index 1152859..c34c900 100644 (file)
@@ -83,6 +83,8 @@ struct rdma_dev_addr {
        int bound_dev_if;
        enum rdma_transport_type transport;
        struct net *net;
+       enum rdma_network_type network;
+       int hoplimit;
 };
 
 /**
@@ -91,8 +93,8 @@ struct rdma_dev_addr {
  *
  * The dev_addr->net field must be initialized.
  */
-int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
-                     u16 *vlan_id);
+int rdma_translate_ip(const struct sockaddr *addr,
+                     struct rdma_dev_addr *dev_addr, u16 *vlan_id);
 
 /**
  * rdma_resolve_ip - Resolve source and destination IP addresses to
@@ -117,6 +119,10 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
                                     struct rdma_dev_addr *addr, void *context),
                    void *context);
 
+int rdma_resolve_ip_route(struct sockaddr *src_addr,
+                         const struct sockaddr *dst_addr,
+                         struct rdma_dev_addr *addr);
+
 void rdma_addr_cancel(struct rdma_dev_addr *addr);
 
 int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
@@ -125,8 +131,10 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
 int rdma_addr_size(struct sockaddr *addr);
 
 int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id);
-int rdma_addr_find_dmac_by_grh(const union ib_gid *sgid, const union ib_gid *dgid,
-                              u8 *smac, u16 *vlan_id, int if_index);
+int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
+                                const union ib_gid *dgid,
+                                u8 *smac, u16 *vlan_id, int *if_index,
+                                int *hoplimit);
 
 static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr)
 {
index 269a27c..e30f19b 100644 (file)
@@ -60,6 +60,7 @@ int ib_get_cached_gid(struct ib_device    *device,
  *   a specified GID value occurs.
  * @device: The device to query.
  * @gid: The GID value to search for.
+ * @gid_type: The GID type to search for.
  * @ndev: In RoCE, the net device of the device. NULL means ignore.
  * @port_num: The port number of the device where the GID value was found.
  * @index: The index into the cached GID table where the GID was found.  This
@@ -70,6 +71,7 @@ int ib_get_cached_gid(struct ib_device    *device,
  */
 int ib_find_cached_gid(struct ib_device *device,
                       const union ib_gid *gid,
+                      enum ib_gid_type gid_type,
                       struct net_device *ndev,
                       u8               *port_num,
                       u16              *index);
@@ -79,6 +81,7 @@ int ib_find_cached_gid(struct ib_device *device,
  * GID value occurs
  * @device: The device to query.
  * @gid: The GID value to search for.
+ * @gid_type: The GID type to search for.
  * @port_num: The port number of the device where the GID value sould be
  *   searched.
  * @ndev: In RoCE, the net device of the device. Null means ignore.
@@ -90,6 +93,7 @@ int ib_find_cached_gid(struct ib_device *device,
  */
 int ib_find_cached_gid_by_port(struct ib_device *device,
                               const union ib_gid *gid,
+                              enum ib_gid_type gid_type,
                               u8               port_num,
                               struct net_device *ndev,
                               u16              *index);
index ec9b44d..0ff049b 100644 (file)
@@ -438,6 +438,7 @@ typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
 /**
  * ib_mad_recv_handler - callback handler for a received MAD.
  * @mad_agent: MAD agent requesting the received MAD.
+ * @send_buf: Send buffer if found, else NULL
  * @mad_recv_wc: Received work completion information on the received MAD.
  *
  * MADs received in response to a send request operation will be handed to
@@ -447,6 +448,7 @@ typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
  * modify the data referenced by @mad_recv_wc.
  */
 typedef void (*ib_mad_recv_handler)(struct ib_mad_agent *mad_agent,
+                                   struct ib_mad_send_buf *send_buf,
                                    struct ib_mad_recv_wc *mad_recv_wc);
 
 /**
index e99d8f9..0f3daae 100644 (file)
@@ -41,6 +41,8 @@ enum {
        IB_ETH_BYTES  = 14,
        IB_VLAN_BYTES = 4,
        IB_GRH_BYTES  = 40,
+       IB_IP4_BYTES  = 20,
+       IB_UDP_BYTES  = 8,
        IB_BTH_BYTES  = 12,
        IB_DETH_BYTES = 8
 };
@@ -223,6 +225,27 @@ struct ib_unpacked_eth {
        __be16  type;
 };
 
+struct ib_unpacked_ip4 {
+       u8      ver;
+       u8      hdr_len;
+       u8      tos;
+       __be16  tot_len;
+       __be16  id;
+       __be16  frag_off;
+       u8      ttl;
+       u8      protocol;
+       __sum16 check;
+       __be32  saddr;
+       __be32  daddr;
+};
+
+struct ib_unpacked_udp {
+       __be16  sport;
+       __be16  dport;
+       __be16  length;
+       __be16  csum;
+};
+
 struct ib_unpacked_vlan {
        __be16  tag;
        __be16  type;
@@ -237,6 +260,10 @@ struct ib_ud_header {
        struct ib_unpacked_vlan vlan;
        int                     grh_present;
        struct ib_unpacked_grh  grh;
+       int                     ipv4_present;
+       struct ib_unpacked_ip4  ip4;
+       int                     udp_present;
+       struct ib_unpacked_udp  udp;
        struct ib_unpacked_bth  bth;
        struct ib_unpacked_deth deth;
        int                     immediate_present;
@@ -253,13 +280,17 @@ void ib_unpack(const struct ib_field        *desc,
               void                         *buf,
               void                         *structure);
 
-void ib_ud_header_init(int                 payload_bytes,
-                      int                  lrh_present,
-                      int                  eth_present,
-                      int                  vlan_present,
-                      int                  grh_present,
-                      int                  immediate_present,
-                      struct ib_ud_header *header);
+__sum16 ib_ud_ip4_csum(struct ib_ud_header *header);
+
+int ib_ud_header_init(int                  payload_bytes,
+                     int                   lrh_present,
+                     int                   eth_present,
+                     int                   vlan_present,
+                     int                   grh_present,
+                     int                   ip_version,
+                     int                   udp_present,
+                     int                   immediate_present,
+                     struct ib_ud_header *header);
 
 int ib_ud_header_pack(struct ib_ud_header *header,
                      void                *buf);
index a5889f1..2f8a65c 100644 (file)
@@ -42,6 +42,7 @@
  */
 #define IB_PMA_CLASS_CAP_ALLPORTSELECT  cpu_to_be16(1 << 8)
 #define IB_PMA_CLASS_CAP_EXT_WIDTH      cpu_to_be16(1 << 9)
+#define IB_PMA_CLASS_CAP_EXT_WIDTH_NOIETF cpu_to_be16(1 << 10)
 #define IB_PMA_CLASS_CAP_XMIT_WAIT      cpu_to_be16(1 << 12)
 
 #define IB_PMA_CLASS_PORT_INFO          cpu_to_be16(0x0001)
index 3019695..cdc1c81 100644 (file)
@@ -160,6 +160,7 @@ struct ib_sa_path_rec {
        int          ifindex;
        /* ignored in IB */
        struct net  *net;
+       enum ib_gid_type gid_type;
 };
 
 static inline struct net_device *ib_get_ndev_from_path(struct ib_sa_path_rec *rec)
@@ -402,6 +403,8 @@ int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num,
  */
 int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
                             struct ib_sa_mcmember_rec *rec,
+                            struct net_device *ndev,
+                            enum ib_gid_type gid_type,
                             struct ib_ah_attr *ah_attr);
 
 /**
index 120da1d..284b00c 100644 (file)
 #include <linux/scatterlist.h>
 #include <linux/workqueue.h>
 #include <linux/socket.h>
+#include <linux/irq_poll.h>
 #include <uapi/linux/if_ether.h>
+#include <net/ipv6.h>
+#include <net/ip.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <linux/atomic.h>
 #include <linux/mmu_notifier.h>
 #include <asm/uaccess.h>
 
 extern struct workqueue_struct *ib_wq;
+extern struct workqueue_struct *ib_comp_wq;
 
 union ib_gid {
        u8      raw[16];
@@ -67,7 +73,17 @@ union ib_gid {
 
 extern union ib_gid zgid;
 
+enum ib_gid_type {
+       /* If link layer is Ethernet, this is RoCE V1 */
+       IB_GID_TYPE_IB        = 0,
+       IB_GID_TYPE_ROCE      = 0,
+       IB_GID_TYPE_ROCE_UDP_ENCAP = 1,
+       IB_GID_TYPE_SIZE
+};
+
+#define ROCE_V2_UDP_DPORT      4791
 struct ib_gid_attr {
+       enum ib_gid_type        gid_type;
        struct net_device       *ndev;
 };
 
@@ -98,6 +114,35 @@ enum rdma_protocol_type {
 __attribute_const__ enum rdma_transport_type
 rdma_node_get_transport(enum rdma_node_type node_type);
 
+enum rdma_network_type {
+       RDMA_NETWORK_IB,
+       RDMA_NETWORK_ROCE_V1 = RDMA_NETWORK_IB,
+       RDMA_NETWORK_IPV4,
+       RDMA_NETWORK_IPV6
+};
+
+static inline enum ib_gid_type ib_network_to_gid_type(enum rdma_network_type network_type)
+{
+       if (network_type == RDMA_NETWORK_IPV4 ||
+           network_type == RDMA_NETWORK_IPV6)
+               return IB_GID_TYPE_ROCE_UDP_ENCAP;
+
+       /* IB_GID_TYPE_IB same as RDMA_NETWORK_ROCE_V1 */
+       return IB_GID_TYPE_IB;
+}
+
+static inline enum rdma_network_type ib_gid_to_network_type(enum ib_gid_type gid_type,
+                                                           union ib_gid *gid)
+{
+       if (gid_type == IB_GID_TYPE_IB)
+               return RDMA_NETWORK_IB;
+
+       if (ipv6_addr_v4mapped((struct in6_addr *)gid))
+               return RDMA_NETWORK_IPV4;
+       else
+               return RDMA_NETWORK_IPV6;
+}
+
 enum rdma_link_layer {
        IB_LINK_LAYER_UNSPECIFIED,
        IB_LINK_LAYER_INFINIBAND,
@@ -105,24 +150,32 @@ enum rdma_link_layer {
 };
 
 enum ib_device_cap_flags {
-       IB_DEVICE_RESIZE_MAX_WR         = 1,
-       IB_DEVICE_BAD_PKEY_CNTR         = (1<<1),
-       IB_DEVICE_BAD_QKEY_CNTR         = (1<<2),
-       IB_DEVICE_RAW_MULTI             = (1<<3),
-       IB_DEVICE_AUTO_PATH_MIG         = (1<<4),
-       IB_DEVICE_CHANGE_PHY_PORT       = (1<<5),
-       IB_DEVICE_UD_AV_PORT_ENFORCE    = (1<<6),
-       IB_DEVICE_CURR_QP_STATE_MOD     = (1<<7),
-       IB_DEVICE_SHUTDOWN_PORT         = (1<<8),
-       IB_DEVICE_INIT_TYPE             = (1<<9),
-       IB_DEVICE_PORT_ACTIVE_EVENT     = (1<<10),
-       IB_DEVICE_SYS_IMAGE_GUID        = (1<<11),
-       IB_DEVICE_RC_RNR_NAK_GEN        = (1<<12),
-       IB_DEVICE_SRQ_RESIZE            = (1<<13),
-       IB_DEVICE_N_NOTIFY_CQ           = (1<<14),
-       IB_DEVICE_LOCAL_DMA_LKEY        = (1<<15),
-       IB_DEVICE_RESERVED              = (1<<16), /* old SEND_W_INV */
-       IB_DEVICE_MEM_WINDOW            = (1<<17),
+       IB_DEVICE_RESIZE_MAX_WR                 = (1 << 0),
+       IB_DEVICE_BAD_PKEY_CNTR                 = (1 << 1),
+       IB_DEVICE_BAD_QKEY_CNTR                 = (1 << 2),
+       IB_DEVICE_RAW_MULTI                     = (1 << 3),
+       IB_DEVICE_AUTO_PATH_MIG                 = (1 << 4),
+       IB_DEVICE_CHANGE_PHY_PORT               = (1 << 5),
+       IB_DEVICE_UD_AV_PORT_ENFORCE            = (1 << 6),
+       IB_DEVICE_CURR_QP_STATE_MOD             = (1 << 7),
+       IB_DEVICE_SHUTDOWN_PORT                 = (1 << 8),
+       IB_DEVICE_INIT_TYPE                     = (1 << 9),
+       IB_DEVICE_PORT_ACTIVE_EVENT             = (1 << 10),
+       IB_DEVICE_SYS_IMAGE_GUID                = (1 << 11),
+       IB_DEVICE_RC_RNR_NAK_GEN                = (1 << 12),
+       IB_DEVICE_SRQ_RESIZE                    = (1 << 13),
+       IB_DEVICE_N_NOTIFY_CQ                   = (1 << 14),
+
+       /*
+        * This device supports a per-device lkey or stag that can be
+        * used without performing a memory registration for the local
+        * memory.  Note that ULPs should never check this flag, but
+        * instead of use the local_dma_lkey flag in the ib_pd structure,
+        * which will always contain a usable lkey.
+        */
+       IB_DEVICE_LOCAL_DMA_LKEY                = (1 << 15),
+       IB_DEVICE_RESERVED /* old SEND_W_INV */ = (1 << 16),
+       IB_DEVICE_MEM_WINDOW                    = (1 << 17),
        /*
         * Devices should set IB_DEVICE_UD_IP_SUM if they support
         * insertion of UDP and TCP checksum on outgoing UD IPoIB
@@ -130,18 +183,35 @@ enum ib_device_cap_flags {
         * incoming messages.  Setting this flag implies that the
         * IPoIB driver may set NETIF_F_IP_CSUM for datagram mode.
         */
-       IB_DEVICE_UD_IP_CSUM            = (1<<18),
-       IB_DEVICE_UD_TSO                = (1<<19),
-       IB_DEVICE_XRC                   = (1<<20),
-       IB_DEVICE_MEM_MGT_EXTENSIONS    = (1<<21),
-       IB_DEVICE_BLOCK_MULTICAST_LOOPBACK = (1<<22),
-       IB_DEVICE_MEM_WINDOW_TYPE_2A    = (1<<23),
-       IB_DEVICE_MEM_WINDOW_TYPE_2B    = (1<<24),
-       IB_DEVICE_RC_IP_CSUM            = (1<<25),
-       IB_DEVICE_RAW_IP_CSUM           = (1<<26),
-       IB_DEVICE_MANAGED_FLOW_STEERING = (1<<29),
-       IB_DEVICE_SIGNATURE_HANDOVER    = (1<<30),
-       IB_DEVICE_ON_DEMAND_PAGING      = (1<<31),
+       IB_DEVICE_UD_IP_CSUM                    = (1 << 18),
+       IB_DEVICE_UD_TSO                        = (1 << 19),
+       IB_DEVICE_XRC                           = (1 << 20),
+
+       /*
+        * This device supports the IB "base memory management extension",
+        * which includes support for fast registrations (IB_WR_REG_MR,
+        * IB_WR_LOCAL_INV and IB_WR_SEND_WITH_INV verbs).  This flag should
+        * also be set by any iWarp device which must support FRs to comply
+        * to the iWarp verbs spec.  iWarp devices also support the
+        * IB_WR_RDMA_READ_WITH_INV verb for RDMA READs that invalidate the
+        * stag.
+        */
+       IB_DEVICE_MEM_MGT_EXTENSIONS            = (1 << 21),
+       IB_DEVICE_BLOCK_MULTICAST_LOOPBACK      = (1 << 22),
+       IB_DEVICE_MEM_WINDOW_TYPE_2A            = (1 << 23),
+       IB_DEVICE_MEM_WINDOW_TYPE_2B            = (1 << 24),
+       IB_DEVICE_RC_IP_CSUM                    = (1 << 25),
+       IB_DEVICE_RAW_IP_CSUM                   = (1 << 26),
+       /*
+        * Devices should set IB_DEVICE_CROSS_CHANNEL if they
+        * support execution of WQEs that involve synchronization
+        * of I/O operations with single completion queue managed
+        * by hardware.
+        */
+       IB_DEVICE_CROSS_CHANNEL         = (1 << 27),
+       IB_DEVICE_MANAGED_FLOW_STEERING         = (1 << 29),
+       IB_DEVICE_SIGNATURE_HANDOVER            = (1 << 30),
+       IB_DEVICE_ON_DEMAND_PAGING              = (1 << 31),
 };
 
 enum ib_signature_prot_cap {
@@ -184,6 +254,7 @@ struct ib_odp_caps {
 
 enum ib_cq_creation_flags {
        IB_CQ_FLAGS_TIMESTAMP_COMPLETION   = 1 << 0,
+       IB_CQ_FLAGS_IGNORE_OVERRUN         = 1 << 1,
 };
 
 struct ib_cq_init_attr {
@@ -393,6 +464,7 @@ union rdma_protocol_stats {
 #define RDMA_CORE_CAP_PROT_IB           0x00100000
 #define RDMA_CORE_CAP_PROT_ROCE         0x00200000
 #define RDMA_CORE_CAP_PROT_IWARP        0x00400000
+#define RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP 0x00800000
 
 #define RDMA_CORE_PORT_IBA_IB          (RDMA_CORE_CAP_PROT_IB  \
                                        | RDMA_CORE_CAP_IB_MAD \
@@ -405,6 +477,12 @@ union rdma_protocol_stats {
                                        | RDMA_CORE_CAP_IB_CM   \
                                        | RDMA_CORE_CAP_AF_IB   \
                                        | RDMA_CORE_CAP_ETH_AH)
+#define RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP                      \
+                                       (RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP \
+                                       | RDMA_CORE_CAP_IB_MAD  \
+                                       | RDMA_CORE_CAP_IB_CM   \
+                                       | RDMA_CORE_CAP_AF_IB   \
+                                       | RDMA_CORE_CAP_ETH_AH)
 #define RDMA_CORE_PORT_IWARP           (RDMA_CORE_CAP_PROT_IWARP \
                                        | RDMA_CORE_CAP_IW_CM)
 #define RDMA_CORE_PORT_INTEL_OPA       (RDMA_CORE_PORT_IBA_IB  \
@@ -519,6 +597,17 @@ struct ib_grh {
        union ib_gid    dgid;
 };
 
+union rdma_network_hdr {
+       struct ib_grh ibgrh;
+       struct {
+               /* The IB spec states that if it's IPv4, the header
+                * is located in the last 20 bytes of the header.
+                */
+               u8              reserved[20];
+               struct iphdr    roce4grh;
+       };
+};
+
 enum {
        IB_MULTICAST_QPN = 0xffffff
 };
@@ -734,7 +823,6 @@ enum ib_wc_opcode {
        IB_WC_RDMA_READ,
        IB_WC_COMP_SWAP,
        IB_WC_FETCH_ADD,
-       IB_WC_BIND_MW,
        IB_WC_LSO,
        IB_WC_LOCAL_INV,
        IB_WC_REG_MR,
@@ -755,10 +843,14 @@ enum ib_wc_flags {
        IB_WC_IP_CSUM_OK        = (1<<3),
        IB_WC_WITH_SMAC         = (1<<4),
        IB_WC_WITH_VLAN         = (1<<5),
+       IB_WC_WITH_NETWORK_HDR_TYPE     = (1<<6),
 };
 
 struct ib_wc {
-       u64                     wr_id;
+       union {
+               u64             wr_id;
+               struct ib_cqe   *wr_cqe;
+       };
        enum ib_wc_status       status;
        enum ib_wc_opcode       opcode;
        u32                     vendor_err;
@@ -777,6 +869,7 @@ struct ib_wc {
        u8                      port_num;       /* valid only for DR SMPs on switches */
        u8                      smac[ETH_ALEN];
        u16                     vlan_id;
+       u8                      network_hdr_type;
 };
 
 enum ib_cq_notify_flags {
@@ -866,6 +959,9 @@ enum ib_qp_type {
 enum ib_qp_create_flags {
        IB_QP_CREATE_IPOIB_UD_LSO               = 1 << 0,
        IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK   = 1 << 1,
+       IB_QP_CREATE_CROSS_CHANNEL              = 1 << 2,
+       IB_QP_CREATE_MANAGED_SEND               = 1 << 3,
+       IB_QP_CREATE_MANAGED_RECV               = 1 << 4,
        IB_QP_CREATE_NETIF_QP                   = 1 << 5,
        IB_QP_CREATE_SIGNATURE_EN               = 1 << 6,
        IB_QP_CREATE_USE_GFP_NOIO               = 1 << 7,
@@ -1027,7 +1123,6 @@ enum ib_wr_opcode {
        IB_WR_REG_MR,
        IB_WR_MASKED_ATOMIC_CMP_AND_SWP,
        IB_WR_MASKED_ATOMIC_FETCH_AND_ADD,
-       IB_WR_BIND_MW,
        IB_WR_REG_SIG_MR,
        /* reserve values for low level drivers' internal use.
         * These values will not be used at all in the ib core layer.
@@ -1062,26 +1157,16 @@ struct ib_sge {
        u32     lkey;
 };
 
-/**
- * struct ib_mw_bind_info - Parameters for a memory window bind operation.
- * @mr: A memory region to bind the memory window to.
- * @addr: The address where the memory window should begin.
- * @length: The length of the memory window, in bytes.
- * @mw_access_flags: Access flags from enum ib_access_flags for the window.
- *
- * This struct contains the shared parameters for type 1 and type 2
- * memory window bind operations.
- */
-struct ib_mw_bind_info {
-       struct ib_mr   *mr;
-       u64             addr;
-       u64             length;
-       int             mw_access_flags;
+struct ib_cqe {
+       void (*done)(struct ib_cq *cq, struct ib_wc *wc);
 };
 
 struct ib_send_wr {
        struct ib_send_wr      *next;
-       u64                     wr_id;
+       union {
+               u64             wr_id;
+               struct ib_cqe   *wr_cqe;
+       };
        struct ib_sge          *sg_list;
        int                     num_sge;
        enum ib_wr_opcode       opcode;
@@ -1147,19 +1232,6 @@ static inline struct ib_reg_wr *reg_wr(struct ib_send_wr *wr)
        return container_of(wr, struct ib_reg_wr, wr);
 }
 
-struct ib_bind_mw_wr {
-       struct ib_send_wr       wr;
-       struct ib_mw            *mw;
-       /* The new rkey for the memory window. */
-       u32                     rkey;
-       struct ib_mw_bind_info  bind_info;
-};
-
-static inline struct ib_bind_mw_wr *bind_mw_wr(struct ib_send_wr *wr)
-{
-       return container_of(wr, struct ib_bind_mw_wr, wr);
-}
-
 struct ib_sig_handover_wr {
        struct ib_send_wr       wr;
        struct ib_sig_attrs    *sig_attrs;
@@ -1175,7 +1247,10 @@ static inline struct ib_sig_handover_wr *sig_handover_wr(struct ib_send_wr *wr)
 
 struct ib_recv_wr {
        struct ib_recv_wr      *next;
-       u64                     wr_id;
+       union {
+               u64             wr_id;
+               struct ib_cqe   *wr_cqe;
+       };
        struct ib_sge          *sg_list;
        int                     num_sge;
 };
@@ -1190,20 +1265,10 @@ enum ib_access_flags {
        IB_ACCESS_ON_DEMAND     = (1<<6),
 };
 
-struct ib_phys_buf {
-       u64      addr;
-       u64      size;
-};
-
-struct ib_mr_attr {
-       struct ib_pd    *pd;
-       u64             device_virt_addr;
-       u64             size;
-       int             mr_access_flags;
-       u32             lkey;
-       u32             rkey;
-};
-
+/*
+ * XXX: these are apparently used for ->rereg_user_mr, no idea why they
+ * are hidden here instead of a uapi header!
+ */
 enum ib_mr_rereg_flags {
        IB_MR_REREG_TRANS       = 1,
        IB_MR_REREG_PD          = (1<<1),
@@ -1211,18 +1276,6 @@ enum ib_mr_rereg_flags {
        IB_MR_REREG_SUPPORTED   = ((IB_MR_REREG_ACCESS << 1) - 1)
 };
 
-/**
- * struct ib_mw_bind - Parameters for a type 1 memory window bind operation.
- * @wr_id:      Work request id.
- * @send_flags: Flags from ib_send_flags enum.
- * @bind_info:  More parameters of the bind operation.
- */
-struct ib_mw_bind {
-       u64                    wr_id;
-       int                    send_flags;
-       struct ib_mw_bind_info bind_info;
-};
-
 struct ib_fmr_attr {
        int     max_pages;
        int     max_maps;
@@ -1307,6 +1360,12 @@ struct ib_ah {
 
 typedef void (*ib_comp_handler)(struct ib_cq *cq, void *cq_context);
 
+enum ib_poll_context {
+       IB_POLL_DIRECT,         /* caller context, no hw completions */
+       IB_POLL_SOFTIRQ,        /* poll from softirq context */
+       IB_POLL_WORKQUEUE,      /* poll from workqueue */
+};
+
 struct ib_cq {
        struct ib_device       *device;
        struct ib_uobject      *uobject;
@@ -1315,6 +1374,12 @@ struct ib_cq {
        void                   *cq_context;
        int                     cqe;
        atomic_t                usecnt; /* count number of work queues */
+       enum ib_poll_context    poll_ctx;
+       struct ib_wc            *wc;
+       union {
+               struct irq_poll         iop;
+               struct work_struct      work;
+       };
 };
 
 struct ib_srq {
@@ -1363,7 +1428,6 @@ struct ib_mr {
        u64                iova;
        u32                length;
        unsigned int       page_size;
-       atomic_t           usecnt; /* count number of MWs */
 };
 
 struct ib_mw {
@@ -1724,11 +1788,6 @@ struct ib_device {
                                                      int wc_cnt);
        struct ib_mr *             (*get_dma_mr)(struct ib_pd *pd,
                                                 int mr_access_flags);
-       struct ib_mr *             (*reg_phys_mr)(struct ib_pd *pd,
-                                                 struct ib_phys_buf *phys_buf_array,
-                                                 int num_phys_buf,
-                                                 int mr_access_flags,
-                                                 u64 *iova_start);
        struct ib_mr *             (*reg_user_mr)(struct ib_pd *pd,
                                                  u64 start, u64 length,
                                                  u64 virt_addr,
@@ -1741,8 +1800,6 @@ struct ib_device {
                                                    int mr_access_flags,
                                                    struct ib_pd *pd,
                                                    struct ib_udata *udata);
-       int                        (*query_mr)(struct ib_mr *mr,
-                                              struct ib_mr_attr *mr_attr);
        int                        (*dereg_mr)(struct ib_mr *mr);
        struct ib_mr *             (*alloc_mr)(struct ib_pd *pd,
                                               enum ib_mr_type mr_type,
@@ -1750,18 +1807,8 @@ struct ib_device {
        int                        (*map_mr_sg)(struct ib_mr *mr,
                                                struct scatterlist *sg,
                                                int sg_nents);
-       int                        (*rereg_phys_mr)(struct ib_mr *mr,
-                                                   int mr_rereg_mask,
-                                                   struct ib_pd *pd,
-                                                   struct ib_phys_buf *phys_buf_array,
-                                                   int num_phys_buf,
-                                                   int mr_access_flags,
-                                                   u64 *iova_start);
        struct ib_mw *             (*alloc_mw)(struct ib_pd *pd,
                                               enum ib_mw_type type);
-       int                        (*bind_mw)(struct ib_qp *qp,
-                                             struct ib_mw *mw,
-                                             struct ib_mw_bind *mw_bind);
        int                        (*dealloc_mw)(struct ib_mw *mw);
        struct ib_fmr *            (*alloc_fmr)(struct ib_pd *pd,
                                                int mr_access_flags,
@@ -1823,6 +1870,7 @@ struct ib_device {
        u16                          is_switch:1;
        u8                           node_type;
        u8                           phys_port_cnt;
+       struct ib_device_attr        attrs;
 
        /**
         * The following mandatory functions are used only at device
@@ -1888,6 +1936,31 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
        return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
 }
 
+static inline bool ib_is_udata_cleared(struct ib_udata *udata,
+                                      size_t offset,
+                                      size_t len)
+{
+       const void __user *p = udata->inbuf + offset;
+       bool ret = false;
+       u8 *buf;
+
+       if (len > USHRT_MAX)
+               return false;
+
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf)
+               return false;
+
+       if (copy_from_user(buf, p, len))
+               goto free;
+
+       ret = !memchr_inv(buf, 0, len);
+
+free:
+       kfree(buf);
+       return ret;
+}
+
 /**
  * ib_modify_qp_is_ok - Check that the supplied attribute mask
  * contains all required attributes and no attributes not allowed for
@@ -1912,9 +1985,6 @@ int ib_register_event_handler  (struct ib_event_handler *event_handler);
 int ib_unregister_event_handler(struct ib_event_handler *event_handler);
 void ib_dispatch_event(struct ib_event *event);
 
-int ib_query_device(struct ib_device *device,
-                   struct ib_device_attr *device_attr);
-
 int ib_query_port(struct ib_device *device,
                  u8 port_num, struct ib_port_attr *port_attr);
 
@@ -1967,6 +2037,17 @@ static inline bool rdma_protocol_ib(const struct ib_device *device, u8 port_num)
 }
 
 static inline bool rdma_protocol_roce(const struct ib_device *device, u8 port_num)
+{
+       return device->port_immutable[port_num].core_cap_flags &
+               (RDMA_CORE_CAP_PROT_ROCE | RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP);
+}
+
+static inline bool rdma_protocol_roce_udp_encap(const struct ib_device *device, u8 port_num)
+{
+       return device->port_immutable[port_num].core_cap_flags & RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP;
+}
+
+static inline bool rdma_protocol_roce_eth_encap(const struct ib_device *device, u8 port_num)
 {
        return device->port_immutable[port_num].core_cap_flags & RDMA_CORE_CAP_PROT_ROCE;
 }
@@ -1978,8 +2059,8 @@ static inline bool rdma_protocol_iwarp(const struct ib_device *device, u8 port_n
 
 static inline bool rdma_ib_or_roce(const struct ib_device *device, u8 port_num)
 {
-       return device->port_immutable[port_num].core_cap_flags &
-               (RDMA_CORE_CAP_PROT_IB | RDMA_CORE_CAP_PROT_ROCE);
+       return rdma_protocol_ib(device, port_num) ||
+               rdma_protocol_roce(device, port_num);
 }
 
 /**
@@ -2220,7 +2301,8 @@ int ib_modify_port(struct ib_device *device,
                   struct ib_port_modify *port_modify);
 
 int ib_find_gid(struct ib_device *device, union ib_gid *gid,
-               struct net_device *ndev, u8 *port_num, u16 *index);
+               enum ib_gid_type gid_type, struct net_device *ndev,
+               u8 *port_num, u16 *index);
 
 int ib_find_pkey(struct ib_device *device,
                 u8 port_num, u16 pkey, u16 *index);
@@ -2454,6 +2536,11 @@ static inline int ib_post_recv(struct ib_qp *qp,
        return qp->device->post_recv(qp, recv_wr, bad_recv_wr);
 }
 
+struct ib_cq *ib_alloc_cq(struct ib_device *dev, void *private,
+               int nr_cqe, int comp_vector, enum ib_poll_context poll_ctx);
+void ib_free_cq(struct ib_cq *cq);
+int ib_process_cq_direct(struct ib_cq *cq, int budget);
+
 /**
  * ib_create_cq - Creates a CQ on the specified device.
  * @device: The device on which to create the CQ.
@@ -2838,13 +2925,6 @@ static inline void ib_dma_free_coherent(struct ib_device *dev,
                dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
 }
 
-/**
- * ib_query_mr - Retrieves information about a specific memory region.
- * @mr: The memory region to retrieve information about.
- * @mr_attr: The attributes of the specified memory region.
- */
-int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr);
-
 /**
  * ib_dereg_mr - Deregisters a memory region and removes it from the
  *   HCA translation table.
@@ -2881,42 +2961,6 @@ static inline u32 ib_inc_rkey(u32 rkey)
        return ((rkey + 1) & mask) | (rkey & ~mask);
 }
 
-/**
- * ib_alloc_mw - Allocates a memory window.
- * @pd: The protection domain associated with the memory window.
- * @type: The type of the memory window (1 or 2).
- */
-struct ib_mw *ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type);
-
-/**
- * ib_bind_mw - Posts a work request to the send queue of the specified
- *   QP, which binds the memory window to the given address range and
- *   remote access attributes.
- * @qp: QP to post the bind work request on.
- * @mw: The memory window to bind.
- * @mw_bind: Specifies information about the memory window, including
- *   its address range, remote access rights, and associated memory region.
- *
- * If there is no immediate error, the function will update the rkey member
- * of the mw parameter to its new value. The bind operation can still fail
- * asynchronously.
- */
-static inline int ib_bind_mw(struct ib_qp *qp,
-                            struct ib_mw *mw,
-                            struct ib_mw_bind *mw_bind)
-{
-       /* XXX reference counting in corresponding MR? */
-       return mw->device->bind_mw ?
-               mw->device->bind_mw(qp, mw, mw_bind) :
-               -ENOSYS;
-}
-
-/**
- * ib_dealloc_mw - Deallocates a memory window.
- * @mw: The memory window to deallocate.
- */
-int ib_dealloc_mw(struct ib_mw *mw);
-
 /**
  * ib_alloc_fmr - Allocates a unmapped fast memory region.
  * @pd: The protection domain associated with the unmapped region.
diff --git a/include/scsi/iser.h b/include/scsi/iser.h
new file mode 100644 (file)
index 0000000..2e678fa
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     - Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer.
+ *
+ *     - Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ISCSI_ISER_H
+#define ISCSI_ISER_H
+
+#define ISER_ZBVA_NOT_SUP              0x80
+#define ISER_SEND_W_INV_NOT_SUP                0x40
+#define ISERT_ZBVA_NOT_USED            0x80
+#define ISERT_SEND_W_INV_NOT_USED      0x40
+
+#define ISCSI_CTRL     0x10
+#define ISER_HELLO     0x20
+#define ISER_HELLORPLY 0x30
+
+#define ISER_VER       0x10
+#define ISER_WSV       0x08
+#define ISER_RSV       0x04
+
+/**
+ * struct iser_cm_hdr - iSER CM header (from iSER Annex A12)
+ *
+ * @flags:        flags support (zbva, send_w_inv)
+ * @rsvd:         reserved
+ */
+struct iser_cm_hdr {
+       u8      flags;
+       u8      rsvd[3];
+} __packed;
+
+/**
+ * struct iser_ctrl - iSER header of iSCSI control PDU
+ *
+ * @flags:        opcode and read/write valid bits
+ * @rsvd:         reserved
+ * @write_stag:   write rkey
+ * @write_va:     write virtual address
+ * @reaf_stag:    read rkey
+ * @read_va:      read virtual address
+ */
+struct iser_ctrl {
+       u8      flags;
+       u8      rsvd[3];
+       __be32  write_stag;
+       __be64  write_va;
+       __be32  read_stag;
+       __be64  read_va;
+} __packed;
+
+#endif /* ISCSI_ISER_H */
index c07d74a..3fb3571 100644 (file)
@@ -72,10 +72,12 @@ enum rpi_firmware_property_tag {
        RPI_FIRMWARE_SET_ENABLE_QPU =                         0x00030012,
        RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =       0x00030014,
        RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
+       RPI_FIRMWARE_GET_DOMAIN_STATE =                       0x00030030,
        RPI_FIRMWARE_SET_CLOCK_STATE =                        0x00038001,
        RPI_FIRMWARE_SET_CLOCK_RATE =                         0x00038002,
        RPI_FIRMWARE_SET_VOLTAGE =                            0x00038003,
        RPI_FIRMWARE_SET_TURBO =                              0x00038009,
+       RPI_FIRMWARE_SET_DOMAIN_STATE =                       0x00038030,
 
        /* Dispmanx TAGS */
        RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE =                   0x00040001,
index 7990469..c4d76ff 100644 (file)
@@ -104,6 +104,7 @@ struct snd_timer_instance {
                           int event,
                           struct timespec * tstamp,
                           unsigned long resolution);
+       void (*disconnect)(struct snd_timer_instance *timeri);
        void *callback_data;
        unsigned long ticks;            /* auto-load ticks when expired */
        unsigned long cticks;           /* current ticks */
index aabf0ac..5d82816 100644 (file)
@@ -63,6 +63,8 @@
 #define DA_UNMAP_GRANULARITY_DEFAULT           0
 /* Default unmap_granularity_alignment */
 #define DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT 0
+/* Default unmap_zeroes_data */
+#define DA_UNMAP_ZEROES_DATA_DEFAULT           0
 /* Default max_write_same_len, disabled by default */
 #define DA_MAX_WRITE_SAME_LEN                  0
 /* Use a model alias based on the configfs backend device name */
@@ -526,6 +528,7 @@ struct se_cmd {
        unsigned int            t_prot_nents;
        sense_reason_t          pi_err;
        sector_t                bad_sector;
+       int                     cpuid;
 };
 
 struct se_ua {
@@ -674,6 +677,7 @@ struct se_dev_attrib {
        int             force_pr_aptpl;
        int             is_nonrot;
        int             emulate_rest_reord;
+       int             unmap_zeroes_data;
        u32             hw_block_size;
        u32             block_size;
        u32             hw_max_sectors;
@@ -864,8 +868,6 @@ struct se_portal_group {
         * Negative values can be used by fabric drivers for internal use TPGs.
         */
        int                     proto_id;
-       /* Number of ACLed Initiator Nodes for this TPG */
-       u32                     num_node_acls;
        /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
        atomic_t                tpg_pr_ref_count;
        /* Spinlock for adding/removing ACLed Nodes */
index 7fb2557..5665340 100644 (file)
@@ -117,7 +117,7 @@ void        __transport_register_session(struct se_portal_group *,
                struct se_node_acl *, struct se_session *, void *);
 void   transport_register_session(struct se_portal_group *,
                struct se_node_acl *, struct se_session *, void *);
-void   target_get_session(struct se_session *);
+int    target_get_session(struct se_session *);
 void   target_put_session(struct se_session *);
 ssize_t        target_show_dynamic_sessions(struct se_portal_group *, char *);
 void   transport_free_session(struct se_session *);
@@ -140,7 +140,7 @@ int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
 int    target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
                unsigned char *sense, u64 unpacked_lun,
                void *fabric_tmr_ptr, unsigned char tm_type,
-               gfp_t, unsigned int, int);
+               gfp_t, u64, int);
 int    transport_handle_cdb_direct(struct se_cmd *);
 sense_reason_t transport_generic_new_cmd(struct se_cmd *);
 
@@ -169,10 +169,11 @@ void      core_allocate_nexus_loss_ua(struct se_node_acl *acl);
 
 struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg,
                unsigned char *);
+bool   target_tpg_has_node_acl(struct se_portal_group *tpg,
+               const char *);
 struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *,
                unsigned char *);
-int    core_tpg_set_initiator_node_queue_depth(struct se_portal_group *,
-               unsigned char *, u32, int);
+int    core_tpg_set_initiator_node_queue_depth(struct se_node_acl *, u32);
 int    core_tpg_set_initiator_node_tag(struct se_portal_group *,
                struct se_node_acl *, const char *);
 int    core_tpg_register(struct se_wwn *, struct se_portal_group *, int);
index 594b4b2..4e4b2fa 100644 (file)
@@ -43,7 +43,7 @@ struct extent_status;
        { EXT4_GET_BLOCKS_METADATA_NOFAIL,      "METADATA_NOFAIL" },    \
        { EXT4_GET_BLOCKS_NO_NORMALIZE,         "NO_NORMALIZE" },       \
        { EXT4_GET_BLOCKS_KEEP_SIZE,            "KEEP_SIZE" },          \
-       { EXT4_GET_BLOCKS_NO_LOCK,              "NO_LOCK" })
+       { EXT4_GET_BLOCKS_ZERO,                 "ZERO" })
 
 #define show_mflags(flags) __print_flags(flags, "",    \
        { EXT4_MAP_NEW,         "N" },                  \
index 0f803d2..47c6212 100644 (file)
@@ -46,10 +46,10 @@ SCAN_STATUS
 
 TRACE_EVENT(mm_khugepaged_scan_pmd,
 
-       TP_PROTO(struct mm_struct *mm, unsigned long pfn, bool writable,
+       TP_PROTO(struct mm_struct *mm, struct page *page, bool writable,
                 bool referenced, int none_or_zero, int status),
 
-       TP_ARGS(mm, pfn, writable, referenced, none_or_zero, status),
+       TP_ARGS(mm, page, writable, referenced, none_or_zero, status),
 
        TP_STRUCT__entry(
                __field(struct mm_struct *, mm)
@@ -62,7 +62,7 @@ TRACE_EVENT(mm_khugepaged_scan_pmd,
 
        TP_fast_assign(
                __entry->mm = mm;
-               __entry->pfn = pfn;
+               __entry->pfn = page ? page_to_pfn(page) : -1;
                __entry->writable = writable;
                __entry->referenced = referenced;
                __entry->none_or_zero = none_or_zero;
@@ -104,10 +104,10 @@ TRACE_EVENT(mm_collapse_huge_page,
 
 TRACE_EVENT(mm_collapse_huge_page_isolate,
 
-       TP_PROTO(unsigned long pfn, int none_or_zero,
+       TP_PROTO(struct page *page, int none_or_zero,
                 bool referenced, bool  writable, int status),
 
-       TP_ARGS(pfn, none_or_zero, referenced, writable, status),
+       TP_ARGS(page, none_or_zero, referenced, writable, status),
 
        TP_STRUCT__entry(
                __field(unsigned long, pfn)
@@ -118,7 +118,7 @@ TRACE_EVENT(mm_collapse_huge_page_isolate,
        ),
 
        TP_fast_assign(
-               __entry->pfn = pfn;
+               __entry->pfn = page ? page_to_pfn(page) : -1;
                __entry->none_or_zero = none_or_zero;
                __entry->referenced = referenced;
                __entry->writable = writable;
index ff8f6c0..f95f25e 100644 (file)
@@ -15,7 +15,7 @@ struct softirq_action;
                         softirq_name(NET_TX)           \
                         softirq_name(NET_RX)           \
                         softirq_name(BLOCK)            \
-                        softirq_name(BLOCK_IOPOLL)     \
+                        softirq_name(IRQ_POLL)         \
                         softirq_name(TASKLET)          \
                         softirq_name(SCHED)            \
                         softirq_name(HRTIMER)          \
index c2e5d6c..ebd10e6 100644 (file)
@@ -307,7 +307,7 @@ header-y += nfs_mount.h
 header-y += nl80211.h
 header-y += n_r3964.h
 header-y += nubus.h
-header-y += nvme.h
+header-y += nvme_ioctl.h
 header-y += nvram.h
 header-y += omap3isp.h
 header-y += omapfb.h
index bc81fb2..1c31549 100644 (file)
@@ -26,6 +26,9 @@
 #define EPOLL_CTL_DEL 2
 #define EPOLL_CTL_MOD 3
 
+/* Set exclusive wakeup mode for the target file descriptor */
+#define EPOLLEXCLUSIVE (1 << 28)
+
 /*
  * Request the handling of system wakeup events so as to prevent system suspends
  * from happening while those events are being processed.
index b8a5b3b..41e0433 100644 (file)
@@ -2,8 +2,11 @@
 #define _UAPI_LINUX_FS_H
 
 /*
- * This file has definitions for some important file table
- * structures etc.
+ * This file has definitions for some important file table structures
+ * and constants and structures used by various generic file system
+ * ioctl's.  Please do not make any changes in this file before
+ * sending patches for review to linux-fsdevel@vger.kernel.org and
+ * linux-api@vger.kernel.org.
  */
 
 #include <linux/limits.h>
@@ -146,6 +149,37 @@ struct inodes_stat_t {
 #define MS_MGC_VAL 0xC0ED0000
 #define MS_MGC_MSK 0xffff0000
 
+/*
+ * Structure for FS_IOC_FSGETXATTR[A] and FS_IOC_FSSETXATTR.
+ */
+struct fsxattr {
+       __u32           fsx_xflags;     /* xflags field value (get/set) */
+       __u32           fsx_extsize;    /* extsize field value (get/set)*/
+       __u32           fsx_nextents;   /* nextents field value (get)   */
+       __u32           fsx_projid;     /* project identifier (get/set) */
+       unsigned char   fsx_pad[12];
+};
+
+/*
+ * Flags for the fsx_xflags field
+ */
+#define FS_XFLAG_REALTIME      0x00000001      /* data in realtime volume */
+#define FS_XFLAG_PREALLOC      0x00000002      /* preallocated file extents */
+#define FS_XFLAG_IMMUTABLE     0x00000008      /* file cannot be modified */
+#define FS_XFLAG_APPEND                0x00000010      /* all writes append */
+#define FS_XFLAG_SYNC          0x00000020      /* all writes synchronous */
+#define FS_XFLAG_NOATIME       0x00000040      /* do not update access time */
+#define FS_XFLAG_NODUMP                0x00000080      /* do not include in backups */
+#define FS_XFLAG_RTINHERIT     0x00000100      /* create with rt bit set */
+#define FS_XFLAG_PROJINHERIT   0x00000200      /* create with parents projid */
+#define FS_XFLAG_NOSYMLINKS    0x00000400      /* disallow symlink creation */
+#define FS_XFLAG_EXTSIZE       0x00000800      /* extent size allocator hint */
+#define FS_XFLAG_EXTSZINHERIT  0x00001000      /* inherit inode extent size */
+#define FS_XFLAG_NODEFRAG      0x00002000      /* do not defragment */
+#define FS_XFLAG_FILESTREAM    0x00004000      /* use filestream allocator */
+#define FS_XFLAG_DAX           0x00008000      /* use DAX for IO */
+#define FS_XFLAG_HASATTR       0x80000000      /* no DIFLAG for this   */
+
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
 
@@ -210,9 +244,28 @@ struct inodes_stat_t {
 #define FS_IOC32_SETFLAGS              _IOW('f', 2, int)
 #define FS_IOC32_GETVERSION            _IOR('v', 1, int)
 #define FS_IOC32_SETVERSION            _IOW('v', 2, int)
+#define FS_IOC_FSGETXATTR              _IOR ('X', 31, struct fsxattr)
+#define FS_IOC_FSSETXATTR              _IOW ('X', 32, struct fsxattr)
 
 /*
  * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
+ *
+ * Note: for historical reasons, these flags were originally used and
+ * defined for use by ext2/ext3, and then other file systems started
+ * using these flags so they wouldn't need to write their own version
+ * of chattr/lsattr (which was shipped as part of e2fsprogs).  You
+ * should think twice before trying to use these flags in new
+ * contexts, or trying to assign these flags, since they are used both
+ * as the UAPI and the on-disk encoding for ext2/3/4.  Also, we are
+ * almost out of 32-bit flags.  :-)
+ *
+ * We have recently hoisted FS_IOC_FSGETXATTR / FS_IOC_FSSETXATTR from
+ * XFS to the generic FS level interface.  This uses a structure that
+ * has padding and hence has more room to grow, so it may be more
+ * appropriate for many new use cases.
+ *
+ * Please do not change these flags or interfaces before checking with
+ * linux-fsdevel@vger.kernel.org and linux-api@vger.kernel.org.
  */
 #define        FS_SECRM_FL                     0x00000001 /* Secure deletion */
 #define        FS_UNRM_FL                      0x00000002 /* Undelete */
@@ -226,8 +279,8 @@ struct inodes_stat_t {
 #define FS_DIRTY_FL                    0x00000100
 #define FS_COMPRBLK_FL                 0x00000200 /* One or more compressed clusters */
 #define FS_NOCOMP_FL                   0x00000400 /* Don't compress */
-#define FS_ECOMPR_FL                   0x00000800 /* Compression error */
 /* End compression flags --- maybe not all used */
+#define FS_ENCRYPT_FL                  0x00000800 /* Encrypted file */
 #define FS_BTREE_FL                    0x00001000 /* btree format dir */
 #define FS_INDEX_FL                    0x00001000 /* hash-indexed directory */
 #define FS_IMAGIC_FL                   0x00002000 /* AFS directory */
@@ -235,9 +288,12 @@ struct inodes_stat_t {
 #define FS_NOTAIL_FL                   0x00008000 /* file tail should not be merged */
 #define FS_DIRSYNC_FL                  0x00010000 /* dirsync behaviour (directories only) */
 #define FS_TOPDIR_FL                   0x00020000 /* Top of directory hierarchies*/
+#define FS_HUGE_FILE_FL                        0x00040000 /* Reserved for ext4 */
 #define FS_EXTENT_FL                   0x00080000 /* Extents */
-#define FS_DIRECTIO_FL                 0x00100000 /* Use direct i/o */
+#define FS_EA_INODE_FL                 0x00200000 /* Inode used for large EA */
+#define FS_EOFBLOCKS_FL                        0x00400000 /* Reserved for ext4 */
 #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
+#define FS_INLINE_DATA_FL              0x10000000 /* Reserved for ext4 */
 #define FS_PROJINHERIT_FL              0x20000000 /* Create with parents projid */
 #define FS_RESERVED_FL                 0x80000000 /* reserved for ext2 lib */
 
index c9aca04..5974fae 100644 (file)
  *  - add ctime and ctimensec to fuse_setattr_in
  *  - add FUSE_RENAME2 request
  *  - add FUSE_NO_OPEN_SUPPORT flag
+ *
+ *  7.24
+ *  - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support
  */
 
 #ifndef _LINUX_FUSE_H
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 23
+#define FUSE_KERNEL_MINOR_VERSION 24
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -358,6 +361,7 @@ enum fuse_opcode {
        FUSE_FALLOCATE     = 43,
        FUSE_READDIRPLUS   = 44,
        FUSE_RENAME2       = 45,
+       FUSE_LSEEK         = 46,
 
        /* CUSE specific operations */
        CUSE_INIT          = 4096,
@@ -758,4 +762,15 @@ struct fuse_notify_retrieve_in {
 /* Device ioctls: */
 #define FUSE_DEV_IOC_CLONE     _IOR(229, 0, uint32_t)
 
+struct fuse_lseek_in {
+       uint64_t        fh;
+       uint64_t        offset;
+       uint32_t        whence;
+       uint32_t        padding;
+};
+
+struct fuse_lseek_out {
+       uint64_t        offset;
+};
+
 #endif /* _LINUX_FUSE_H */
index 928f989..774a431 100644 (file)
@@ -33,6 +33,7 @@
 
 #define NVM_TTYPE_NAME_MAX 48
 #define NVM_TTYPE_MAX 63
+#define NVM_MMTYPE_LEN 8
 
 #define NVM_CTRL_FILE "/dev/lightnvm/control"
 
@@ -100,6 +101,26 @@ struct nvm_ioctl_remove {
        __u32 flags;
 };
 
+struct nvm_ioctl_dev_init {
+       char dev[DISK_NAME_LEN];                /* open-channel SSD device */
+       char mmtype[NVM_MMTYPE_LEN];            /* register to media manager */
+
+       __u32 flags;
+};
+
+enum {
+       NVM_FACTORY_ERASE_ONLY_USER     = 1 << 0, /* erase only blocks used as
+                                                  * host blks or grown blks */
+       NVM_FACTORY_RESET_HOST_BLKS     = 1 << 1, /* remove host blk marks */
+       NVM_FACTORY_RESET_GRWN_BBLKS    = 1 << 2, /* remove grown blk marks */
+       NVM_FACTORY_NR_BITS             = 1 << 3, /* stops here */
+};
+
+struct nvm_ioctl_dev_factory {
+       char dev[DISK_NAME_LEN];
+
+       __u32 flags;
+};
 
 /* The ioctl type, 'L', 0x20 - 0x2F documented in ioctl-number.txt */
 enum {
@@ -110,6 +131,12 @@ enum {
        /* device level cmds */
        NVM_DEV_CREATE_CMD,
        NVM_DEV_REMOVE_CMD,
+
+       /* Init a device to support LightNVM media managers */
+       NVM_DEV_INIT_CMD,
+
+       /* Factory reset device */
+       NVM_DEV_FACTORY_CMD,
 };
 
 #define NVM_IOCTL 'L' /* 0x4c */
@@ -122,6 +149,10 @@ enum {
                                                struct nvm_ioctl_create)
 #define NVM_DEV_REMOVE         _IOW(NVM_IOCTL, NVM_DEV_REMOVE_CMD, \
                                                struct nvm_ioctl_remove)
+#define NVM_DEV_INIT           _IOW(NVM_IOCTL, NVM_DEV_INIT_CMD, \
+                                               struct nvm_ioctl_dev_init)
+#define NVM_DEV_FACTORY                _IOW(NVM_IOCTL, NVM_DEV_FACTORY_CMD, \
+                                               struct nvm_ioctl_dev_factory)
 
 #define NVM_VERSION_MAJOR      1
 #define NVM_VERSION_MINOR      0
index b283d56..0de181a 100644 (file)
@@ -31,6 +31,7 @@
 #define PSTOREFS_MAGIC         0x6165676C
 #define EFIVARFS_MAGIC         0xde5e81e4
 #define HOSTFS_SUPER_MAGIC     0x00c0ffee
+#define OVERLAYFS_SUPER_MAGIC  0x794c7630
 
 #define MINIX_SUPER_MAGIC      0x137F          /* minix v1 fs, 14 char names */
 #define MINIX_SUPER_MAGIC2     0x138F          /* minix v1 fs, 30 char names */
index c33e1c4..8b8cfad 100644 (file)
 typedef uint16_t blkif_vdev_t;
 typedef uint64_t blkif_sector_t;
 
+/*
+ * Multiple hardware queues/rings:
+ * If supported, the backend will write the key "multi-queue-max-queues" to
+ * the directory for that vbd, and set its value to the maximum supported
+ * number of queues.
+ * Frontends that are aware of this feature and wish to use it can write the
+ * key "multi-queue-num-queues" with the number they wish to use, which must be
+ * greater than zero, and no more than the value reported by the backend in
+ * "multi-queue-max-queues".
+ *
+ * For frontends requesting just one queue, the usual event-channel and
+ * ring-ref keys are written as before, simplifying the backend processing
+ * to avoid distinguishing between a frontend that doesn't understand the
+ * multi-queue feature, and one that does, but requested only one queue.
+ *
+ * Frontends requesting two or more queues must not write the toplevel
+ * event-channel and ring-ref keys, instead writing those keys under sub-keys
+ * having the name "queue-N" where N is the integer ID of the queue/ring for
+ * which those keys belong. Queues are indexed from zero.
+ * For example, a frontend with two queues must write the following set of
+ * queue-related keys:
+ *
+ * /local/domain/1/device/vbd/0/multi-queue-num-queues = "2"
+ * /local/domain/1/device/vbd/0/queue-0 = ""
+ * /local/domain/1/device/vbd/0/queue-0/ring-ref = "<ring-ref#0>"
+ * /local/domain/1/device/vbd/0/queue-0/event-channel = "<evtchn#0>"
+ * /local/domain/1/device/vbd/0/queue-1 = ""
+ * /local/domain/1/device/vbd/0/queue-1/ring-ref = "<ring-ref#1>"
+ * /local/domain/1/device/vbd/0/queue-1/event-channel = "<evtchn#1>"
+ *
+ * It is also possible to use multiple queues/rings together with
+ * feature multi-page ring buffer.
+ * For example, a frontend requests two queues/rings and the size of each ring
+ * buffer is two pages must write the following set of related keys:
+ *
+ * /local/domain/1/device/vbd/0/multi-queue-num-queues = "2"
+ * /local/domain/1/device/vbd/0/ring-page-order = "1"
+ * /local/domain/1/device/vbd/0/queue-0 = ""
+ * /local/domain/1/device/vbd/0/queue-0/ring-ref0 = "<ring-ref#0>"
+ * /local/domain/1/device/vbd/0/queue-0/ring-ref1 = "<ring-ref#1>"
+ * /local/domain/1/device/vbd/0/queue-0/event-channel = "<evtchn#0>"
+ * /local/domain/1/device/vbd/0/queue-1 = ""
+ * /local/domain/1/device/vbd/0/queue-1/ring-ref0 = "<ring-ref#2>"
+ * /local/domain/1/device/vbd/0/queue-1/ring-ref1 = "<ring-ref#3>"
+ * /local/domain/1/device/vbd/0/queue-1/event-channel = "<evtchn#1>"
+ *
+ */
+
 /*
  * REQUEST CODES.
  */
index 5b86082..2232080 100644 (file)
@@ -964,17 +964,6 @@ config MEMCG_SWAP_ENABLED
          For those who want to have the feature enabled by default should
          select this option (if, for some reason, they need to disable it
          then swapaccount=0 does the trick).
-config MEMCG_KMEM
-       bool "Memory Resource Controller Kernel Memory accounting"
-       depends on MEMCG
-       depends on SLUB || SLAB
-       help
-         The Kernel Memory extension for Memory Resource Controller can limit
-         the amount of memory used by kernel objects in the system. Those are
-         fundamentally different from the entities handled by the standard
-         Memory Controller, which are page-based, and can be swapped. Users of
-         the kmem extension can use it to guarantee that no group of processes
-         will ever exhaust kernel resources alone.
 
 config BLK_CGROUP
        bool "IO controller"
@@ -1071,6 +1060,11 @@ config CGROUP_FREEZER
          Provides a way to freeze and unfreeze all tasks in a
          cgroup.
 
+         This option affects the ORIGINAL cgroup interface. The cgroup2 memory
+         controller includes important in-kernel memory consumers per default.
+
+         If you're using cgroup2, say N.
+
 config CGROUP_HUGETLB
        bool "HugeTLB controller"
        depends on HUGETLB_PAGE
@@ -1182,10 +1176,9 @@ config USER_NS
          to provide different user info for different servers.
 
          When user namespaces are enabled in the kernel it is
-         recommended that the MEMCG and MEMCG_KMEM options also be
-         enabled and that user-space use the memory control groups to
-         limit the amount of memory a memory unprivileged users can
-         use.
+         recommended that the MEMCG option also be enabled and that
+         user-space use the memory control groups to limit the amount
+         of memory a memory unprivileged users can use.
 
          If unsure, say N.
 
index f5b978a..067af1d 100644 (file)
@@ -57,11 +57,11 @@ static inline int rd_load_image(char *from) { return 0; }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-int __init initrd_load(void);
+bool __init initrd_load(void);
 
 #else
 
-static inline int initrd_load(void) { return 0; }
+static inline bool initrd_load(void) { return false; }
 
 #endif
 
index 3e0878e..a1000ca 100644 (file)
@@ -116,7 +116,7 @@ static void __init handle_initrd(void)
        }
 }
 
-int __init initrd_load(void)
+bool __init initrd_load(void)
 {
        if (mount_initrd) {
                create_dev("/dev/ram", Root_RAM0);
@@ -129,9 +129,9 @@ int __init initrd_load(void)
                if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
                        sys_unlink("/initrd.image");
                        handle_initrd();
-                       return 1;
+                       return true;
                }
        }
        sys_unlink("/initrd.image");
-       return 0;
+       return false;
 }
index c6ebefa..58c9e37 100644 (file)
@@ -164,10 +164,10 @@ static const char *panic_later, *panic_param;
 
 extern const struct obs_kernel_param __setup_start[], __setup_end[];
 
-static int __init obsolete_checksetup(char *line)
+static bool __init obsolete_checksetup(char *line)
 {
        const struct obs_kernel_param *p;
-       int had_early_param = 0;
+       bool had_early_param = false;
 
        p = __setup_start;
        do {
@@ -179,13 +179,13 @@ static int __init obsolete_checksetup(char *line)
                                 * Keep iterating, as we can have early
                                 * params and __setups of same names 8( */
                                if (line[n] == '\0' || line[n] == '=')
-                                       had_early_param = 1;
+                                       had_early_param = true;
                        } else if (!p->setup_func) {
                                pr_warn("Parameter %s is obsolete, ignored\n",
                                        p->str);
-                               return 1;
+                               return true;
                        } else if (p->setup_func(line + n))
-                               return 1;
+                               return true;
                }
                p++;
        } while (p < __setup_end);
index f4617cf..781c139 100644 (file)
@@ -795,7 +795,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
 
        ro = mnt_want_write(mnt);       /* we'll drop it in any case */
        error = 0;
-       mutex_lock(&d_inode(root)->i_mutex);
+       inode_lock(d_inode(root));
        path.dentry = lookup_one_len(name->name, root, strlen(name->name));
        if (IS_ERR(path.dentry)) {
                error = PTR_ERR(path.dentry);
@@ -841,7 +841,7 @@ out_putfd:
                put_unused_fd(fd);
                fd = error;
        }
-       mutex_unlock(&d_inode(root)->i_mutex);
+       inode_unlock(d_inode(root));
        if (!ro)
                mnt_drop_write(mnt);
 out_putname:
@@ -866,7 +866,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        err = mnt_want_write(mnt);
        if (err)
                goto out_name;
-       mutex_lock_nested(&d_inode(mnt->mnt_root)->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(d_inode(mnt->mnt_root), I_MUTEX_PARENT);
        dentry = lookup_one_len(name->name, mnt->mnt_root,
                                strlen(name->name));
        if (IS_ERR(dentry)) {
@@ -884,7 +884,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        dput(dentry);
 
 out_unlock:
-       mutex_unlock(&d_inode(mnt->mnt_root)->i_mutex);
+       inode_unlock(d_inode(mnt->mnt_root));
        if (inode)
                iput(inode);
        mnt_drop_write(mnt);
index b471e5a..cddd5b5 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1493,7 +1493,7 @@ out_rcu_wakeup:
        wake_up_sem_queue_do(&tasks);
 out_free:
        if (sem_io != fast_sem_io)
-               ipc_free(sem_io, sizeof(ushort)*nsems);
+               ipc_free(sem_io);
        return err;
 }
 
index 4178727..ed3027d 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -459,7 +459,7 @@ static const struct file_operations shm_file_operations_huge = {
        .fallocate      = shm_fallocate,
 };
 
-int is_file_shm_hugepages(struct file *file)
+bool is_file_shm_hugepages(struct file *file)
 {
        return file->f_op == &shm_file_operations_huge;
 }
index 0f401d9..798cad1 100644 (file)
@@ -414,17 +414,12 @@ void *ipc_alloc(int size)
 /**
  * ipc_free - free ipc space
  * @ptr: pointer returned by ipc_alloc
- * @size: size of block
  *
- * Free a block created with ipc_alloc(). The caller must know the size
- * used in the allocation call.
+ * Free a block created with ipc_alloc().
  */
-void ipc_free(void *ptr, int size)
+void ipc_free(void *ptr)
 {
-       if (size > PAGE_SIZE)
-               vfree(ptr);
-       else
-               kfree(ptr);
+       kvfree(ptr);
 }
 
 /**
index 3a8a5a0..51f7ca5 100644 (file)
@@ -118,7 +118,7 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg);
  * both function can sleep
  */
 void *ipc_alloc(int size);
-void ipc_free(void *ptr, int size);
+void ipc_free(void *ptr);
 
 /*
  * For allocation that need to be freed by RCU.
index 27c6046..f84f8d0 100644 (file)
@@ -95,7 +95,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa
        if (IS_ERR(dentry))
                return (void *)dentry; /* returning an error */
        inode = path.dentry->d_inode;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL);
        if (unlikely(!audit_mark)) {
index 656c7e9..9f194aa 100644 (file)
@@ -364,7 +364,7 @@ static int audit_get_nd(struct audit_watch *watch, struct path *parent)
        struct dentry *d = kern_path_locked(watch->path, parent);
        if (IS_ERR(d))
                return PTR_ERR(d);
-       mutex_unlock(&d_backing_inode(parent->dentry)->i_mutex);
+       inode_unlock(d_backing_inode(parent->dentry));
        if (d_is_positive(d)) {
                /* update watch filter fields */
                watch->dev = d_backing_inode(d)->i_sb->s_dev;
index 85ff5e2..5b9d396 100644 (file)
@@ -759,71 +759,33 @@ const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
 EXPORT_SYMBOL(cpu_all_bits);
 
 #ifdef CONFIG_INIT_ALL_POSSIBLE
-static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly
-       = CPU_BITS_ALL;
+struct cpumask __cpu_possible_mask __read_mostly
+       = {CPU_BITS_ALL};
 #else
-static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
+struct cpumask __cpu_possible_mask __read_mostly;
 #endif
-const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits);
-EXPORT_SYMBOL(cpu_possible_mask);
+EXPORT_SYMBOL(__cpu_possible_mask);
 
-static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly;
-const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits);
-EXPORT_SYMBOL(cpu_online_mask);
+struct cpumask __cpu_online_mask __read_mostly;
+EXPORT_SYMBOL(__cpu_online_mask);
 
-static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly;
-const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits);
-EXPORT_SYMBOL(cpu_present_mask);
+struct cpumask __cpu_present_mask __read_mostly;
+EXPORT_SYMBOL(__cpu_present_mask);
 
-static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly;
-const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits);
-EXPORT_SYMBOL(cpu_active_mask);
-
-void set_cpu_possible(unsigned int cpu, bool possible)
-{
-       if (possible)
-               cpumask_set_cpu(cpu, to_cpumask(cpu_possible_bits));
-       else
-               cpumask_clear_cpu(cpu, to_cpumask(cpu_possible_bits));
-}
-
-void set_cpu_present(unsigned int cpu, bool present)
-{
-       if (present)
-               cpumask_set_cpu(cpu, to_cpumask(cpu_present_bits));
-       else
-               cpumask_clear_cpu(cpu, to_cpumask(cpu_present_bits));
-}
-
-void set_cpu_online(unsigned int cpu, bool online)
-{
-       if (online) {
-               cpumask_set_cpu(cpu, to_cpumask(cpu_online_bits));
-               cpumask_set_cpu(cpu, to_cpumask(cpu_active_bits));
-       } else {
-               cpumask_clear_cpu(cpu, to_cpumask(cpu_online_bits));
-       }
-}
-
-void set_cpu_active(unsigned int cpu, bool active)
-{
-       if (active)
-               cpumask_set_cpu(cpu, to_cpumask(cpu_active_bits));
-       else
-               cpumask_clear_cpu(cpu, to_cpumask(cpu_active_bits));
-}
+struct cpumask __cpu_active_mask __read_mostly;
+EXPORT_SYMBOL(__cpu_active_mask);
 
 void init_cpu_present(const struct cpumask *src)
 {
-       cpumask_copy(to_cpumask(cpu_present_bits), src);
+       cpumask_copy(&__cpu_present_mask, src);
 }
 
 void init_cpu_possible(const struct cpumask *src)
 {
-       cpumask_copy(to_cpumask(cpu_possible_bits), src);
+       cpumask_copy(&__cpu_possible_mask, src);
 }
 
 void init_cpu_online(const struct cpumask *src)
 {
-       cpumask_copy(to_cpumask(cpu_online_bits), src);
+       cpumask_copy(&__cpu_online_mask, src);
 }
index bf82441..06ae52e 100644 (file)
@@ -3376,7 +3376,7 @@ find_lively_task_by_vpid(pid_t vpid)
 
        /* Reuse ptrace permission checks for now. */
        err = -EACCES;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
                goto errout;
 
        return task;
@@ -4872,9 +4872,9 @@ static int perf_fasync(int fd, struct file *filp, int on)
        struct perf_event *event = filp->private_data;
        int retval;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        retval = fasync_helper(fd, filp, on, &event->fasync);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (retval < 0)
                return retval;
index 07110c6..10e0882 100644 (file)
@@ -59,8 +59,6 @@
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 
-static void exit_mm(struct task_struct *tsk);
-
 static void __unhash_process(struct task_struct *p, bool group_dead)
 {
        nr_threads--;
@@ -1120,8 +1118,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
 static int *task_stopped_code(struct task_struct *p, bool ptrace)
 {
        if (ptrace) {
-               if (task_is_stopped_or_traced(p) &&
-                   !(p->jobctl & JOBCTL_LISTENING))
+               if (task_is_traced(p) && !(p->jobctl & JOBCTL_LISTENING))
                        return &p->exit_code;
        } else {
                if (p->signal->flags & SIGNAL_STOP_STOPPED)
index c6f5145..0773f2b 100644 (file)
@@ -2884,7 +2884,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
        }
 
        ret = -EPERM;
-       if (!ptrace_may_access(p, PTRACE_MODE_READ))
+       if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
                goto err_unlock;
 
        head = p->robust_list;
index 55c8c93..4ae3232 100644 (file)
@@ -155,7 +155,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid,
        }
 
        ret = -EPERM;
-       if (!ptrace_may_access(p, PTRACE_MODE_READ))
+       if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
                goto err_unlock;
 
        head = p->compat_robust_list;
index 8cf95de..6e655f7 100644 (file)
@@ -1061,6 +1061,7 @@ void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
        __irq_set_handler(virq, handler, 0, handler_name);
        irq_set_handler_data(virq, handler_data);
 }
+EXPORT_SYMBOL(irq_domain_set_info);
 
 /**
  * irq_domain_reset_irq_data - Clear hwirq, chip and chip_data in @irq_data
index 15b249e..38e89ce 100644 (file)
@@ -109,9 +109,11 @@ static int msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
        if (irq_find_mapping(domain, hwirq) > 0)
                return -EEXIST;
 
-       ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
-       if (ret < 0)
-               return ret;
+       if (domain->parent) {
+               ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
+               if (ret < 0)
+                       return ret;
+       }
 
        for (i = 0; i < nr_irqs; i++) {
                ret = ops->msi_init(domain, info, virq + i, hwirq + i, arg);
index 0aa69ea..3a47fa9 100644 (file)
@@ -122,8 +122,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,
                        &task2->signal->cred_guard_mutex);
        if (ret)
                goto err;
-       if (!ptrace_may_access(task1, PTRACE_MODE_READ) ||
-           !ptrace_may_access(task2, PTRACE_MODE_READ)) {
+       if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) ||
+           !ptrace_may_access(task2, PTRACE_MODE_READ_REALCREDS)) {
                ret = -EPERM;
                goto err_unlock;
        }
index d873b64..ee70aef 100644 (file)
@@ -63,16 +63,16 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
        if (ret)
                goto out_free_image;
 
-       ret = sanity_check_segment_list(image);
-       if (ret)
-               goto out_free_image;
-
-        /* Enable the special crash kernel control page allocation policy. */
        if (kexec_on_panic) {
+               /* Enable special crash kernel control page alloc policy. */
                image->control_page = crashk_res.start;
                image->type = KEXEC_TYPE_CRASH;
        }
 
+       ret = sanity_check_segment_list(image);
+       if (ret)
+               goto out_free_image;
+
        /*
         * Find a location for the control code buffer, and add it
         * the vector of segments so that it's pages will also be
index c823f30..8dc6591 100644 (file)
@@ -310,12 +310,9 @@ static void kimage_free_pages(struct page *page)
 
 void kimage_free_page_list(struct list_head *list)
 {
-       struct list_head *pos, *next;
+       struct page *page, *next;
 
-       list_for_each_safe(pos, next, list) {
-               struct page *page;
-
-               page = list_entry(pos, struct page, lru);
+       list_for_each_entry_safe(page, next, list, lru) {
                list_del(&page->lru);
                kimage_free_pages(page);
        }
index b70ada0..007b791 100644 (file)
@@ -109,11 +109,13 @@ int __weak arch_kimage_file_post_load_cleanup(struct kimage *image)
        return -EINVAL;
 }
 
+#ifdef CONFIG_KEXEC_VERIFY_SIG
 int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf,
                                        unsigned long buf_len)
 {
        return -EKEYREJECTED;
 }
+#endif
 
 /* Apply relocations of type RELA */
 int __weak
index e4392a6..0a52315 100644 (file)
@@ -15,6 +15,27 @@ int kimage_is_destination_range(struct kimage *image,
 extern struct mutex kexec_mutex;
 
 #ifdef CONFIG_KEXEC_FILE
+struct kexec_sha_region {
+       unsigned long start;
+       unsigned long len;
+};
+
+/*
+ * Keeps track of buffer parameters as provided by caller for requesting
+ * memory placement of buffer.
+ */
+struct kexec_buf {
+       struct kimage *image;
+       char *buffer;
+       unsigned long bufsz;
+       unsigned long mem;
+       unsigned long memsz;
+       unsigned long buf_align;
+       unsigned long buf_min;
+       unsigned long buf_max;
+       bool top_down;          /* allocate from top of memory hole */
+};
+
 void kimage_file_post_load_cleanup(struct kimage *image);
 #else /* CONFIG_KEXEC_FILE */
 static inline void kimage_file_post_load_cleanup(struct kimage *image) { }
index e794391..c963ba5 100644 (file)
@@ -233,7 +233,11 @@ struct printk_log {
        u8 facility;            /* syslog facility */
        u8 flags:5;             /* internal record flags */
        u8 level:3;             /* syslog level */
-};
+}
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+__packed __aligned(4)
+#endif
+;
 
 /*
  * The logbuf_lock protects kmsg buffer, indices, counters.  This can be taken
@@ -274,11 +278,7 @@ static u32 clear_idx;
 #define LOG_FACILITY(v)                ((v) >> 3 & 0xff)
 
 /* record buffer */
-#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-#define LOG_ALIGN 4
-#else
 #define LOG_ALIGN __alignof__(struct printk_log)
-#endif
 #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
 static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
 static char *log_buf = __log_buf;
index b760bae..2341efe 100644 (file)
@@ -219,6 +219,14 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
 static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
        const struct cred *cred = current_cred(), *tcred;
+       int dumpable = 0;
+       kuid_t caller_uid;
+       kgid_t caller_gid;
+
+       if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) {
+               WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n");
+               return -EPERM;
+       }
 
        /* May we inspect the given task?
         * This check is used both for attaching with ptrace
@@ -228,18 +236,33 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
         * because setting up the necessary parent/child relationship
         * or halting the specified task is impossible.
         */
-       int dumpable = 0;
+
        /* Don't let security modules deny introspection */
        if (same_thread_group(task, current))
                return 0;
        rcu_read_lock();
+       if (mode & PTRACE_MODE_FSCREDS) {
+               caller_uid = cred->fsuid;
+               caller_gid = cred->fsgid;
+       } else {
+               /*
+                * Using the euid would make more sense here, but something
+                * in userland might rely on the old behavior, and this
+                * shouldn't be a security problem since
+                * PTRACE_MODE_REALCREDS implies that the caller explicitly
+                * used a syscall that requests access to another process
+                * (and not a filesystem syscall to procfs).
+                */
+               caller_uid = cred->uid;
+               caller_gid = cred->gid;
+       }
        tcred = __task_cred(task);
-       if (uid_eq(cred->uid, tcred->euid) &&
-           uid_eq(cred->uid, tcred->suid) &&
-           uid_eq(cred->uid, tcred->uid)  &&
-           gid_eq(cred->gid, tcred->egid) &&
-           gid_eq(cred->gid, tcred->sgid) &&
-           gid_eq(cred->gid, tcred->gid))
+       if (uid_eq(caller_uid, tcred->euid) &&
+           uid_eq(caller_uid, tcred->suid) &&
+           uid_eq(caller_uid, tcred->uid)  &&
+           gid_eq(caller_gid, tcred->egid) &&
+           gid_eq(caller_gid, tcred->sgid) &&
+           gid_eq(caller_gid, tcred->gid))
                goto ok;
        if (ptrace_has_cap(tcred->user_ns, mode))
                goto ok;
@@ -306,7 +329,7 @@ static int ptrace_attach(struct task_struct *task, long request,
                goto out;
 
        task_lock(task);
-       retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
+       retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
        task_unlock(task);
        if (retval)
                goto unlock_creds;
@@ -364,8 +387,14 @@ unlock_creds:
        mutex_unlock(&task->signal->cred_guard_mutex);
 out:
        if (!retval) {
-               wait_on_bit(&task->jobctl, JOBCTL_TRAPPING_BIT,
-                           TASK_UNINTERRUPTIBLE);
+               /*
+                * We do not bother to change retval or clear JOBCTL_TRAPPING
+                * if wait_on_bit() was interrupted by SIGKILL. The tracer will
+                * not return to user-mode, it will exit and clear this bit in
+                * __ptrace_unlink() if it wasn't already cleared by the tracee;
+                * and until then nobody can ptrace this task.
+                */
+               wait_on_bit(&task->jobctl, JOBCTL_TRAPPING_BIT, TASK_KILLABLE);
                proc_ptrace_connector(task, PTRACE_ATTACH);
        }
 
index 0b4570c..074994b 100644 (file)
@@ -1133,7 +1133,7 @@ static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
        if (!desc->count)
                return 0;
 
-       mutex_lock(&file_inode(filp)->i_mutex);
+       inode_lock(file_inode(filp));
        do {
                if (!relay_file_read_avail(buf, *ppos))
                        break;
@@ -1153,7 +1153,7 @@ static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
                        *ppos = relay_file_read_end_pos(buf, read_start, ret);
                }
        } while (desc->count && ret);
-       mutex_unlock(&file_inode(filp)->i_mutex);
+       inode_unlock(file_inode(filp));
 
        return desc->written;
 }
index 44253ad..63d3a24 100644 (file)
@@ -222,9 +222,9 @@ sched_feat_write(struct file *filp, const char __user *ubuf,
 
        /* Ensure the static_key remains in a consistent state */
        inode = file_inode(filp);
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        i = sched_feat_set(cmp);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if (i == __SCHED_FEAT_NR)
                return -EINVAL;
 
index 2489140..de0e786 100644 (file)
@@ -97,12 +97,6 @@ void default_idle_call(void)
 static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                      int next_state)
 {
-       /* Fall back to the default arch idle method on errors. */
-       if (next_state < 0) {
-               default_idle_call();
-               return next_state;
-       }
-
        /*
         * The idle task must be scheduled, it is pointless to go to idle, just
         * update no idle residency and return.
index 6af9212..78947de 100644 (file)
@@ -1853,11 +1853,13 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
                user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
        }
 
-       if (prctl_map.exe_fd != (u32)-1)
+       if (prctl_map.exe_fd != (u32)-1) {
                error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
-       down_read(&mm->mmap_sem);
-       if (error)
-               goto out;
+               if (error)
+                       return error;
+       }
+
+       down_write(&mm->mmap_sem);
 
        /*
         * We don't validate if these members are pointing to
@@ -1894,10 +1896,8 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
        if (prctl_map.auxv_size)
                memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
 
-       error = 0;
-out:
-       up_read(&mm->mmap_sem);
-       return error;
+       up_write(&mm->mmap_sem);
+       return 0;
 }
 #endif /* CONFIG_CHECKPOINT_RESTORE */
 
@@ -1963,7 +1963,7 @@ static int prctl_set_mm(int opt, unsigned long addr,
 
        error = -EINVAL;
 
-       down_read(&mm->mmap_sem);
+       down_write(&mm->mmap_sem);
        vma = find_vma(mm, addr);
 
        prctl_map.start_code    = mm->start_code;
@@ -2056,7 +2056,7 @@ static int prctl_set_mm(int opt, unsigned long addr,
 
        error = 0;
 out:
-       up_read(&mm->mmap_sem);
+       up_write(&mm->mmap_sem);
        return error;
 }
 
index c810f8a..97715fd 100644 (file)
@@ -173,7 +173,7 @@ extern int no_unaligned_warning;
 #define SYSCTL_WRITES_WARN      0
 #define SYSCTL_WRITES_STRICT    1
 
-static int sysctl_writes_strict = SYSCTL_WRITES_WARN;
+static int sysctl_writes_strict = SYSCTL_WRITES_STRICT;
 
 static int proc_do_cad_pid(struct ctl_table *table, int write,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
@@ -1757,6 +1757,20 @@ static struct ctl_table fs_table[] = {
                .proc_handler   = &pipe_proc_fn,
                .extra1         = &pipe_min_size,
        },
+       {
+               .procname       = "pipe-user-pages-hard",
+               .data           = &pipe_user_pages_hard,
+               .maxlen         = sizeof(pipe_user_pages_hard),
+               .mode           = 0644,
+               .proc_handler   = proc_doulongvec_minmax,
+       },
+       {
+               .procname       = "pipe-user-pages-soft",
+               .data           = &pipe_user_pages_soft,
+               .maxlen         = sizeof(pipe_user_pages_soft),
+               .mode           = 0644,
+               .proc_handler   = proc_doulongvec_minmax,
+       },
        { }
 };
 
index 9cc20af..9d7a053 100644 (file)
@@ -387,7 +387,7 @@ void __init tick_nohz_init(void)
 /*
  * NO HZ enabled ?
  */
-static int tick_nohz_enabled __read_mostly  = 1;
+int tick_nohz_enabled __read_mostly = 1;
 unsigned long tick_nohz_active  __read_mostly;
 /*
  * Enable / Disable tickless mode
index 5a0c1c8..133ebc0 100644 (file)
@@ -210,9 +210,11 @@ config RANDOM32_SELFTEST
 # compression support is select'ed if needed
 #
 config 842_COMPRESS
+       select CRC32
        tristate
 
 config 842_DECOMPRESS
+       select CRC32
        tristate
 
 config ZLIB_INFLATE
@@ -475,6 +477,11 @@ config DDR
          information. This data is useful for drivers handling
          DDR SDRAM controllers.
 
+config IRQ_POLL
+       bool "IRQ polling library"
+       help
+         Helper library to poll interrupt mitigation using polling.
+
 config MPILIB
        tristate
        select CLZ_TAB
index f75a33f..ecb9e75 100644 (file)
@@ -1893,6 +1893,8 @@ source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
 
+source "lib/Kconfig.ubsan"
+
 config ARCH_HAS_DEVMEM_IS_ALLOWED
        bool
 
@@ -1919,7 +1921,6 @@ config STRICT_DEVMEM
 config IO_STRICT_DEVMEM
        bool "Filter I/O access to /dev/mem"
        depends on STRICT_DEVMEM
-       default STRICT_DEVMEM
        ---help---
          If this option is disabled, you allow userspace (root) access to all
          io-memory regardless of whether a driver is actively using that
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
new file mode 100644 (file)
index 0000000..49518fb
--- /dev/null
@@ -0,0 +1,29 @@
+config ARCH_HAS_UBSAN_SANITIZE_ALL
+       bool
+
+config UBSAN
+       bool "Undefined behaviour sanity checker"
+       help
+         This option enables undefined behaviour sanity checker
+         Compile-time instrumentation is used to detect various undefined
+         behaviours in runtime. Various types of checks may be enabled
+         via boot parameter ubsan_handle (see: Documentation/ubsan.txt).
+
+config UBSAN_SANITIZE_ALL
+       bool "Enable instrumentation for the entire kernel"
+       depends on UBSAN
+       depends on ARCH_HAS_UBSAN_SANITIZE_ALL
+       default y
+       help
+         This option activates instrumentation for the entire kernel.
+         If you don't enable this option, you have to explicitly specify
+         UBSAN_SANITIZE := y for the files/directories you want to check for UB.
+
+config UBSAN_ALIGNMENT
+       bool "Enable checking of pointers alignment"
+       depends on UBSAN
+       default y if !HAVE_EFFICIENT_UNALIGNED_ACCESS
+       help
+         This option enables detection of unaligned memory accesses.
+         Enabling this option on architectures that support unalligned
+         accesses may produce a lot of false positives.
index 180dd4d..a7c26a4 100644 (file)
@@ -31,7 +31,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
 obj-y += hexdump.o
-obj-$(CONFIG_TEST_HEXDUMP) += test-hexdump.o
+obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
 obj-y += kstrtox.o
 obj-$(CONFIG_TEST_BPF) += test_bpf.o
 obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
@@ -154,7 +154,7 @@ obj-$(CONFIG_GLOB) += glob.o
 obj-$(CONFIG_MPILIB) += mpi/
 obj-$(CONFIG_SIGNATURE) += digsig.o
 
-obj-$(CONFIG_CLZ_TAB) += clz_tab.o
+lib-$(CONFIG_CLZ_TAB) += clz_tab.o
 
 obj-$(CONFIG_DDR) += jedec_ddr_data.o
 
@@ -165,6 +165,7 @@ obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o
 
 obj-$(CONFIG_SG_SPLIT) += sg_split.o
 obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
+obj-$(CONFIG_IRQ_POLL) += irq_poll.o
 
 libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
               fdt_empty_tree.o
@@ -209,3 +210,6 @@ quiet_cmd_build_OID_registry = GEN     $@
 clean-files    += oid_registry_data.c
 
 obj-$(CONFIG_UCS2_STRING) += ucs2_string.o
+obj-$(CONFIG_UBSAN) += ubsan.o
+
+UBSAN_SANITIZE_ubsan.o := n
index 62a698a..7f34525 100644 (file)
@@ -13,7 +13,8 @@
  *
  * Code generated for this function might be very inefficient
  * for some CPUs. __div64_32() can be overridden by linking arch-specific
- * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S.
+ * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S
+ * or by defining a preprocessor macro in arch/include/asm/div64.h.
  */
 
 #include <linux/export.h>
@@ -23,6 +24,7 @@
 /* Not needed on 64bit architectures */
 #if BITS_PER_LONG == 32
 
+#ifndef __div64_32
 uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
 {
        uint64_t rem = *n;
@@ -55,8 +57,8 @@ uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
        *n = res;
        return rem;
 }
-
 EXPORT_SYMBOL(__div64_32);
+#endif
 
 #ifndef div_s64_rem
 s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
index 4527e75..b8f1d6c 100644 (file)
@@ -41,6 +41,27 @@ void __attribute__((weak)) __iowrite32_copy(void __iomem *to,
 }
 EXPORT_SYMBOL_GPL(__iowrite32_copy);
 
+/**
+ * __ioread32_copy - copy data from MMIO space, in 32-bit units
+ * @to: destination (must be 32-bit aligned)
+ * @from: source, in MMIO space (must be 32-bit aligned)
+ * @count: number of 32-bit quantities to copy
+ *
+ * Copy data from MMIO space to kernel space, in units of 32 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void __ioread32_copy(void *to, const void __iomem *from, size_t count)
+{
+       u32 *dst = to;
+       const u32 __iomem *src = from;
+       const u32 __iomem *end = src + count;
+
+       while (src < end)
+               *dst++ = __raw_readl(src++);
+}
+EXPORT_SYMBOL_GPL(__ioread32_copy);
+
 /**
  * __iowrite64_copy - copy data to MMIO space, in 64-bit or 32-bit units
  * @to: destination, in MMIO space (must be 64-bit aligned)
diff --git a/lib/irq_poll.c b/lib/irq_poll.c
new file mode 100644 (file)
index 0000000..836f7db
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Functions related to interrupt-poll handling in the block layer. This
+ * is similar to NAPI for network devices.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/bio.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/irq_poll.h>
+#include <linux/delay.h>
+
+static unsigned int irq_poll_budget __read_mostly = 256;
+
+static DEFINE_PER_CPU(struct list_head, blk_cpu_iopoll);
+
+/**
+ * irq_poll_sched - Schedule a run of the iopoll handler
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     Add this irq_poll structure to the pending poll list and trigger the
+ *     raise of the blk iopoll softirq.
+ **/
+void irq_poll_sched(struct irq_poll *iop)
+{
+       unsigned long flags;
+
+       if (test_bit(IRQ_POLL_F_DISABLE, &iop->state))
+               return;
+       if (test_and_set_bit(IRQ_POLL_F_SCHED, &iop->state))
+               return;
+
+       local_irq_save(flags);
+       list_add_tail(&iop->list, this_cpu_ptr(&blk_cpu_iopoll));
+       __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(irq_poll_sched);
+
+/**
+ * __irq_poll_complete - Mark this @iop as un-polled again
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     See irq_poll_complete(). This function must be called with interrupts
+ *     disabled.
+ **/
+static void __irq_poll_complete(struct irq_poll *iop)
+{
+       list_del(&iop->list);
+       smp_mb__before_atomic();
+       clear_bit_unlock(IRQ_POLL_F_SCHED, &iop->state);
+}
+
+/**
+ * irq_poll_complete - Mark this @iop as un-polled again
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     If a driver consumes less than the assigned budget in its run of the
+ *     iopoll handler, it'll end the polled mode by calling this function. The
+ *     iopoll handler will not be invoked again before irq_poll_sched()
+ *     is called.
+ **/
+void irq_poll_complete(struct irq_poll *iop)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __irq_poll_complete(iop);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(irq_poll_complete);
+
+static void irq_poll_softirq(struct softirq_action *h)
+{
+       struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll);
+       int rearm = 0, budget = irq_poll_budget;
+       unsigned long start_time = jiffies;
+
+       local_irq_disable();
+
+       while (!list_empty(list)) {
+               struct irq_poll *iop;
+               int work, weight;
+
+               /*
+                * If softirq window is exhausted then punt.
+                */
+               if (budget <= 0 || time_after(jiffies, start_time)) {
+                       rearm = 1;
+                       break;
+               }
+
+               local_irq_enable();
+
+               /* Even though interrupts have been re-enabled, this
+                * access is safe because interrupts can only add new
+                * entries to the tail of this list, and only ->poll()
+                * calls can remove this head entry from the list.
+                */
+               iop = list_entry(list->next, struct irq_poll, list);
+
+               weight = iop->weight;
+               work = 0;
+               if (test_bit(IRQ_POLL_F_SCHED, &iop->state))
+                       work = iop->poll(iop, weight);
+
+               budget -= work;
+
+               local_irq_disable();
+
+               /*
+                * Drivers must not modify the iopoll state, if they
+                * consume their assigned weight (or more, some drivers can't
+                * easily just stop processing, they have to complete an
+                * entire mask of commands).In such cases this code
+                * still "owns" the iopoll instance and therefore can
+                * move the instance around on the list at-will.
+                */
+               if (work >= weight) {
+                       if (test_bit(IRQ_POLL_F_DISABLE, &iop->state))
+                               __irq_poll_complete(iop);
+                       else
+                               list_move_tail(&iop->list, list);
+               }
+       }
+
+       if (rearm)
+               __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ);
+
+       local_irq_enable();
+}
+
+/**
+ * irq_poll_disable - Disable iopoll on this @iop
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     Disable io polling and wait for any pending callbacks to have completed.
+ **/
+void irq_poll_disable(struct irq_poll *iop)
+{
+       set_bit(IRQ_POLL_F_DISABLE, &iop->state);
+       while (test_and_set_bit(IRQ_POLL_F_SCHED, &iop->state))
+               msleep(1);
+       clear_bit(IRQ_POLL_F_DISABLE, &iop->state);
+}
+EXPORT_SYMBOL(irq_poll_disable);
+
+/**
+ * irq_poll_enable - Enable iopoll on this @iop
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     Enable iopoll on this @iop. Note that the handler run will not be
+ *     scheduled, it will only mark it as active.
+ **/
+void irq_poll_enable(struct irq_poll *iop)
+{
+       BUG_ON(!test_bit(IRQ_POLL_F_SCHED, &iop->state));
+       smp_mb__before_atomic();
+       clear_bit_unlock(IRQ_POLL_F_SCHED, &iop->state);
+}
+EXPORT_SYMBOL(irq_poll_enable);
+
+/**
+ * irq_poll_init - Initialize this @iop
+ * @iop:      The parent iopoll structure
+ * @weight:   The default weight (or command completion budget)
+ * @poll_fn:  The handler to invoke
+ *
+ * Description:
+ *     Initialize and enable this irq_poll structure.
+ **/
+void irq_poll_init(struct irq_poll *iop, int weight, irq_poll_fn *poll_fn)
+{
+       memset(iop, 0, sizeof(*iop));
+       INIT_LIST_HEAD(&iop->list);
+       iop->weight = weight;
+       iop->poll = poll_fn;
+}
+EXPORT_SYMBOL(irq_poll_init);
+
+static int irq_poll_cpu_notify(struct notifier_block *self,
+                                unsigned long action, void *hcpu)
+{
+       /*
+        * If a CPU goes away, splice its entries to the current CPU
+        * and trigger a run of the softirq
+        */
+       if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
+               int cpu = (unsigned long) hcpu;
+
+               local_irq_disable();
+               list_splice_init(&per_cpu(blk_cpu_iopoll, cpu),
+                                this_cpu_ptr(&blk_cpu_iopoll));
+               __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ);
+               local_irq_enable();
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block irq_poll_cpu_notifier = {
+       .notifier_call  = irq_poll_cpu_notify,
+};
+
+static __init int irq_poll_setup(void)
+{
+       int i;
+
+       for_each_possible_cpu(i)
+               INIT_LIST_HEAD(&per_cpu(blk_cpu_iopoll, i));
+
+       open_softirq(IRQ_POLL_SOFTIRQ, irq_poll_softirq);
+       register_hotcpu_notifier(&irq_poll_cpu_notifier);
+       return 0;
+}
+subsys_initcall(irq_poll_setup);
index 6a08ce7..74a54b7 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/crc32c.h>
 
 static struct crypto_shash *tfm;
 
@@ -74,3 +75,4 @@ module_exit(libcrc32c_mod_fini);
 MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
 MODULE_LICENSE("GPL");
+MODULE_SOFTDEP("pre: crc32c");
index 028f5d9..28ba40b 100644 (file)
@@ -238,7 +238,7 @@ void lc_reset(struct lru_cache *lc)
  * @seq: the seq_file to print into
  * @lc: the lru cache to print statistics of
  */
-size_t lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc)
+void lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc)
 {
        /* NOTE:
         * total calls to lc_get are
@@ -250,8 +250,6 @@ size_t lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc)
        seq_printf(seq, "\t%s: used:%u/%u hits:%lu misses:%lu starving:%lu locked:%lu changed:%lu\n",
                   lc->name, lc->used, lc->nr_elements,
                   lc->hits, lc->misses, lc->starving, lc->locked, lc->changed);
-
-       return 0;
 }
 
 static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr)
index 40e03ea..2c5de86 100644 (file)
@@ -49,7 +49,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
                if (rs->missed)
                        printk(KERN_WARNING "%s: %d callbacks suppressed\n",
                                func, rs->missed);
-               rs->begin   = 0;
+               rs->begin   = jiffies;
                rs->printed = 0;
                rs->missed  = 0;
        }
index 5939f63..5c88204 100644 (file)
@@ -43,50 +43,73 @@ void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
                [STRING_UNITS_10] = 1000,
                [STRING_UNITS_2] = 1024,
        };
-       int i, j;
-       u32 remainder = 0, sf_cap, exp;
+       static const unsigned int rounding[] = { 500, 50, 5 };
+       int i = 0, j;
+       u32 remainder = 0, sf_cap;
        char tmp[8];
        const char *unit;
 
        tmp[0] = '\0';
-       i = 0;
-       if (!size)
+
+       if (blk_size == 0)
+               size = 0;
+       if (size == 0)
                goto out;
 
-       while (blk_size >= divisor[units]) {
-               remainder = do_div(blk_size, divisor[units]);
+       /* This is Napier's algorithm.  Reduce the original block size to
+        *
+        * coefficient * divisor[units]^i
+        *
+        * we do the reduction so both coefficients are just under 32 bits so
+        * that multiplying them together won't overflow 64 bits and we keep
+        * as much precision as possible in the numbers.
+        *
+        * Note: it's safe to throw away the remainders here because all the
+        * precision is in the coefficients.
+        */
+       while (blk_size >> 32) {
+               do_div(blk_size, divisor[units]);
                i++;
        }
 
-       exp = divisor[units] / (u32)blk_size;
-       /*
-        * size must be strictly greater than exp here to ensure that remainder
-        * is greater than divisor[units] coming out of the if below.
-        */
-       if (size > exp) {
-               remainder = do_div(size, divisor[units]);
-               remainder *= blk_size;
+       while (size >> 32) {
+               do_div(size, divisor[units]);
                i++;
-       } else {
-               remainder *= size;
        }
 
+       /* now perform the actual multiplication keeping i as the sum of the
+        * two logarithms */
        size *= blk_size;
-       size += remainder / divisor[units];
-       remainder %= divisor[units];
 
+       /* and logarithmically reduce it until it's just under the divisor */
        while (size >= divisor[units]) {
                remainder = do_div(size, divisor[units]);
                i++;
        }
 
+       /* work out in j how many digits of precision we need from the
+        * remainder */
        sf_cap = size;
        for (j = 0; sf_cap*10 < 1000; j++)
                sf_cap *= 10;
 
-       if (j) {
+       if (units == STRING_UNITS_2) {
+               /* express the remainder as a decimal.  It's currently the
+                * numerator of a fraction whose denominator is
+                * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
                remainder *= 1000;
-               remainder /= divisor[units];
+               remainder >>= 10;
+       }
+
+       /* add a 5 to the digit below what will be printed to ensure
+        * an arithmetical round up and carry it through to size */
+       remainder += rounding[j];
+       if (remainder >= 1000) {
+               remainder -= 1000;
+               size += 1;
+       }
+
+       if (j) {
                snprintf(tmp, sizeof(tmp), ".%03u", remainder);
                tmp[j+1] = '\0';
        }
index e0af6ff..3384032 100644 (file)
@@ -39,7 +39,7 @@ static inline long do_strncpy_from_user(char *dst, const char __user *src, long
                unsigned long c, data;
 
                /* Fall back to byte-at-a-time if we get a page fault */
-               if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
+               if (unlikely(unsafe_get_user(c,(unsigned long __user *)(src+res))))
                        break;
                *(unsigned long *)(dst+res) = c;
                if (has_zero(c, &data, &constants)) {
@@ -55,7 +55,7 @@ byte_at_a_time:
        while (max) {
                char c;
 
-               if (unlikely(__get_user(c,src+res)))
+               if (unlikely(unsafe_get_user(c,src+res)))
                        return -EFAULT;
                dst[res] = c;
                if (!c)
@@ -107,7 +107,12 @@ long strncpy_from_user(char *dst, const char __user *src, long count)
        src_addr = (unsigned long)src;
        if (likely(src_addr < max_addr)) {
                unsigned long max = max_addr - src_addr;
-               return do_strncpy_from_user(dst, src, count, max);
+               long retval;
+
+               user_access_begin();
+               retval = do_strncpy_from_user(dst, src, count, max);
+               user_access_end();
+               return retval;
        }
        return -EFAULT;
 }
index 3a5f2b3..2625943 100644 (file)
@@ -45,7 +45,7 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count,
        src -= align;
        max += align;
 
-       if (unlikely(__get_user(c,(unsigned long __user *)src)))
+       if (unlikely(unsafe_get_user(c,(unsigned long __user *)src)))
                return 0;
        c |= aligned_byte_mask(align);
 
@@ -61,7 +61,7 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count,
                if (unlikely(max <= sizeof(unsigned long)))
                        break;
                max -= sizeof(unsigned long);
-               if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
+               if (unlikely(unsafe_get_user(c,(unsigned long __user *)(src+res))))
                        return 0;
        }
        res -= align;
@@ -112,7 +112,12 @@ long strnlen_user(const char __user *str, long count)
        src_addr = (unsigned long)str;
        if (likely(src_addr < max_addr)) {
                unsigned long max = max_addr - src_addr;
-               return do_strnlen_user(str, count, max);
+               long retval;
+
+               user_access_begin();
+               retval = do_strnlen_user(str, count, max);
+               user_access_end();
+               return retval;
        }
        return 0;
 }
@@ -141,7 +146,12 @@ long strlen_user(const char __user *str)
        src_addr = (unsigned long)str;
        if (likely(src_addr < max_addr)) {
                unsigned long max = max_addr - src_addr;
-               return do_strnlen_user(str, ~0ul, max);
+               long retval;
+
+               user_access_begin();
+               retval = do_strnlen_user(str, ~0ul, max);
+               user_access_end();
+               return retval;
        }
        return 0;
 }
diff --git a/lib/test-hexdump.c b/lib/test-hexdump.c
deleted file mode 100644 (file)
index 5241df3..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Test cases for lib/hexdump.c module.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/random.h>
-#include <linux/string.h>
-
-static const unsigned char data_b[] = {
-       '\xbe', '\x32', '\xdb', '\x7b', '\x0a', '\x18', '\x93', '\xb2', /* 00 - 07 */
-       '\x70', '\xba', '\xc4', '\x24', '\x7d', '\x83', '\x34', '\x9b', /* 08 - 0f */
-       '\xa6', '\x9c', '\x31', '\xad', '\x9c', '\x0f', '\xac', '\xe9', /* 10 - 17 */
-       '\x4c', '\xd1', '\x19', '\x99', '\x43', '\xb1', '\xaf', '\x0c', /* 18 - 1f */
-};
-
-static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
-
-static const char * const test_data_1_le[] __initconst = {
-       "be", "32", "db", "7b", "0a", "18", "93", "b2",
-       "70", "ba", "c4", "24", "7d", "83", "34", "9b",
-       "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
-       "4c", "d1", "19", "99", "43", "b1", "af", "0c",
-};
-
-static const char * const test_data_2_le[] __initconst = {
-       "32be", "7bdb", "180a", "b293",
-       "ba70", "24c4", "837d", "9b34",
-       "9ca6", "ad31", "0f9c", "e9ac",
-       "d14c", "9919", "b143", "0caf",
-};
-
-static const char * const test_data_4_le[] __initconst = {
-       "7bdb32be", "b293180a", "24c4ba70", "9b34837d",
-       "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
-};
-
-static const char * const test_data_8_le[] __initconst = {
-       "b293180a7bdb32be", "9b34837d24c4ba70",
-       "e9ac0f9cad319ca6", "0cafb1439919d14c",
-};
-
-static void __init test_hexdump(size_t len, int rowsize, int groupsize,
-                               bool ascii)
-{
-       char test[32 * 3 + 2 + 32 + 1];
-       char real[32 * 3 + 2 + 32 + 1];
-       char *p;
-       const char * const *result;
-       size_t l = len;
-       int gs = groupsize, rs = rowsize;
-       unsigned int i;
-
-       hex_dump_to_buffer(data_b, l, rs, gs, real, sizeof(real), ascii);
-
-       if (rs != 16 && rs != 32)
-               rs = 16;
-
-       if (l > rs)
-               l = rs;
-
-       if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
-               gs = 1;
-
-       if (gs == 8)
-               result = test_data_8_le;
-       else if (gs == 4)
-               result = test_data_4_le;
-       else if (gs == 2)
-               result = test_data_2_le;
-       else
-               result = test_data_1_le;
-
-       memset(test, ' ', sizeof(test));
-
-       /* hex dump */
-       p = test;
-       for (i = 0; i < l / gs; i++) {
-               const char *q = *result++;
-               size_t amount = strlen(q);
-
-               strncpy(p, q, amount);
-               p += amount + 1;
-       }
-       if (i)
-               p--;
-
-       /* ASCII part */
-       if (ascii) {
-               p = test + rs * 2 + rs / gs + 1;
-               strncpy(p, data_a, l);
-               p += l;
-       }
-
-       *p = '\0';
-
-       if (strcmp(test, real)) {
-               pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
-               pr_err("Result: '%s'\n", real);
-               pr_err("Expect: '%s'\n", test);
-       }
-}
-
-static void __init test_hexdump_set(int rowsize, bool ascii)
-{
-       size_t d = min_t(size_t, sizeof(data_b), rowsize);
-       size_t len = get_random_int() % d + 1;
-
-       test_hexdump(len, rowsize, 4, ascii);
-       test_hexdump(len, rowsize, 2, ascii);
-       test_hexdump(len, rowsize, 8, ascii);
-       test_hexdump(len, rowsize, 1, ascii);
-}
-
-static void __init test_hexdump_overflow(bool ascii)
-{
-       char buf[56];
-       const char *t = test_data_1_le[0];
-       size_t l = get_random_int() % sizeof(buf);
-       bool a;
-       int e, r;
-
-       memset(buf, ' ', sizeof(buf));
-
-       r = hex_dump_to_buffer(data_b, 1, 16, 1, buf, l, ascii);
-
-       if (ascii)
-               e = 50;
-       else
-               e = 2;
-       buf[e + 2] = '\0';
-
-       if (!l) {
-               a = r == e && buf[0] == ' ';
-       } else if (l < 3) {
-               a = r == e && buf[0] == '\0';
-       } else if (l < 4) {
-               a = r == e && !strcmp(buf, t);
-       } else if (ascii) {
-               if (l < 51)
-                       a = r == e && buf[l - 1] == '\0' && buf[l - 2] == ' ';
-               else
-                       a = r == e && buf[50] == '\0' && buf[49] == '.';
-       } else {
-               a = r == e && buf[e] == '\0';
-       }
-
-       if (!a) {
-               pr_err("Len: %zu rc: %u strlen: %zu\n", l, r, strlen(buf));
-               pr_err("Result: '%s'\n", buf);
-       }
-}
-
-static int __init test_hexdump_init(void)
-{
-       unsigned int i;
-       int rowsize;
-
-       pr_info("Running tests...\n");
-
-       rowsize = (get_random_int() % 2 + 1) * 16;
-       for (i = 0; i < 16; i++)
-               test_hexdump_set(rowsize, false);
-
-       rowsize = (get_random_int() % 2 + 1) * 16;
-       for (i = 0; i < 16; i++)
-               test_hexdump_set(rowsize, true);
-
-       for (i = 0; i < 16; i++)
-               test_hexdump_overflow(false);
-
-       for (i = 0; i < 16; i++)
-               test_hexdump_overflow(true);
-
-       return -EINVAL;
-}
-module_init(test_hexdump_init);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/test_hexdump.c b/lib/test_hexdump.c
new file mode 100644 (file)
index 0000000..3f415d8
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Test cases for lib/hexdump.c module.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/string.h>
+
+static const unsigned char data_b[] = {
+       '\xbe', '\x32', '\xdb', '\x7b', '\x0a', '\x18', '\x93', '\xb2', /* 00 - 07 */
+       '\x70', '\xba', '\xc4', '\x24', '\x7d', '\x83', '\x34', '\x9b', /* 08 - 0f */
+       '\xa6', '\x9c', '\x31', '\xad', '\x9c', '\x0f', '\xac', '\xe9', /* 10 - 17 */
+       '\x4c', '\xd1', '\x19', '\x99', '\x43', '\xb1', '\xaf', '\x0c', /* 18 - 1f */
+};
+
+static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
+
+static const char * const test_data_1_le[] __initconst = {
+       "be", "32", "db", "7b", "0a", "18", "93", "b2",
+       "70", "ba", "c4", "24", "7d", "83", "34", "9b",
+       "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
+       "4c", "d1", "19", "99", "43", "b1", "af", "0c",
+};
+
+static const char * const test_data_2_le[] __initconst = {
+       "32be", "7bdb", "180a", "b293",
+       "ba70", "24c4", "837d", "9b34",
+       "9ca6", "ad31", "0f9c", "e9ac",
+       "d14c", "9919", "b143", "0caf",
+};
+
+static const char * const test_data_4_le[] __initconst = {
+       "7bdb32be", "b293180a", "24c4ba70", "9b34837d",
+       "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
+};
+
+static const char * const test_data_8_le[] __initconst = {
+       "b293180a7bdb32be", "9b34837d24c4ba70",
+       "e9ac0f9cad319ca6", "0cafb1439919d14c",
+};
+
+#define FILL_CHAR      '#'
+
+static unsigned total_tests __initdata;
+static unsigned failed_tests __initdata;
+
+static void __init test_hexdump_prepare_test(size_t len, int rowsize,
+                                            int groupsize, char *test,
+                                            size_t testlen, bool ascii)
+{
+       char *p;
+       const char * const *result;
+       size_t l = len;
+       int gs = groupsize, rs = rowsize;
+       unsigned int i;
+
+       if (rs != 16 && rs != 32)
+               rs = 16;
+
+       if (l > rs)
+               l = rs;
+
+       if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
+               gs = 1;
+
+       if (gs == 8)
+               result = test_data_8_le;
+       else if (gs == 4)
+               result = test_data_4_le;
+       else if (gs == 2)
+               result = test_data_2_le;
+       else
+               result = test_data_1_le;
+
+       /* hex dump */
+       p = test;
+       for (i = 0; i < l / gs; i++) {
+               const char *q = *result++;
+               size_t amount = strlen(q);
+
+               strncpy(p, q, amount);
+               p += amount;
+
+               *p++ = ' ';
+       }
+       if (i)
+               p--;
+
+       /* ASCII part */
+       if (ascii) {
+               do {
+                       *p++ = ' ';
+               } while (p < test + rs * 2 + rs / gs + 1);
+
+               strncpy(p, data_a, l);
+               p += l;
+       }
+
+       *p = '\0';
+}
+
+#define TEST_HEXDUMP_BUF_SIZE          (32 * 3 + 2 + 32 + 1)
+
+static void __init test_hexdump(size_t len, int rowsize, int groupsize,
+                               bool ascii)
+{
+       char test[TEST_HEXDUMP_BUF_SIZE];
+       char real[TEST_HEXDUMP_BUF_SIZE];
+
+       total_tests++;
+
+       memset(real, FILL_CHAR, sizeof(real));
+       hex_dump_to_buffer(data_b, len, rowsize, groupsize, real, sizeof(real),
+                          ascii);
+
+       memset(test, FILL_CHAR, sizeof(test));
+       test_hexdump_prepare_test(len, rowsize, groupsize, test, sizeof(test),
+                                 ascii);
+
+       if (memcmp(test, real, TEST_HEXDUMP_BUF_SIZE)) {
+               pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
+               pr_err("Result: '%s'\n", real);
+               pr_err("Expect: '%s'\n", test);
+               failed_tests++;
+       }
+}
+
+static void __init test_hexdump_set(int rowsize, bool ascii)
+{
+       size_t d = min_t(size_t, sizeof(data_b), rowsize);
+       size_t len = get_random_int() % d + 1;
+
+       test_hexdump(len, rowsize, 4, ascii);
+       test_hexdump(len, rowsize, 2, ascii);
+       test_hexdump(len, rowsize, 8, ascii);
+       test_hexdump(len, rowsize, 1, ascii);
+}
+
+static void __init test_hexdump_overflow(size_t buflen, size_t len,
+                                        int rowsize, int groupsize,
+                                        bool ascii)
+{
+       char test[TEST_HEXDUMP_BUF_SIZE];
+       char buf[TEST_HEXDUMP_BUF_SIZE];
+       int rs = rowsize, gs = groupsize;
+       int ae, he, e, f, r;
+       bool a;
+
+       total_tests++;
+
+       memset(buf, FILL_CHAR, sizeof(buf));
+
+       r = hex_dump_to_buffer(data_b, len, rs, gs, buf, buflen, ascii);
+
+       /*
+        * Caller must provide the data length multiple of groupsize. The
+        * calculations below are made with that assumption in mind.
+        */
+       ae = rs * 2 /* hex */ + rs / gs /* spaces */ + 1 /* space */ + len /* ascii */;
+       he = (gs * 2 /* hex */ + 1 /* space */) * len / gs - 1 /* no trailing space */;
+
+       if (ascii)
+               e = ae;
+       else
+               e = he;
+
+       f = min_t(int, e + 1, buflen);
+       if (buflen) {
+               test_hexdump_prepare_test(len, rs, gs, test, sizeof(test), ascii);
+               test[f - 1] = '\0';
+       }
+       memset(test + f, FILL_CHAR, sizeof(test) - f);
+
+       a = r == e && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
+
+       buf[sizeof(buf) - 1] = '\0';
+
+       if (!a) {
+               pr_err("Len: %zu buflen: %zu strlen: %zu\n",
+                       len, buflen, strnlen(buf, sizeof(buf)));
+               pr_err("Result: %d '%s'\n", r, buf);
+               pr_err("Expect: %d '%s'\n", e, test);
+               failed_tests++;
+       }
+}
+
+static void __init test_hexdump_overflow_set(size_t buflen, bool ascii)
+{
+       unsigned int i = 0;
+       int rs = (get_random_int() % 2 + 1) * 16;
+
+       do {
+               int gs = 1 << i;
+               size_t len = get_random_int() % rs + gs;
+
+               test_hexdump_overflow(buflen, rounddown(len, gs), rs, gs, ascii);
+       } while (i++ < 3);
+}
+
+static int __init test_hexdump_init(void)
+{
+       unsigned int i;
+       int rowsize;
+
+       rowsize = (get_random_int() % 2 + 1) * 16;
+       for (i = 0; i < 16; i++)
+               test_hexdump_set(rowsize, false);
+
+       rowsize = (get_random_int() % 2 + 1) * 16;
+       for (i = 0; i < 16; i++)
+               test_hexdump_set(rowsize, true);
+
+       for (i = 0; i <= TEST_HEXDUMP_BUF_SIZE; i++)
+               test_hexdump_overflow_set(i, false);
+
+       for (i = 0; i <= TEST_HEXDUMP_BUF_SIZE; i++)
+               test_hexdump_overflow_set(i, true);
+
+       if (failed_tests == 0)
+               pr_info("all %u tests passed\n", total_tests);
+       else
+               pr_err("failed %u out of %u tests\n", failed_tests, total_tests);
+
+       return failed_tests ? -EINVAL : 0;
+}
+module_init(test_hexdump_init);
+
+static void __exit test_hexdump_exit(void)
+{
+       /* do nothing */
+}
+module_exit(test_hexdump_exit);
+
+MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/ubsan.c b/lib/ubsan.c
new file mode 100644 (file)
index 0000000..8799ae5
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * UBSAN error reporting functions
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.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/bitops.h>
+#include <linux/bug.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include "ubsan.h"
+
+const char *type_check_kinds[] = {
+       "load of",
+       "store to",
+       "reference binding to",
+       "member access within",
+       "member call on",
+       "constructor call on",
+       "downcast of",
+       "downcast of"
+};
+
+#define REPORTED_BIT 31
+
+#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
+#define COLUMN_MASK (~(1U << REPORTED_BIT))
+#define LINE_MASK   (~0U)
+#else
+#define COLUMN_MASK   (~0U)
+#define LINE_MASK (~(1U << REPORTED_BIT))
+#endif
+
+#define VALUE_LENGTH 40
+
+static bool was_reported(struct source_location *location)
+{
+       return test_and_set_bit(REPORTED_BIT, &location->reported);
+}
+
+static void print_source_location(const char *prefix,
+                               struct source_location *loc)
+{
+       pr_err("%s %s:%d:%d\n", prefix, loc->file_name,
+               loc->line & LINE_MASK, loc->column & COLUMN_MASK);
+}
+
+static bool suppress_report(struct source_location *loc)
+{
+       return current->in_ubsan || was_reported(loc);
+}
+
+static bool type_is_int(struct type_descriptor *type)
+{
+       return type->type_kind == type_kind_int;
+}
+
+static bool type_is_signed(struct type_descriptor *type)
+{
+       WARN_ON(!type_is_int(type));
+       return  type->type_info & 1;
+}
+
+static unsigned type_bit_width(struct type_descriptor *type)
+{
+       return 1 << (type->type_info >> 1);
+}
+
+static bool is_inline_int(struct type_descriptor *type)
+{
+       unsigned inline_bits = sizeof(unsigned long)*8;
+       unsigned bits = type_bit_width(type);
+
+       WARN_ON(!type_is_int(type));
+
+       return bits <= inline_bits;
+}
+
+static s_max get_signed_val(struct type_descriptor *type, unsigned long val)
+{
+       if (is_inline_int(type)) {
+               unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
+               return ((s_max)val) << extra_bits >> extra_bits;
+       }
+
+       if (type_bit_width(type) == 64)
+               return *(s64 *)val;
+
+       return *(s_max *)val;
+}
+
+static bool val_is_negative(struct type_descriptor *type, unsigned long val)
+{
+       return type_is_signed(type) && get_signed_val(type, val) < 0;
+}
+
+static u_max get_unsigned_val(struct type_descriptor *type, unsigned long val)
+{
+       if (is_inline_int(type))
+               return val;
+
+       if (type_bit_width(type) == 64)
+               return *(u64 *)val;
+
+       return *(u_max *)val;
+}
+
+static void val_to_string(char *str, size_t size, struct type_descriptor *type,
+       unsigned long value)
+{
+       if (type_is_int(type)) {
+               if (type_bit_width(type) == 128) {
+#if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
+                       u_max val = get_unsigned_val(type, value);
+
+                       scnprintf(str, size, "0x%08x%08x%08x%08x",
+                               (u32)(val >> 96),
+                               (u32)(val >> 64),
+                               (u32)(val >> 32),
+                               (u32)(val));
+#else
+                       WARN_ON(1);
+#endif
+               } else if (type_is_signed(type)) {
+                       scnprintf(str, size, "%lld",
+                               (s64)get_signed_val(type, value));
+               } else {
+                       scnprintf(str, size, "%llu",
+                               (u64)get_unsigned_val(type, value));
+               }
+       }
+}
+
+static bool location_is_valid(struct source_location *loc)
+{
+       return loc->file_name != NULL;
+}
+
+static DEFINE_SPINLOCK(report_lock);
+
+static void ubsan_prologue(struct source_location *location,
+                       unsigned long *flags)
+{
+       current->in_ubsan++;
+       spin_lock_irqsave(&report_lock, *flags);
+
+       pr_err("========================================"
+               "========================================\n");
+       print_source_location("UBSAN: Undefined behaviour in", location);
+}
+
+static void ubsan_epilogue(unsigned long *flags)
+{
+       dump_stack();
+       pr_err("========================================"
+               "========================================\n");
+       spin_unlock_irqrestore(&report_lock, *flags);
+       current->in_ubsan--;
+}
+
+static void handle_overflow(struct overflow_data *data, unsigned long lhs,
+                       unsigned long rhs, char op)
+{
+
+       struct type_descriptor *type = data->type;
+       unsigned long flags;
+       char lhs_val_str[VALUE_LENGTH];
+       char rhs_val_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
+       val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
+       pr_err("%s integer overflow:\n",
+               type_is_signed(type) ? "signed" : "unsigned");
+       pr_err("%s %c %s cannot be represented in type %s\n",
+               lhs_val_str,
+               op,
+               rhs_val_str,
+               type->type_name);
+
+       ubsan_epilogue(&flags);
+}
+
+void __ubsan_handle_add_overflow(struct overflow_data *data,
+                               unsigned long lhs,
+                               unsigned long rhs)
+{
+
+       handle_overflow(data, lhs, rhs, '+');
+}
+EXPORT_SYMBOL(__ubsan_handle_add_overflow);
+
+void __ubsan_handle_sub_overflow(struct overflow_data *data,
+                               unsigned long lhs,
+                               unsigned long rhs)
+{
+       handle_overflow(data, lhs, rhs, '-');
+}
+EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
+
+void __ubsan_handle_mul_overflow(struct overflow_data *data,
+                               unsigned long lhs,
+                               unsigned long rhs)
+{
+       handle_overflow(data, lhs, rhs, '*');
+}
+EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
+
+void __ubsan_handle_negate_overflow(struct overflow_data *data,
+                               unsigned long old_val)
+{
+       unsigned long flags;
+       char old_val_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
+
+       pr_err("negation of %s cannot be represented in type %s:\n",
+               old_val_str, data->type->type_name);
+
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
+
+
+void __ubsan_handle_divrem_overflow(struct overflow_data *data,
+                               unsigned long lhs,
+                               unsigned long rhs)
+{
+       unsigned long flags;
+       char rhs_val_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
+
+       if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
+               pr_err("division of %s by -1 cannot be represented in type %s\n",
+                       rhs_val_str, data->type->type_name);
+       else
+               pr_err("division by zero\n");
+
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
+
+static void handle_null_ptr_deref(struct type_mismatch_data *data)
+{
+       unsigned long flags;
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       pr_err("%s null pointer of type %s\n",
+               type_check_kinds[data->type_check_kind],
+               data->type->type_name);
+
+       ubsan_epilogue(&flags);
+}
+
+static void handle_missaligned_access(struct type_mismatch_data *data,
+                               unsigned long ptr)
+{
+       unsigned long flags;
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       pr_err("%s misaligned address %p for type %s\n",
+               type_check_kinds[data->type_check_kind],
+               (void *)ptr, data->type->type_name);
+       pr_err("which requires %ld byte alignment\n", data->alignment);
+
+       ubsan_epilogue(&flags);
+}
+
+static void handle_object_size_mismatch(struct type_mismatch_data *data,
+                                       unsigned long ptr)
+{
+       unsigned long flags;
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+       pr_err("%s address %pk with insufficient space\n",
+               type_check_kinds[data->type_check_kind],
+               (void *) ptr);
+       pr_err("for an object of type %s\n", data->type->type_name);
+       ubsan_epilogue(&flags);
+}
+
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
+                               unsigned long ptr)
+{
+
+       if (!ptr)
+               handle_null_ptr_deref(data);
+       else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
+               handle_missaligned_access(data, ptr);
+       else
+               handle_object_size_mismatch(data, ptr);
+}
+EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
+
+void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
+{
+       unsigned long flags;
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       pr_err("null pointer returned from function declared to never return null\n");
+
+       if (location_is_valid(&data->attr_location))
+               print_source_location("returns_nonnull attribute specified in",
+                               &data->attr_location);
+
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_nonnull_return);
+
+void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
+                                       unsigned long bound)
+{
+       unsigned long flags;
+       char bound_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(bound_str, sizeof(bound_str), data->type, bound);
+       pr_err("variable length array bound value %s <= 0\n", bound_str);
+
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_vla_bound_not_positive);
+
+void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
+                               unsigned long index)
+{
+       unsigned long flags;
+       char index_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(index_str, sizeof(index_str), data->index_type, index);
+       pr_err("index %s is out of range for type %s\n", index_str,
+               data->array_type->type_name);
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
+
+void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
+                                       unsigned long lhs, unsigned long rhs)
+{
+       unsigned long flags;
+       struct type_descriptor *rhs_type = data->rhs_type;
+       struct type_descriptor *lhs_type = data->lhs_type;
+       char rhs_str[VALUE_LENGTH];
+       char lhs_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
+       val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
+
+       if (val_is_negative(rhs_type, rhs))
+               pr_err("shift exponent %s is negative\n", rhs_str);
+
+       else if (get_unsigned_val(rhs_type, rhs) >=
+               type_bit_width(lhs_type))
+               pr_err("shift exponent %s is too large for %u-bit type %s\n",
+                       rhs_str,
+                       type_bit_width(lhs_type),
+                       lhs_type->type_name);
+       else if (val_is_negative(lhs_type, lhs))
+               pr_err("left shift of negative value %s\n",
+                       lhs_str);
+       else
+               pr_err("left shift of %s by %s places cannot be"
+                       " represented in type %s\n",
+                       lhs_str, rhs_str,
+                       lhs_type->type_name);
+
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
+
+
+void __noreturn
+__ubsan_handle_builtin_unreachable(struct unreachable_data *data)
+{
+       unsigned long flags;
+
+       ubsan_prologue(&data->location, &flags);
+       pr_err("calling __builtin_unreachable()\n");
+       ubsan_epilogue(&flags);
+       panic("can't return from __builtin_unreachable()");
+}
+EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
+
+void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
+                               unsigned long val)
+{
+       unsigned long flags;
+       char val_str[VALUE_LENGTH];
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, &flags);
+
+       val_to_string(val_str, sizeof(val_str), data->type, val);
+
+       pr_err("load of value %s is not a valid value for type %s\n",
+               val_str, data->type->type_name);
+
+       ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
diff --git a/lib/ubsan.h b/lib/ubsan.h
new file mode 100644 (file)
index 0000000..b2d18d4
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _LIB_UBSAN_H
+#define _LIB_UBSAN_H
+
+enum {
+       type_kind_int = 0,
+       type_kind_float = 1,
+       type_unknown = 0xffff
+};
+
+struct type_descriptor {
+       u16 type_kind;
+       u16 type_info;
+       char type_name[1];
+};
+
+struct source_location {
+       const char *file_name;
+       union {
+               unsigned long reported;
+               struct {
+                       u32 line;
+                       u32 column;
+               };
+       };
+};
+
+struct overflow_data {
+       struct source_location location;
+       struct type_descriptor *type;
+};
+
+struct type_mismatch_data {
+       struct source_location location;
+       struct type_descriptor *type;
+       unsigned long alignment;
+       unsigned char type_check_kind;
+};
+
+struct nonnull_arg_data {
+       struct source_location location;
+       struct source_location attr_location;
+       int arg_index;
+};
+
+struct nonnull_return_data {
+       struct source_location location;
+       struct source_location attr_location;
+};
+
+struct vla_bound_data {
+       struct source_location location;
+       struct type_descriptor *type;
+};
+
+struct out_of_bounds_data {
+       struct source_location location;
+       struct type_descriptor *array_type;
+       struct type_descriptor *index_type;
+};
+
+struct shift_out_of_bounds_data {
+       struct source_location location;
+       struct type_descriptor *lhs_type;
+       struct type_descriptor *rhs_type;
+};
+
+struct unreachable_data {
+       struct source_location location;
+};
+
+struct invalid_value_data {
+       struct source_location location;
+       struct type_descriptor *type;
+};
+
+#if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
+typedef __int128 s_max;
+typedef unsigned __int128 u_max;
+#else
+typedef s64 s_max;
+typedef u64 u_max;
+#endif
+
+#endif
index 847ee43..bc94386 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/export.h>
 #include <linux/compiler.h>
+#include <linux/dax.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/capability.h>
@@ -123,9 +124,9 @@ static void page_cache_tree_delete(struct address_space *mapping,
        __radix_tree_lookup(&mapping->page_tree, page->index, &node, &slot);
 
        if (shadow) {
-               mapping->nrshadows++;
+               mapping->nrexceptional++;
                /*
-                * Make sure the nrshadows update is committed before
+                * Make sure the nrexceptional update is committed before
                 * the nrpages update so that final truncate racing
                 * with reclaim does not see both counters 0 at the
                 * same time and miss a shadow entry.
@@ -481,6 +482,12 @@ int filemap_write_and_wait_range(struct address_space *mapping,
 {
        int err = 0;
 
+       if (dax_mapping(mapping) && mapping->nrexceptional) {
+               err = dax_writeback_mapping_range(mapping, lstart, lend);
+               if (err)
+                       return err;
+       }
+
        if (mapping->nrpages) {
                err = __filemap_fdatawrite_range(mapping, lstart, lend,
                                                 WB_SYNC_ALL);
@@ -579,9 +586,13 @@ static int page_cache_tree_insert(struct address_space *mapping,
                p = radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
                if (!radix_tree_exceptional_entry(p))
                        return -EEXIST;
+
+               if (WARN_ON(dax_mapping(mapping)))
+                       return -EINVAL;
+
                if (shadowp)
                        *shadowp = p;
-               mapping->nrshadows--;
+               mapping->nrexceptional--;
                if (node)
                        workingset_node_shadows_dec(node);
        }
@@ -1245,9 +1256,9 @@ repeat:
                        if (radix_tree_deref_retry(page))
                                goto restart;
                        /*
-                        * A shadow entry of a recently evicted page,
-                        * or a swap entry from shmem/tmpfs.  Return
-                        * it without attempting to raise page count.
+                        * A shadow entry of a recently evicted page, a swap
+                        * entry from shmem/tmpfs or a DAX entry.  Return it
+                        * without attempting to raise page count.
                         */
                        goto export;
                }
@@ -1494,6 +1505,74 @@ repeat:
 }
 EXPORT_SYMBOL(find_get_pages_tag);
 
+/**
+ * find_get_entries_tag - find and return entries that match @tag
+ * @mapping:   the address_space to search
+ * @start:     the starting page cache index
+ * @tag:       the tag index
+ * @nr_entries:        the maximum number of entries
+ * @entries:   where the resulting entries are placed
+ * @indices:   the cache indices corresponding to the entries in @entries
+ *
+ * Like find_get_entries, except we only return entries which are tagged with
+ * @tag.
+ */
+unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
+                       int tag, unsigned int nr_entries,
+                       struct page **entries, pgoff_t *indices)
+{
+       void **slot;
+       unsigned int ret = 0;
+       struct radix_tree_iter iter;
+
+       if (!nr_entries)
+               return 0;
+
+       rcu_read_lock();
+restart:
+       radix_tree_for_each_tagged(slot, &mapping->page_tree,
+                                  &iter, start, tag) {
+               struct page *page;
+repeat:
+               page = radix_tree_deref_slot(slot);
+               if (unlikely(!page))
+                       continue;
+               if (radix_tree_exception(page)) {
+                       if (radix_tree_deref_retry(page)) {
+                               /*
+                                * Transient condition which can only trigger
+                                * when entry at index 0 moves out of or back
+                                * to root: none yet gotten, safe to restart.
+                                */
+                               goto restart;
+                       }
+
+                       /*
+                        * A shadow entry of a recently evicted page, a swap
+                        * entry from shmem/tmpfs or a DAX entry.  Return it
+                        * without attempting to raise page count.
+                        */
+                       goto export;
+               }
+               if (!page_cache_get_speculative(page))
+                       goto repeat;
+
+               /* Has the page moved? */
+               if (unlikely(page != *slot)) {
+                       page_cache_release(page);
+                       goto repeat;
+               }
+export:
+               indices[ret] = iter.index;
+               entries[ret] = page;
+               if (++ret == nr_entries)
+                       break;
+       }
+       rcu_read_unlock();
+       return ret;
+}
+EXPORT_SYMBOL(find_get_entries_tag);
+
 /*
  * CD/DVDs are error prone. When a medium error occurs, the driver may fail
  * a _large_ part of the i/o request. Imagine the worst scenario:
@@ -2684,11 +2763,11 @@ ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        struct inode *inode = file->f_mapping->host;
        ssize_t ret;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = generic_write_checks(iocb, from);
        if (ret > 0)
                ret = __generic_file_write_iter(iocb, from);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        if (ret > 0) {
                ssize_t err;
index b1cf73b..fd3a07b 100644 (file)
@@ -1560,7 +1560,8 @@ int madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
        struct mm_struct *mm = tlb->mm;
        int ret = 0;
 
-       if (!pmd_trans_huge_lock(pmd, vma, &ptl))
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (!ptl)
                goto out_unlocked;
 
        orig_pmd = *pmd;
@@ -1627,7 +1628,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
        pmd_t orig_pmd;
        spinlock_t *ptl;
 
-       if (!__pmd_trans_huge_lock(pmd, vma, &ptl))
+       ptl = __pmd_trans_huge_lock(pmd, vma);
+       if (!ptl)
                return 0;
        /*
         * For architectures like ppc64 we look at deposited pgtable
@@ -1690,7 +1692,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, struct vm_area_struct *new_vma,
         * We don't have to worry about the ordering of src and dst
         * ptlocks because exclusive mmap_sem prevents deadlock.
         */
-       if (__pmd_trans_huge_lock(old_pmd, vma, &old_ptl)) {
+       old_ptl = __pmd_trans_huge_lock(old_pmd, vma);
+       if (old_ptl) {
                new_ptl = pmd_lockptr(mm, new_pmd);
                if (new_ptl != old_ptl)
                        spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
@@ -1724,7 +1727,8 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
        spinlock_t *ptl;
        int ret = 0;
 
-       if (__pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = __pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                pmd_t entry;
                bool preserve_write = prot_numa && pmd_write(*pmd);
                ret = 1;
@@ -1760,14 +1764,14 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
  * Note that if it returns true, this routine returns without unlocking page
  * table lock. So callers must unlock it.
  */
-bool __pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma,
-               spinlock_t **ptl)
+spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma)
 {
-       *ptl = pmd_lock(vma->vm_mm, pmd);
+       spinlock_t *ptl;
+       ptl = pmd_lock(vma->vm_mm, pmd);
        if (likely(pmd_trans_huge(*pmd) || pmd_devmap(*pmd)))
-               return true;
-       spin_unlock(*ptl);
-       return false;
+               return ptl;
+       spin_unlock(ptl);
+       return NULL;
 }
 
 #define VM_NO_THP (VM_SPECIAL | VM_HUGETLB | VM_SHARED | VM_MAYSHARE)
@@ -2068,7 +2072,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
        if (likely(writable)) {
                if (likely(referenced)) {
                        result = SCAN_SUCCEED;
-                       trace_mm_collapse_huge_page_isolate(page_to_pfn(page), none_or_zero,
+                       trace_mm_collapse_huge_page_isolate(page, none_or_zero,
                                                            referenced, writable, result);
                        return 1;
                }
@@ -2078,7 +2082,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
 
 out:
        release_pte_pages(pte, _pte);
-       trace_mm_collapse_huge_page_isolate(page_to_pfn(page), none_or_zero,
+       trace_mm_collapse_huge_page_isolate(page, none_or_zero,
                                            referenced, writable, result);
        return 0;
 }
@@ -2576,7 +2580,7 @@ out_unmap:
                collapse_huge_page(mm, address, hpage, vma, node);
        }
 out:
-       trace_mm_khugepaged_scan_pmd(mm, page_to_pfn(page), writable, referenced,
+       trace_mm_khugepaged_scan_pmd(mm, page, writable, referenced,
                                     none_or_zero, result);
        return ret;
 }
@@ -3357,6 +3361,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
        struct anon_vma *anon_vma;
        int count, mapcount, ret;
        bool mlocked;
+       unsigned long flags;
 
        VM_BUG_ON_PAGE(is_huge_zero_page(page), page);
        VM_BUG_ON_PAGE(!PageAnon(page), page);
@@ -3396,7 +3401,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
                lru_add_drain();
 
        /* Prevent deferred_split_scan() touching ->_count */
-       spin_lock(&split_queue_lock);
+       spin_lock_irqsave(&split_queue_lock, flags);
        count = page_count(head);
        mapcount = total_mapcount(head);
        if (!mapcount && count == 1) {
@@ -3404,11 +3409,11 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
                        split_queue_len--;
                        list_del(page_deferred_list(head));
                }
-               spin_unlock(&split_queue_lock);
+               spin_unlock_irqrestore(&split_queue_lock, flags);
                __split_huge_page(page, list);
                ret = 0;
        } else if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) {
-               spin_unlock(&split_queue_lock);
+               spin_unlock_irqrestore(&split_queue_lock, flags);
                pr_alert("total_mapcount: %u, page_count(): %u\n",
                                mapcount, count);
                if (PageTail(page))
@@ -3416,7 +3421,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
                dump_page(page, "total_mapcount(head) > 0");
                BUG();
        } else {
-               spin_unlock(&split_queue_lock);
+               spin_unlock_irqrestore(&split_queue_lock, flags);
                unfreeze_page(anon_vma, head);
                ret = -EBUSY;
        }
index 6471014..a61460d 100644 (file)
@@ -1,4 +1,5 @@
 KASAN_SANITIZE := n
+UBSAN_SANITIZE_kasan.o := n
 
 CFLAGS_REMOVE_kasan.o = -pg
 # Function splitter causes unnecessary splits in __asan_load1/__asan_store1
index afc71ea..1d05cb9 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/mutex.h>
 #include <linux/memcontrol.h>
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 static LIST_HEAD(list_lrus);
 static DEFINE_MUTEX(list_lrus_mutex);
 
@@ -37,9 +37,9 @@ static void list_lru_register(struct list_lru *lru)
 static void list_lru_unregister(struct list_lru *lru)
 {
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 static inline bool list_lru_memcg_aware(struct list_lru *lru)
 {
        /*
@@ -104,7 +104,7 @@ list_lru_from_kmem(struct list_lru_node *nlru, void *ptr)
 {
        return &nlru->lru;
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
 
 bool list_lru_add(struct list_lru *lru, struct list_head *item)
 {
@@ -292,7 +292,7 @@ static void init_one_lru(struct list_lru_one *l)
        l->nr_items = 0;
 }
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 static void __memcg_destroy_list_lru_node(struct list_lru_memcg *memcg_lrus,
                                          int begin, int end)
 {
@@ -529,7 +529,7 @@ static int memcg_init_list_lru(struct list_lru *lru, bool memcg_aware)
 static void memcg_destroy_list_lru(struct list_lru *lru)
 {
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
 
 int __list_lru_init(struct list_lru *lru, bool memcg_aware,
                    struct lock_class_key *key)
index 0eda673..d06cae2 100644 (file)
@@ -66,7 +66,6 @@
 #include "internal.h"
 #include <net/sock.h>
 #include <net/ip.h>
-#include <net/tcp_memcontrol.h>
 #include "slab.h"
 
 #include <asm/uaccess.h>
@@ -83,6 +82,9 @@ struct mem_cgroup *root_mem_cgroup __read_mostly;
 /* Socket memory accounting disabled? */
 static bool cgroup_memory_nosocket;
 
+/* Kernel memory accounting disabled? */
+static bool cgroup_memory_nokmem;
+
 /* Whether the swap controller is active */
 #ifdef CONFIG_MEMCG_SWAP
 int do_swap_account __read_mostly;
@@ -239,6 +241,7 @@ enum res_type {
        _MEMSWAP,
        _OOM_TYPE,
        _KMEM,
+       _TCP,
 };
 
 #define MEMFILE_PRIVATE(x, val)        ((x) << 16 | (val))
@@ -247,13 +250,6 @@ enum res_type {
 /* Used for OOM nofiier */
 #define OOM_CONTROL            (0)
 
-/*
- * The memcg_create_mutex will be held whenever a new cgroup is created.
- * As a consequence, any change that needs to protect against new child cgroups
- * appearing has to hold it as well.
- */
-static DEFINE_MUTEX(memcg_create_mutex);
-
 /* Some nice accessors for the vmpressure. */
 struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg)
 {
@@ -297,7 +293,7 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
        return mem_cgroup_from_css(css);
 }
 
-#ifdef CONFIG_MEMCG_KMEM
+#ifndef CONFIG_SLOB
 /*
  * This will be the memcg's index in each cache's ->memcg_params.memcg_caches.
  * The main reason for not using cgroup id for this:
@@ -349,7 +345,7 @@ void memcg_put_cache_ids(void)
 DEFINE_STATIC_KEY_FALSE(memcg_kmem_enabled_key);
 EXPORT_SYMBOL(memcg_kmem_enabled_key);
 
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* !CONFIG_SLOB */
 
 static struct mem_cgroup_per_zone *
 mem_cgroup_zone_zoneinfo(struct mem_cgroup *memcg, struct zone *zone)
@@ -370,13 +366,6 @@ mem_cgroup_zone_zoneinfo(struct mem_cgroup *memcg, struct zone *zone)
  *
  * If memcg is bound to a traditional hierarchy, the css of root_mem_cgroup
  * is returned.
- *
- * XXX: The above description of behavior on the default hierarchy isn't
- * strictly true yet as replace_page_cache_page() can modify the
- * association before @page is released even on the default hierarchy;
- * however, the current and planned usages don't mix the the two functions
- * and replace_page_cache_page() will soon be updated to make the invariant
- * actually true.
  */
 struct cgroup_subsys_state *mem_cgroup_css_from_page(struct page *page)
 {
@@ -896,17 +885,8 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
                if (css == &root->css)
                        break;
 
-               if (css_tryget(css)) {
-                       /*
-                        * Make sure the memcg is initialized:
-                        * mem_cgroup_css_online() orders the the
-                        * initialization against setting the flag.
-                        */
-                       if (smp_load_acquire(&memcg->initialized))
-                               break;
-
-                       css_put(css);
-               }
+               if (css_tryget(css))
+                       break;
 
                memcg = NULL;
        }
@@ -1233,7 +1213,7 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
                pr_cont(":");
 
                for (i = 0; i < MEM_CGROUP_STAT_NSTATS; i++) {
-                       if (i == MEM_CGROUP_STAT_SWAP && !do_memsw_account())
+                       if (i == MEM_CGROUP_STAT_SWAP && !do_swap_account)
                                continue;
                        pr_cont(" %s:%luKB", mem_cgroup_stat_names[i],
                                K(mem_cgroup_read_stat(iter, i)));
@@ -1272,9 +1252,12 @@ static unsigned long mem_cgroup_get_limit(struct mem_cgroup *memcg)
        limit = memcg->memory.limit;
        if (mem_cgroup_swappiness(memcg)) {
                unsigned long memsw_limit;
+               unsigned long swap_limit;
 
                memsw_limit = memcg->memsw.limit;
-               limit = min(limit + total_swap_pages, memsw_limit);
+               swap_limit = memcg->swap.limit;
+               swap_limit = min(swap_limit, (unsigned long)total_swap_pages);
+               limit = min(limit + swap_limit, memsw_limit);
        }
        return limit;
 }
@@ -2203,7 +2186,7 @@ static void commit_charge(struct page *page, struct mem_cgroup *memcg,
                unlock_page_lru(page, isolated);
 }
 
-#ifdef CONFIG_MEMCG_KMEM
+#ifndef CONFIG_SLOB
 static int memcg_alloc_cache_id(void)
 {
        int id, size;
@@ -2378,16 +2361,17 @@ int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order,
        struct page_counter *counter;
        int ret;
 
-       if (!memcg_kmem_is_active(memcg))
+       if (!memcg_kmem_online(memcg))
                return 0;
 
-       if (!page_counter_try_charge(&memcg->kmem, nr_pages, &counter))
-               return -ENOMEM;
-
        ret = try_charge(memcg, gfp, nr_pages);
-       if (ret) {
-               page_counter_uncharge(&memcg->kmem, nr_pages);
+       if (ret)
                return ret;
+
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) &&
+           !page_counter_try_charge(&memcg->kmem, nr_pages, &counter)) {
+               cancel_charge(memcg, nr_pages);
+               return -ENOMEM;
        }
 
        page->mem_cgroup = memcg;
@@ -2416,7 +2400,9 @@ void __memcg_kmem_uncharge(struct page *page, int order)
 
        VM_BUG_ON_PAGE(mem_cgroup_is_root(memcg), page);
 
-       page_counter_uncharge(&memcg->kmem, nr_pages);
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
+               page_counter_uncharge(&memcg->kmem, nr_pages);
+
        page_counter_uncharge(&memcg->memory, nr_pages);
        if (do_memsw_account())
                page_counter_uncharge(&memcg->memsw, nr_pages);
@@ -2424,7 +2410,7 @@ void __memcg_kmem_uncharge(struct page *page, int order)
        page->mem_cgroup = NULL;
        css_put_many(&memcg->css, nr_pages);
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* !CONFIG_SLOB */
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 
@@ -2684,14 +2670,6 @@ static inline bool memcg_has_children(struct mem_cgroup *memcg)
 {
        bool ret;
 
-       /*
-        * The lock does not prevent addition or deletion of children, but
-        * it prevents a new child from being initialized based on this
-        * parent in css_online(), so it's enough to decide whether
-        * hierarchically inherited attributes can still be changed or not.
-        */
-       lockdep_assert_held(&memcg_create_mutex);
-
        rcu_read_lock();
        ret = css_next_child(NULL, &memcg->css);
        rcu_read_unlock();
@@ -2754,10 +2732,8 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
        struct mem_cgroup *parent_memcg = mem_cgroup_from_css(memcg->css.parent);
 
-       mutex_lock(&memcg_create_mutex);
-
        if (memcg->use_hierarchy == val)
-               goto out;
+               return 0;
 
        /*
         * If parent's use_hierarchy is set, we can't make any modifications
@@ -2776,9 +2752,6 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
        } else
                retval = -EINVAL;
 
-out:
-       mutex_unlock(&memcg_create_mutex);
-
        return retval;
 }
 
@@ -2794,6 +2767,18 @@ static unsigned long tree_stat(struct mem_cgroup *memcg,
        return val;
 }
 
+static unsigned long tree_events(struct mem_cgroup *memcg,
+                                enum mem_cgroup_events_index idx)
+{
+       struct mem_cgroup *iter;
+       unsigned long val = 0;
+
+       for_each_mem_cgroup_tree(iter, memcg)
+               val += mem_cgroup_read_events(iter, idx);
+
+       return val;
+}
+
 static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
 {
        unsigned long val;
@@ -2836,6 +2821,9 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
        case _KMEM:
                counter = &memcg->kmem;
                break;
+       case _TCP:
+               counter = &memcg->tcpmem;
+               break;
        default:
                BUG();
        }
@@ -2860,103 +2848,180 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
        }
 }
 
-#ifdef CONFIG_MEMCG_KMEM
-static int memcg_activate_kmem(struct mem_cgroup *memcg,
-                              unsigned long nr_pages)
+#ifndef CONFIG_SLOB
+static int memcg_online_kmem(struct mem_cgroup *memcg)
 {
-       int err = 0;
        int memcg_id;
 
        BUG_ON(memcg->kmemcg_id >= 0);
-       BUG_ON(memcg->kmem_acct_activated);
-       BUG_ON(memcg->kmem_acct_active);
-
-       /*
-        * For simplicity, we won't allow this to be disabled.  It also can't
-        * be changed if the cgroup has children already, or if tasks had
-        * already joined.
-        *
-        * If tasks join before we set the limit, a person looking at
-        * kmem.usage_in_bytes will have no way to determine when it took
-        * place, which makes the value quite meaningless.
-        *
-        * After it first became limited, changes in the value of the limit are
-        * of course permitted.
-        */
-       mutex_lock(&memcg_create_mutex);
-       if (cgroup_is_populated(memcg->css.cgroup) ||
-           (memcg->use_hierarchy && memcg_has_children(memcg)))
-               err = -EBUSY;
-       mutex_unlock(&memcg_create_mutex);
-       if (err)
-               goto out;
+       BUG_ON(memcg->kmem_state);
 
        memcg_id = memcg_alloc_cache_id();
-       if (memcg_id < 0) {
-               err = memcg_id;
-               goto out;
-       }
-
-       /*
-        * We couldn't have accounted to this cgroup, because it hasn't got
-        * activated yet, so this should succeed.
-        */
-       err = page_counter_limit(&memcg->kmem, nr_pages);
-       VM_BUG_ON(err);
+       if (memcg_id < 0)
+               return memcg_id;
 
        static_branch_inc(&memcg_kmem_enabled_key);
        /*
-        * A memory cgroup is considered kmem-active as soon as it gets
+        * A memory cgroup is considered kmem-online as soon as it gets
         * kmemcg_id. Setting the id after enabling static branching will
         * guarantee no one starts accounting before all call sites are
         * patched.
         */
        memcg->kmemcg_id = memcg_id;
-       memcg->kmem_acct_activated = true;
-       memcg->kmem_acct_active = true;
-out:
-       return err;
+       memcg->kmem_state = KMEM_ONLINE;
+
+       return 0;
 }
 
-static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
-                                  unsigned long limit)
+static int memcg_propagate_kmem(struct mem_cgroup *parent,
+                               struct mem_cgroup *memcg)
 {
-       int ret;
+       int ret = 0;
 
        mutex_lock(&memcg_limit_mutex);
-       if (!memcg_kmem_is_active(memcg))
-               ret = memcg_activate_kmem(memcg, limit);
-       else
-               ret = page_counter_limit(&memcg->kmem, limit);
+       /*
+        * If the parent cgroup is not kmem-online now, it cannot be
+        * onlined after this point, because it has at least one child
+        * already.
+        */
+       if (memcg_kmem_online(parent) ||
+           (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nokmem))
+               ret = memcg_online_kmem(memcg);
        mutex_unlock(&memcg_limit_mutex);
        return ret;
 }
 
-static int memcg_propagate_kmem(struct mem_cgroup *memcg)
+static void memcg_offline_kmem(struct mem_cgroup *memcg)
 {
-       int ret = 0;
-       struct mem_cgroup *parent = parent_mem_cgroup(memcg);
+       struct cgroup_subsys_state *css;
+       struct mem_cgroup *parent, *child;
+       int kmemcg_id;
+
+       if (memcg->kmem_state != KMEM_ONLINE)
+               return;
+       /*
+        * Clear the online state before clearing memcg_caches array
+        * entries. The slab_mutex in memcg_deactivate_kmem_caches()
+        * guarantees that no cache will be created for this cgroup
+        * after we are done (see memcg_create_kmem_cache()).
+        */
+       memcg->kmem_state = KMEM_ALLOCATED;
 
+       memcg_deactivate_kmem_caches(memcg);
+
+       kmemcg_id = memcg->kmemcg_id;
+       BUG_ON(kmemcg_id < 0);
+
+       parent = parent_mem_cgroup(memcg);
        if (!parent)
-               return 0;
+               parent = root_mem_cgroup;
 
-       mutex_lock(&memcg_limit_mutex);
        /*
-        * If the parent cgroup is not kmem-active now, it cannot be activated
-        * after this point, because it has at least one child already.
+        * Change kmemcg_id of this cgroup and all its descendants to the
+        * parent's id, and then move all entries from this cgroup's list_lrus
+        * to ones of the parent. After we have finished, all list_lrus
+        * corresponding to this cgroup are guaranteed to remain empty. The
+        * ordering is imposed by list_lru_node->lock taken by
+        * memcg_drain_all_list_lrus().
         */
-       if (memcg_kmem_is_active(parent))
-               ret = memcg_activate_kmem(memcg, PAGE_COUNTER_MAX);
-       mutex_unlock(&memcg_limit_mutex);
-       return ret;
+       css_for_each_descendant_pre(css, &memcg->css) {
+               child = mem_cgroup_from_css(css);
+               BUG_ON(child->kmemcg_id != kmemcg_id);
+               child->kmemcg_id = parent->kmemcg_id;
+               if (!memcg->use_hierarchy)
+                       break;
+       }
+       memcg_drain_all_list_lrus(kmemcg_id, parent->kmemcg_id);
+
+       memcg_free_cache_id(kmemcg_id);
+}
+
+static void memcg_free_kmem(struct mem_cgroup *memcg)
+{
+       /* css_alloc() failed, offlining didn't happen */
+       if (unlikely(memcg->kmem_state == KMEM_ONLINE))
+               memcg_offline_kmem(memcg);
+
+       if (memcg->kmem_state == KMEM_ALLOCATED) {
+               memcg_destroy_kmem_caches(memcg);
+               static_branch_dec(&memcg_kmem_enabled_key);
+               WARN_ON(page_counter_read(&memcg->kmem));
+       }
 }
 #else
+static int memcg_propagate_kmem(struct mem_cgroup *parent, struct mem_cgroup *memcg)
+{
+       return 0;
+}
+static int memcg_online_kmem(struct mem_cgroup *memcg)
+{
+       return 0;
+}
+static void memcg_offline_kmem(struct mem_cgroup *memcg)
+{
+}
+static void memcg_free_kmem(struct mem_cgroup *memcg)
+{
+}
+#endif /* !CONFIG_SLOB */
+
 static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
                                   unsigned long limit)
 {
-       return -EINVAL;
+       int ret = 0;
+
+       mutex_lock(&memcg_limit_mutex);
+       /* Top-level cgroup doesn't propagate from root */
+       if (!memcg_kmem_online(memcg)) {
+               if (cgroup_is_populated(memcg->css.cgroup) ||
+                   (memcg->use_hierarchy && memcg_has_children(memcg)))
+                       ret = -EBUSY;
+               if (ret)
+                       goto out;
+               ret = memcg_online_kmem(memcg);
+               if (ret)
+                       goto out;
+       }
+       ret = page_counter_limit(&memcg->kmem, limit);
+out:
+       mutex_unlock(&memcg_limit_mutex);
+       return ret;
+}
+
+static int memcg_update_tcp_limit(struct mem_cgroup *memcg, unsigned long limit)
+{
+       int ret;
+
+       mutex_lock(&memcg_limit_mutex);
+
+       ret = page_counter_limit(&memcg->tcpmem, limit);
+       if (ret)
+               goto out;
+
+       if (!memcg->tcpmem_active) {
+               /*
+                * The active flag needs to be written after the static_key
+                * update. This is what guarantees that the socket activation
+                * function is the last one to run. See sock_update_memcg() for
+                * details, and note that we don't mark any socket as belonging
+                * to this memcg until that flag is up.
+                *
+                * We need to do this, because static_keys will span multiple
+                * sites, but we can't control their order. If we mark a socket
+                * as accounted, but the accounting functions are not patched in
+                * yet, we'll lose accounting.
+                *
+                * We never race with the readers in sock_update_memcg(),
+                * because when this value change, the code to process it is not
+                * patched in yet.
+                */
+               static_branch_inc(&memcg_sockets_enabled_key);
+               memcg->tcpmem_active = true;
+       }
+out:
+       mutex_unlock(&memcg_limit_mutex);
+       return ret;
 }
-#endif /* CONFIG_MEMCG_KMEM */
 
 /*
  * The user of this function is...
@@ -2990,6 +3055,9 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of,
                case _KMEM:
                        ret = memcg_update_kmem_limit(memcg, nr_pages);
                        break;
+               case _TCP:
+                       ret = memcg_update_tcp_limit(memcg, nr_pages);
+                       break;
                }
                break;
        case RES_SOFT_LIMIT:
@@ -3016,6 +3084,9 @@ static ssize_t mem_cgroup_reset(struct kernfs_open_file *of, char *buf,
        case _KMEM:
                counter = &memcg->kmem;
                break;
+       case _TCP:
+               counter = &memcg->tcpmem;
+               break;
        default:
                BUG();
        }
@@ -3582,88 +3653,6 @@ static int mem_cgroup_oom_control_write(struct cgroup_subsys_state *css,
        return 0;
 }
 
-#ifdef CONFIG_MEMCG_KMEM
-static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
-{
-       int ret;
-
-       ret = memcg_propagate_kmem(memcg);
-       if (ret)
-               return ret;
-
-       return tcp_init_cgroup(memcg, ss);
-}
-
-static void memcg_deactivate_kmem(struct mem_cgroup *memcg)
-{
-       struct cgroup_subsys_state *css;
-       struct mem_cgroup *parent, *child;
-       int kmemcg_id;
-
-       if (!memcg->kmem_acct_active)
-               return;
-
-       /*
-        * Clear the 'active' flag before clearing memcg_caches arrays entries.
-        * Since we take the slab_mutex in memcg_deactivate_kmem_caches(), it
-        * guarantees no cache will be created for this cgroup after we are
-        * done (see memcg_create_kmem_cache()).
-        */
-       memcg->kmem_acct_active = false;
-
-       memcg_deactivate_kmem_caches(memcg);
-
-       kmemcg_id = memcg->kmemcg_id;
-       BUG_ON(kmemcg_id < 0);
-
-       parent = parent_mem_cgroup(memcg);
-       if (!parent)
-               parent = root_mem_cgroup;
-
-       /*
-        * Change kmemcg_id of this cgroup and all its descendants to the
-        * parent's id, and then move all entries from this cgroup's list_lrus
-        * to ones of the parent. After we have finished, all list_lrus
-        * corresponding to this cgroup are guaranteed to remain empty. The
-        * ordering is imposed by list_lru_node->lock taken by
-        * memcg_drain_all_list_lrus().
-        */
-       css_for_each_descendant_pre(css, &memcg->css) {
-               child = mem_cgroup_from_css(css);
-               BUG_ON(child->kmemcg_id != kmemcg_id);
-               child->kmemcg_id = parent->kmemcg_id;
-               if (!memcg->use_hierarchy)
-                       break;
-       }
-       memcg_drain_all_list_lrus(kmemcg_id, parent->kmemcg_id);
-
-       memcg_free_cache_id(kmemcg_id);
-}
-
-static void memcg_destroy_kmem(struct mem_cgroup *memcg)
-{
-       if (memcg->kmem_acct_activated) {
-               memcg_destroy_kmem_caches(memcg);
-               static_branch_dec(&memcg_kmem_enabled_key);
-               WARN_ON(page_counter_read(&memcg->kmem));
-       }
-       tcp_destroy_cgroup(memcg);
-}
-#else
-static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
-{
-       return 0;
-}
-
-static void memcg_deactivate_kmem(struct mem_cgroup *memcg)
-{
-}
-
-static void memcg_destroy_kmem(struct mem_cgroup *memcg)
-{
-}
-#endif
-
 #ifdef CONFIG_CGROUP_WRITEBACK
 
 struct list_head *mem_cgroup_cgwb_list(struct mem_cgroup *memcg)
@@ -4051,7 +4040,6 @@ static struct cftype mem_cgroup_legacy_files[] = {
                .seq_show = memcg_numa_stat_show,
        },
 #endif
-#ifdef CONFIG_MEMCG_KMEM
        {
                .name = "kmem.limit_in_bytes",
                .private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT),
@@ -4084,7 +4072,29 @@ static struct cftype mem_cgroup_legacy_files[] = {
                .seq_show = memcg_slab_show,
        },
 #endif
-#endif
+       {
+               .name = "kmem.tcp.limit_in_bytes",
+               .private = MEMFILE_PRIVATE(_TCP, RES_LIMIT),
+               .write = mem_cgroup_write,
+               .read_u64 = mem_cgroup_read_u64,
+       },
+       {
+               .name = "kmem.tcp.usage_in_bytes",
+               .private = MEMFILE_PRIVATE(_TCP, RES_USAGE),
+               .read_u64 = mem_cgroup_read_u64,
+       },
+       {
+               .name = "kmem.tcp.failcnt",
+               .private = MEMFILE_PRIVATE(_TCP, RES_FAILCNT),
+               .write = mem_cgroup_reset,
+               .read_u64 = mem_cgroup_read_u64,
+       },
+       {
+               .name = "kmem.tcp.max_usage_in_bytes",
+               .private = MEMFILE_PRIVATE(_TCP, RES_MAX_USAGE),
+               .write = mem_cgroup_reset,
+               .read_u64 = mem_cgroup_read_u64,
+       },
        { },    /* terminate */
 };
 
@@ -4123,147 +4133,92 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
        kfree(memcg->nodeinfo[node]);
 }
 
-static struct mem_cgroup *mem_cgroup_alloc(void)
-{
-       struct mem_cgroup *memcg;
-       size_t size;
-
-       size = sizeof(struct mem_cgroup);
-       size += nr_node_ids * sizeof(struct mem_cgroup_per_node *);
-
-       memcg = kzalloc(size, GFP_KERNEL);
-       if (!memcg)
-               return NULL;
-
-       memcg->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
-       if (!memcg->stat)
-               goto out_free;
-
-       if (memcg_wb_domain_init(memcg, GFP_KERNEL))
-               goto out_free_stat;
-
-       return memcg;
-
-out_free_stat:
-       free_percpu(memcg->stat);
-out_free:
-       kfree(memcg);
-       return NULL;
-}
-
-/*
- * At destroying mem_cgroup, references from swap_cgroup can remain.
- * (scanning all at force_empty is too costly...)
- *
- * Instead of clearing all references at force_empty, we remember
- * the number of reference from swap_cgroup and free mem_cgroup when
- * it goes down to 0.
- *
- * Removal of cgroup itself succeeds regardless of refs from swap.
- */
-
-static void __mem_cgroup_free(struct mem_cgroup *memcg)
+static void mem_cgroup_free(struct mem_cgroup *memcg)
 {
        int node;
 
-       cancel_work_sync(&memcg->high_work);
-
-       mem_cgroup_remove_from_trees(memcg);
-
+       memcg_wb_domain_exit(memcg);
        for_each_node(node)
                free_mem_cgroup_per_zone_info(memcg, node);
-
        free_percpu(memcg->stat);
-       memcg_wb_domain_exit(memcg);
        kfree(memcg);
 }
 
-static struct cgroup_subsys_state * __ref
-mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
+static struct mem_cgroup *mem_cgroup_alloc(void)
 {
        struct mem_cgroup *memcg;
-       long error = -ENOMEM;
+       size_t size;
        int node;
 
-       memcg = mem_cgroup_alloc();
+       size = sizeof(struct mem_cgroup);
+       size += nr_node_ids * sizeof(struct mem_cgroup_per_node *);
+
+       memcg = kzalloc(size, GFP_KERNEL);
        if (!memcg)
-               return ERR_PTR(error);
+               return NULL;
+
+       memcg->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
+       if (!memcg->stat)
+               goto fail;
 
        for_each_node(node)
                if (alloc_mem_cgroup_per_zone_info(memcg, node))
-                       goto free_out;
+                       goto fail;
 
-       /* root ? */
-       if (parent_css == NULL) {
-               root_mem_cgroup = memcg;
-               page_counter_init(&memcg->memory, NULL);
-               memcg->high = PAGE_COUNTER_MAX;
-               memcg->soft_limit = PAGE_COUNTER_MAX;
-               page_counter_init(&memcg->memsw, NULL);
-               page_counter_init(&memcg->kmem, NULL);
-       }
+       if (memcg_wb_domain_init(memcg, GFP_KERNEL))
+               goto fail;
 
        INIT_WORK(&memcg->high_work, high_work_func);
        memcg->last_scanned_node = MAX_NUMNODES;
        INIT_LIST_HEAD(&memcg->oom_notify);
-       memcg->move_charge_at_immigrate = 0;
        mutex_init(&memcg->thresholds_lock);
        spin_lock_init(&memcg->move_lock);
        vmpressure_init(&memcg->vmpressure);
        INIT_LIST_HEAD(&memcg->event_list);
        spin_lock_init(&memcg->event_list_lock);
-#ifdef CONFIG_MEMCG_KMEM
+       memcg->socket_pressure = jiffies;
+#ifndef CONFIG_SLOB
        memcg->kmemcg_id = -1;
 #endif
 #ifdef CONFIG_CGROUP_WRITEBACK
        INIT_LIST_HEAD(&memcg->cgwb_list);
 #endif
-#ifdef CONFIG_INET
-       memcg->socket_pressure = jiffies;
-#endif
-       return &memcg->css;
-
-free_out:
-       __mem_cgroup_free(memcg);
-       return ERR_PTR(error);
+       return memcg;
+fail:
+       mem_cgroup_free(memcg);
+       return NULL;
 }
 
-static int
-mem_cgroup_css_online(struct cgroup_subsys_state *css)
+static struct cgroup_subsys_state * __ref
+mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
 {
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-       struct mem_cgroup *parent = mem_cgroup_from_css(css->parent);
-       int ret;
-
-       if (css->id > MEM_CGROUP_ID_MAX)
-               return -ENOSPC;
-
-       if (!parent)
-               return 0;
-
-       mutex_lock(&memcg_create_mutex);
+       struct mem_cgroup *parent = mem_cgroup_from_css(parent_css);
+       struct mem_cgroup *memcg;
+       long error = -ENOMEM;
 
-       memcg->use_hierarchy = parent->use_hierarchy;
-       memcg->oom_kill_disable = parent->oom_kill_disable;
-       memcg->swappiness = mem_cgroup_swappiness(parent);
+       memcg = mem_cgroup_alloc();
+       if (!memcg)
+               return ERR_PTR(error);
 
-       if (parent->use_hierarchy) {
+       memcg->high = PAGE_COUNTER_MAX;
+       memcg->soft_limit = PAGE_COUNTER_MAX;
+       if (parent) {
+               memcg->swappiness = mem_cgroup_swappiness(parent);
+               memcg->oom_kill_disable = parent->oom_kill_disable;
+       }
+       if (parent && parent->use_hierarchy) {
+               memcg->use_hierarchy = true;
                page_counter_init(&memcg->memory, &parent->memory);
-               memcg->high = PAGE_COUNTER_MAX;
-               memcg->soft_limit = PAGE_COUNTER_MAX;
+               page_counter_init(&memcg->swap, &parent->swap);
                page_counter_init(&memcg->memsw, &parent->memsw);
                page_counter_init(&memcg->kmem, &parent->kmem);
-
-               /*
-                * No need to take a reference to the parent because cgroup
-                * core guarantees its existence.
-                */
+               page_counter_init(&memcg->tcpmem, &parent->tcpmem);
        } else {
                page_counter_init(&memcg->memory, NULL);
-               memcg->high = PAGE_COUNTER_MAX;
-               memcg->soft_limit = PAGE_COUNTER_MAX;
+               page_counter_init(&memcg->swap, NULL);
                page_counter_init(&memcg->memsw, NULL);
                page_counter_init(&memcg->kmem, NULL);
+               page_counter_init(&memcg->tcpmem, NULL);
                /*
                 * Deeper hierachy with use_hierarchy == false doesn't make
                 * much sense so let cgroup subsystem know about this
@@ -4272,23 +4227,31 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css)
                if (parent != root_mem_cgroup)
                        memory_cgrp_subsys.broken_hierarchy = true;
        }
-       mutex_unlock(&memcg_create_mutex);
 
-       ret = memcg_init_kmem(memcg, &memory_cgrp_subsys);
-       if (ret)
-               return ret;
+       /* The following stuff does not apply to the root */
+       if (!parent) {
+               root_mem_cgroup = memcg;
+               return &memcg->css;
+       }
+
+       error = memcg_propagate_kmem(parent, memcg);
+       if (error)
+               goto fail;
 
-#ifdef CONFIG_INET
        if (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nosocket)
                static_branch_inc(&memcg_sockets_enabled_key);
-#endif
 
-       /*
-        * Make sure the memcg is initialized: mem_cgroup_iter()
-        * orders reading memcg->initialized against its callers
-        * reading the memcg members.
-        */
-       smp_store_release(&memcg->initialized, 1);
+       return &memcg->css;
+fail:
+       mem_cgroup_free(memcg);
+       return NULL;
+}
+
+static int
+mem_cgroup_css_online(struct cgroup_subsys_state *css)
+{
+       if (css->id > MEM_CGROUP_ID_MAX)
+               return -ENOSPC;
 
        return 0;
 }
@@ -4310,10 +4273,7 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
        }
        spin_unlock(&memcg->event_list_lock);
 
-       vmpressure_cleanup(&memcg->vmpressure);
-
-       memcg_deactivate_kmem(memcg);
-
+       memcg_offline_kmem(memcg);
        wb_memcg_offline(memcg);
 }
 
@@ -4328,12 +4288,17 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 
-       memcg_destroy_kmem(memcg);
-#ifdef CONFIG_INET
        if (cgroup_subsys_on_dfl(memory_cgrp_subsys) && !cgroup_memory_nosocket)
                static_branch_dec(&memcg_sockets_enabled_key);
-#endif
-       __mem_cgroup_free(memcg);
+
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_active)
+               static_branch_dec(&memcg_sockets_enabled_key);
+
+       vmpressure_cleanup(&memcg->vmpressure);
+       cancel_work_sync(&memcg->high_work);
+       mem_cgroup_remove_from_trees(memcg);
+       memcg_free_kmem(memcg);
+       mem_cgroup_free(memcg);
 }
 
 /**
@@ -4673,7 +4638,8 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd,
        pte_t *pte;
        spinlock_t *ptl;
 
-       if (pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                if (get_mctgt_type_thp(vma, addr, *pmd, NULL) == MC_TARGET_PAGE)
                        mc.precharge += HPAGE_PMD_NR;
                spin_unlock(ptl);
@@ -4861,7 +4827,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
        union mc_target target;
        struct page *page;
 
-       if (pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                if (mc.precharge < HPAGE_PMD_NR) {
                        spin_unlock(ptl);
                        return 0;
@@ -5143,6 +5110,59 @@ static int memory_events_show(struct seq_file *m, void *v)
        return 0;
 }
 
+static int memory_stat_show(struct seq_file *m, void *v)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
+       int i;
+
+       /*
+        * Provide statistics on the state of the memory subsystem as
+        * well as cumulative event counters that show past behavior.
+        *
+        * This list is ordered following a combination of these gradients:
+        * 1) generic big picture -> specifics and details
+        * 2) reflecting userspace activity -> reflecting kernel heuristics
+        *
+        * Current memory state:
+        */
+
+       seq_printf(m, "anon %llu\n",
+                  (u64)tree_stat(memcg, MEM_CGROUP_STAT_RSS) * PAGE_SIZE);
+       seq_printf(m, "file %llu\n",
+                  (u64)tree_stat(memcg, MEM_CGROUP_STAT_CACHE) * PAGE_SIZE);
+       seq_printf(m, "sock %llu\n",
+                  (u64)tree_stat(memcg, MEMCG_SOCK) * PAGE_SIZE);
+
+       seq_printf(m, "file_mapped %llu\n",
+                  (u64)tree_stat(memcg, MEM_CGROUP_STAT_FILE_MAPPED) *
+                  PAGE_SIZE);
+       seq_printf(m, "file_dirty %llu\n",
+                  (u64)tree_stat(memcg, MEM_CGROUP_STAT_DIRTY) *
+                  PAGE_SIZE);
+       seq_printf(m, "file_writeback %llu\n",
+                  (u64)tree_stat(memcg, MEM_CGROUP_STAT_WRITEBACK) *
+                  PAGE_SIZE);
+
+       for (i = 0; i < NR_LRU_LISTS; i++) {
+               struct mem_cgroup *mi;
+               unsigned long val = 0;
+
+               for_each_mem_cgroup_tree(mi, memcg)
+                       val += mem_cgroup_nr_lru_pages(mi, BIT(i));
+               seq_printf(m, "%s %llu\n",
+                          mem_cgroup_lru_names[i], (u64)val * PAGE_SIZE);
+       }
+
+       /* Accumulated memory events */
+
+       seq_printf(m, "pgfault %lu\n",
+                  tree_events(memcg, MEM_CGROUP_EVENTS_PGFAULT));
+       seq_printf(m, "pgmajfault %lu\n",
+                  tree_events(memcg, MEM_CGROUP_EVENTS_PGMAJFAULT));
+
+       return 0;
+}
+
 static struct cftype memory_files[] = {
        {
                .name = "current",
@@ -5173,6 +5193,11 @@ static struct cftype memory_files[] = {
                .file_offset = offsetof(struct mem_cgroup, events_file),
                .seq_show = memory_events_show,
        },
+       {
+               .name = "stat",
+               .flags = CFTYPE_NOT_ON_ROOT,
+               .seq_show = memory_stat_show,
+       },
        { }     /* terminate */
 };
 
@@ -5269,7 +5294,7 @@ int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm,
                if (page->mem_cgroup)
                        goto out;
 
-               if (do_memsw_account()) {
+               if (do_swap_account) {
                        swp_entry_t ent = { .val = page_private(page), };
                        unsigned short id = lookup_swap_cgroup_id(ent);
 
@@ -5504,7 +5529,8 @@ void mem_cgroup_uncharge_list(struct list_head *page_list)
 void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
 {
        struct mem_cgroup *memcg;
-       int isolated;
+       unsigned int nr_pages;
+       bool compound;
 
        VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage);
        VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
@@ -5524,14 +5550,22 @@ void mem_cgroup_replace_page(struct page *oldpage, struct page *newpage)
        if (!memcg)
                return;
 
-       lock_page_lru(oldpage, &isolated);
-       oldpage->mem_cgroup = NULL;
-       unlock_page_lru(oldpage, isolated);
+       /* Force-charge the new page. The old one will be freed soon */
+       compound = PageTransHuge(newpage);
+       nr_pages = compound ? hpage_nr_pages(newpage) : 1;
+
+       page_counter_charge(&memcg->memory, nr_pages);
+       if (do_memsw_account())
+               page_counter_charge(&memcg->memsw, nr_pages);
+       css_get_many(&memcg->css, nr_pages);
 
        commit_charge(newpage, memcg, true);
-}
 
-#ifdef CONFIG_INET
+       local_irq_disable();
+       mem_cgroup_charge_statistics(memcg, newpage, compound, nr_pages);
+       memcg_check_events(memcg, newpage);
+       local_irq_enable();
+}
 
 DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key);
 EXPORT_SYMBOL(memcg_sockets_enabled_key);
@@ -5558,10 +5592,8 @@ void sock_update_memcg(struct sock *sk)
        memcg = mem_cgroup_from_task(current);
        if (memcg == root_mem_cgroup)
                goto out;
-#ifdef CONFIG_MEMCG_KMEM
-       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && !memcg->tcp_mem.active)
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && !memcg->tcpmem_active)
                goto out;
-#endif
        if (css_tryget_online(&memcg->css))
                sk->sk_memcg = memcg;
 out:
@@ -5587,24 +5619,24 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
 {
        gfp_t gfp_mask = GFP_KERNEL;
 
-#ifdef CONFIG_MEMCG_KMEM
        if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) {
-               struct page_counter *counter;
+               struct page_counter *fail;
 
-               if (page_counter_try_charge(&memcg->tcp_mem.memory_allocated,
-                                           nr_pages, &counter)) {
-                       memcg->tcp_mem.memory_pressure = 0;
+               if (page_counter_try_charge(&memcg->tcpmem, nr_pages, &fail)) {
+                       memcg->tcpmem_pressure = 0;
                        return true;
                }
-               page_counter_charge(&memcg->tcp_mem.memory_allocated, nr_pages);
-               memcg->tcp_mem.memory_pressure = 1;
+               page_counter_charge(&memcg->tcpmem, nr_pages);
+               memcg->tcpmem_pressure = 1;
                return false;
        }
-#endif
+
        /* Don't block in the packet receive path */
        if (in_softirq())
                gfp_mask = GFP_NOWAIT;
 
+       this_cpu_add(memcg->stat->count[MEMCG_SOCK], nr_pages);
+
        if (try_charge(memcg, gfp_mask, nr_pages) == 0)
                return true;
 
@@ -5619,19 +5651,17 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
  */
 void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
 {
-#ifdef CONFIG_MEMCG_KMEM
        if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) {
-               page_counter_uncharge(&memcg->tcp_mem.memory_allocated,
-                                     nr_pages);
+               page_counter_uncharge(&memcg->tcpmem, nr_pages);
                return;
        }
-#endif
+
+       this_cpu_sub(memcg->stat->count[MEMCG_SOCK], nr_pages);
+
        page_counter_uncharge(&memcg->memory, nr_pages);
        css_put_many(&memcg->css, nr_pages);
 }
 
-#endif /* CONFIG_INET */
-
 static int __init cgroup_memory(char *s)
 {
        char *token;
@@ -5641,6 +5671,8 @@ static int __init cgroup_memory(char *s)
                        continue;
                if (!strcmp(token, "nosocket"))
                        cgroup_memory_nosocket = true;
+               if (!strcmp(token, "nokmem"))
+                       cgroup_memory_nokmem = true;
        }
        return 0;
 }
@@ -5730,32 +5762,107 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
        memcg_check_events(memcg, page);
 }
 
+/*
+ * mem_cgroup_try_charge_swap - try charging a swap entry
+ * @page: page being added to swap
+ * @entry: swap entry to charge
+ *
+ * Try to charge @entry to the memcg that @page belongs to.
+ *
+ * Returns 0 on success, -ENOMEM on failure.
+ */
+int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
+{
+       struct mem_cgroup *memcg;
+       struct page_counter *counter;
+       unsigned short oldid;
+
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) || !do_swap_account)
+               return 0;
+
+       memcg = page->mem_cgroup;
+
+       /* Readahead page, never charged */
+       if (!memcg)
+               return 0;
+
+       if (!mem_cgroup_is_root(memcg) &&
+           !page_counter_try_charge(&memcg->swap, 1, &counter))
+               return -ENOMEM;
+
+       oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
+       VM_BUG_ON_PAGE(oldid, page);
+       mem_cgroup_swap_statistics(memcg, true);
+
+       css_get(&memcg->css);
+       return 0;
+}
+
 /**
  * mem_cgroup_uncharge_swap - uncharge a swap entry
  * @entry: swap entry to uncharge
  *
- * Drop the memsw charge associated with @entry.
+ * Drop the swap charge associated with @entry.
  */
 void mem_cgroup_uncharge_swap(swp_entry_t entry)
 {
        struct mem_cgroup *memcg;
        unsigned short id;
 
-       if (!do_memsw_account())
+       if (!do_swap_account)
                return;
 
        id = swap_cgroup_record(entry, 0);
        rcu_read_lock();
        memcg = mem_cgroup_from_id(id);
        if (memcg) {
-               if (!mem_cgroup_is_root(memcg))
-                       page_counter_uncharge(&memcg->memsw, 1);
+               if (!mem_cgroup_is_root(memcg)) {
+                       if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
+                               page_counter_uncharge(&memcg->swap, 1);
+                       else
+                               page_counter_uncharge(&memcg->memsw, 1);
+               }
                mem_cgroup_swap_statistics(memcg, false);
                css_put(&memcg->css);
        }
        rcu_read_unlock();
 }
 
+long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg)
+{
+       long nr_swap_pages = get_nr_swap_pages();
+
+       if (!do_swap_account || !cgroup_subsys_on_dfl(memory_cgrp_subsys))
+               return nr_swap_pages;
+       for (; memcg != root_mem_cgroup; memcg = parent_mem_cgroup(memcg))
+               nr_swap_pages = min_t(long, nr_swap_pages,
+                                     READ_ONCE(memcg->swap.limit) -
+                                     page_counter_read(&memcg->swap));
+       return nr_swap_pages;
+}
+
+bool mem_cgroup_swap_full(struct page *page)
+{
+       struct mem_cgroup *memcg;
+
+       VM_BUG_ON_PAGE(!PageLocked(page), page);
+
+       if (vm_swap_full())
+               return true;
+       if (!do_swap_account || !cgroup_subsys_on_dfl(memory_cgrp_subsys))
+               return false;
+
+       memcg = page->mem_cgroup;
+       if (!memcg)
+               return false;
+
+       for (; memcg != root_mem_cgroup; memcg = parent_mem_cgroup(memcg))
+               if (page_counter_read(&memcg->swap) * 2 >= memcg->swap.limit)
+                       return true;
+
+       return false;
+}
+
 /* for remember boot option*/
 #ifdef CONFIG_MEMCG_SWAP_ENABLED
 static int really_do_swap_account __initdata = 1;
@@ -5773,6 +5880,63 @@ static int __init enable_swap_account(char *s)
 }
 __setup("swapaccount=", enable_swap_account);
 
+static u64 swap_current_read(struct cgroup_subsys_state *css,
+                            struct cftype *cft)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+
+       return (u64)page_counter_read(&memcg->swap) * PAGE_SIZE;
+}
+
+static int swap_max_show(struct seq_file *m, void *v)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
+       unsigned long max = READ_ONCE(memcg->swap.limit);
+
+       if (max == PAGE_COUNTER_MAX)
+               seq_puts(m, "max\n");
+       else
+               seq_printf(m, "%llu\n", (u64)max * PAGE_SIZE);
+
+       return 0;
+}
+
+static ssize_t swap_max_write(struct kernfs_open_file *of,
+                             char *buf, size_t nbytes, loff_t off)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+       unsigned long max;
+       int err;
+
+       buf = strstrip(buf);
+       err = page_counter_memparse(buf, "max", &max);
+       if (err)
+               return err;
+
+       mutex_lock(&memcg_limit_mutex);
+       err = page_counter_limit(&memcg->swap, max);
+       mutex_unlock(&memcg_limit_mutex);
+       if (err)
+               return err;
+
+       return nbytes;
+}
+
+static struct cftype swap_files[] = {
+       {
+               .name = "swap.current",
+               .flags = CFTYPE_NOT_ON_ROOT,
+               .read_u64 = swap_current_read,
+       },
+       {
+               .name = "swap.max",
+               .flags = CFTYPE_NOT_ON_ROOT,
+               .seq_show = swap_max_show,
+               .write = swap_max_write,
+       },
+       { }     /* terminate */
+};
+
 static struct cftype memsw_cgroup_files[] = {
        {
                .name = "memsw.usage_in_bytes",
@@ -5804,6 +5968,8 @@ static int __init mem_cgroup_swap_init(void)
 {
        if (!mem_cgroup_disabled() && really_do_swap_account) {
                do_swap_account = 1;
+               WARN_ON(cgroup_add_dfl_cftypes(&memory_cgrp_subsys,
+                                              swap_files));
                WARN_ON(cgroup_add_legacy_cftypes(&memory_cgrp_subsys,
                                                  memsw_cgroup_files));
        }
index ff17850..30991f8 100644 (file)
@@ -2582,7 +2582,8 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
        }
 
        swap_free(entry);
-       if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
+       if (mem_cgroup_swap_full(page) ||
+           (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
                try_to_free_swap(page);
        unlock_page(page);
        if (page != swapcache) {
index 2a565ed..563f320 100644 (file)
@@ -117,7 +117,8 @@ static int mincore_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
        unsigned char *vec = walk->private;
        int nr = (end - addr) >> PAGE_SHIFT;
 
-       if (pmd_trans_huge_lock(pmd, vma, &ptl)) {
+       ptl = pmd_trans_huge_lock(pmd, vma);
+       if (ptl) {
                memset(vec, 1, nr);
                spin_unlock(ptl);
                goto out;
index e1e2b12..96f0010 100644 (file)
@@ -175,7 +175,7 @@ static void __munlock_isolation_failed(struct page *page)
  */
 unsigned int munlock_vma_page(struct page *page)
 {
-       unsigned int nr_pages;
+       int nr_pages;
        struct zone *zone = page_zone(page);
 
        /* For try_to_munlock() and to serialize with page migration */
index 8a943b9..998607a 100644 (file)
@@ -305,16 +305,12 @@ static void *pcpu_mem_zalloc(size_t size)
 /**
  * pcpu_mem_free - free memory
  * @ptr: memory to free
- * @size: size of the area
  *
  * Free @ptr.  @ptr should have been allocated using pcpu_mem_zalloc().
  */
-static void pcpu_mem_free(void *ptr, size_t size)
+static void pcpu_mem_free(void *ptr)
 {
-       if (size <= PAGE_SIZE)
-               kfree(ptr);
-       else
-               vfree(ptr);
+       kvfree(ptr);
 }
 
 /**
@@ -463,8 +459,8 @@ out_unlock:
         * pcpu_mem_free() might end up calling vfree() which uses
         * IRQ-unsafe lock and thus can't be called under pcpu_lock.
         */
-       pcpu_mem_free(old, old_size);
-       pcpu_mem_free(new, new_size);
+       pcpu_mem_free(old);
+       pcpu_mem_free(new);
 
        return 0;
 }
@@ -732,7 +728,7 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void)
        chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC *
                                                sizeof(chunk->map[0]));
        if (!chunk->map) {
-               pcpu_mem_free(chunk, pcpu_chunk_struct_size);
+               pcpu_mem_free(chunk);
                return NULL;
        }
 
@@ -753,8 +749,8 @@ static void pcpu_free_chunk(struct pcpu_chunk *chunk)
 {
        if (!chunk)
                return;
-       pcpu_mem_free(chunk->map, chunk->map_alloc * sizeof(chunk->map[0]));
-       pcpu_mem_free(chunk, pcpu_chunk_struct_size);
+       pcpu_mem_free(chunk->map);
+       pcpu_mem_free(chunk);
 }
 
 /**
index e88d071..5d453e5 100644 (file)
@@ -194,7 +194,7 @@ static ssize_t process_vm_rw_core(pid_t pid, struct iov_iter *iter,
                goto free_proc_pages;
        }
 
-       mm = mm_access(task, PTRACE_MODE_ATTACH);
+       mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS);
        if (!mm || IS_ERR(mm)) {
                rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
                /*
index b98e101..440e2a7 100644 (file)
@@ -701,8 +701,7 @@ static void shmem_evict_inode(struct inode *inode)
                        list_del_init(&info->swaplist);
                        mutex_unlock(&shmem_swaplist_mutex);
                }
-       } else
-               kfree(info->symlink);
+       }
 
        simple_xattrs_free(&info->xattrs);
        WARN_ON(inode->i_blocks);
@@ -912,6 +911,9 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
        if (!swap.val)
                goto redirty;
 
+       if (mem_cgroup_try_charge_swap(page, swap))
+               goto free_swap;
+
        /*
         * Add inode to shmem_unuse()'s list of swapped-out inodes,
         * if it's not already there.  Do it now before the page is
@@ -940,6 +942,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
        }
 
        mutex_unlock(&shmem_swaplist_mutex);
+free_swap:
        swapcache_free(swap);
 redirty:
        set_page_dirty(page);
@@ -1898,7 +1901,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
        if (whence != SEEK_DATA && whence != SEEK_HOLE)
                return generic_file_llseek_size(file, offset, whence,
                                        MAX_LFS_FILESIZE, i_size_read(inode));
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        /* We're holding i_mutex so we can access i_size directly */
 
        if (offset < 0)
@@ -1922,7 +1925,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
 
        if (offset >= 0)
                offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return offset;
 }
 
@@ -2087,7 +2090,7 @@ int shmem_add_seals(struct file *file, unsigned int seals)
        if (seals & ~(unsigned int)F_ALL_SEALS)
                return -EINVAL;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (info->seals & F_SEAL_SEAL) {
                error = -EPERM;
@@ -2110,7 +2113,7 @@ int shmem_add_seals(struct file *file, unsigned int seals)
        error = 0;
 
 unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return error;
 }
 EXPORT_SYMBOL_GPL(shmem_add_seals);
@@ -2160,7 +2163,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
        if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
                return -EOPNOTSUPP;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (mode & FALLOC_FL_PUNCH_HOLE) {
                struct address_space *mapping = file->f_mapping;
@@ -2273,7 +2276,7 @@ undone:
        inode->i_private = NULL;
        spin_unlock(&inode->i_lock);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return error;
 }
 
@@ -2545,13 +2548,12 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
        info = SHMEM_I(inode);
        inode->i_size = len-1;
        if (len <= SHORT_SYMLINK_LEN) {
-               info->symlink = kmemdup(symname, len, GFP_KERNEL);
-               if (!info->symlink) {
+               inode->i_link = kmemdup(symname, len, GFP_KERNEL);
+               if (!inode->i_link) {
                        iput(inode);
                        return -ENOMEM;
                }
                inode->i_op = &shmem_short_symlink_operations;
-               inode->i_link = info->symlink;
        } else {
                inode_nohighmem(inode);
                error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
@@ -3128,6 +3130,7 @@ static struct inode *shmem_alloc_inode(struct super_block *sb)
 static void shmem_destroy_callback(struct rcu_head *head)
 {
        struct inode *inode = container_of(head, struct inode, i_rcu);
+       kfree(inode->i_link);
        kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
 }
 
index c63b869..834ad24 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -173,7 +173,7 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
 void __kmem_cache_free_bulk(struct kmem_cache *, size_t, void **);
 int __kmem_cache_alloc_bulk(struct kmem_cache *, gfp_t, size_t, void **);
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 /*
  * Iterate over all memcg caches of the given root cache. The caller must hold
  * slab_mutex.
@@ -251,7 +251,7 @@ static __always_inline int memcg_charge_slab(struct page *page,
 
 extern void slab_init_memcg_params(struct kmem_cache *);
 
-#else /* !CONFIG_MEMCG_KMEM */
+#else /* CONFIG_MEMCG && !CONFIG_SLOB */
 
 #define for_each_memcg_cache(iter, root) \
        for ((void)(iter), (void)(root); 0; )
@@ -292,7 +292,7 @@ static inline int memcg_charge_slab(struct page *page, gfp_t gfp, int order,
 static inline void slab_init_memcg_params(struct kmem_cache *s)
 {
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
 
 static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
 {
index e016178..b50aef0 100644 (file)
@@ -128,7 +128,7 @@ int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr,
        return i;
 }
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 void slab_init_memcg_params(struct kmem_cache *s)
 {
        s->memcg_params.is_root_cache = true;
@@ -221,7 +221,7 @@ static inline int init_memcg_params(struct kmem_cache *s,
 static inline void destroy_memcg_params(struct kmem_cache *s)
 {
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
 
 /*
  * Find a mergeable slab cache
@@ -477,7 +477,7 @@ static void release_caches(struct list_head *release, bool need_rcu_barrier)
        }
 }
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 /*
  * memcg_create_kmem_cache - Create a cache for a memory cgroup.
  * @memcg: The memory cgroup the new cache is for.
@@ -503,10 +503,10 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg,
        mutex_lock(&slab_mutex);
 
        /*
-        * The memory cgroup could have been deactivated while the cache
+        * The memory cgroup could have been offlined while the cache
         * creation work was pending.
         */
-       if (!memcg_kmem_is_active(memcg))
+       if (!memcg_kmem_online(memcg))
                goto out_unlock;
 
        idx = memcg_cache_id(memcg);
@@ -689,7 +689,7 @@ static inline int shutdown_memcg_caches(struct kmem_cache *s,
 {
        return 0;
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_MEMCG && !CONFIG_SLOB */
 
 void slab_kmem_cache_release(struct kmem_cache *s)
 {
@@ -1123,7 +1123,7 @@ static int slab_show(struct seq_file *m, void *p)
        return 0;
 }
 
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
 int memcg_slab_show(struct seq_file *m, void *p)
 {
        struct kmem_cache *s = list_entry(p, struct kmem_cache, list);
index b21fd24..2e1355a 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5207,7 +5207,7 @@ static ssize_t slab_attr_store(struct kobject *kobj,
                return -EIO;
 
        err = attribute->store(s, buf, len);
-#ifdef CONFIG_MEMCG_KMEM
+#ifdef CONFIG_MEMCG
        if (slab_state >= FULL && err >= 0 && is_root_cache(s)) {
                struct kmem_cache *c;
 
@@ -5242,7 +5242,7 @@ static ssize_t slab_attr_store(struct kobject *kobj,
 
 static void memcg_propagate_slab_attrs(struct kmem_cache *s)
 {
-#ifdef CONFIG_MEMCG_KMEM
+#ifdef CONFIG_MEMCG
        int i;
        char *buffer = NULL;
        struct kmem_cache *root_cache;
@@ -5328,7 +5328,7 @@ static struct kset *slab_kset;
 
 static inline struct kset *cache_kset(struct kmem_cache *s)
 {
-#ifdef CONFIG_MEMCG_KMEM
+#ifdef CONFIG_MEMCG
        if (!is_root_cache(s))
                return s->memcg_params.root_cache->memcg_kset;
 #endif
@@ -5405,7 +5405,7 @@ static int sysfs_slab_add(struct kmem_cache *s)
        if (err)
                goto out_del_kobj;
 
-#ifdef CONFIG_MEMCG_KMEM
+#ifdef CONFIG_MEMCG
        if (is_root_cache(s)) {
                s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj);
                if (!s->memcg_kset) {
@@ -5438,7 +5438,7 @@ void sysfs_slab_remove(struct kmem_cache *s)
                 */
                return;
 
-#ifdef CONFIG_MEMCG_KMEM
+#ifdef CONFIG_MEMCG
        kset_unregister(s->memcg_kset);
 #endif
        kobject_uevent(&s->kobj, KOBJ_REMOVE);
index 676ff29..69cb246 100644 (file)
@@ -170,6 +170,11 @@ int add_to_swap(struct page *page, struct list_head *list)
        if (!entry.val)
                return 0;
 
+       if (mem_cgroup_try_charge_swap(page, entry)) {
+               swapcache_free(entry);
+               return 0;
+       }
+
        if (unlikely(PageTransHuge(page)))
                if (unlikely(split_huge_page_to_list(page, list))) {
                        swapcache_free(entry);
index 2bb30aa..d2c3736 100644 (file)
@@ -785,14 +785,12 @@ static unsigned char swap_entry_free(struct swap_info_struct *p,
                        count--;
        }
 
-       if (!count)
-               mem_cgroup_uncharge_swap(entry);
-
        usage = count | has_cache;
        p->swap_map[offset] = usage;
 
        /* free if no reference */
        if (!usage) {
+               mem_cgroup_uncharge_swap(entry);
                dec_cluster_info_page(p, p->cluster_info, offset);
                if (offset < p->lowest_bit)
                        p->lowest_bit = offset;
@@ -1008,7 +1006,7 @@ int free_swap_and_cache(swp_entry_t entry)
                 * Also recheck PageSwapCache now page is locked (above).
                 */
                if (PageSwapCache(page) && !PageWriteback(page) &&
-                               (!page_mapped(page) || vm_swap_full())) {
+                   (!page_mapped(page) || mem_cgroup_swap_full(page))) {
                        delete_from_swap_cache(page);
                        SetPageDirty(page);
                }
@@ -1958,9 +1956,9 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
                set_blocksize(bdev, old_block_size);
                blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
        } else {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                inode->i_flags &= ~S_SWAPFILE;
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
        filp_close(swap_file, NULL);
 
@@ -2185,7 +2183,7 @@ static int claim_swapfile(struct swap_info_struct *p, struct inode *inode)
                p->flags |= SWP_BLKDEV;
        } else if (S_ISREG(inode->i_mode)) {
                p->bdev = inode->i_sb->s_bdev;
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                if (IS_SWAPFILE(inode))
                        return -EBUSY;
        } else
@@ -2418,7 +2416,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
        mapping = swap_file->f_mapping;
        inode = mapping->host;
 
-       /* If S_ISREG(inode->i_mode) will do mutex_lock(&inode->i_mutex); */
+       /* If S_ISREG(inode->i_mode) will do inode_lock(inode); */
        error = claim_swapfile(p, inode);
        if (unlikely(error))
                goto bad_swap;
@@ -2563,7 +2561,7 @@ bad_swap:
        vfree(cluster_info);
        if (swap_file) {
                if (inode && S_ISREG(inode->i_mode)) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        inode = NULL;
                }
                filp_close(swap_file, NULL);
@@ -2576,7 +2574,7 @@ out:
        if (name)
                putname(name);
        if (inode && S_ISREG(inode->i_mode))
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        return error;
 }
 
index 76e35ad..e3ee0e2 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/backing-dev.h>
+#include <linux/dax.h>
 #include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
@@ -34,31 +35,39 @@ static void clear_exceptional_entry(struct address_space *mapping,
                return;
 
        spin_lock_irq(&mapping->tree_lock);
-       /*
-        * Regular page slots are stabilized by the page lock even
-        * without the tree itself locked.  These unlocked entries
-        * need verification under the tree lock.
-        */
-       if (!__radix_tree_lookup(&mapping->page_tree, index, &node, &slot))
-               goto unlock;
-       if (*slot != entry)
-               goto unlock;
-       radix_tree_replace_slot(slot, NULL);
-       mapping->nrshadows--;
-       if (!node)
-               goto unlock;
-       workingset_node_shadows_dec(node);
-       /*
-        * Don't track node without shadow entries.
-        *
-        * Avoid acquiring the list_lru lock if already untracked.
-        * The list_empty() test is safe as node->private_list is
-        * protected by mapping->tree_lock.
-        */
-       if (!workingset_node_shadows(node) &&
-           !list_empty(&node->private_list))
-               list_lru_del(&workingset_shadow_nodes, &node->private_list);
-       __radix_tree_delete_node(&mapping->page_tree, node);
+
+       if (dax_mapping(mapping)) {
+               if (radix_tree_delete_item(&mapping->page_tree, index, entry))
+                       mapping->nrexceptional--;
+       } else {
+               /*
+                * Regular page slots are stabilized by the page lock even
+                * without the tree itself locked.  These unlocked entries
+                * need verification under the tree lock.
+                */
+               if (!__radix_tree_lookup(&mapping->page_tree, index, &node,
+                                       &slot))
+                       goto unlock;
+               if (*slot != entry)
+                       goto unlock;
+               radix_tree_replace_slot(slot, NULL);
+               mapping->nrexceptional--;
+               if (!node)
+                       goto unlock;
+               workingset_node_shadows_dec(node);
+               /*
+                * Don't track node without shadow entries.
+                *
+                * Avoid acquiring the list_lru lock if already untracked.
+                * The list_empty() test is safe as node->private_list is
+                * protected by mapping->tree_lock.
+                */
+               if (!workingset_node_shadows(node) &&
+                   !list_empty(&node->private_list))
+                       list_lru_del(&workingset_shadow_nodes,
+                                       &node->private_list);
+               __radix_tree_delete_node(&mapping->page_tree, node);
+       }
 unlock:
        spin_unlock_irq(&mapping->tree_lock);
 }
@@ -228,7 +237,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
        int             i;
 
        cleancache_invalidate_inode(mapping);
-       if (mapping->nrpages == 0 && mapping->nrshadows == 0)
+       if (mapping->nrpages == 0 && mapping->nrexceptional == 0)
                return;
 
        /* Offsets within partial pages */
@@ -402,7 +411,7 @@ EXPORT_SYMBOL(truncate_inode_pages);
  */
 void truncate_inode_pages_final(struct address_space *mapping)
 {
-       unsigned long nrshadows;
+       unsigned long nrexceptional;
        unsigned long nrpages;
 
        /*
@@ -416,14 +425,14 @@ void truncate_inode_pages_final(struct address_space *mapping)
 
        /*
         * When reclaim installs eviction entries, it increases
-        * nrshadows first, then decreases nrpages.  Make sure we see
+        * nrexceptional first, then decreases nrpages.  Make sure we see
         * this in the right order or we might miss an entry.
         */
        nrpages = mapping->nrpages;
        smp_rmb();
-       nrshadows = mapping->nrshadows;
+       nrexceptional = mapping->nrexceptional;
 
-       if (nrpages || nrshadows) {
+       if (nrpages || nrexceptional) {
                /*
                 * As truncation uses a lockless tree lookup, cycle
                 * the tree lock to make sure any ongoing tree
index 6d1f920..c108a65 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -476,17 +476,25 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
        int res = 0;
        unsigned int len;
        struct mm_struct *mm = get_task_mm(task);
+       unsigned long arg_start, arg_end, env_start, env_end;
        if (!mm)
                goto out;
        if (!mm->arg_end)
                goto out_mm;    /* Shh! No looking before we're done */
 
-       len = mm->arg_end - mm->arg_start;
+       down_read(&mm->mmap_sem);
+       arg_start = mm->arg_start;
+       arg_end = mm->arg_end;
+       env_start = mm->env_start;
+       env_end = mm->env_end;
+       up_read(&mm->mmap_sem);
+
+       len = arg_end - arg_start;
 
        if (len > buflen)
                len = buflen;
 
-       res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+       res = access_process_vm(task, arg_start, buffer, len, 0);
 
        /*
         * If the nul at the end of args has been overwritten, then
@@ -497,10 +505,10 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
                if (len < res) {
                        res = len;
                } else {
-                       len = mm->env_end - mm->env_start;
+                       len = env_end - env_start;
                        if (len > buflen - res)
                                len = buflen - res;
-                       res += access_process_vm(task, mm->env_start,
+                       res += access_process_vm(task, env_start,
                                                 buffer+res, len, 0);
                        res = strnlen(buffer, res);
                }
index 5ac8695..eb3dd37 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/oom.h>
 #include <linux/prefetch.h>
 #include <linux/printk.h>
+#include <linux/dax.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -411,7 +412,7 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
        struct shrinker *shrinker;
        unsigned long freed = 0;
 
-       if (memcg && !memcg_kmem_is_active(memcg))
+       if (memcg && !memcg_kmem_online(memcg))
                return 0;
 
        if (nr_scanned == 0)
@@ -671,9 +672,15 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
                 * inode reclaim needs to empty out the radix tree or
                 * the nodes are lost.  Don't plant shadows behind its
                 * back.
+                *
+                * We also don't store shadows for DAX mappings because the
+                * only page cache pages found in these are zero pages
+                * covering holes, and because we don't want to mix DAX
+                * exceptional entries and shadow exceptional entries in the
+                * same page_tree.
                 */
                if (reclaimed && page_is_file_cache(page) &&
-                   !mapping_exiting(mapping))
+                   !mapping_exiting(mapping) && !dax_mapping(mapping))
                        shadow = workingset_eviction(mapping, page);
                __delete_from_page_cache(page, shadow, memcg);
                spin_unlock_irqrestore(&mapping->tree_lock, flags);
@@ -1214,7 +1221,7 @@ cull_mlocked:
 
 activate_locked:
                /* Not a candidate for swapping, so reclaim swap space. */
-               if (PageSwapCache(page) && vm_swap_full())
+               if (PageSwapCache(page) && mem_cgroup_swap_full(page))
                        try_to_free_swap(page);
                VM_BUG_ON_PAGE(PageActive(page), page);
                SetPageActive(page);
@@ -1966,10 +1973,11 @@ enum scan_balance {
  * nr[0] = anon inactive pages to scan; nr[1] = anon active pages to scan
  * nr[2] = file inactive pages to scan; nr[3] = file active pages to scan
  */
-static void get_scan_count(struct lruvec *lruvec, int swappiness,
+static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
                           struct scan_control *sc, unsigned long *nr,
                           unsigned long *lru_pages)
 {
+       int swappiness = mem_cgroup_swappiness(memcg);
        struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat;
        u64 fraction[2];
        u64 denominator = 0;    /* gcc */
@@ -1996,14 +2004,14 @@ static void get_scan_count(struct lruvec *lruvec, int swappiness,
        if (current_is_kswapd()) {
                if (!zone_reclaimable(zone))
                        force_scan = true;
-               if (!mem_cgroup_lruvec_online(lruvec))
+               if (!mem_cgroup_online(memcg))
                        force_scan = true;
        }
        if (!global_reclaim(sc))
                force_scan = true;
 
        /* If we have no swap space, do not bother scanning anon pages. */
-       if (!sc->may_swap || (get_nr_swap_pages() <= 0)) {
+       if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) {
                scan_balance = SCAN_FILE;
                goto out;
        }
@@ -2193,9 +2201,10 @@ static inline void init_tlb_ubc(void)
 /*
  * This is a basic per-zone page freer.  Used by both kswapd and direct reclaim.
  */
-static void shrink_lruvec(struct lruvec *lruvec, int swappiness,
-                         struct scan_control *sc, unsigned long *lru_pages)
+static void shrink_zone_memcg(struct zone *zone, struct mem_cgroup *memcg,
+                             struct scan_control *sc, unsigned long *lru_pages)
 {
+       struct lruvec *lruvec = mem_cgroup_zone_lruvec(zone, memcg);
        unsigned long nr[NR_LRU_LISTS];
        unsigned long targets[NR_LRU_LISTS];
        unsigned long nr_to_scan;
@@ -2205,7 +2214,7 @@ static void shrink_lruvec(struct lruvec *lruvec, int swappiness,
        struct blk_plug plug;
        bool scan_adjusted;
 
-       get_scan_count(lruvec, swappiness, sc, nr, lru_pages);
+       get_scan_count(lruvec, memcg, sc, nr, lru_pages);
 
        /* Record the original scan target for proportional adjustments later */
        memcpy(targets, nr, sizeof(nr));
@@ -2409,8 +2418,6 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc,
                        unsigned long lru_pages;
                        unsigned long reclaimed;
                        unsigned long scanned;
-                       struct lruvec *lruvec;
-                       int swappiness;
 
                        if (mem_cgroup_low(root, memcg)) {
                                if (!sc->may_thrash)
@@ -2418,12 +2425,10 @@ static bool shrink_zone(struct zone *zone, struct scan_control *sc,
                                mem_cgroup_events(memcg, MEMCG_LOW, 1);
                        }
 
-                       lruvec = mem_cgroup_zone_lruvec(zone, memcg);
-                       swappiness = mem_cgroup_swappiness(memcg);
                        reclaimed = sc->nr_reclaimed;
                        scanned = sc->nr_scanned;
 
-                       shrink_lruvec(lruvec, swappiness, sc, &lru_pages);
+                       shrink_zone_memcg(zone, memcg, sc, &lru_pages);
                        zone_lru_pages += lru_pages;
 
                        if (memcg && is_classzone)
@@ -2893,8 +2898,6 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *memcg,
                .may_unmap = 1,
                .may_swap = !noswap,
        };
-       struct lruvec *lruvec = mem_cgroup_zone_lruvec(zone, memcg);
-       int swappiness = mem_cgroup_swappiness(memcg);
        unsigned long lru_pages;
 
        sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
@@ -2911,7 +2914,7 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *memcg,
         * will pick up pages from other mem cgroup's as well. We hack
         * the priority and make it zero.
         */
-       shrink_lruvec(lruvec, swappiness, &sc, &lru_pages);
+       shrink_zone_memcg(zone, memcg, &sc, &lru_pages);
 
        trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed);
 
index 64bd0aa..40b2c74 100644 (file)
@@ -1408,17 +1408,7 @@ static void vmstat_update(struct work_struct *w)
                 * Defer the checking for differentials to the
                 * shepherd thread on a different processor.
                 */
-               int r;
-               /*
-                * Shepherd work thread does not race since it never
-                * changes the bit if its zero but the cpu
-                * online / off line code may race if
-                * worker threads are still allowed during
-                * shutdown / startup.
-                */
-               r = cpumask_test_and_set_cpu(smp_processor_id(),
-                       cpu_stat_off);
-               VM_BUG_ON(r);
+               cpumask_set_cpu(smp_processor_id(), cpu_stat_off);
        }
 }
 
index aa01713..61ead9e 100644 (file)
@@ -351,8 +351,8 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
                        node->slots[i] = NULL;
                        BUG_ON(node->count < (1U << RADIX_TREE_COUNT_SHIFT));
                        node->count -= 1U << RADIX_TREE_COUNT_SHIFT;
-                       BUG_ON(!mapping->nrshadows);
-                       mapping->nrshadows--;
+                       BUG_ON(!mapping->nrexceptional);
+                       mapping->nrexceptional--;
                }
        }
        BUG_ON(node->count);
index e7414ce..2d7c4c1 100644 (file)
@@ -309,7 +309,12 @@ static void free_handle(struct zs_pool *pool, unsigned long handle)
 
 static void record_obj(unsigned long handle, unsigned long obj)
 {
-       *(unsigned long *)handle = obj;
+       /*
+        * lsb of @obj represents handle lock while other bits
+        * represent object value the handle is pointing so
+        * updating shouldn't do store tearing.
+        */
+       WRITE_ONCE(*(unsigned long *)handle, obj);
 }
 
 /* zpool driver */
@@ -1635,6 +1640,13 @@ static int migrate_zspage(struct zs_pool *pool, struct size_class *class,
                free_obj = obj_malloc(d_page, class, handle);
                zs_object_copy(free_obj, used_obj, class);
                index++;
+               /*
+                * record_obj updates handle's value to free_obj and it will
+                * invalidate lock bit(ie, HANDLE_PIN_BIT) of handle, which
+                * breaks synchronization using pin_tag(e,g, zs_free) so
+                * let's keep the lock bit.
+                */
+               free_obj |= BIT(HANDLE_PIN_BIT);
                record_obj(handle, free_obj);
                unpin_tag(handle);
                obj_free(pool, class, used_obj);
index bced8c0..7bc2208 100644 (file)
@@ -108,9 +108,7 @@ struct p9_poll_wait {
  * @unsent_req_list: accounting for requests that haven't been sent
  * @req: current request being processed (if any)
  * @tmp_buf: temporary buffer to read in header
- * @rsize: amount to read for current frame
- * @rpos: read position in current frame
- * @rbuf: current read buffer
+ * @rc: temporary fcall for reading current frame
  * @wpos: write position for current frame
  * @wsize: amount of data to write for current frame
  * @wbuf: current write buffer
@@ -131,9 +129,7 @@ struct p9_conn {
        struct list_head unsent_req_list;
        struct p9_req_t *req;
        char tmp_buf[7];
-       int rsize;
-       int rpos;
-       char *rbuf;
+       struct p9_fcall rc;
        int wpos;
        int wsize;
        char *wbuf;
@@ -305,69 +301,77 @@ static void p9_read_work(struct work_struct *work)
        if (m->err < 0)
                return;
 
-       p9_debug(P9_DEBUG_TRANS, "start mux %p pos %d\n", m, m->rpos);
+       p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset);
 
-       if (!m->rbuf) {
-               m->rbuf = m->tmp_buf;
-               m->rpos = 0;
-               m->rsize = 7; /* start by reading header */
+       if (!m->rc.sdata) {
+               m->rc.sdata = m->tmp_buf;
+               m->rc.offset = 0;
+               m->rc.capacity = 7; /* start by reading header */
        }
 
        clear_bit(Rpending, &m->wsched);
-       p9_debug(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d\n",
-                m, m->rpos, m->rsize, m->rsize-m->rpos);
-       err = p9_fd_read(m->client, m->rbuf + m->rpos,
-                                               m->rsize - m->rpos);
+       p9_debug(P9_DEBUG_TRANS, "read mux %p pos %zd size: %zd = %zd\n",
+                m, m->rc.offset, m->rc.capacity,
+                m->rc.capacity - m->rc.offset);
+       err = p9_fd_read(m->client, m->rc.sdata + m->rc.offset,
+                        m->rc.capacity - m->rc.offset);
        p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
-       if (err == -EAGAIN) {
+       if (err == -EAGAIN)
                goto end_clear;
-       }
 
        if (err <= 0)
                goto error;
 
-       m->rpos += err;
+       m->rc.offset += err;
 
-       if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */
-               u16 tag;
+       /* header read in */
+       if ((!m->req) && (m->rc.offset == m->rc.capacity)) {
                p9_debug(P9_DEBUG_TRANS, "got new header\n");
 
-               n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */
-               if (n >= m->client->msize) {
+               err = p9_parse_header(&m->rc, NULL, NULL, NULL, 0);
+               if (err) {
+                       p9_debug(P9_DEBUG_ERROR,
+                                "error parsing header: %d\n", err);
+                       goto error;
+               }
+
+               if (m->rc.size >= m->client->msize) {
                        p9_debug(P9_DEBUG_ERROR,
-                                "requested packet size too big: %d\n", n);
+                                "requested packet size too big: %d\n",
+                                m->rc.size);
                        err = -EIO;
                        goto error;
                }
 
-               tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
                p9_debug(P9_DEBUG_TRANS,
-                        "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag);
+                        "mux %p pkt: size: %d bytes tag: %d\n",
+                        m, m->rc.size, m->rc.tag);
 
-               m->req = p9_tag_lookup(m->client, tag);
+               m->req = p9_tag_lookup(m->client, m->rc.tag);
                if (!m->req || (m->req->status != REQ_STATUS_SENT)) {
                        p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
-                                tag);
+                                m->rc.tag);
                        err = -EIO;
                        goto error;
                }
 
                if (m->req->rc == NULL) {
-                       m->req->rc = kmalloc(sizeof(struct p9_fcall) +
-                                               m->client->msize, GFP_NOFS);
-                       if (!m->req->rc) {
-                               m->req = NULL;
-                               err = -ENOMEM;
-                               goto error;
-                       }
+                       p9_debug(P9_DEBUG_ERROR,
+                                "No recv fcall for tag %d (req %p), disconnecting!\n",
+                                m->rc.tag, m->req);
+                       m->req = NULL;
+                       err = -EIO;
+                       goto error;
                }
-               m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall);
-               memcpy(m->rbuf, m->tmp_buf, m->rsize);
-               m->rsize = n;
+               m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall);
+               memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
+               m->rc.capacity = m->rc.size;
        }
 
-       /* not an else because some packets (like clunk) have no payload */
-       if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */
+       /* packet is read in
+        * not an else because some packets (like clunk) have no payload
+        */
+       if ((m->req) && (m->rc.offset == m->rc.capacity)) {
                p9_debug(P9_DEBUG_TRANS, "got new packet\n");
                spin_lock(&m->client->lock);
                if (m->req->status != REQ_STATUS_ERROR)
@@ -375,9 +379,9 @@ static void p9_read_work(struct work_struct *work)
                list_del(&m->req->req_list);
                spin_unlock(&m->client->lock);
                p9_client_cb(m->client, m->req, status);
-               m->rbuf = NULL;
-               m->rpos = 0;
-               m->rsize = 0;
+               m->rc.sdata = NULL;
+               m->rc.offset = 0;
+               m->rc.capacity = 0;
                m->req = NULL;
        }
 
index 199bc76..4acb1d5 100644 (file)
@@ -658,7 +658,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
        mutex_unlock(&virtio_9p_lock);
 
        if (!found) {
-               pr_err("no channels available\n");
+               pr_err("no channels available for device %s\n", devname);
                return ret;
        }
 
index 10d8775..9e43a31 100644 (file)
@@ -152,7 +152,6 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        void *ticket_buf = NULL;
        void *tp, *tpend;
        void **ptp;
-       struct ceph_timespec new_validity;
        struct ceph_crypto_key new_session_key;
        struct ceph_buffer *new_ticket_blob;
        unsigned long new_expires, new_renew_after;
@@ -193,8 +192,8 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        if (ret)
                goto out;
 
-       ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
-       ceph_decode_timespec(&validity, &new_validity);
+       ceph_decode_timespec(&validity, dp);
+       dp += sizeof(struct ceph_timespec);
        new_expires = get_seconds() + validity.tv_sec;
        new_renew_after = new_expires - (validity.tv_sec / 4);
        dout(" expires=%lu renew_after=%lu\n", new_expires,
@@ -233,10 +232,10 @@ static int process_one_ticket(struct ceph_auth_client *ac,
                ceph_buffer_put(th->ticket_blob);
        th->session_key = new_session_key;
        th->ticket_blob = new_ticket_blob;
-       th->validity = new_validity;
        th->secret_id = new_secret_id;
        th->expires = new_expires;
        th->renew_after = new_renew_after;
+       th->have_key = true;
        dout(" got ticket service %d (%s) secret_id %lld len %d\n",
             type, ceph_entity_type_name(type), th->secret_id,
             (int)th->ticket_blob->vec.iov_len);
@@ -384,6 +383,24 @@ bad:
        return -ERANGE;
 }
 
+static bool need_key(struct ceph_x_ticket_handler *th)
+{
+       if (!th->have_key)
+               return true;
+
+       return get_seconds() >= th->renew_after;
+}
+
+static bool have_key(struct ceph_x_ticket_handler *th)
+{
+       if (th->have_key) {
+               if (get_seconds() >= th->expires)
+                       th->have_key = false;
+       }
+
+       return th->have_key;
+}
+
 static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
 {
        int want = ac->want_keys;
@@ -402,20 +419,18 @@ static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
                        continue;
 
                th = get_ticket_handler(ac, service);
-
                if (IS_ERR(th)) {
                        *pneed |= service;
                        continue;
                }
 
-               if (get_seconds() >= th->renew_after)
+               if (need_key(th))
                        *pneed |= service;
-               if (get_seconds() >= th->expires)
+               if (!have_key(th))
                        xi->have_keys &= ~service;
        }
 }
 
-
 static int ceph_x_build_request(struct ceph_auth_client *ac,
                                void *buf, void *end)
 {
@@ -667,14 +682,26 @@ static void ceph_x_destroy(struct ceph_auth_client *ac)
        ac->private = NULL;
 }
 
-static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
-                                  int peer_type)
+static void invalidate_ticket(struct ceph_auth_client *ac, int peer_type)
 {
        struct ceph_x_ticket_handler *th;
 
        th = get_ticket_handler(ac, peer_type);
        if (!IS_ERR(th))
-               memset(&th->validity, 0, sizeof(th->validity));
+               th->have_key = false;
+}
+
+static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
+                                        int peer_type)
+{
+       /*
+        * We are to invalidate a service ticket in the hopes of
+        * getting a new, hopefully more valid, one.  But, we won't get
+        * it unless our AUTH ticket is good, so invalidate AUTH ticket
+        * as well, just in case.
+        */
+       invalidate_ticket(ac, peer_type);
+       invalidate_ticket(ac, CEPH_ENTITY_TYPE_AUTH);
 }
 
 static int calcu_signature(struct ceph_x_authorizer *au,
index e8b7c69..40b1a3c 100644 (file)
@@ -16,7 +16,7 @@ struct ceph_x_ticket_handler {
        unsigned int service;
 
        struct ceph_crypto_key session_key;
-       struct ceph_timespec validity;
+       bool have_key;
 
        u64 secret_id;
        struct ceph_buffer *ticket_blob;
index 9981039..9cfedf5 100644 (file)
@@ -23,9 +23,6 @@
 #include <linux/ceph/pagelist.h>
 #include <linux/export.h>
 
-#define list_entry_next(pos, member)                                   \
-       list_entry(pos->member.next, typeof(*pos), member)
-
 /*
  * Ceph uses the messenger to exchange ceph_msg messages with other
  * hosts in the system.  The messenger provides ordered and reliable
@@ -672,6 +669,8 @@ static void reset_connection(struct ceph_connection *con)
        }
        con->in_seq = 0;
        con->in_seq_acked = 0;
+
+       con->out_skip = 0;
 }
 
 /*
@@ -771,6 +770,8 @@ static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt)
 
 static void con_out_kvec_reset(struct ceph_connection *con)
 {
+       BUG_ON(con->out_skip);
+
        con->out_kvec_left = 0;
        con->out_kvec_bytes = 0;
        con->out_kvec_cur = &con->out_kvec[0];
@@ -779,9 +780,9 @@ static void con_out_kvec_reset(struct ceph_connection *con)
 static void con_out_kvec_add(struct ceph_connection *con,
                                size_t size, void *data)
 {
-       int index;
+       int index = con->out_kvec_left;
 
-       index = con->out_kvec_left;
+       BUG_ON(con->out_skip);
        BUG_ON(index >= ARRAY_SIZE(con->out_kvec));
 
        con->out_kvec[index].iov_len = size;
@@ -790,6 +791,27 @@ static void con_out_kvec_add(struct ceph_connection *con,
        con->out_kvec_bytes += size;
 }
 
+/*
+ * Chop off a kvec from the end.  Return residual number of bytes for
+ * that kvec, i.e. how many bytes would have been written if the kvec
+ * hadn't been nuked.
+ */
+static int con_out_kvec_skip(struct ceph_connection *con)
+{
+       int off = con->out_kvec_cur - con->out_kvec;
+       int skip = 0;
+
+       if (con->out_kvec_bytes > 0) {
+               skip = con->out_kvec[off + con->out_kvec_left - 1].iov_len;
+               BUG_ON(con->out_kvec_bytes < skip);
+               BUG_ON(!con->out_kvec_left);
+               con->out_kvec_bytes -= skip;
+               con->out_kvec_left--;
+       }
+
+       return skip;
+}
+
 #ifdef CONFIG_BLOCK
 
 /*
@@ -1042,7 +1064,7 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor,
        /* Move on to the next page */
 
        BUG_ON(list_is_last(&cursor->page->lru, &pagelist->head));
-       cursor->page = list_entry_next(cursor->page, lru);
+       cursor->page = list_next_entry(cursor->page, lru);
        cursor->last_piece = cursor->resid <= PAGE_SIZE;
 
        return true;
@@ -1166,7 +1188,7 @@ static bool ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor,
        if (!cursor->resid && cursor->total_resid) {
                WARN_ON(!cursor->last_piece);
                BUG_ON(list_is_last(&cursor->data->links, cursor->data_head));
-               cursor->data = list_entry_next(cursor->data, links);
+               cursor->data = list_next_entry(cursor->data, links);
                __ceph_msg_data_cursor_init(cursor);
                new_piece = true;
        }
@@ -1197,7 +1219,6 @@ static void prepare_write_message_footer(struct ceph_connection *con)
        m->footer.flags |= CEPH_MSG_FOOTER_COMPLETE;
 
        dout("prepare_write_message_footer %p\n", con);
-       con->out_kvec_is_msg = true;
        con->out_kvec[v].iov_base = &m->footer;
        if (con->peer_features & CEPH_FEATURE_MSG_AUTH) {
                if (con->ops->sign_message)
@@ -1225,7 +1246,6 @@ static void prepare_write_message(struct ceph_connection *con)
        u32 crc;
 
        con_out_kvec_reset(con);
-       con->out_kvec_is_msg = true;
        con->out_msg_done = false;
 
        /* Sneak an ack in there first?  If we can get it into the same
@@ -1265,18 +1285,19 @@ static void prepare_write_message(struct ceph_connection *con)
 
        /* tag + hdr + front + middle */
        con_out_kvec_add(con, sizeof (tag_msg), &tag_msg);
-       con_out_kvec_add(con, sizeof (m->hdr), &m->hdr);
+       con_out_kvec_add(con, sizeof(con->out_hdr), &con->out_hdr);
        con_out_kvec_add(con, m->front.iov_len, m->front.iov_base);
 
        if (m->middle)
                con_out_kvec_add(con, m->middle->vec.iov_len,
                        m->middle->vec.iov_base);
 
-       /* fill in crc (except data pages), footer */
+       /* fill in hdr crc and finalize hdr */
        crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc));
        con->out_msg->hdr.crc = cpu_to_le32(crc);
-       con->out_msg->footer.flags = 0;
+       memcpy(&con->out_hdr, &con->out_msg->hdr, sizeof(con->out_hdr));
 
+       /* fill in front and middle crc, footer */
        crc = crc32c(0, m->front.iov_base, m->front.iov_len);
        con->out_msg->footer.front_crc = cpu_to_le32(crc);
        if (m->middle) {
@@ -1288,6 +1309,7 @@ static void prepare_write_message(struct ceph_connection *con)
        dout("%s front_crc %u middle_crc %u\n", __func__,
             le32_to_cpu(con->out_msg->footer.front_crc),
             le32_to_cpu(con->out_msg->footer.middle_crc));
+       con->out_msg->footer.flags = 0;
 
        /* is there a data payload? */
        con->out_msg->footer.data_crc = 0;
@@ -1492,7 +1514,6 @@ static int write_partial_kvec(struct ceph_connection *con)
                }
        }
        con->out_kvec_left = 0;
-       con->out_kvec_is_msg = false;
        ret = 1;
 out:
        dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con,
@@ -1584,6 +1605,7 @@ static int write_partial_skip(struct ceph_connection *con)
 {
        int ret;
 
+       dout("%s %p %d left\n", __func__, con, con->out_skip);
        while (con->out_skip > 0) {
                size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE);
 
@@ -2506,13 +2528,13 @@ more:
 
 more_kvec:
        /* kvec data queued? */
-       if (con->out_skip) {
-               ret = write_partial_skip(con);
+       if (con->out_kvec_left) {
+               ret = write_partial_kvec(con);
                if (ret <= 0)
                        goto out;
        }
-       if (con->out_kvec_left) {
-               ret = write_partial_kvec(con);
+       if (con->out_skip) {
+               ret = write_partial_skip(con);
                if (ret <= 0)
                        goto out;
        }
@@ -2805,13 +2827,17 @@ static bool con_backoff(struct ceph_connection *con)
 
 static void con_fault_finish(struct ceph_connection *con)
 {
+       dout("%s %p\n", __func__, con);
+
        /*
         * in case we faulted due to authentication, invalidate our
         * current tickets so that we can get new ones.
         */
-       if (con->auth_retry && con->ops->invalidate_authorizer) {
-               dout("calling invalidate_authorizer()\n");
-               con->ops->invalidate_authorizer(con);
+       if (con->auth_retry) {
+               dout("auth_retry %d, invalidating\n", con->auth_retry);
+               if (con->ops->invalidate_authorizer)
+                       con->ops->invalidate_authorizer(con);
+               con->auth_retry = 0;
        }
 
        if (con->ops->fault)
@@ -3050,16 +3076,31 @@ void ceph_msg_revoke(struct ceph_msg *msg)
                ceph_msg_put(msg);
        }
        if (con->out_msg == msg) {
-               dout("%s %p msg %p - was sending\n", __func__, con, msg);
-               con->out_msg = NULL;
-               if (con->out_kvec_is_msg) {
-                       con->out_skip = con->out_kvec_bytes;
-                       con->out_kvec_is_msg = false;
+               BUG_ON(con->out_skip);
+               /* footer */
+               if (con->out_msg_done) {
+                       con->out_skip += con_out_kvec_skip(con);
+               } else {
+                       BUG_ON(!msg->data_length);
+                       if (con->peer_features & CEPH_FEATURE_MSG_AUTH)
+                               con->out_skip += sizeof(msg->footer);
+                       else
+                               con->out_skip += sizeof(msg->old_footer);
                }
+               /* data, middle, front */
+               if (msg->data_length)
+                       con->out_skip += msg->cursor.total_resid;
+               if (msg->middle)
+                       con->out_skip += con_out_kvec_skip(con);
+               con->out_skip += con_out_kvec_skip(con);
+
+               dout("%s %p msg %p - was sending, will write %d skip %d\n",
+                    __func__, con, msg, con->out_kvec_bytes, con->out_skip);
                msg->hdr.seq = 0;
-
+               con->out_msg = NULL;
                ceph_msg_put(msg);
        }
+
        mutex_unlock(&con->mutex);
 }
 
@@ -3361,9 +3402,7 @@ static void ceph_msg_free(struct ceph_msg *m)
 static void ceph_msg_release(struct kref *kref)
 {
        struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);
-       LIST_HEAD(data);
-       struct list_head *links;
-       struct list_head *next;
+       struct ceph_msg_data *data, *next;
 
        dout("%s %p\n", __func__, m);
        WARN_ON(!list_empty(&m->list_head));
@@ -3376,12 +3415,8 @@ static void ceph_msg_release(struct kref *kref)
                m->middle = NULL;
        }
 
-       list_splice_init(&m->data, &data);
-       list_for_each_safe(links, next, &data) {
-               struct ceph_msg_data *data;
-
-               data = list_entry(links, struct ceph_msg_data, links);
-               list_del_init(links);
+       list_for_each_entry_safe(data, next, &m->data, links) {
+               list_del_init(&data->links);
                ceph_msg_data_destroy(data);
        }
        m->data_length = 0;
index edda016..de85ddd 100644 (file)
@@ -364,10 +364,6 @@ static bool have_debugfs_info(struct ceph_mon_client *monc)
        return monc->client->have_fsid && monc->auth->global_id > 0;
 }
 
-/*
- * The monitor responds with mount ack indicate mount success.  The
- * included client ticket allows the client to talk to MDSs and OSDs.
- */
 static void ceph_monc_handle_map(struct ceph_mon_client *monc,
                                 struct ceph_msg *msg)
 {
index c29809f..62c049b 100644 (file)
@@ -56,7 +56,6 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
 obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
 obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
 obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
-obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o
 obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
 
 obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
index 744e593..7aea0cc 100644 (file)
@@ -289,10 +289,8 @@ static void __node_free_rcu(struct rcu_head *head)
 
        if (!n->tn_bits)
                kmem_cache_free(trie_leaf_kmem, n);
-       else if (n->tn_bits <= TNODE_KMALLOC_MAX)
-               kfree(n);
        else
-               vfree(n);
+               kvfree(n);
 }
 
 #define node_free(n) call_rcu(&tn_info(n)->rcu, __node_free_rcu)
index 46ce410..4d367b4 100644 (file)
@@ -24,7 +24,6 @@
 #include <net/cipso_ipv4.h>
 #include <net/inet_frag.h>
 #include <net/ping.h>
-#include <net/tcp_memcontrol.h>
 
 static int zero;
 static int one = 1;
index c7d1fb5..5ced3e4 100644 (file)
@@ -73,7 +73,6 @@
 #include <net/timewait_sock.h>
 #include <net/xfrm.h>
 #include <net/secure_seq.h>
-#include <net/tcp_memcontrol.h>
 #include <net/busy_poll.h>
 
 #include <linux/inet.h>
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
deleted file mode 100644 (file)
index 18bc7f7..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-#include <net/tcp.h>
-#include <net/tcp_memcontrol.h>
-#include <net/sock.h>
-#include <net/ip.h>
-#include <linux/nsproxy.h>
-#include <linux/memcontrol.h>
-#include <linux/module.h>
-
-int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
-{
-       struct mem_cgroup *parent = parent_mem_cgroup(memcg);
-       struct page_counter *counter_parent = NULL;
-       /*
-        * The root cgroup does not use page_counters, but rather,
-        * rely on the data already collected by the network
-        * subsystem
-        */
-       if (memcg == root_mem_cgroup)
-               return 0;
-
-       memcg->tcp_mem.memory_pressure = 0;
-
-       if (parent)
-               counter_parent = &parent->tcp_mem.memory_allocated;
-
-       page_counter_init(&memcg->tcp_mem.memory_allocated, counter_parent);
-
-       return 0;
-}
-
-void tcp_destroy_cgroup(struct mem_cgroup *memcg)
-{
-       if (memcg == root_mem_cgroup)
-               return;
-
-       if (memcg->tcp_mem.active)
-               static_branch_dec(&memcg_sockets_enabled_key);
-}
-
-static int tcp_update_limit(struct mem_cgroup *memcg, unsigned long nr_pages)
-{
-       int ret;
-
-       if (memcg == root_mem_cgroup)
-               return -EINVAL;
-
-       ret = page_counter_limit(&memcg->tcp_mem.memory_allocated, nr_pages);
-       if (ret)
-               return ret;
-
-       if (!memcg->tcp_mem.active) {
-               /*
-                * The active flag needs to be written after the static_key
-                * update. This is what guarantees that the socket activation
-                * function is the last one to run. See sock_update_memcg() for
-                * details, and note that we don't mark any socket as belonging
-                * to this memcg until that flag is up.
-                *
-                * We need to do this, because static_keys will span multiple
-                * sites, but we can't control their order. If we mark a socket
-                * as accounted, but the accounting functions are not patched in
-                * yet, we'll lose accounting.
-                *
-                * We never race with the readers in sock_update_memcg(),
-                * because when this value change, the code to process it is not
-                * patched in yet.
-                */
-               static_branch_inc(&memcg_sockets_enabled_key);
-               memcg->tcp_mem.active = true;
-       }
-
-       return 0;
-}
-
-enum {
-       RES_USAGE,
-       RES_LIMIT,
-       RES_MAX_USAGE,
-       RES_FAILCNT,
-};
-
-static DEFINE_MUTEX(tcp_limit_mutex);
-
-static ssize_t tcp_cgroup_write(struct kernfs_open_file *of,
-                               char *buf, size_t nbytes, loff_t off)
-{
-       struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
-       unsigned long nr_pages;
-       int ret = 0;
-
-       buf = strstrip(buf);
-
-       switch (of_cft(of)->private) {
-       case RES_LIMIT:
-               /* see memcontrol.c */
-               ret = page_counter_memparse(buf, "-1", &nr_pages);
-               if (ret)
-                       break;
-               mutex_lock(&tcp_limit_mutex);
-               ret = tcp_update_limit(memcg, nr_pages);
-               mutex_unlock(&tcp_limit_mutex);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret ?: nbytes;
-}
-
-static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
-       struct mem_cgroup *memcg = mem_cgroup_from_css(css);
-       u64 val;
-
-       switch (cft->private) {
-       case RES_LIMIT:
-               if (memcg == root_mem_cgroup)
-                       val = PAGE_COUNTER_MAX;
-               else
-                       val = memcg->tcp_mem.memory_allocated.limit;
-               val *= PAGE_SIZE;
-               break;
-       case RES_USAGE:
-               if (memcg == root_mem_cgroup)
-                       val = atomic_long_read(&tcp_memory_allocated);
-               else
-                       val = page_counter_read(&memcg->tcp_mem.memory_allocated);
-               val *= PAGE_SIZE;
-               break;
-       case RES_FAILCNT:
-               if (memcg == root_mem_cgroup)
-                       return 0;
-               val = memcg->tcp_mem.memory_allocated.failcnt;
-               break;
-       case RES_MAX_USAGE:
-               if (memcg == root_mem_cgroup)
-                       return 0;
-               val = memcg->tcp_mem.memory_allocated.watermark;
-               val *= PAGE_SIZE;
-               break;
-       default:
-               BUG();
-       }
-       return val;
-}
-
-static ssize_t tcp_cgroup_reset(struct kernfs_open_file *of,
-                               char *buf, size_t nbytes, loff_t off)
-{
-       struct mem_cgroup *memcg;
-
-       memcg = mem_cgroup_from_css(of_css(of));
-       if (memcg == root_mem_cgroup)
-               return nbytes;
-
-       switch (of_cft(of)->private) {
-       case RES_MAX_USAGE:
-               page_counter_reset_watermark(&memcg->tcp_mem.memory_allocated);
-               break;
-       case RES_FAILCNT:
-               memcg->tcp_mem.memory_allocated.failcnt = 0;
-               break;
-       }
-
-       return nbytes;
-}
-
-static struct cftype tcp_files[] = {
-       {
-               .name = "kmem.tcp.limit_in_bytes",
-               .write = tcp_cgroup_write,
-               .read_u64 = tcp_cgroup_read,
-               .private = RES_LIMIT,
-       },
-       {
-               .name = "kmem.tcp.usage_in_bytes",
-               .read_u64 = tcp_cgroup_read,
-               .private = RES_USAGE,
-       },
-       {
-               .name = "kmem.tcp.failcnt",
-               .private = RES_FAILCNT,
-               .write = tcp_cgroup_reset,
-               .read_u64 = tcp_cgroup_read,
-       },
-       {
-               .name = "kmem.tcp.max_usage_in_bytes",
-               .private = RES_MAX_USAGE,
-               .write = tcp_cgroup_reset,
-               .read_u64 = tcp_cgroup_read,
-       },
-       { }     /* terminate */
-};
-
-static int __init tcp_memcontrol_init(void)
-{
-       WARN_ON(cgroup_add_legacy_cftypes(&memory_cgrp_subsys, tcp_files));
-       return 0;
-}
-__initcall(tcp_memcontrol_init);
index 4ad8edb..006396e 100644 (file)
@@ -61,7 +61,6 @@
 #include <net/timewait_sock.h>
 #include <net/inet_common.h>
 #include <net/secure_seq.h>
-#include <net/tcp_memcontrol.h>
 #include <net/busy_poll.h>
 
 #include <linux/proc_fs.h>
index abbdff0..3e24d0d 100644 (file)
@@ -91,7 +91,7 @@ static const struct file_operations reset_ops = {
 };
 #endif
 
-static const char *hw_flag_names[NUM_IEEE80211_HW_FLAGS + 1] = {
+static const char *hw_flag_names[] = {
 #define FLAG(F)        [IEEE80211_HW_##F] = #F
        FLAG(HAS_RATE_CONTROL),
        FLAG(RX_INCLUDES_FCS),
@@ -126,9 +126,6 @@ static const char *hw_flag_names[NUM_IEEE80211_HW_FLAGS + 1] = {
        FLAG(SUPPORTS_AMSDU_IN_AMPDU),
        FLAG(BEACON_TX_STATUS),
        FLAG(NEEDS_UNIQUE_STA_ADDR),
-
-       /* keep last for the build bug below */
-       (void *)0x1
 #undef FLAG
 };
 
@@ -148,7 +145,7 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
        /* fail compilation if somebody adds or removes
         * a flag without updating the name array above
         */
-       BUILD_BUG_ON(hw_flag_names[NUM_IEEE80211_HW_FLAGS] != (void *)0x1);
+       BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
 
        for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
                if (test_bit(i, local->hw.flags))
index f222885..9481d55 100644 (file)
@@ -122,44 +122,34 @@ void rds_ib_dev_put(struct rds_ib_device *rds_ibdev)
 static void rds_ib_add_one(struct ib_device *device)
 {
        struct rds_ib_device *rds_ibdev;
-       struct ib_device_attr *dev_attr;
 
        /* Only handle IB (no iWARP) devices */
        if (device->node_type != RDMA_NODE_IB_CA)
                return;
 
-       dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL);
-       if (!dev_attr)
-               return;
-
-       if (ib_query_device(device, dev_attr)) {
-               rdsdebug("Query device failed for %s\n", device->name);
-               goto free_attr;
-       }
-
        rds_ibdev = kzalloc_node(sizeof(struct rds_ib_device), GFP_KERNEL,
                                 ibdev_to_node(device));
        if (!rds_ibdev)
-               goto free_attr;
+               return;
 
        spin_lock_init(&rds_ibdev->spinlock);
        atomic_set(&rds_ibdev->refcount, 1);
        INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free);
 
-       rds_ibdev->max_wrs = dev_attr->max_qp_wr;
-       rds_ibdev->max_sge = min(dev_attr->max_sge, RDS_IB_MAX_SGE);
+       rds_ibdev->max_wrs = device->attrs.max_qp_wr;
+       rds_ibdev->max_sge = min(device->attrs.max_sge, RDS_IB_MAX_SGE);
 
-       rds_ibdev->fmr_max_remaps = dev_attr->max_map_per_fmr?: 32;
-       rds_ibdev->max_1m_fmrs = dev_attr->max_mr ?
-               min_t(unsigned int, (dev_attr->max_mr / 2),
+       rds_ibdev->fmr_max_remaps = device->attrs.max_map_per_fmr?: 32;
+       rds_ibdev->max_1m_fmrs = device->attrs.max_mr ?
+               min_t(unsigned int, (device->attrs.max_mr / 2),
                      rds_ib_fmr_1m_pool_size) : rds_ib_fmr_1m_pool_size;
 
-       rds_ibdev->max_8k_fmrs = dev_attr->max_mr ?
-               min_t(unsigned int, ((dev_attr->max_mr / 2) * RDS_MR_8K_SCALE),
+       rds_ibdev->max_8k_fmrs = device->attrs.max_mr ?
+               min_t(unsigned int, ((device->attrs.max_mr / 2) * RDS_MR_8K_SCALE),
                      rds_ib_fmr_8k_pool_size) : rds_ib_fmr_8k_pool_size;
 
-       rds_ibdev->max_initiator_depth = dev_attr->max_qp_init_rd_atom;
-       rds_ibdev->max_responder_resources = dev_attr->max_qp_rd_atom;
+       rds_ibdev->max_initiator_depth = device->attrs.max_qp_init_rd_atom;
+       rds_ibdev->max_responder_resources = device->attrs.max_qp_rd_atom;
 
        rds_ibdev->dev = device;
        rds_ibdev->pd = ib_alloc_pd(device);
@@ -183,7 +173,7 @@ static void rds_ib_add_one(struct ib_device *device)
        }
 
        rdsdebug("RDS/IB: max_mr = %d, max_wrs = %d, max_sge = %d, fmr_max_remaps = %d, max_1m_fmrs = %d, max_8k_fmrs = %d\n",
-                dev_attr->max_fmr, rds_ibdev->max_wrs, rds_ibdev->max_sge,
+                device->attrs.max_fmr, rds_ibdev->max_wrs, rds_ibdev->max_sge,
                 rds_ibdev->fmr_max_remaps, rds_ibdev->max_1m_fmrs,
                 rds_ibdev->max_8k_fmrs);
 
@@ -202,8 +192,6 @@ static void rds_ib_add_one(struct ib_device *device)
 
 put_dev:
        rds_ib_dev_put(rds_ibdev);
-free_attr:
-       kfree(dev_attr);
 }
 
 /*
index 576f182..f4a9fff 100644 (file)
@@ -60,30 +60,20 @@ LIST_HEAD(iw_nodev_conns);
 static void rds_iw_add_one(struct ib_device *device)
 {
        struct rds_iw_device *rds_iwdev;
-       struct ib_device_attr *dev_attr;
 
        /* Only handle iwarp devices */
        if (device->node_type != RDMA_NODE_RNIC)
                return;
 
-       dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL);
-       if (!dev_attr)
-               return;
-
-       if (ib_query_device(device, dev_attr)) {
-               rdsdebug("Query device failed for %s\n", device->name);
-               goto free_attr;
-       }
-
        rds_iwdev = kmalloc(sizeof *rds_iwdev, GFP_KERNEL);
        if (!rds_iwdev)
-               goto free_attr;
+               return;
 
        spin_lock_init(&rds_iwdev->spinlock);
 
-       rds_iwdev->dma_local_lkey = !!(dev_attr->device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY);
-       rds_iwdev->max_wrs = dev_attr->max_qp_wr;
-       rds_iwdev->max_sge = min(dev_attr->max_sge, RDS_IW_MAX_SGE);
+       rds_iwdev->dma_local_lkey = !!(device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY);
+       rds_iwdev->max_wrs = device->attrs.max_qp_wr;
+       rds_iwdev->max_sge = min(device->attrs.max_sge, RDS_IW_MAX_SGE);
 
        rds_iwdev->dev = device;
        rds_iwdev->pd = ib_alloc_pd(device);
@@ -111,8 +101,7 @@ static void rds_iw_add_one(struct ib_device *device)
        list_add_tail(&rds_iwdev->list, &rds_iw_devices);
 
        ib_set_client_data(device, &rds_iw_client, rds_iwdev);
-
-       goto free_attr;
+       return;
 
 err_mr:
        if (rds_iwdev->mr)
@@ -121,8 +110,6 @@ err_pd:
        ib_dealloc_pd(rds_iwdev->pd);
 free_dev:
        kfree(rds_iwdev);
-free_attr:
-       kfree(dev_attr);
 }
 
 static void rds_iw_remove_one(struct ib_device *device, void *client_data)
index 5e4f815..2b32fd6 100644 (file)
@@ -771,7 +771,7 @@ static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
        if (count == 0)
                return 0;
 
-       mutex_lock(&inode->i_mutex); /* protect against multiple concurrent
+       inode_lock(inode); /* protect against multiple concurrent
                              * readers on this file */
  again:
        spin_lock(&queue_lock);
@@ -784,7 +784,7 @@ static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
        }
        if (rp->q.list.next == &cd->queue) {
                spin_unlock(&queue_lock);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                WARN_ON_ONCE(rp->offset);
                return 0;
        }
@@ -838,7 +838,7 @@ static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
        }
        if (err == -EAGAIN)
                goto again;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return err ? err :  count;
 }
 
@@ -909,9 +909,9 @@ static ssize_t cache_write(struct file *filp, const char __user *buf,
        if (!cd->cache_parse)
                goto out;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = cache_downcall(mapping, buf, count, cd);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 out:
        return ret;
 }
index 14f45bf..31789ef 100644 (file)
@@ -172,7 +172,7 @@ rpc_close_pipes(struct inode *inode)
        int need_release;
        LIST_HEAD(free_list);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        spin_lock(&pipe->lock);
        need_release = pipe->nreaders != 0 || pipe->nwriters != 0;
        pipe->nreaders = 0;
@@ -188,7 +188,7 @@ rpc_close_pipes(struct inode *inode)
        cancel_delayed_work_sync(&pipe->queue_timeout);
        rpc_inode_setowner(inode, NULL);
        RPC_I(inode)->pipe = NULL;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 }
 
 static struct inode *
@@ -221,7 +221,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp)
        int first_open;
        int res = -ENXIO;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        pipe = RPC_I(inode)->pipe;
        if (pipe == NULL)
                goto out;
@@ -237,7 +237,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp)
                pipe->nwriters++;
        res = 0;
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return res;
 }
 
@@ -248,7 +248,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
        struct rpc_pipe_msg *msg;
        int last_close;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        pipe = RPC_I(inode)->pipe;
        if (pipe == NULL)
                goto out;
@@ -278,7 +278,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
        if (last_close && pipe->ops->release_pipe)
                pipe->ops->release_pipe(inode);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return 0;
 }
 
@@ -290,7 +290,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
        struct rpc_pipe_msg *msg;
        int res = 0;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        pipe = RPC_I(inode)->pipe;
        if (pipe == NULL) {
                res = -EPIPE;
@@ -322,7 +322,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
                pipe->ops->destroy_msg(msg);
        }
 out_unlock:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return res;
 }
 
@@ -332,11 +332,11 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of
        struct inode *inode = file_inode(filp);
        int res;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        res = -EPIPE;
        if (RPC_I(inode)->pipe != NULL)
                res = RPC_I(inode)->pipe->ops->downcall(filp, buf, len);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return res;
 }
 
@@ -349,12 +349,12 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
 
        poll_wait(filp, &rpci->waitq, wait);
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        if (rpci->pipe == NULL)
                mask |= POLLERR | POLLHUP;
        else if (filp->private_data || !list_empty(&rpci->pipe->pipe))
                mask |= POLLIN | POLLRDNORM;
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        return mask;
 }
 
@@ -367,10 +367,10 @@ rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
        case FIONREAD:
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                pipe = RPC_I(inode)->pipe;
                if (pipe == NULL) {
-                       mutex_unlock(&inode->i_mutex);
+                       inode_unlock(inode);
                        return -EPIPE;
                }
                spin_lock(&pipe->lock);
@@ -381,7 +381,7 @@ rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        len += msg->len - msg->copied;
                }
                spin_unlock(&pipe->lock);
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
                return put_user(len, (int __user *)arg);
        default:
                return -EINVAL;
@@ -617,9 +617,9 @@ int rpc_rmdir(struct dentry *dentry)
 
        parent = dget_parent(dentry);
        dir = d_inode(parent);
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
        error = __rpc_rmdir(dir, dentry);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        dput(parent);
        return error;
 }
@@ -701,9 +701,9 @@ static void rpc_depopulate(struct dentry *parent,
 {
        struct inode *dir = d_inode(parent);
 
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_CHILD);
+       inode_lock_nested(dir, I_MUTEX_CHILD);
        __rpc_depopulate(parent, files, start, eof);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
 }
 
 static int rpc_populate(struct dentry *parent,
@@ -715,7 +715,7 @@ static int rpc_populate(struct dentry *parent,
        struct dentry *dentry;
        int i, err;
 
-       mutex_lock(&dir->i_mutex);
+       inode_lock(dir);
        for (i = start; i < eof; i++) {
                dentry = __rpc_lookup_create_exclusive(parent, files[i].name);
                err = PTR_ERR(dentry);
@@ -739,11 +739,11 @@ static int rpc_populate(struct dentry *parent,
                if (err != 0)
                        goto out_bad;
        }
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        return 0;
 out_bad:
        __rpc_depopulate(parent, files, start, eof);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        printk(KERN_WARNING "%s: %s failed to populate directory %pd\n",
                        __FILE__, __func__, parent);
        return err;
@@ -757,7 +757,7 @@ static struct dentry *rpc_mkdir_populate(struct dentry *parent,
        struct inode *dir = d_inode(parent);
        int error;
 
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
        dentry = __rpc_lookup_create_exclusive(parent, name);
        if (IS_ERR(dentry))
                goto out;
@@ -770,7 +770,7 @@ static struct dentry *rpc_mkdir_populate(struct dentry *parent,
                        goto err_rmdir;
        }
 out:
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        return dentry;
 err_rmdir:
        __rpc_rmdir(dir, dentry);
@@ -788,11 +788,11 @@ static int rpc_rmdir_depopulate(struct dentry *dentry,
 
        parent = dget_parent(dentry);
        dir = d_inode(parent);
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
        if (depopulate != NULL)
                depopulate(dentry);
        error = __rpc_rmdir(dir, dentry);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        dput(parent);
        return error;
 }
@@ -828,7 +828,7 @@ struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
        if (pipe->ops->downcall == NULL)
                umode &= ~S_IWUGO;
 
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
        dentry = __rpc_lookup_create_exclusive(parent, name);
        if (IS_ERR(dentry))
                goto out;
@@ -837,7 +837,7 @@ struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
        if (err)
                goto out_err;
 out:
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        return dentry;
 out_err:
        dentry = ERR_PTR(err);
@@ -865,9 +865,9 @@ rpc_unlink(struct dentry *dentry)
 
        parent = dget_parent(dentry);
        dir = d_inode(parent);
-       mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+       inode_lock_nested(dir, I_MUTEX_PARENT);
        error = __rpc_rmpipe(dir, dentry);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        dput(parent);
        return error;
 }
index 2e98f4a..37edea6 100644 (file)
@@ -1425,3 +1425,4 @@ void xprt_put(struct rpc_xprt *xprt)
        if (atomic_dec_and_test(&xprt->count))
                xprt_destroy(xprt);
 }
+EXPORT_SYMBOL_GPL(xprt_put);
index 33f99d3..dc9f3b5 100644 (file)
@@ -2,7 +2,7 @@ obj-$(CONFIG_SUNRPC_XPRT_RDMA) += rpcrdma.o
 
 rpcrdma-y := transport.o rpc_rdma.o verbs.o \
        fmr_ops.o frwr_ops.o physical_ops.o \
-       svc_rdma.o svc_rdma_transport.o \
+       svc_rdma.o svc_rdma_backchannel.o svc_rdma_transport.o \
        svc_rdma_marshal.o svc_rdma_sendto.o svc_rdma_recvfrom.o \
        module.o
 rpcrdma-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel.o
index c683684..e165673 100644 (file)
@@ -190,12 +190,11 @@ static int
 frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
             struct rpcrdma_create_data_internal *cdata)
 {
-       struct ib_device_attr *devattr = &ia->ri_devattr;
        int depth, delta;
 
        ia->ri_max_frmr_depth =
                        min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
-                             devattr->max_fast_reg_page_list_len);
+                             ia->ri_device->attrs.max_fast_reg_page_list_len);
        dprintk("RPC:       %s: device's max FR page list len = %u\n",
                __func__, ia->ri_max_frmr_depth);
 
@@ -222,8 +221,8 @@ frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
        }
 
        ep->rep_attr.cap.max_send_wr *= depth;
-       if (ep->rep_attr.cap.max_send_wr > devattr->max_qp_wr) {
-               cdata->max_requests = devattr->max_qp_wr / depth;
+       if (ep->rep_attr.cap.max_send_wr > ia->ri_device->attrs.max_qp_wr) {
+               cdata->max_requests = ia->ri_device->attrs.max_qp_wr / depth;
                if (!cdata->max_requests)
                        return -EINVAL;
                ep->rep_attr.cap.max_send_wr = cdata->max_requests *
index 1b7051b..c846ca9 100644 (file)
@@ -55,6 +55,7 @@ unsigned int svcrdma_ord = RPCRDMA_ORD;
 static unsigned int min_ord = 1;
 static unsigned int max_ord = 4096;
 unsigned int svcrdma_max_requests = RPCRDMA_MAX_REQUESTS;
+unsigned int svcrdma_max_bc_requests = RPCRDMA_MAX_BC_REQUESTS;
 static unsigned int min_max_requests = 4;
 static unsigned int max_max_requests = 16384;
 unsigned int svcrdma_max_req_size = RPCRDMA_MAX_REQ_SIZE;
@@ -71,10 +72,6 @@ atomic_t rdma_stat_rq_prod;
 atomic_t rdma_stat_sq_poll;
 atomic_t rdma_stat_sq_prod;
 
-/* Temporary NFS request map and context caches */
-struct kmem_cache *svc_rdma_map_cachep;
-struct kmem_cache *svc_rdma_ctxt_cachep;
-
 struct workqueue_struct *svc_rdma_wq;
 
 /*
@@ -243,17 +240,16 @@ void svc_rdma_cleanup(void)
        svc_unreg_xprt_class(&svc_rdma_bc_class);
 #endif
        svc_unreg_xprt_class(&svc_rdma_class);
-       kmem_cache_destroy(svc_rdma_map_cachep);
-       kmem_cache_destroy(svc_rdma_ctxt_cachep);
 }
 
 int svc_rdma_init(void)
 {
        dprintk("SVCRDMA Module Init, register RPC RDMA transport\n");
        dprintk("\tsvcrdma_ord      : %d\n", svcrdma_ord);
-       dprintk("\tmax_requests     : %d\n", svcrdma_max_requests);
-       dprintk("\tsq_depth         : %d\n",
+       dprintk("\tmax_requests     : %u\n", svcrdma_max_requests);
+       dprintk("\tsq_depth         : %u\n",
                svcrdma_max_requests * RPCRDMA_SQ_DEPTH_MULT);
+       dprintk("\tmax_bc_requests  : %u\n", svcrdma_max_bc_requests);
        dprintk("\tmax_inline       : %d\n", svcrdma_max_req_size);
 
        svc_rdma_wq = alloc_workqueue("svc_rdma", 0, 0);
@@ -264,39 +260,10 @@ int svc_rdma_init(void)
                svcrdma_table_header =
                        register_sysctl_table(svcrdma_root_table);
 
-       /* Create the temporary map cache */
-       svc_rdma_map_cachep = kmem_cache_create("svc_rdma_map_cache",
-                                               sizeof(struct svc_rdma_req_map),
-                                               0,
-                                               SLAB_HWCACHE_ALIGN,
-                                               NULL);
-       if (!svc_rdma_map_cachep) {
-               printk(KERN_INFO "Could not allocate map cache.\n");
-               goto err0;
-       }
-
-       /* Create the temporary context cache */
-       svc_rdma_ctxt_cachep =
-               kmem_cache_create("svc_rdma_ctxt_cache",
-                                 sizeof(struct svc_rdma_op_ctxt),
-                                 0,
-                                 SLAB_HWCACHE_ALIGN,
-                                 NULL);
-       if (!svc_rdma_ctxt_cachep) {
-               printk(KERN_INFO "Could not allocate WR ctxt cache.\n");
-               goto err1;
-       }
-
        /* Register RDMA with the SVC transport switch */
        svc_reg_xprt_class(&svc_rdma_class);
 #if defined(CONFIG_SUNRPC_BACKCHANNEL)
        svc_reg_xprt_class(&svc_rdma_bc_class);
 #endif
        return 0;
- err1:
-       kmem_cache_destroy(svc_rdma_map_cachep);
- err0:
-       unregister_sysctl_table(svcrdma_table_header);
-       destroy_workqueue(svc_rdma_wq);
-       return -ENOMEM;
 }
diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
new file mode 100644 (file)
index 0000000..65a7c23
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2015 Oracle.  All rights reserved.
+ *
+ * Support for backward direction RPCs on RPC/RDMA (server-side).
+ */
+
+#include <linux/sunrpc/svc_rdma.h>
+#include "xprt_rdma.h"
+
+#define RPCDBG_FACILITY        RPCDBG_SVCXPRT
+
+#undef SVCRDMA_BACKCHANNEL_DEBUG
+
+int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, struct rpcrdma_msg *rmsgp,
+                            struct xdr_buf *rcvbuf)
+{
+       struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+       struct kvec *dst, *src = &rcvbuf->head[0];
+       struct rpc_rqst *req;
+       unsigned long cwnd;
+       u32 credits;
+       size_t len;
+       __be32 xid;
+       __be32 *p;
+       int ret;
+
+       p = (__be32 *)src->iov_base;
+       len = src->iov_len;
+       xid = rmsgp->rm_xid;
+
+#ifdef SVCRDMA_BACKCHANNEL_DEBUG
+       pr_info("%s: xid=%08x, length=%zu\n",
+               __func__, be32_to_cpu(xid), len);
+       pr_info("%s: RPC/RDMA: %*ph\n",
+               __func__, (int)RPCRDMA_HDRLEN_MIN, rmsgp);
+       pr_info("%s:      RPC: %*ph\n",
+               __func__, (int)len, p);
+#endif
+
+       ret = -EAGAIN;
+       if (src->iov_len < 24)
+               goto out_shortreply;
+
+       spin_lock_bh(&xprt->transport_lock);
+       req = xprt_lookup_rqst(xprt, xid);
+       if (!req)
+               goto out_notfound;
+
+       dst = &req->rq_private_buf.head[0];
+       memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf));
+       if (dst->iov_len < len)
+               goto out_unlock;
+       memcpy(dst->iov_base, p, len);
+
+       credits = be32_to_cpu(rmsgp->rm_credit);
+       if (credits == 0)
+               credits = 1;    /* don't deadlock */
+       else if (credits > r_xprt->rx_buf.rb_bc_max_requests)
+               credits = r_xprt->rx_buf.rb_bc_max_requests;
+
+       cwnd = xprt->cwnd;
+       xprt->cwnd = credits << RPC_CWNDSHIFT;
+       if (xprt->cwnd > cwnd)
+               xprt_release_rqst_cong(req->rq_task);
+
+       ret = 0;
+       xprt_complete_rqst(req->rq_task, rcvbuf->len);
+       rcvbuf->len = 0;
+
+out_unlock:
+       spin_unlock_bh(&xprt->transport_lock);
+out:
+       return ret;
+
+out_shortreply:
+       dprintk("svcrdma: short bc reply: xprt=%p, len=%zu\n",
+               xprt, src->iov_len);
+       goto out;
+
+out_notfound:
+       dprintk("svcrdma: unrecognized bc reply: xprt=%p, xid=%08x\n",
+               xprt, be32_to_cpu(xid));
+
+       goto out_unlock;
+}
+
+/* Send a backwards direction RPC call.
+ *
+ * Caller holds the connection's mutex and has already marshaled
+ * the RPC/RDMA request.
+ *
+ * This is similar to svc_rdma_reply, but takes an rpc_rqst
+ * instead, does not support chunks, and avoids blocking memory
+ * allocation.
+ *
+ * XXX: There is still an opportunity to block in svc_rdma_send()
+ * if there are no SQ entries to post the Send. This may occur if
+ * the adapter has a small maximum SQ depth.
+ */
+static int svc_rdma_bc_sendto(struct svcxprt_rdma *rdma,
+                             struct rpc_rqst *rqst)
+{
+       struct xdr_buf *sndbuf = &rqst->rq_snd_buf;
+       struct svc_rdma_op_ctxt *ctxt;
+       struct svc_rdma_req_map *vec;
+       struct ib_send_wr send_wr;
+       int ret;
+
+       vec = svc_rdma_get_req_map(rdma);
+       ret = svc_rdma_map_xdr(rdma, sndbuf, vec);
+       if (ret)
+               goto out_err;
+
+       /* Post a recv buffer to handle the reply for this request. */
+       ret = svc_rdma_post_recv(rdma, GFP_NOIO);
+       if (ret) {
+               pr_err("svcrdma: Failed to post bc receive buffer, err=%d.\n",
+                      ret);
+               pr_err("svcrdma: closing transport %p.\n", rdma);
+               set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
+               ret = -ENOTCONN;
+               goto out_err;
+       }
+
+       ctxt = svc_rdma_get_context(rdma);
+       ctxt->pages[0] = virt_to_page(rqst->rq_buffer);
+       ctxt->count = 1;
+
+       ctxt->wr_op = IB_WR_SEND;
+       ctxt->direction = DMA_TO_DEVICE;
+       ctxt->sge[0].lkey = rdma->sc_pd->local_dma_lkey;
+       ctxt->sge[0].length = sndbuf->len;
+       ctxt->sge[0].addr =
+           ib_dma_map_page(rdma->sc_cm_id->device, ctxt->pages[0], 0,
+                           sndbuf->len, DMA_TO_DEVICE);
+       if (ib_dma_mapping_error(rdma->sc_cm_id->device, ctxt->sge[0].addr)) {
+               ret = -EIO;
+               goto out_unmap;
+       }
+       atomic_inc(&rdma->sc_dma_used);
+
+       memset(&send_wr, 0, sizeof(send_wr));
+       send_wr.wr_id = (unsigned long)ctxt;
+       send_wr.sg_list = ctxt->sge;
+       send_wr.num_sge = 1;
+       send_wr.opcode = IB_WR_SEND;
+       send_wr.send_flags = IB_SEND_SIGNALED;
+
+       ret = svc_rdma_send(rdma, &send_wr);
+       if (ret) {
+               ret = -EIO;
+               goto out_unmap;
+       }
+
+out_err:
+       svc_rdma_put_req_map(rdma, vec);
+       dprintk("svcrdma: %s returns %d\n", __func__, ret);
+       return ret;
+
+out_unmap:
+       svc_rdma_unmap_dma(ctxt);
+       svc_rdma_put_context(ctxt, 1);
+       goto out_err;
+}
+
+/* Server-side transport endpoint wants a whole page for its send
+ * buffer. The client RPC code constructs the RPC header in this
+ * buffer before it invokes ->send_request.
+ *
+ * Returns NULL if there was a temporary allocation failure.
+ */
+static void *
+xprt_rdma_bc_allocate(struct rpc_task *task, size_t size)
+{
+       struct rpc_rqst *rqst = task->tk_rqstp;
+       struct svc_xprt *sxprt = rqst->rq_xprt->bc_xprt;
+       struct svcxprt_rdma *rdma;
+       struct page *page;
+
+       rdma = container_of(sxprt, struct svcxprt_rdma, sc_xprt);
+
+       /* Prevent an infinite loop: try to make this case work */
+       if (size > PAGE_SIZE)
+               WARN_ONCE(1, "svcrdma: large bc buffer request (size %zu)\n",
+                         size);
+
+       page = alloc_page(RPCRDMA_DEF_GFP);
+       if (!page)
+               return NULL;
+
+       return page_address(page);
+}
+
+static void
+xprt_rdma_bc_free(void *buffer)
+{
+       /* No-op: ctxt and page have already been freed. */
+}
+
+static int
+rpcrdma_bc_send_request(struct svcxprt_rdma *rdma, struct rpc_rqst *rqst)
+{
+       struct rpc_xprt *xprt = rqst->rq_xprt;
+       struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+       struct rpcrdma_msg *headerp = (struct rpcrdma_msg *)rqst->rq_buffer;
+       int rc;
+
+       /* Space in the send buffer for an RPC/RDMA header is reserved
+        * via xprt->tsh_size.
+        */
+       headerp->rm_xid = rqst->rq_xid;
+       headerp->rm_vers = rpcrdma_version;
+       headerp->rm_credit = cpu_to_be32(r_xprt->rx_buf.rb_bc_max_requests);
+       headerp->rm_type = rdma_msg;
+       headerp->rm_body.rm_chunks[0] = xdr_zero;
+       headerp->rm_body.rm_chunks[1] = xdr_zero;
+       headerp->rm_body.rm_chunks[2] = xdr_zero;
+
+#ifdef SVCRDMA_BACKCHANNEL_DEBUG
+       pr_info("%s: %*ph\n", __func__, 64, rqst->rq_buffer);
+#endif
+
+       rc = svc_rdma_bc_sendto(rdma, rqst);
+       if (rc)
+               goto drop_connection;
+       return rc;
+
+drop_connection:
+       dprintk("svcrdma: failed to send bc call\n");
+       xprt_disconnect_done(xprt);
+       return -ENOTCONN;
+}
+
+/* Send an RPC call on the passive end of a transport
+ * connection.
+ */
+static int
+xprt_rdma_bc_send_request(struct rpc_task *task)
+{
+       struct rpc_rqst *rqst = task->tk_rqstp;
+       struct svc_xprt *sxprt = rqst->rq_xprt->bc_xprt;
+       struct svcxprt_rdma *rdma;
+       int ret;
+
+       dprintk("svcrdma: sending bc call with xid: %08x\n",
+               be32_to_cpu(rqst->rq_xid));
+
+       if (!mutex_trylock(&sxprt->xpt_mutex)) {
+               rpc_sleep_on(&sxprt->xpt_bc_pending, task, NULL);
+               if (!mutex_trylock(&sxprt->xpt_mutex))
+                       return -EAGAIN;
+               rpc_wake_up_queued_task(&sxprt->xpt_bc_pending, task);
+       }
+
+       ret = -ENOTCONN;
+       rdma = container_of(sxprt, struct svcxprt_rdma, sc_xprt);
+       if (!test_bit(XPT_DEAD, &sxprt->xpt_flags))
+               ret = rpcrdma_bc_send_request(rdma, rqst);
+
+       mutex_unlock(&sxprt->xpt_mutex);
+
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
+static void
+xprt_rdma_bc_close(struct rpc_xprt *xprt)
+{
+       dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
+}
+
+static void
+xprt_rdma_bc_put(struct rpc_xprt *xprt)
+{
+       dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
+
+       xprt_free(xprt);
+       module_put(THIS_MODULE);
+}
+
+static struct rpc_xprt_ops xprt_rdma_bc_procs = {
+       .reserve_xprt           = xprt_reserve_xprt_cong,
+       .release_xprt           = xprt_release_xprt_cong,
+       .alloc_slot             = xprt_alloc_slot,
+       .release_request        = xprt_release_rqst_cong,
+       .buf_alloc              = xprt_rdma_bc_allocate,
+       .buf_free               = xprt_rdma_bc_free,
+       .send_request           = xprt_rdma_bc_send_request,
+       .set_retrans_timeout    = xprt_set_retrans_timeout_def,
+       .close                  = xprt_rdma_bc_close,
+       .destroy                = xprt_rdma_bc_put,
+       .print_stats            = xprt_rdma_print_stats
+};
+
+static const struct rpc_timeout xprt_rdma_bc_timeout = {
+       .to_initval = 60 * HZ,
+       .to_maxval = 60 * HZ,
+};
+
+/* It shouldn't matter if the number of backchannel session slots
+ * doesn't match the number of RPC/RDMA credits. That just means
+ * one or the other will have extra slots that aren't used.
+ */
+static struct rpc_xprt *
+xprt_setup_rdma_bc(struct xprt_create *args)
+{
+       struct rpc_xprt *xprt;
+       struct rpcrdma_xprt *new_xprt;
+
+       if (args->addrlen > sizeof(xprt->addr)) {
+               dprintk("RPC:       %s: address too large\n", __func__);
+               return ERR_PTR(-EBADF);
+       }
+
+       xprt = xprt_alloc(args->net, sizeof(*new_xprt),
+                         RPCRDMA_MAX_BC_REQUESTS,
+                         RPCRDMA_MAX_BC_REQUESTS);
+       if (!xprt) {
+               dprintk("RPC:       %s: couldn't allocate rpc_xprt\n",
+                       __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       xprt->timeout = &xprt_rdma_bc_timeout;
+       xprt_set_bound(xprt);
+       xprt_set_connected(xprt);
+       xprt->bind_timeout = RPCRDMA_BIND_TO;
+       xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO;
+       xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO;
+
+       xprt->prot = XPRT_TRANSPORT_BC_RDMA;
+       xprt->tsh_size = RPCRDMA_HDRLEN_MIN / sizeof(__be32);
+       xprt->ops = &xprt_rdma_bc_procs;
+
+       memcpy(&xprt->addr, args->dstaddr, args->addrlen);
+       xprt->addrlen = args->addrlen;
+       xprt_rdma_format_addresses(xprt, (struct sockaddr *)&xprt->addr);
+       xprt->resvport = 0;
+
+       xprt->max_payload = xprt_rdma_max_inline_read;
+
+       new_xprt = rpcx_to_rdmax(xprt);
+       new_xprt->rx_buf.rb_bc_max_requests = xprt->max_reqs;
+
+       xprt_get(xprt);
+       args->bc_xprt->xpt_bc_xprt = xprt;
+       xprt->bc_xprt = args->bc_xprt;
+
+       if (!try_module_get(THIS_MODULE))
+               goto out_fail;
+
+       /* Final put for backchannel xprt is in __svc_rdma_free */
+       xprt_get(xprt);
+       return xprt;
+
+out_fail:
+       xprt_rdma_free_addresses(xprt);
+       args->bc_xprt->xpt_bc_xprt = NULL;
+       xprt_put(xprt);
+       xprt_free(xprt);
+       return ERR_PTR(-EINVAL);
+}
+
+struct xprt_class xprt_rdma_bc = {
+       .list                   = LIST_HEAD_INIT(xprt_rdma_bc.list),
+       .name                   = "rdma backchannel",
+       .owner                  = THIS_MODULE,
+       .ident                  = XPRT_TRANSPORT_BC_RDMA,
+       .setup                  = xprt_setup_rdma_bc,
+};
index ff4f01e..c8b8a8b 100644 (file)
@@ -144,6 +144,7 @@ int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
 
                head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no];
                head->arg.page_len += len;
+
                head->arg.len += len;
                if (!pg_off)
                        head->count++;
@@ -160,8 +161,7 @@ int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
                        goto err;
                atomic_inc(&xprt->sc_dma_used);
 
-               /* The lkey here is either a local dma lkey or a dma_mr lkey */
-               ctxt->sge[pno].lkey = xprt->sc_dma_lkey;
+               ctxt->sge[pno].lkey = xprt->sc_pd->local_dma_lkey;
                ctxt->sge[pno].length = len;
                ctxt->count++;
 
@@ -567,6 +567,38 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
        return ret;
 }
 
+/* By convention, backchannel calls arrive via rdma_msg type
+ * messages, and never populate the chunk lists. This makes
+ * the RPC/RDMA header small and fixed in size, so it is
+ * straightforward to check the RPC header's direction field.
+ */
+static bool
+svc_rdma_is_backchannel_reply(struct svc_xprt *xprt, struct rpcrdma_msg *rmsgp)
+{
+       __be32 *p = (__be32 *)rmsgp;
+
+       if (!xprt->xpt_bc_xprt)
+               return false;
+
+       if (rmsgp->rm_type != rdma_msg)
+               return false;
+       if (rmsgp->rm_body.rm_chunks[0] != xdr_zero)
+               return false;
+       if (rmsgp->rm_body.rm_chunks[1] != xdr_zero)
+               return false;
+       if (rmsgp->rm_body.rm_chunks[2] != xdr_zero)
+               return false;
+
+       /* sanity */
+       if (p[7] != rmsgp->rm_xid)
+               return false;
+       /* call direction */
+       if (p[8] == cpu_to_be32(RPC_CALL))
+               return false;
+
+       return true;
+}
+
 /*
  * Set up the rqstp thread context to point to the RQ buffer. If
  * necessary, pull additional data from the client with an RDMA_READ
@@ -632,6 +664,15 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
                goto close_out;
        }
 
+       if (svc_rdma_is_backchannel_reply(xprt, rmsgp)) {
+               ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, rmsgp,
+                                              &rqstp->rq_arg);
+               svc_rdma_put_context(ctxt, 0);
+               if (ret)
+                       goto repost;
+               return ret;
+       }
+
        /* Read read-list data. */
        ret = rdma_read_chunks(rdma_xprt, rmsgp, rqstp, ctxt);
        if (ret > 0) {
@@ -668,4 +709,15 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
        set_bit(XPT_CLOSE, &xprt->xpt_flags);
 defer:
        return 0;
+
+repost:
+       ret = svc_rdma_post_recv(rdma_xprt, GFP_KERNEL);
+       if (ret) {
+               pr_err("svcrdma: could not post a receive buffer, err=%d.\n",
+                      ret);
+               pr_err("svcrdma: closing transport %p.\n", rdma_xprt);
+               set_bit(XPT_CLOSE, &rdma_xprt->sc_xprt.xpt_flags);
+               ret = -ENOTCONN;
+       }
+       return ret;
 }
index 969a1ab..df57f3c 100644 (file)
@@ -50,9 +50,9 @@
 
 #define RPCDBG_FACILITY        RPCDBG_SVCXPRT
 
-static int map_xdr(struct svcxprt_rdma *xprt,
-                  struct xdr_buf *xdr,
-                  struct svc_rdma_req_map *vec)
+int svc_rdma_map_xdr(struct svcxprt_rdma *xprt,
+                    struct xdr_buf *xdr,
+                    struct svc_rdma_req_map *vec)
 {
        int sge_no;
        u32 sge_bytes;
@@ -62,7 +62,7 @@ static int map_xdr(struct svcxprt_rdma *xprt,
 
        if (xdr->len !=
            (xdr->head[0].iov_len + xdr->page_len + xdr->tail[0].iov_len)) {
-               pr_err("svcrdma: map_xdr: XDR buffer length error\n");
+               pr_err("svcrdma: %s: XDR buffer length error\n", __func__);
                return -EIO;
        }
 
@@ -97,9 +97,9 @@ static int map_xdr(struct svcxprt_rdma *xprt,
                sge_no++;
        }
 
-       dprintk("svcrdma: map_xdr: sge_no %d page_no %d "
+       dprintk("svcrdma: %s: sge_no %d page_no %d "
                "page_base %u page_len %u head_len %zu tail_len %zu\n",
-               sge_no, page_no, xdr->page_base, xdr->page_len,
+               __func__, sge_no, page_no, xdr->page_base, xdr->page_len,
                xdr->head[0].iov_len, xdr->tail[0].iov_len);
 
        vec->count = sge_no;
@@ -265,7 +265,7 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
                                         sge[sge_no].addr))
                        goto err;
                atomic_inc(&xprt->sc_dma_used);
-               sge[sge_no].lkey = xprt->sc_dma_lkey;
+               sge[sge_no].lkey = xprt->sc_pd->local_dma_lkey;
                ctxt->count++;
                sge_off = 0;
                sge_no++;
@@ -465,7 +465,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
        int ret;
 
        /* Post a recv buffer to handle another request. */
-       ret = svc_rdma_post_recv(rdma);
+       ret = svc_rdma_post_recv(rdma, GFP_KERNEL);
        if (ret) {
                printk(KERN_INFO
                       "svcrdma: could not post a receive buffer, err=%d."
@@ -480,7 +480,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
        ctxt->count = 1;
 
        /* Prepare the SGE for the RPCRDMA Header */
-       ctxt->sge[0].lkey = rdma->sc_dma_lkey;
+       ctxt->sge[0].lkey = rdma->sc_pd->local_dma_lkey;
        ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp);
        ctxt->sge[0].addr =
            ib_dma_map_page(rdma->sc_cm_id->device, page, 0,
@@ -504,7 +504,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
                                         ctxt->sge[sge_no].addr))
                        goto err;
                atomic_inc(&rdma->sc_dma_used);
-               ctxt->sge[sge_no].lkey = rdma->sc_dma_lkey;
+               ctxt->sge[sge_no].lkey = rdma->sc_pd->local_dma_lkey;
                ctxt->sge[sge_no].length = sge_bytes;
        }
        if (byte_count != 0) {
@@ -591,14 +591,17 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
        /* Build an req vec for the XDR */
        ctxt = svc_rdma_get_context(rdma);
        ctxt->direction = DMA_TO_DEVICE;
-       vec = svc_rdma_get_req_map();
-       ret = map_xdr(rdma, &rqstp->rq_res, vec);
+       vec = svc_rdma_get_req_map(rdma);
+       ret = svc_rdma_map_xdr(rdma, &rqstp->rq_res, vec);
        if (ret)
                goto err0;
        inline_bytes = rqstp->rq_res.len;
 
        /* Create the RDMA response header */
-       res_page = alloc_page(GFP_KERNEL | __GFP_NOFAIL);
+       ret = -ENOMEM;
+       res_page = alloc_page(GFP_KERNEL);
+       if (!res_page)
+               goto err0;
        rdma_resp = page_address(res_page);
        reply_ary = svc_rdma_get_reply_array(rdma_argp);
        if (reply_ary)
@@ -630,14 +633,14 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
 
        ret = send_reply(rdma, rqstp, res_page, rdma_resp, ctxt, vec,
                         inline_bytes);
-       svc_rdma_put_req_map(vec);
+       svc_rdma_put_req_map(rdma, vec);
        dprintk("svcrdma: send_reply returns %d\n", ret);
        return ret;
 
  err1:
        put_page(res_page);
  err0:
-       svc_rdma_put_req_map(vec);
+       svc_rdma_put_req_map(rdma, vec);
        svc_rdma_put_context(ctxt, 0);
        return ret;
 }
index b348b4a..5763825 100644 (file)
@@ -153,18 +153,76 @@ static void svc_rdma_bc_free(struct svc_xprt *xprt)
 }
 #endif /* CONFIG_SUNRPC_BACKCHANNEL */
 
-struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
+static struct svc_rdma_op_ctxt *alloc_ctxt(struct svcxprt_rdma *xprt,
+                                          gfp_t flags)
 {
        struct svc_rdma_op_ctxt *ctxt;
 
-       ctxt = kmem_cache_alloc(svc_rdma_ctxt_cachep,
-                               GFP_KERNEL | __GFP_NOFAIL);
-       ctxt->xprt = xprt;
-       INIT_LIST_HEAD(&ctxt->dto_q);
+       ctxt = kmalloc(sizeof(*ctxt), flags);
+       if (ctxt) {
+               ctxt->xprt = xprt;
+               INIT_LIST_HEAD(&ctxt->free);
+               INIT_LIST_HEAD(&ctxt->dto_q);
+       }
+       return ctxt;
+}
+
+static bool svc_rdma_prealloc_ctxts(struct svcxprt_rdma *xprt)
+{
+       unsigned int i;
+
+       /* Each RPC/RDMA credit can consume a number of send
+        * and receive WQEs. One ctxt is allocated for each.
+        */
+       i = xprt->sc_sq_depth + xprt->sc_rq_depth;
+
+       while (i--) {
+               struct svc_rdma_op_ctxt *ctxt;
+
+               ctxt = alloc_ctxt(xprt, GFP_KERNEL);
+               if (!ctxt) {
+                       dprintk("svcrdma: No memory for RDMA ctxt\n");
+                       return false;
+               }
+               list_add(&ctxt->free, &xprt->sc_ctxts);
+       }
+       return true;
+}
+
+struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
+{
+       struct svc_rdma_op_ctxt *ctxt = NULL;
+
+       spin_lock_bh(&xprt->sc_ctxt_lock);
+       xprt->sc_ctxt_used++;
+       if (list_empty(&xprt->sc_ctxts))
+               goto out_empty;
+
+       ctxt = list_first_entry(&xprt->sc_ctxts,
+                               struct svc_rdma_op_ctxt, free);
+       list_del_init(&ctxt->free);
+       spin_unlock_bh(&xprt->sc_ctxt_lock);
+
+out:
        ctxt->count = 0;
        ctxt->frmr = NULL;
-       atomic_inc(&xprt->sc_ctxt_used);
        return ctxt;
+
+out_empty:
+       /* Either pre-allocation missed the mark, or send
+        * queue accounting is broken.
+        */
+       spin_unlock_bh(&xprt->sc_ctxt_lock);
+
+       ctxt = alloc_ctxt(xprt, GFP_NOIO);
+       if (ctxt)
+               goto out;
+
+       spin_lock_bh(&xprt->sc_ctxt_lock);
+       xprt->sc_ctxt_used--;
+       spin_unlock_bh(&xprt->sc_ctxt_lock);
+       WARN_ONCE(1, "svcrdma: empty RDMA ctxt list?\n");
+       return NULL;
 }
 
 void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt)
@@ -174,11 +232,11 @@ void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt)
        for (i = 0; i < ctxt->count && ctxt->sge[i].length; i++) {
                /*
                 * Unmap the DMA addr in the SGE if the lkey matches
-                * the sc_dma_lkey, otherwise, ignore it since it is
+                * the local_dma_lkey, otherwise, ignore it since it is
                 * an FRMR lkey and will be unmapped later when the
                 * last WR that uses it completes.
                 */
-               if (ctxt->sge[i].lkey == xprt->sc_dma_lkey) {
+               if (ctxt->sge[i].lkey == xprt->sc_pd->local_dma_lkey) {
                        atomic_dec(&xprt->sc_dma_used);
                        ib_dma_unmap_page(xprt->sc_cm_id->device,
                                            ctxt->sge[i].addr,
@@ -190,35 +248,108 @@ void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt)
 
 void svc_rdma_put_context(struct svc_rdma_op_ctxt *ctxt, int free_pages)
 {
-       struct svcxprt_rdma *xprt;
+       struct svcxprt_rdma *xprt = ctxt->xprt;
        int i;
 
-       xprt = ctxt->xprt;
        if (free_pages)
                for (i = 0; i < ctxt->count; i++)
                        put_page(ctxt->pages[i]);
 
-       kmem_cache_free(svc_rdma_ctxt_cachep, ctxt);
-       atomic_dec(&xprt->sc_ctxt_used);
+       spin_lock_bh(&xprt->sc_ctxt_lock);
+       xprt->sc_ctxt_used--;
+       list_add(&ctxt->free, &xprt->sc_ctxts);
+       spin_unlock_bh(&xprt->sc_ctxt_lock);
 }
 
-/*
- * Temporary NFS req mappings are shared across all transport
- * instances. These are short lived and should be bounded by the number
- * of concurrent server threads * depth of the SQ.
- */
-struct svc_rdma_req_map *svc_rdma_get_req_map(void)
+static void svc_rdma_destroy_ctxts(struct svcxprt_rdma *xprt)
+{
+       while (!list_empty(&xprt->sc_ctxts)) {
+               struct svc_rdma_op_ctxt *ctxt;
+
+               ctxt = list_first_entry(&xprt->sc_ctxts,
+                                       struct svc_rdma_op_ctxt, free);
+               list_del(&ctxt->free);
+               kfree(ctxt);
+       }
+}
+
+static struct svc_rdma_req_map *alloc_req_map(gfp_t flags)
 {
        struct svc_rdma_req_map *map;
-       map = kmem_cache_alloc(svc_rdma_map_cachep,
-                              GFP_KERNEL | __GFP_NOFAIL);
+
+       map = kmalloc(sizeof(*map), flags);
+       if (map)
+               INIT_LIST_HEAD(&map->free);
+       return map;
+}
+
+static bool svc_rdma_prealloc_maps(struct svcxprt_rdma *xprt)
+{
+       unsigned int i;
+
+       /* One for each receive buffer on this connection. */
+       i = xprt->sc_max_requests;
+
+       while (i--) {
+               struct svc_rdma_req_map *map;
+
+               map = alloc_req_map(GFP_KERNEL);
+               if (!map) {
+                       dprintk("svcrdma: No memory for request map\n");
+                       return false;
+               }
+               list_add(&map->free, &xprt->sc_maps);
+       }
+       return true;
+}
+
+struct svc_rdma_req_map *svc_rdma_get_req_map(struct svcxprt_rdma *xprt)
+{
+       struct svc_rdma_req_map *map = NULL;
+
+       spin_lock(&xprt->sc_map_lock);
+       if (list_empty(&xprt->sc_maps))
+               goto out_empty;
+
+       map = list_first_entry(&xprt->sc_maps,
+                              struct svc_rdma_req_map, free);
+       list_del_init(&map->free);
+       spin_unlock(&xprt->sc_map_lock);
+
+out:
        map->count = 0;
        return map;
+
+out_empty:
+       spin_unlock(&xprt->sc_map_lock);
+
+       /* Pre-allocation amount was incorrect */
+       map = alloc_req_map(GFP_NOIO);
+       if (map)
+               goto out;
+
+       WARN_ONCE(1, "svcrdma: empty request map list?\n");
+       return NULL;
+}
+
+void svc_rdma_put_req_map(struct svcxprt_rdma *xprt,
+                         struct svc_rdma_req_map *map)
+{
+       spin_lock(&xprt->sc_map_lock);
+       list_add(&map->free, &xprt->sc_maps);
+       spin_unlock(&xprt->sc_map_lock);
 }
 
-void svc_rdma_put_req_map(struct svc_rdma_req_map *map)
+static void svc_rdma_destroy_maps(struct svcxprt_rdma *xprt)
 {
-       kmem_cache_free(svc_rdma_map_cachep, map);
+       while (!list_empty(&xprt->sc_maps)) {
+               struct svc_rdma_req_map *map;
+
+               map = list_first_entry(&xprt->sc_maps,
+                                      struct svc_rdma_req_map, free);
+               list_del(&map->free);
+               kfree(map);
+       }
 }
 
 /* ib_cq event handler */
@@ -386,46 +517,44 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt)
 static void process_context(struct svcxprt_rdma *xprt,
                            struct svc_rdma_op_ctxt *ctxt)
 {
+       struct svc_rdma_op_ctxt *read_hdr;
+       int free_pages = 0;
+
        svc_rdma_unmap_dma(ctxt);
 
        switch (ctxt->wr_op) {
        case IB_WR_SEND:
-               if (ctxt->frmr)
-                       pr_err("svcrdma: SEND: ctxt->frmr != NULL\n");
-               svc_rdma_put_context(ctxt, 1);
+               free_pages = 1;
                break;
 
        case IB_WR_RDMA_WRITE:
-               if (ctxt->frmr)
-                       pr_err("svcrdma: WRITE: ctxt->frmr != NULL\n");
-               svc_rdma_put_context(ctxt, 0);
                break;
 
        case IB_WR_RDMA_READ:
        case IB_WR_RDMA_READ_WITH_INV:
                svc_rdma_put_frmr(xprt, ctxt->frmr);
-               if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
-                       struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
-                       if (read_hdr) {
-                               spin_lock_bh(&xprt->sc_rq_dto_lock);
-                               set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
-                               list_add_tail(&read_hdr->dto_q,
-                                             &xprt->sc_read_complete_q);
-                               spin_unlock_bh(&xprt->sc_rq_dto_lock);
-                       } else {
-                               pr_err("svcrdma: ctxt->read_hdr == NULL\n");
-                       }
-                       svc_xprt_enqueue(&xprt->sc_xprt);
-               }
+
+               if (!test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags))
+                       break;
+
+               read_hdr = ctxt->read_hdr;
                svc_rdma_put_context(ctxt, 0);
-               break;
+
+               spin_lock_bh(&xprt->sc_rq_dto_lock);
+               set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
+               list_add_tail(&read_hdr->dto_q,
+                             &xprt->sc_read_complete_q);
+               spin_unlock_bh(&xprt->sc_rq_dto_lock);
+               svc_xprt_enqueue(&xprt->sc_xprt);
+               return;
 
        default:
-               printk(KERN_ERR "svcrdma: unexpected completion type, "
-                      "opcode=%d\n",
-                      ctxt->wr_op);
+               dprintk("svcrdma: unexpected completion opcode=%d\n",
+                       ctxt->wr_op);
                break;
        }
+
+       svc_rdma_put_context(ctxt, free_pages);
 }
 
 /*
@@ -523,19 +652,15 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
        INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q);
        INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q);
        INIT_LIST_HEAD(&cma_xprt->sc_frmr_q);
+       INIT_LIST_HEAD(&cma_xprt->sc_ctxts);
+       INIT_LIST_HEAD(&cma_xprt->sc_maps);
        init_waitqueue_head(&cma_xprt->sc_send_wait);
 
        spin_lock_init(&cma_xprt->sc_lock);
        spin_lock_init(&cma_xprt->sc_rq_dto_lock);
        spin_lock_init(&cma_xprt->sc_frmr_q_lock);
-
-       cma_xprt->sc_ord = svcrdma_ord;
-
-       cma_xprt->sc_max_req_size = svcrdma_max_req_size;
-       cma_xprt->sc_max_requests = svcrdma_max_requests;
-       cma_xprt->sc_sq_depth = svcrdma_max_requests * RPCRDMA_SQ_DEPTH_MULT;
-       atomic_set(&cma_xprt->sc_sq_count, 0);
-       atomic_set(&cma_xprt->sc_ctxt_used, 0);
+       spin_lock_init(&cma_xprt->sc_ctxt_lock);
+       spin_lock_init(&cma_xprt->sc_map_lock);
 
        if (listener)
                set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags);
@@ -543,7 +668,7 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
        return cma_xprt;
 }
 
-int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
+int svc_rdma_post_recv(struct svcxprt_rdma *xprt, gfp_t flags)
 {
        struct ib_recv_wr recv_wr, *bad_recv_wr;
        struct svc_rdma_op_ctxt *ctxt;
@@ -561,7 +686,9 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
                        pr_err("svcrdma: Too many sges (%d)\n", sge_no);
                        goto err_put_ctxt;
                }
-               page = alloc_page(GFP_KERNEL | __GFP_NOFAIL);
+               page = alloc_page(flags);
+               if (!page)
+                       goto err_put_ctxt;
                ctxt->pages[sge_no] = page;
                pa = ib_dma_map_page(xprt->sc_cm_id->device,
                                     page, 0, PAGE_SIZE,
@@ -571,7 +698,7 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
                atomic_inc(&xprt->sc_dma_used);
                ctxt->sge[sge_no].addr = pa;
                ctxt->sge[sge_no].length = PAGE_SIZE;
-               ctxt->sge[sge_no].lkey = xprt->sc_dma_lkey;
+               ctxt->sge[sge_no].lkey = xprt->sc_pd->local_dma_lkey;
                ctxt->count = sge_no + 1;
                buflen += PAGE_SIZE;
        }
@@ -886,11 +1013,9 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
        struct rdma_conn_param conn_param;
        struct ib_cq_init_attr cq_attr = {};
        struct ib_qp_init_attr qp_attr;
-       struct ib_device_attr devattr;
-       int uninitialized_var(dma_mr_acc);
-       int need_dma_mr = 0;
-       int ret;
-       int i;
+       struct ib_device *dev;
+       unsigned int i;
+       int ret = 0;
 
        listen_rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt);
        clear_bit(XPT_CONN, &xprt->xpt_flags);
@@ -910,37 +1035,42 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
        dprintk("svcrdma: newxprt from accept queue = %p, cm_id=%p\n",
                newxprt, newxprt->sc_cm_id);
 
-       ret = ib_query_device(newxprt->sc_cm_id->device, &devattr);
-       if (ret) {
-               dprintk("svcrdma: could not query device attributes on "
-                       "device %p, rc=%d\n", newxprt->sc_cm_id->device, ret);
-               goto errout;
-       }
+       dev = newxprt->sc_cm_id->device;
 
        /* Qualify the transport resource defaults with the
         * capabilities of this particular device */
-       newxprt->sc_max_sge = min((size_t)devattr.max_sge,
+       newxprt->sc_max_sge = min((size_t)dev->attrs.max_sge,
                                  (size_t)RPCSVC_MAXPAGES);
-       newxprt->sc_max_sge_rd = min_t(size_t, devattr.max_sge_rd,
+       newxprt->sc_max_sge_rd = min_t(size_t, dev->attrs.max_sge_rd,
                                       RPCSVC_MAXPAGES);
-       newxprt->sc_max_requests = min((size_t)devattr.max_qp_wr,
-                                  (size_t)svcrdma_max_requests);
-       newxprt->sc_sq_depth = RPCRDMA_SQ_DEPTH_MULT * newxprt->sc_max_requests;
+       newxprt->sc_max_req_size = svcrdma_max_req_size;
+       newxprt->sc_max_requests = min_t(u32, dev->attrs.max_qp_wr,
+                                        svcrdma_max_requests);
+       newxprt->sc_max_bc_requests = min_t(u32, dev->attrs.max_qp_wr,
+                                           svcrdma_max_bc_requests);
+       newxprt->sc_rq_depth = newxprt->sc_max_requests +
+                              newxprt->sc_max_bc_requests;
+       newxprt->sc_sq_depth = RPCRDMA_SQ_DEPTH_MULT * newxprt->sc_rq_depth;
+
+       if (!svc_rdma_prealloc_ctxts(newxprt))
+               goto errout;
+       if (!svc_rdma_prealloc_maps(newxprt))
+               goto errout;
 
        /*
         * Limit ORD based on client limit, local device limit, and
         * configured svcrdma limit.
         */
-       newxprt->sc_ord = min_t(size_t, devattr.max_qp_rd_atom, newxprt->sc_ord);
+       newxprt->sc_ord = min_t(size_t, dev->attrs.max_qp_rd_atom, newxprt->sc_ord);
        newxprt->sc_ord = min_t(size_t, svcrdma_ord, newxprt->sc_ord);
 
-       newxprt->sc_pd = ib_alloc_pd(newxprt->sc_cm_id->device);
+       newxprt->sc_pd = ib_alloc_pd(dev);
        if (IS_ERR(newxprt->sc_pd)) {
                dprintk("svcrdma: error creating PD for connect request\n");
                goto errout;
        }
        cq_attr.cqe = newxprt->sc_sq_depth;
-       newxprt->sc_sq_cq = ib_create_cq(newxprt->sc_cm_id->device,
+       newxprt->sc_sq_cq = ib_create_cq(dev,
                                         sq_comp_handler,
                                         cq_event_handler,
                                         newxprt,
@@ -949,8 +1079,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
                dprintk("svcrdma: error creating SQ CQ for connect request\n");
                goto errout;
        }
-       cq_attr.cqe = newxprt->sc_max_requests;
-       newxprt->sc_rq_cq = ib_create_cq(newxprt->sc_cm_id->device,
+       cq_attr.cqe = newxprt->sc_rq_depth;
+       newxprt->sc_rq_cq = ib_create_cq(dev,
                                         rq_comp_handler,
                                         cq_event_handler,
                                         newxprt,
@@ -964,7 +1094,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
        qp_attr.event_handler = qp_event_handler;
        qp_attr.qp_context = &newxprt->sc_xprt;
        qp_attr.cap.max_send_wr = newxprt->sc_sq_depth;
-       qp_attr.cap.max_recv_wr = newxprt->sc_max_requests;
+       qp_attr.cap.max_recv_wr = newxprt->sc_rq_depth;
        qp_attr.cap.max_send_sge = newxprt->sc_max_sge;
        qp_attr.cap.max_recv_sge = newxprt->sc_max_sge;
        qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
@@ -978,7 +1108,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
                "    cap.max_send_sge = %d\n"
                "    cap.max_recv_sge = %d\n",
                newxprt->sc_cm_id, newxprt->sc_pd,
-               newxprt->sc_cm_id->device, newxprt->sc_pd->device,
+               dev, newxprt->sc_pd->device,
                qp_attr.cap.max_send_wr,
                qp_attr.cap.max_recv_wr,
                qp_attr.cap.max_send_sge,
@@ -1014,9 +1144,9 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
         *      of an RDMA_READ. IB does not.
         */
        newxprt->sc_reader = rdma_read_chunk_lcl;
-       if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
+       if (dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
                newxprt->sc_frmr_pg_list_len =
-                       devattr.max_fast_reg_page_list_len;
+                       dev->attrs.max_fast_reg_page_list_len;
                newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG;
                newxprt->sc_reader = rdma_read_chunk_frmr;
        }
@@ -1024,44 +1154,16 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
        /*
         * Determine if a DMA MR is required and if so, what privs are required
         */
-       if (!rdma_protocol_iwarp(newxprt->sc_cm_id->device,
-                                newxprt->sc_cm_id->port_num) &&
-           !rdma_ib_or_roce(newxprt->sc_cm_id->device,
-                            newxprt->sc_cm_id->port_num))
+       if (!rdma_protocol_iwarp(dev, newxprt->sc_cm_id->port_num) &&
+           !rdma_ib_or_roce(dev, newxprt->sc_cm_id->port_num))
                goto errout;
 
-       if (!(newxprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG) ||
-           !(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) {
-               need_dma_mr = 1;
-               dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
-               if (rdma_protocol_iwarp(newxprt->sc_cm_id->device,
-                                       newxprt->sc_cm_id->port_num) &&
-                   !(newxprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG))
-                       dma_mr_acc |= IB_ACCESS_REMOTE_WRITE;
-       }
-
-       if (rdma_protocol_iwarp(newxprt->sc_cm_id->device,
-                               newxprt->sc_cm_id->port_num))
+       if (rdma_protocol_iwarp(dev, newxprt->sc_cm_id->port_num))
                newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_READ_W_INV;
 
-       /* Create the DMA MR if needed, otherwise, use the DMA LKEY */
-       if (need_dma_mr) {
-               /* Register all of physical memory */
-               newxprt->sc_phys_mr =
-                       ib_get_dma_mr(newxprt->sc_pd, dma_mr_acc);
-               if (IS_ERR(newxprt->sc_phys_mr)) {
-                       dprintk("svcrdma: Failed to create DMA MR ret=%d\n",
-                               ret);
-                       goto errout;
-               }
-               newxprt->sc_dma_lkey = newxprt->sc_phys_mr->lkey;
-       } else
-               newxprt->sc_dma_lkey =
-                       newxprt->sc_cm_id->device->local_dma_lkey;
-
        /* Post receive buffers */
-       for (i = 0; i < newxprt->sc_max_requests; i++) {
-               ret = svc_rdma_post_recv(newxprt);
+       for (i = 0; i < newxprt->sc_rq_depth; i++) {
+               ret = svc_rdma_post_recv(newxprt, GFP_KERNEL);
                if (ret) {
                        dprintk("svcrdma: failure posting receive buffers\n");
                        goto errout;
@@ -1160,12 +1262,14 @@ static void __svc_rdma_free(struct work_struct *work)
 {
        struct svcxprt_rdma *rdma =
                container_of(work, struct svcxprt_rdma, sc_work);
-       dprintk("svcrdma: svc_rdma_free(%p)\n", rdma);
+       struct svc_xprt *xprt = &rdma->sc_xprt;
+
+       dprintk("svcrdma: %s(%p)\n", __func__, rdma);
 
        /* We should only be called from kref_put */
-       if (atomic_read(&rdma->sc_xprt.xpt_ref.refcount) != 0)
+       if (atomic_read(&xprt->xpt_ref.refcount) != 0)
                pr_err("svcrdma: sc_xprt still in use? (%d)\n",
-                      atomic_read(&rdma->sc_xprt.xpt_ref.refcount));
+                      atomic_read(&xprt->xpt_ref.refcount));
 
        /*
         * Destroy queued, but not processed read completions. Note
@@ -1193,15 +1297,22 @@ static void __svc_rdma_free(struct work_struct *work)
        }
 
        /* Warn if we leaked a resource or under-referenced */
-       if (atomic_read(&rdma->sc_ctxt_used) != 0)
+       if (rdma->sc_ctxt_used != 0)
                pr_err("svcrdma: ctxt still in use? (%d)\n",
-                      atomic_read(&rdma->sc_ctxt_used));
+                      rdma->sc_ctxt_used);
        if (atomic_read(&rdma->sc_dma_used) != 0)
                pr_err("svcrdma: dma still in use? (%d)\n",
                       atomic_read(&rdma->sc_dma_used));
 
-       /* De-allocate fastreg mr */
+       /* Final put of backchannel client transport */
+       if (xprt->xpt_bc_xprt) {
+               xprt_put(xprt->xpt_bc_xprt);
+               xprt->xpt_bc_xprt = NULL;
+       }
+
        rdma_dealloc_frmr_q(rdma);
+       svc_rdma_destroy_ctxts(rdma);
+       svc_rdma_destroy_maps(rdma);
 
        /* Destroy the QP if present (not a listener) */
        if (rdma->sc_qp && !IS_ERR(rdma->sc_qp))
@@ -1213,9 +1324,6 @@ static void __svc_rdma_free(struct work_struct *work)
        if (rdma->sc_rq_cq && !IS_ERR(rdma->sc_rq_cq))
                ib_destroy_cq(rdma->sc_rq_cq);
 
-       if (rdma->sc_phys_mr && !IS_ERR(rdma->sc_phys_mr))
-               ib_dereg_mr(rdma->sc_phys_mr);
-
        if (rdma->sc_pd && !IS_ERR(rdma->sc_pd))
                ib_dealloc_pd(rdma->sc_pd);
 
@@ -1321,7 +1429,9 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
        int length;
        int ret;
 
-       p = alloc_page(GFP_KERNEL | __GFP_NOFAIL);
+       p = alloc_page(GFP_KERNEL);
+       if (!p)
+               return;
        va = page_address(p);
 
        /* XDR encode error */
@@ -1341,7 +1451,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
                return;
        }
        atomic_inc(&xprt->sc_dma_used);
-       ctxt->sge[0].lkey = xprt->sc_dma_lkey;
+       ctxt->sge[0].lkey = xprt->sc_pd->local_dma_lkey;
        ctxt->sge[0].length = length;
 
        /* Prepare SEND WR */
index 740bddc..b1b009f 100644 (file)
@@ -63,7 +63,7 @@
  */
 
 static unsigned int xprt_rdma_slot_table_entries = RPCRDMA_DEF_SLOT_TABLE;
-static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
+unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
 static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
 static unsigned int xprt_rdma_inline_write_padding;
 static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
@@ -143,12 +143,7 @@ static struct ctl_table sunrpc_table[] = {
 
 #endif
 
-#define RPCRDMA_BIND_TO                (60U * HZ)
-#define RPCRDMA_INIT_REEST_TO  (5U * HZ)
-#define RPCRDMA_MAX_REEST_TO   (30U * HZ)
-#define RPCRDMA_IDLE_DISC_TO   (5U * 60 * HZ)
-
-static struct rpc_xprt_ops xprt_rdma_procs;    /* forward reference */
+static struct rpc_xprt_ops xprt_rdma_procs;    /*forward reference */
 
 static void
 xprt_rdma_format_addresses4(struct rpc_xprt *xprt, struct sockaddr *sap)
@@ -174,7 +169,7 @@ xprt_rdma_format_addresses6(struct rpc_xprt *xprt, struct sockaddr *sap)
        xprt->address_strings[RPC_DISPLAY_NETID] = RPCBIND_NETID_RDMA6;
 }
 
-static void
+void
 xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap)
 {
        char buf[128];
@@ -203,7 +198,7 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap)
        xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma";
 }
 
-static void
+void
 xprt_rdma_free_addresses(struct rpc_xprt *xprt)
 {
        unsigned int i;
@@ -499,7 +494,7 @@ xprt_rdma_allocate(struct rpc_task *task, size_t size)
        if (req == NULL)
                return NULL;
 
-       flags = GFP_NOIO | __GFP_NOWARN;
+       flags = RPCRDMA_DEF_GFP;
        if (RPC_IS_SWAPPER(task))
                flags = __GFP_MEMALLOC | GFP_NOWAIT | __GFP_NOWARN;
 
@@ -642,7 +637,7 @@ drop_connection:
        return -ENOTCONN;       /* implies disconnect */
 }
 
-static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
+void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 {
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
        long idle_time = 0;
@@ -743,6 +738,11 @@ void xprt_rdma_cleanup(void)
 
        rpcrdma_destroy_wq();
        frwr_destroy_recovery_wq();
+
+       rc = xprt_unregister_transport(&xprt_rdma_bc);
+       if (rc)
+               dprintk("RPC:       %s: xprt_unregister(bc) returned %i\n",
+                       __func__, rc);
 }
 
 int xprt_rdma_init(void)
@@ -766,6 +766,14 @@ int xprt_rdma_init(void)
                return rc;
        }
 
+       rc = xprt_register_transport(&xprt_rdma_bc);
+       if (rc) {
+               xprt_unregister_transport(&xprt_rdma);
+               rpcrdma_destroy_wq();
+               frwr_destroy_recovery_wq();
+               return rc;
+       }
+
        dprintk("RPCRDMA Module Init, register RPC RDMA transport\n");
 
        dprintk("Defaults:\n");
index 732c71c..878f1bf 100644 (file)
@@ -462,7 +462,6 @@ int
 rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
 {
        struct rpcrdma_ia *ia = &xprt->rx_ia;
-       struct ib_device_attr *devattr = &ia->ri_devattr;
        int rc;
 
        ia->ri_dma_mr = NULL;
@@ -482,16 +481,10 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
                goto out2;
        }
 
-       rc = ib_query_device(ia->ri_device, devattr);
-       if (rc) {
-               dprintk("RPC:       %s: ib_query_device failed %d\n",
-                       __func__, rc);
-               goto out3;
-       }
-
        if (memreg == RPCRDMA_FRMR) {
-               if (!(devattr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) ||
-                   (devattr->max_fast_reg_page_list_len == 0)) {
+               if (!(ia->ri_device->attrs.device_cap_flags &
+                               IB_DEVICE_MEM_MGT_EXTENSIONS) ||
+                   (ia->ri_device->attrs.max_fast_reg_page_list_len == 0)) {
                        dprintk("RPC:       %s: FRMR registration "
                                "not supported by HCA\n", __func__);
                        memreg = RPCRDMA_MTHCAFMR;
@@ -566,24 +559,23 @@ int
 rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
                                struct rpcrdma_create_data_internal *cdata)
 {
-       struct ib_device_attr *devattr = &ia->ri_devattr;
        struct ib_cq *sendcq, *recvcq;
        struct ib_cq_init_attr cq_attr = {};
        unsigned int max_qp_wr;
        int rc, err;
 
-       if (devattr->max_sge < RPCRDMA_MAX_IOVS) {
+       if (ia->ri_device->attrs.max_sge < RPCRDMA_MAX_IOVS) {
                dprintk("RPC:       %s: insufficient sge's available\n",
                        __func__);
                return -ENOMEM;
        }
 
-       if (devattr->max_qp_wr <= RPCRDMA_BACKWARD_WRS) {
+       if (ia->ri_device->attrs.max_qp_wr <= RPCRDMA_BACKWARD_WRS) {
                dprintk("RPC:       %s: insufficient wqe's available\n",
                        __func__);
                return -ENOMEM;
        }
-       max_qp_wr = devattr->max_qp_wr - RPCRDMA_BACKWARD_WRS;
+       max_qp_wr = ia->ri_device->attrs.max_qp_wr - RPCRDMA_BACKWARD_WRS;
 
        /* check provider's send/recv wr limits */
        if (cdata->max_requests > max_qp_wr)
@@ -668,11 +660,11 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
 
        /* Client offers RDMA Read but does not initiate */
        ep->rep_remote_cma.initiator_depth = 0;
-       if (devattr->max_qp_rd_atom > 32)       /* arbitrary but <= 255 */
+       if (ia->ri_device->attrs.max_qp_rd_atom > 32)   /* arbitrary but <= 255 */
                ep->rep_remote_cma.responder_resources = 32;
        else
                ep->rep_remote_cma.responder_resources =
-                                               devattr->max_qp_rd_atom;
+                                               ia->ri_device->attrs.max_qp_rd_atom;
 
        ep->rep_remote_cma.retry_count = 7;
        ep->rep_remote_cma.flow_control = 0;
index 728101d..38fe11b 100644 (file)
 #define RDMA_RESOLVE_TIMEOUT   (5000)  /* 5 seconds */
 #define RDMA_CONNECT_RETRY_MAX (2)     /* retries if no listener backlog */
 
+#define RPCRDMA_BIND_TO                (60U * HZ)
+#define RPCRDMA_INIT_REEST_TO  (5U * HZ)
+#define RPCRDMA_MAX_REEST_TO   (30U * HZ)
+#define RPCRDMA_IDLE_DISC_TO   (5U * 60 * HZ)
+
 /*
  * Interface Adapter -- one per transport instance
  */
@@ -68,7 +73,6 @@ struct rpcrdma_ia {
        struct completion       ri_done;
        int                     ri_async_rc;
        unsigned int            ri_max_frmr_depth;
-       struct ib_device_attr   ri_devattr;
        struct ib_qp_attr       ri_qp_attr;
        struct ib_qp_init_attr  ri_qp_init_attr;
 };
@@ -142,6 +146,8 @@ rdmab_to_msg(struct rpcrdma_regbuf *rb)
        return (struct rpcrdma_msg *)rb->rg_base;
 }
 
+#define RPCRDMA_DEF_GFP                (GFP_NOIO | __GFP_NOWARN)
+
 /*
  * struct rpcrdma_rep -- this structure encapsulates state required to recv
  * and complete a reply, asychronously. It needs several pieces of
@@ -309,6 +315,8 @@ struct rpcrdma_buffer {
        u32                     rb_bc_srv_max_requests;
        spinlock_t              rb_reqslock;    /* protect rb_allreqs */
        struct list_head        rb_allreqs;
+
+       u32                     rb_bc_max_requests;
 };
 #define rdmab_to_ia(b) (&container_of((b), struct rpcrdma_xprt, rx_buf)->rx_ia)
 
@@ -516,6 +524,10 @@ int rpcrdma_marshal_req(struct rpc_rqst *);
 
 /* RPC/RDMA module init - xprtrdma/transport.c
  */
+extern unsigned int xprt_rdma_max_inline_read;
+void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap);
+void xprt_rdma_free_addresses(struct rpc_xprt *xprt);
+void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq);
 int xprt_rdma_init(void);
 void xprt_rdma_cleanup(void);
 
@@ -531,11 +543,6 @@ void xprt_rdma_bc_free_rqst(struct rpc_rqst *);
 void xprt_rdma_bc_destroy(struct rpc_xprt *, unsigned int);
 #endif /* CONFIG_SUNRPC_BACKCHANNEL */
 
-/* Temporary NFS request map cache. Created in svc_rdma.c  */
-extern struct kmem_cache *svc_rdma_map_cachep;
-/* WR context cache. Created in svc_rdma.c  */
-extern struct kmem_cache *svc_rdma_ctxt_cachep;
-/* Workqueue created in svc_rdma.c */
-extern struct workqueue_struct *svc_rdma_wq;
+extern struct xprt_class xprt_rdma_bc;
 
 #endif                         /* _LINUX_SUNRPC_XPRT_RDMA_H */
index 39d6bb1..2edbcad 100644 (file)
@@ -130,6 +130,12 @@ _c_flags += $(if $(patsubst n%,, \
                $(CFLAGS_KASAN))
 endif
 
+ifeq ($(CONFIG_UBSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+               $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \
+               $(CFLAGS_UBSAN))
+endif
+
 # If building the kernel in a separate objtree expand all occurrences
 # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
 
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
new file mode 100644 (file)
index 0000000..8ab6867
--- /dev/null
@@ -0,0 +1,17 @@
+ifdef CONFIG_UBSAN
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=vla-bound)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=null)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=returns-nonnull-attribute)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=bool)
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=enum)
+
+ifdef CONFIG_UBSAN_ALIGNMENT
+      CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment)
+endif
+endif
index c7bf1aa..0147c91 100755 (executable)
@@ -433,6 +433,28 @@ our @typeList = (
        qr{${Ident}_handler_fn},
        @typeListMisordered,
 );
+
+our $C90_int_types = qr{(?x:
+       long\s+long\s+int\s+(?:un)?signed|
+       long\s+long\s+(?:un)?signed\s+int|
+       long\s+long\s+(?:un)?signed|
+       (?:(?:un)?signed\s+)?long\s+long\s+int|
+       (?:(?:un)?signed\s+)?long\s+long|
+       int\s+long\s+long\s+(?:un)?signed|
+       int\s+(?:(?:un)?signed\s+)?long\s+long|
+
+       long\s+int\s+(?:un)?signed|
+       long\s+(?:un)?signed\s+int|
+       long\s+(?:un)?signed|
+       (?:(?:un)?signed\s+)?long\s+int|
+       (?:(?:un)?signed\s+)?long|
+       int\s+long\s+(?:un)?signed|
+       int\s+(?:(?:un)?signed\s+)?long|
+
+       int\s+(?:un)?signed|
+       (?:(?:un)?signed\s+)?int
+)};
+
 our @typeListFile = ();
 our @typeListWithAttr = (
        @typeList,
@@ -4517,7 +4539,7 @@ sub process {
                        #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
 
                        $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
-                       $has_arg_concat = 1 if ($ctx =~ /\#\#/);
+                       $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
 
                        $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
                        $dstat =~ s/$;//g;
@@ -4528,7 +4550,7 @@ sub process {
                        # Flatten any parentheses and braces
                        while ($dstat =~ s/\([^\(\)]*\)/1/ ||
                               $dstat =~ s/\{[^\{\}]*\}/1/ ||
-                              $dstat =~ s/\[[^\[\]]*\]/1/)
+                              $dstat =~ s/.\[[^\[\]]*\]/1/)
                        {
                        }
 
@@ -4548,7 +4570,8 @@ sub process {
                                union|
                                struct|
                                \.$Ident\s*=\s*|
-                               ^\"|\"$
+                               ^\"|\"$|
+                               ^\[
                        }x;
                        #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
                        if ($dstat ne '' &&
@@ -5272,6 +5295,26 @@ sub process {
                        }
                }
 
+# check for cast of C90 native int or longer types constants
+               if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
+                       my $cast = $1;
+                       my $const = $2;
+                       if (WARN("TYPECAST_INT_CONSTANT",
+                                "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
+                           $fix) {
+                               my $suffix = "";
+                               my $newconst = $const;
+                               $newconst =~ s/${Int_type}$//;
+                               $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
+                               if ($cast =~ /\blong\s+long\b/) {
+                                       $suffix .= 'LL';
+                               } elsif ($cast =~ /\blong\b/) {
+                                       $suffix .= 'L';
+                               }
+                               $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
+                       }
+               }
+
 # check for sizeof(&)
                if ($line =~ /\bsizeof\s*\(\s*\&/) {
                        WARN("SIZEOF_ADDRESS",
index cab641a..1873421 100755 (executable)
@@ -16,7 +16,9 @@ my $P = $0;
 my $V = '0.26';
 
 use Getopt::Long qw(:config no_auto_abbrev);
+use Cwd;
 
+my $cur_path = fastgetcwd() . '/';
 my $lk_path = "./";
 my $email = 1;
 my $email_usename = 1;
@@ -429,6 +431,8 @@ foreach my $file (@ARGV) {
        }
     }
     if ($from_filename) {
+       $file =~ s/^\Q${cur_path}\E//;  #strip any absolute path
+       $file =~ s/^\Q${lk_path}\E//;   #or the path to the lk tree
        push(@files, $file);
        if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
            open(my $f, '<', $file)
index 1832cf7..48071ed 100644 (file)
@@ -137,12 +137,17 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
 {
        int ret = 0;
        const struct cred *cred, *child_cred;
+       const kernel_cap_t *caller_caps;
 
        rcu_read_lock();
        cred = current_cred();
        child_cred = __task_cred(child);
+       if (mode & PTRACE_MODE_FSCREDS)
+               caller_caps = &cred->cap_effective;
+       else
+               caller_caps = &cred->cap_permitted;
        if (cred->user_ns == child_cred->user_ns &&
-           cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
+           cap_issubset(child_cred->cap_permitted, *caller_caps))
                goto out;
        if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
                goto out;
index 16622ae..28414b0 100644 (file)
@@ -99,7 +99,7 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode,
 
        dir = d_inode(parent);
 
-       mutex_lock(&dir->i_mutex);
+       inode_lock(dir);
        dentry = lookup_one_len(name, parent, strlen(name));
        if (IS_ERR(dentry))
                goto out;
@@ -129,14 +129,14 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode,
        }
        d_instantiate(dentry, inode);
        dget(dentry);
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        return dentry;
 
 out1:
        dput(dentry);
        dentry = ERR_PTR(error);
 out:
-       mutex_unlock(&dir->i_mutex);
+       inode_unlock(dir);
        simple_release_fs(&mount, &mount_count);
        return dentry;
 }
@@ -195,7 +195,7 @@ void securityfs_remove(struct dentry *dentry)
        if (!parent || d_really_is_negative(parent))
                return;
 
-       mutex_lock(&d_inode(parent)->i_mutex);
+       inode_lock(d_inode(parent));
        if (simple_positive(dentry)) {
                if (d_is_dir(dentry))
                        simple_rmdir(d_inode(parent), dentry);
@@ -203,7 +203,7 @@ void securityfs_remove(struct dentry *dentry)
                        simple_unlink(d_inode(parent), dentry);
                dput(dentry);
        }
-       mutex_unlock(&d_inode(parent)->i_mutex);
+       inode_unlock(d_inode(parent));
        simple_release_fs(&mount, &mount_count);
 }
 EXPORT_SYMBOL_GPL(securityfs_remove);
index c21f09b..9d96551 100644 (file)
@@ -121,7 +121,7 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
        if (!(mode & FMODE_WRITE))
                return;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        if (atomic_read(&inode->i_writecount) == 1) {
                if ((iint->version != inode->i_version) ||
                    (iint->flags & IMA_NEW_FILE)) {
@@ -130,7 +130,7 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
                                ima_update_xattr(iint, file);
                }
        }
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 }
 
 /**
@@ -186,7 +186,7 @@ static int process_measurement(struct file *file, int mask, int function,
        if (action & IMA_FILE_APPRAISE)
                function = FILE_CHECK;
 
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
 
        if (action) {
                iint = integrity_inode_get(inode);
@@ -250,7 +250,7 @@ out_free:
        if (pathbuf)
                __putname(pathbuf);
 out:
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
        if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
                return -EACCES;
        return 0;
index 732c1c7..1b1fd27 100644 (file)
@@ -380,9 +380,9 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
                goto err;
 
        if (i_size_read(inode) != security_policydb_len()) {
-               mutex_lock(&inode->i_mutex);
+               inode_lock(inode);
                i_size_write(inode, security_policydb_len());
-               mutex_unlock(&inode->i_mutex);
+               inode_unlock(inode);
        }
 
        rc = security_read_policy(&plm->data, &plm->len);
index 8d85435..2d6e9bd 100644 (file)
@@ -398,12 +398,10 @@ static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
  */
 static inline unsigned int smk_ptrace_mode(unsigned int mode)
 {
-       switch (mode) {
-       case PTRACE_MODE_READ:
-               return MAY_READ;
-       case PTRACE_MODE_ATTACH:
+       if (mode & PTRACE_MODE_ATTACH)
                return MAY_READWRITE;
-       }
+       if (mode & PTRACE_MODE_READ)
+               return MAY_READ;
 
        return 0;
 }
index d3c19c9..cb6ed10 100644 (file)
@@ -281,7 +281,7 @@ static int yama_ptrace_access_check(struct task_struct *child,
        int rc = 0;
 
        /* require ptrace target be a child of ptracer on attach */
-       if (mode == PTRACE_MODE_ATTACH) {
+       if (mode & PTRACE_MODE_ATTACH) {
                switch (ptrace_scope) {
                case YAMA_SCOPE_DISABLED:
                        /* No additional restrictions. */
@@ -307,7 +307,7 @@ static int yama_ptrace_access_check(struct task_struct *child,
                }
        }
 
-       if (rc) {
+       if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0) {
                printk_ratelimited(KERN_NOTICE
                        "ptrace of pid %d was attempted by: %s (pid %d)\n",
                        child->pid, current->comm, current->pid);
index 196a6fe..a85d455 100644 (file)
@@ -1405,6 +1405,8 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
                return -EFAULT;
        if (tlv.length < sizeof(unsigned int) * 2)
                return -EINVAL;
+       if (!tlv.numid)
+               return -EINVAL;
        down_read(&card->controls_rwsem);
        kctl = snd_ctl_find_numid(card, tlv.numid);
        if (kctl == NULL) {
index f845ecf..656d9a9 100644 (file)
@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_timer *t)
        struct snd_hrtimer *stime = t->private_data;
 
        atomic_set(&stime->running, 0);
-       hrtimer_cancel(&stime->hrt);
+       hrtimer_try_to_cancel(&stime->hrt);
        hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
                      HRTIMER_MODE_REL);
        atomic_set(&stime->running, 1);
@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
 {
        struct snd_hrtimer *stime = t->private_data;
        atomic_set(&stime->running, 0);
+       hrtimer_try_to_cancel(&stime->hrt);
        return 0;
 }
 
index b48b434..9630e9f 100644 (file)
@@ -255,10 +255,15 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
        if (! (runtime = substream->runtime))
                return -ENOTTY;
 
-       /* only fifo_size is different, so just copy all */
-       data = memdup_user(data32, sizeof(*data32));
-       if (IS_ERR(data))
-               return PTR_ERR(data);
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       /* only fifo_size (RO from userspace) is different, so just copy all */
+       if (copy_from_user(data, data32, sizeof(*data32))) {
+               err = -EFAULT;
+               goto error;
+       }
 
        if (refine)
                err = snd_pcm_hw_refine(substream, data);
index 81f7c10..6517590 100644 (file)
@@ -49,11 +49,12 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
        struct snd_seq_port_info *data;
        mm_segment_t fs;
 
-       data = memdup_user(data32, sizeof(*data32));
-       if (IS_ERR(data))
-               return PTR_ERR(data);
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
-       if (get_user(data->flags, &data32->flags) ||
+       if (copy_from_user(data, data32, sizeof(*data32)) ||
+           get_user(data->flags, &data32->flags) ||
            get_user(data->time_queue, &data32->time_queue))
                goto error;
        data->kernel = NULL;
index cb25ade..af1f68f 100644 (file)
@@ -65,6 +65,7 @@ struct snd_timer_user {
        int qtail;
        int qused;
        int queue_size;
+       bool disconnected;
        struct snd_timer_read *queue;
        struct snd_timer_tread *tqueue;
        spinlock_t qlock;
@@ -290,6 +291,9 @@ int snd_timer_open(struct snd_timer_instance **ti,
                mutex_unlock(&register_mutex);
                return -ENOMEM;
        }
+       /* take a card refcount for safe disconnection */
+       if (timer->card)
+               get_device(&timer->card->card_dev);
        timeri->slave_class = tid->dev_sclass;
        timeri->slave_id = slave_id;
        if (list_empty(&timer->open_list_head) && timer->hw.open)
@@ -359,6 +363,9 @@ int snd_timer_close(struct snd_timer_instance *timeri)
                }
                spin_unlock(&timer->lock);
                spin_unlock_irq(&slave_active_lock);
+               /* release a card refcount for safe disconnection */
+               if (timer->card)
+                       put_device(&timer->card->card_dev);
                mutex_unlock(&register_mutex);
        }
  out:
@@ -474,6 +481,8 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
        timer = timeri->timer;
        if (timer == NULL)
                return -EINVAL;
+       if (timer->card && timer->card->shutdown)
+               return -ENODEV;
        spin_lock_irqsave(&timer->lock, flags);
        timeri->ticks = timeri->cticks = ticks;
        timeri->pticks = 0;
@@ -505,6 +514,10 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
        spin_lock_irqsave(&timer->lock, flags);
        list_del_init(&timeri->ack_list);
        list_del_init(&timeri->active_list);
+       if (timer->card && timer->card->shutdown) {
+               spin_unlock_irqrestore(&timer->lock, flags);
+               return 0;
+       }
        if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
            !(--timer->running)) {
                timer->hw.stop(timer);
@@ -565,6 +578,8 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
        timer = timeri->timer;
        if (! timer)
                return -EINVAL;
+       if (timer->card && timer->card->shutdown)
+               return -ENODEV;
        spin_lock_irqsave(&timer->lock, flags);
        if (!timeri->cticks)
                timeri->cticks = 1;
@@ -628,6 +643,9 @@ static void snd_timer_tasklet(unsigned long arg)
        unsigned long resolution, ticks;
        unsigned long flags;
 
+       if (timer->card && timer->card->shutdown)
+               return;
+
        spin_lock_irqsave(&timer->lock, flags);
        /* now process all callbacks */
        while (!list_empty(&timer->sack_list_head)) {
@@ -668,6 +686,9 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
        if (timer == NULL)
                return;
 
+       if (timer->card && timer->card->shutdown)
+               return;
+
        spin_lock_irqsave(&timer->lock, flags);
 
        /* remember the current resolution */
@@ -881,8 +902,15 @@ static int snd_timer_dev_register(struct snd_device *dev)
 static int snd_timer_dev_disconnect(struct snd_device *device)
 {
        struct snd_timer *timer = device->device_data;
+       struct snd_timer_instance *ti;
+
        mutex_lock(&register_mutex);
        list_del_init(&timer->device_list);
+       /* wake up pending sleepers */
+       list_for_each_entry(ti, &timer->open_list_head, open_list) {
+               if (ti->disconnect)
+                       ti->disconnect(ti);
+       }
        mutex_unlock(&register_mutex);
        return 0;
 }
@@ -893,6 +921,8 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
        unsigned long resolution = 0;
        struct snd_timer_instance *ti, *ts;
 
+       if (timer->card && timer->card->shutdown)
+               return;
        if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
                return;
        if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
@@ -1051,6 +1081,8 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
 
        mutex_lock(&register_mutex);
        list_for_each_entry(timer, &snd_timer_list, device_list) {
+               if (timer->card && timer->card->shutdown)
+                       continue;
                switch (timer->tmr_class) {
                case SNDRV_TIMER_CLASS_GLOBAL:
                        snd_iprintf(buffer, "G%i: ", timer->tmr_device);
@@ -1185,6 +1217,14 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
        wake_up(&tu->qchange_sleep);
 }
 
+static void snd_timer_user_disconnect(struct snd_timer_instance *timeri)
+{
+       struct snd_timer_user *tu = timeri->callback_data;
+
+       tu->disconnected = true;
+       wake_up(&tu->qchange_sleep);
+}
+
 static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
                                      unsigned long resolution,
                                      unsigned long ticks)
@@ -1558,6 +1598,7 @@ static int snd_timer_user_tselect(struct file *file,
                        ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
                tu->timeri->ccallback = snd_timer_user_ccallback;
                tu->timeri->callback_data = (void *)tu;
+               tu->timeri->disconnect = snd_timer_user_disconnect;
        }
 
       __err:
@@ -1876,6 +1917,10 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
 
                        remove_wait_queue(&tu->qchange_sleep, &wait);
 
+                       if (tu->disconnected) {
+                               err = -ENODEV;
+                               break;
+                       }
                        if (signal_pending(current)) {
                                err = -ERESTARTSYS;
                                break;
@@ -1925,6 +1970,8 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
        mask = 0;
        if (tu->qused)
                mask |= POLLIN | POLLRDNORM;
+       if (tu->disconnected)
+               mask |= POLLERR;
 
        return mask;
 }
index c50177f..f6854db 100644 (file)
@@ -306,7 +306,7 @@ out_master_del:
 out_err:
        kfree(acomp);
        bus->audio_component = NULL;
-       dev_err(dev, "failed to add i915 component master (%d)\n", ret);
+       dev_info(dev, "failed to add i915 component master (%d)\n", ret);
 
        return ret;
 }
index 70671ad..6efadbf 100644 (file)
@@ -174,14 +174,40 @@ static inline bool codec_probed(struct hda_codec *codec)
        return device_attach(hda_codec_dev(codec)) > 0 && codec->preset;
 }
 
-/* try to auto-load and bind the codec module */
-static void codec_bind_module(struct hda_codec *codec)
+/* try to auto-load codec module */
+static void request_codec_module(struct hda_codec *codec)
 {
 #ifdef MODULE
        char modalias[32];
+       const char *mod = NULL;
+
+       switch (codec->probe_id) {
+       case HDA_CODEC_ID_GENERIC_HDMI:
+#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
+               mod = "snd-hda-codec-hdmi";
+#endif
+               break;
+       case HDA_CODEC_ID_GENERIC:
+#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
+               mod = "snd-hda-codec-generic";
+#endif
+               break;
+       default:
+               snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
+               mod = modalias;
+               break;
+       }
+
+       if (mod)
+               request_module(mod);
+#endif /* MODULE */
+}
 
-       snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
-       request_module(modalias);
+/* try to auto-load and bind the codec module */
+static void codec_bind_module(struct hda_codec *codec)
+{
+#ifdef MODULE
+       request_codec_module(codec);
        if (codec_probed(codec))
                return;
 #endif
@@ -218,17 +244,13 @@ static int codec_bind_generic(struct hda_codec *codec)
 
        if (is_likely_hdmi_codec(codec)) {
                codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI;
-#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
-               request_module("snd-hda-codec-hdmi");
-#endif
+               request_codec_module(codec);
                if (codec_probed(codec))
                        return 0;
        }
 
        codec->probe_id = HDA_CODEC_ID_GENERIC;
-#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
-       request_module("snd-hda-codec-generic");
-#endif
+       request_codec_module(codec);
        if (codec_probed(codec))
                return 0;
        return -ENODEV;
index c0bef11..256e6cd 100644 (file)
@@ -2078,9 +2078,11 @@ static int azx_probe_continue(struct azx *chip)
                         * for other chips, still continue probing as other
                         * codecs can be on the same link.
                         */
-                       if (CONTROLLER_IN_GPU(pci))
+                       if (CONTROLLER_IN_GPU(pci)) {
+                               dev_err(chip->card->dev,
+                                       "HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");
                                goto out_free;
-                       else
+                       else
                                goto skip_i915;
                }
 
@@ -2149,9 +2151,17 @@ i915_power_fail:
 static void azx_remove(struct pci_dev *pci)
 {
        struct snd_card *card = pci_get_drvdata(pci);
+       struct azx *chip;
+       struct hda_intel *hda;
+
+       if (card) {
+               /* flush the pending probing work */
+               chip = card->private_data;
+               hda = container_of(chip, struct hda_intel, chip);
+               flush_work(&hda->probe_work);
 
-       if (card)
                snd_card_free(card);
+       }
 }
 
 static void azx_shutdown(struct pci_dev *pci)
index 8143c0e..3375324 100644 (file)
@@ -6566,6 +6566,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
        SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
+       SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
        SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
        SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
        SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
index a0fe37f..425ee2b 100644 (file)
  *
  */
 
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/jack.h>
 
-#include <mach/gpio-samsung.h>
-#include <asm/mach-types.h>
-
 #include "i2s.h"
 #include "../codecs/wm8750.h"
 
@@ -96,7 +93,7 @@ static struct snd_soc_jack_pin smartq_jack_pins[] = {
 
 static struct snd_soc_jack_gpio smartq_jack_gpios[] = {
        {
-               .gpio           = S3C64XX_GPL(12),
+               .gpio           = -1,
                .name           = "headphone detect",
                .report         = SND_JACK_HEADPHONE,
                .debounce_time  = 200,
@@ -113,7 +110,9 @@ static int smartq_speaker_event(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *k,
                                int event)
 {
-       gpio_set_value(S3C64XX_GPK(12), SND_SOC_DAPM_EVENT_OFF(event));
+       struct gpio_desc *gpio = snd_soc_card_get_drvdata(&snd_soc_smartq);
+
+       gpiod_set_value(gpio, SND_SOC_DAPM_EVENT_OFF(event));
 
        return 0;
 }
@@ -199,62 +198,39 @@ static struct snd_soc_card snd_soc_smartq = {
        .num_controls = ARRAY_SIZE(wm8987_smartq_controls),
 };
 
-static struct platform_device *smartq_snd_device;
-
-static int __init smartq_init(void)
+static int smartq_probe(struct platform_device *pdev)
 {
+       struct gpio_desc *gpio;
        int ret;
 
-       if (!machine_is_smartq7() && !machine_is_smartq5()) {
-               pr_info("Only SmartQ is supported by this ASoC driver\n");
-               return -ENODEV;
-       }
-
-       smartq_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!smartq_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(smartq_snd_device, &snd_soc_smartq);
-
-       ret = platform_device_add(smartq_snd_device);
-       if (ret) {
-               platform_device_put(smartq_snd_device);
-               return ret;
-       }
+       platform_set_drvdata(pdev, &snd_soc_smartq);
 
        /* Initialise GPIOs used by amplifiers */
-       ret = gpio_request(S3C64XX_GPK(12), "amplifiers shutdown");
-       if (ret) {
-               dev_err(&smartq_snd_device->dev, "Failed to register GPK12\n");
-               goto err_unregister_device;
+       gpio = devm_gpiod_get(&pdev->dev, "amplifiers shutdown",
+                             GPIOD_OUT_HIGH);
+       if (IS_ERR(gpio)) {
+               dev_err(&pdev->dev, "Failed to register GPK12\n");
+               ret = PTR_ERR(gpio);
+               goto out;
        }
+       snd_soc_card_set_drvdata(&snd_soc_smartq, gpio);
 
-       /* Disable amplifiers */
-       ret = gpio_direction_output(S3C64XX_GPK(12), 1);
-       if (ret) {
-               dev_err(&smartq_snd_device->dev, "Failed to configure GPK12\n");
-               goto err_free_gpio_amp_shut;
-       }
-
-       return 0;
-
-err_free_gpio_amp_shut:
-       gpio_free(S3C64XX_GPK(12));
-err_unregister_device:
-       platform_device_unregister(smartq_snd_device);
+       ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_smartq);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to register card\n");
 
+out:
        return ret;
 }
 
-static void __exit smartq_exit(void)
-{
-       gpio_free(S3C64XX_GPK(12));
-
-       platform_device_unregister(smartq_snd_device);
-}
+static struct platform_driver smartq_driver = {
+       .driver = {
+               .name = "smartq-audio",
+       },
+       .probe = smartq_probe,
+};
 
-module_init(smartq_init);
-module_exit(smartq_exit);
+module_platform_driver(smartq_driver);
 
 /* Module information */
 MODULE_AUTHOR("Maurus Cuelenaere <mcuelenaere@gmail.com>");
index 3952236..fac7e6e 100644 (file)
@@ -221,6 +221,8 @@ static int snd_at73c213_pcm_open(struct snd_pcm_substream *substream)
        runtime->hw = snd_at73c213_playback_hw;
        chip->substream = substream;
 
+       clk_enable(chip->ssc->clk);
+
        return 0;
 }
 
@@ -228,6 +230,7 @@ static int snd_at73c213_pcm_close(struct snd_pcm_substream *substream)
 {
        struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
        chip->substream = NULL;
+       clk_disable(chip->ssc->clk);
        return 0;
 }
 
@@ -897,6 +900,8 @@ static int snd_at73c213_dev_init(struct snd_card *card,
        chip->card = card;
        chip->irq = -1;
 
+       clk_enable(chip->ssc->clk);
+
        retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip);
        if (retval) {
                dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq);
@@ -935,6 +940,8 @@ out_irq:
        free_irq(chip->irq, chip);
        chip->irq = -1;
 out:
+       clk_disable(chip->ssc->clk);
+
        return retval;
 }
 
@@ -1012,7 +1019,9 @@ static int snd_at73c213_remove(struct spi_device *spi)
        int retval;
 
        /* Stop playback. */
+       clk_enable(chip->ssc->clk);
        ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
+       clk_disable(chip->ssc->clk);
 
        /* Mute sound. */
        retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
@@ -1080,6 +1089,7 @@ static int snd_at73c213_suspend(struct device *dev)
        struct snd_at73c213 *chip = card->private_data;
 
        ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
+       clk_disable(chip->ssc->clk);
        clk_disable(chip->board->dac_clk);
 
        return 0;
@@ -1091,6 +1101,7 @@ static int snd_at73c213_resume(struct device *dev)
        struct snd_at73c213 *chip = card->private_data;
 
        clk_enable(chip->board->dac_clk);
+       clk_enable(chip->ssc->clk);
        ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
 
        return 0;
index ea69ce3..c3bd294 100644 (file)
@@ -3746,7 +3746,7 @@ static const struct flag flags[] = {
        { "NET_TX_SOFTIRQ", 2 },
        { "NET_RX_SOFTIRQ", 3 },
        { "BLOCK_SOFTIRQ", 4 },
-       { "BLOCK_IOPOLL_SOFTIRQ", 5 },
+       { "IRQ_POLL_SOFTIRQ", 5 },
        { "TASKLET_SOFTIRQ", 6 },
        { "SCHED_SOFTIRQ", 7 },
        { "HRTIMER_SOFTIRQ", 8 },
index 8ff7d62..33b52ea 100644 (file)
@@ -209,7 +209,7 @@ static const struct flag flags[] = {
        { "NET_TX_SOFTIRQ", 2 },
        { "NET_RX_SOFTIRQ", 3 },
        { "BLOCK_SOFTIRQ", 4 },
-       { "BLOCK_IOPOLL_SOFTIRQ", 5 },
+       { "IRQ_POLL_SOFTIRQ", 5 },
        { "TASKLET_SOFTIRQ", 6 },
        { "SCHED_SOFTIRQ", 7 },
        { "HRTIMER_SOFTIRQ", 8 },
index eec6880..e73a79f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index efefe30..0bd343f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6df7583..11f4aba 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index dd5008b..d0e6b85 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e153fcb..66c4bad 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 44ad488..3818fd0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6858c08..08cb8b2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index eed5344..025c232 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 61d0de8..da44458 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bbdf9e8..5fcd970 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 57620f6..c3c0915 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2015, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 8f3f5bb..590d12a 100644 (file)
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 
 #include <getopt.h>